import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
import type { Api, ImageContent, Model, TextContent } from "@earendil-works/pi-ai/compat";
import type { KeyId } from "@earendil-works/pi-tui";
import type { TSchema } from "typebox";
import type { EventBus } from "../event-bus.ts";
import type { ExecOptions, ExecResult } from "../exec.ts";
import type { CustomMessage } from "../messages.ts";
import type { ResolvedResource } from "../package-manager.ts";
import type { DefaultResourceLoaderInheritanceSnapshot } from "../resource-loader.ts";
import type { SlashCommandInfo } from "../slash-commands.ts";
import type { AfterProviderResponseEvent, AgentEndEvent, AgentStartEvent, BeforeAgentStartEvent, BeforeProviderRequestEvent, ContextEvent, InputEvent, InputEventResult, MessageEndEvent, MessageStartEvent, MessageUpdateEvent, ModelSelectEvent, ProjectTrustHandler, ThinkingLevelSelectEvent, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent, TurnEndEvent, TurnStartEvent, UserBashEvent } from "./agent-events.ts";
import type { RegisteredCommand } from "./command-types.ts";
import type { ExtensionContext } from "./context-types.ts";
import type { BeforeAgentStartEventResult, BeforeProviderRequestEventResult, ContextEventResult, MessageEndEventResult, SessionBeforeCompactResult, SessionBeforeForkResult, SessionBeforeSwitchResult, SessionBeforeTreeResult, ToolCallEventResult, ToolResultEventResult, UserBashEventResult } from "./event-results.ts";
import type { MessageRenderer, SendMessageOptions } from "./message-types.ts";
import type { ProviderConfig } from "./provider-types.ts";
import type { ResourcesDiscoverEvent, ResourcesDiscoverResult, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionInfoChangedEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent } from "./session-events.ts";
import type { ToolDefinition, ToolInfo } from "./tool-types.ts";
import type { ToolCallEvent, ToolResultEvent } from "./tool-events.ts";
/** Handler function type for events */
export type ExtensionHandler<E, R = undefined> = (event: E, ctx: ExtensionContext) => Promise<R | void> | R | void;
/**
 * ExtensionAPI passed to extension factory functions.
 */
export interface ExtensionAPI {
    on(event: "resources_discover", handler: ExtensionHandler<ResourcesDiscoverEvent, ResourcesDiscoverResult>): void;
    on(event: "session_info_changed", handler: ExtensionHandler<SessionInfoChangedEvent>): void;
    on(event: "session_start", handler: ExtensionHandler<SessionStartEvent>): void;
    on(event: "session_before_switch", handler: ExtensionHandler<SessionBeforeSwitchEvent, SessionBeforeSwitchResult>): void;
    on(event: "session_before_fork", handler: ExtensionHandler<SessionBeforeForkEvent, SessionBeforeForkResult>): void;
    on(event: "session_before_compact", handler: ExtensionHandler<SessionBeforeCompactEvent, SessionBeforeCompactResult>): void;
    on(event: "session_compact", handler: ExtensionHandler<SessionCompactEvent>): void;
    on(event: "session_shutdown", handler: ExtensionHandler<SessionShutdownEvent>): void;
    on(event: "session_before_tree", handler: ExtensionHandler<SessionBeforeTreeEvent, SessionBeforeTreeResult>): void;
    on(event: "session_tree", handler: ExtensionHandler<SessionTreeEvent>): void;
    on(event: "context", handler: ExtensionHandler<ContextEvent, ContextEventResult>): void;
    on(event: "before_provider_request", handler: ExtensionHandler<BeforeProviderRequestEvent, BeforeProviderRequestEventResult>): void;
    on(event: "after_provider_response", handler: ExtensionHandler<AfterProviderResponseEvent>): void;
    on(event: "before_agent_start", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;
    on(event: "agent_start", handler: ExtensionHandler<AgentStartEvent>): void;
    on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
    on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
    on(event: "turn_end", handler: ExtensionHandler<TurnEndEvent>): void;
    on(event: "message_start", handler: ExtensionHandler<MessageStartEvent>): void;
    on(event: "message_update", handler: ExtensionHandler<MessageUpdateEvent>): void;
    on(event: "message_end", handler: ExtensionHandler<MessageEndEvent, MessageEndEventResult>): void;
    on(event: "tool_execution_start", handler: ExtensionHandler<ToolExecutionStartEvent>): void;
    on(event: "tool_execution_update", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;
    on(event: "tool_execution_end", handler: ExtensionHandler<ToolExecutionEndEvent>): void;
    on(event: "model_select", handler: ExtensionHandler<ModelSelectEvent>): void;
    on(event: "thinking_level_select", handler: ExtensionHandler<ThinkingLevelSelectEvent>): void;
    on(event: "tool_call", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;
    on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
    on(event: "user_bash", handler: ExtensionHandler<UserBashEvent, UserBashEventResult>): void;
    on(event: "project_trust", handler: ProjectTrustHandler): void;
    on(event: "input", handler: ExtensionHandler<InputEvent, InputEventResult>): void;
    /** Register a tool that the LLM can call. */
    registerTool<TParams extends TSchema = TSchema, TDetails = unknown, TState = unknown>(tool: ToolDefinition<TParams, TDetails, TState>): void;
    /** Register a custom command. */
    registerCommand(name: string, options: Omit<RegisteredCommand, "name" | "sourceInfo">): void;
    /** Register a keyboard shortcut. */
    registerShortcut(shortcut: KeyId, options: {
        description?: string;
        handler: (ctx: ExtensionContext) => Promise<void> | void;
    }): void;
    /** Register a CLI flag. */
    registerFlag(name: string, options: {
        description?: string;
        type: "boolean" | "string";
        default?: boolean | string;
    }): void;
    /** Get the value of a registered CLI flag. */
    getFlag(name: string): boolean | string | undefined;
    /** Return package-provided workflow files discovered for this session. */
    getWorkflowResources(): ResolvedResource[];
    /**
     * Re-read package/settings workflow resources and return the updated snapshot when supported by the host.
     * Does not reload extensions, skills, prompts, themes, or context files.
     */
    refreshWorkflowResources?: () => Promise<ResolvedResource[]>;
    /**
     * Return the resource-loader options that child Atomic sessions should inherit without sharing this loader instance.
     */
    getResourceLoaderInheritanceSnapshot?: () => DefaultResourceLoaderInheritanceSnapshot;
    /** Register a custom renderer for CustomMessageEntry. */
    registerMessageRenderer<T = unknown>(customType: string, renderer: MessageRenderer<T>): void;
    /** Send a custom message to the session. */
    sendMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details">, options?: SendMessageOptions): void;
    /**
     * Send a user message to the agent. Always triggers a turn.
     * When the agent is streaming, use deliverAs to specify how to queue the message.
     */
    sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
        deliverAs?: "steer" | "followUp";
    }): void;
    /** Append a custom entry to the session for state persistence (not sent to LLM). */
    appendEntry<T = unknown>(customType: string, data?: T): void;
    /** Set the session display name (shown in session selector). */
    setSessionName(name: string): void;
    /** Get the current session name, if set. */
    getSessionName(): string | undefined;
    /** Set or clear a label on an entry. Labels are user-defined markers for bookmarking/navigation. */
    setLabel(entryId: string, label: string | undefined): void;
    /** Execute a shell command. */
    exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
    /** Get the list of currently active tool names. */
    getActiveTools(): string[];
    /** Get all configured tools with parameter schema and source metadata. */
    getAllTools(): ToolInfo[];
    /** Set the active tools by name. */
    setActiveTools(toolNames: string[]): void;
    /** Get available slash commands in the current session. */
    getCommands(): SlashCommandInfo[];
    /** Set the current model. Returns false if no API key available. */
    setModel(model: Model<Api>): Promise<boolean>;
    /** Get current thinking level. */
    getThinkingLevel(): ThinkingLevel;
    /** Set thinking level (clamped to model capabilities). */
    setThinkingLevel(level: ThinkingLevel): void;
    /**
     * Register or override a model provider.
     *
     * If `models` is provided: replaces all existing models for this provider.
     * If only `baseUrl` is provided: overrides the URL for existing models.
     * If `oauth` is provided: registers OAuth provider for /login support.
     * If `streamSimple` is provided: registers a custom API stream handler.
     *
     * During initial extension load this call is queued and applied once the
     * runner has bound its context. After that it takes effect immediately, so
     * it is safe to call from command handlers or event callbacks without
     * requiring a `/reload`.
     *
     * @example
     * // Register a new provider with custom models
     * pi.registerProvider("my-proxy", {
     *   baseUrl: "https://proxy.example.com",
     *   apiKey: "$PROXY_API_KEY",
     *   api: "anthropic-messages",
     *   models: [
     *     {
     *       id: "claude-sonnet-4-20250514",
     *       name: "Claude 4 Sonnet (proxy)",
     *       reasoning: false,
     *       input: ["text", "image"],
     *       cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
     *       contextWindow: 200000,
     *       maxTokens: 16384
     *     }
     *   ]
     * });
     *
     * @example
     * // Override baseUrl for an existing provider
     * pi.registerProvider("anthropic", {
     *   baseUrl: "https://proxy.example.com"
     * });
     *
     * @example
     * // Register provider with OAuth support
     * pi.registerProvider("corporate-ai", {
     *   baseUrl: "https://ai.corp.com",
     *   api: "openai-responses",
     *   models: [...],
     *   oauth: {
     *     name: "Corporate AI (SSO)",
     *     async login(callbacks) { ... },
     *     async refreshToken(credentials) { ... },
     *     getApiKey(credentials) { return credentials.access; }
     *   }
     * });
     */
    registerProvider(name: string, config: ProviderConfig): void;
    /**
     * Unregister a previously registered provider.
     *
     * Removes all models belonging to the named provider and restores any
     * built-in models that were overridden by it. Has no effect if the provider
     * is not currently registered.
     *
     * Like `registerProvider`, this takes effect immediately when called after
     * the initial load phase.
     *
     * @example
     * pi.unregisterProvider("my-proxy");
     */
    unregisterProvider(name: string): void;
    /** Shared event bus for extension communication. */
    events: EventBus;
}
//# sourceMappingURL=api-types.d.ts.map