import type { Agent, AgentEvent, AgentLoopFramework, AgentLoopFrameworkInput, AgentLoopPolicyOptions, AgentMessage, AgentState, AgentTool, ThinkingLevel } from "@catui/agent-core"; import type { AssistantMessage, DocumentContent, ImageContent, Model, TextContent } from "@catui/ai/types"; import type { Theme as ThemeContract } from "../theme-contract.js"; import type { BashResult } from "../platform/exec/bash-executor.js"; import { type CompactionResult } from "../session/compaction/index.js"; import { type ContextUsage, type ExtensionCommandContextActions, type ExtensionErrorListener, ExtensionRunner, type ExtensionUIContext, type InputSource, type ShutdownHandler, type ToolDefinition, type ToolInfo } from "../extensions-host/index.js"; import type { CustomMessage } from "../messages.js"; import type { ModelRegistry } from "../model-registry.js"; import { type PromptTemplate } from "../prompt/prompt-templates.js"; import type { ResourceLoader } from "../platform/config/resource-loader.js"; import { SessionManager, type BranchSummaryEntry, type SessionInfo, type SessionListProgress } from "../session/session-manager.js"; import type { SettingsManager } from "../platform/config/settings-manager.js"; import { AgentDirContext } from "../agent-dir/agent-dir-context.js"; import type { BashOperations } from "../tools/bash.js"; import { type ModelCycleResult } from "./model-controller.js"; import { type SessionSlashCommandDescriptor } from "./slash-command-catalog.js"; import { type CreateSessionFn } from "../sub-agent/index.js"; export type { SessionSlashCommandDescriptor } from "./slash-command-catalog.js"; export { CycleModelError } from "./model-controller.js"; export type { ModelCycleResult } from "./model-controller.js"; /** Parsed skill block from a user message */ export interface ParsedSkillBlock { name: string; location: string; content: string; userMessage: string | undefined; } /** * Parse a skill block from message text. * Returns null if the text doesn't contain a skill block. */ export declare function parseSkillBlock(text: string): ParsedSkillBlock | null; export declare function pruneRecoverableErrorTail(messages: AgentMessage[], assistantMessage: AssistantMessage): AgentMessage[]; /** Session-specific events that extend the core AgentEvent */ export type AgentSessionEvent = AgentEvent | { type: "auto_compaction_start"; reason: "threshold" | "overflow"; } | { type: "auto_compaction_end"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string; } | { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string; } | { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string; } | { type: "sdk:error"; source: "soul" | "mcp" | "eventbus"; error: unknown; } | { type: "sdk:mcp_ready"; toolCount: number; /** Full list of active tool names at the time of emission. */ tools: string[]; /** Current model ID, if any. */ model?: string; /** Names of MCP-powered tools (subset of tools[]). */ mcpTools: string[]; } | { type: "sub_agent_start"; subAgentId: string; agentType: string; description: string; isAsync: boolean; parentToolCallId?: string; } | { type: "sub_agent_tool_start"; subAgentId: string; toolName: string; input?: unknown; parentToolCallId?: string; } | { type: "sub_agent_tool_end"; subAgentId: string; toolName: string; isError: boolean; output?: unknown; durationMs?: number; parentToolCallId?: string; } | { type: "sub_agent_end"; subAgentId: string; success: boolean; parentToolCallId?: string; } | { type: "tool_input_delta"; toolCallId: string; toolName: string; delta: string; } | { type: "session_state_changed"; state: "idle" | "running" | "compacting" | "retrying"; timestamp: number; } | { type: "debug"; level: "basic" | "verbose"; source: "session" | "mcp" | "model" | "tool" | "resource" | "extension"; message: string; data?: Record; timestamp: number; }; /** Listener function for agent session events */ export type AgentSessionEventListener = (event: AgentSessionEvent) => void; export interface AgentSessionConfig { agent: Agent; sessionManager: SessionManager; settingsManager: SettingsManager; cwd: string; /** Global agent config directory for user-scoped resources. */ agentDir: string; /** Multi-agent context. */ agentCtx: AgentDirContext; /** Models to cycle through with Ctrl+P (from --models flag) */ scopedModels?: Array<{ model: Model; thinkingLevel: ThinkingLevel; }>; /** Resource loader for skills, prompts, themes, context files, system prompt */ resourceLoader: ResourceLoader; /** SDK custom tools registered outside extensions */ customTools?: ToolDefinition[]; /** Optional dynamic tool factory (e.g. MCP) refreshed on reload */ mcpToolsFactory?: () => Promise; /** Initial dynamic tools for first session build */ initialMcpTools?: ToolDefinition[]; /** Soul manager factory refreshed on reload (for persona/dir switching) */ soulManagerFactory?: () => Promise; /** Model registry for API key resolution and model discovery */ modelRegistry: ModelRegistry; /** Soul manager for AI personality evolution */ soulManager?: any; /** Initial active built-in tool names. Default: [read, bash, edit, write] */ initialActiveToolNames?: string[]; /** Override base tools (useful for custom runtimes). */ baseToolsOverride?: Record; /** Mutable ref used by Agent to access the current ExtensionRunner */ extensionRunnerRef?: { current?: ExtensionRunner; }; /** External abort signal for stopping the session (e.g., from SubAgent runtime) */ signal?: AbortSignal; /** * Theme used to render custom extension tools when exporting a session to HTML. * Injected by the composition root (UI layer owns the theme); when omitted, HTML * export still works but skips custom-tool rendering. Keeps core/runtime from * importing the modes/ UI theme singleton (U2). */ theme?: ThemeContract; /** * Factory for creating child AgentSession instances (used by the Agent sub-agent tool). * Injected by the composition root (sdk.ts) to avoid a circular dependency * between agent-session.ts and sdk.ts. */ createSession?: CreateSessionFn; /** Debug event verbosity level. Default: "off" */ debugLevel?: "off" | "basic" | "verbose"; } export interface ExtensionBindings { uiContext?: ExtensionUIContext; commandContextActions?: ExtensionCommandContextActions; shutdownHandler?: ShutdownHandler; onError?: ExtensionErrorListener; } /** Options for AgentSession.prompt() */ export interface PromptOptions { /** Whether to expand file-based prompt templates (default: true) */ expandPromptTemplates?: boolean; /** Image attachments */ images?: ImageContent[]; /** When streaming, how to queue the message: "steer" (interrupt) or "followUp" (wait). Required if streaming. */ streamingBehavior?: "steer" | "followUp"; /** Source of input for extension input event handlers. Defaults to "interactive". */ source?: InputSource; } /** Session statistics for /session command */ export interface SessionStats { sessionFile: string | undefined; sessionId: string; userMessages: number; assistantMessages: number; toolCalls: number; toolResults: number; totalMessages: number; tokens: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; }; cost: number; } export type SlashCommandExecutor = (text: string) => Promise; /** Standard thinking levels */ export declare class AgentSession { readonly agent: Agent; readonly sessionManager: SessionManager; readonly settingsManager: SettingsManager; readonly agentCtx: AgentDirContext; private _scopedModels; private _unsubscribeAgent?; private _detachExternalAbort?; private readonly _listeners; /** Tracks pending steering messages for UI display. Removed when delivered. */ private _steeringMessages; /** Tracks pending follow-up messages for UI display. Removed when delivered. */ private _followUpMessages; /** Messages queued to be included with the next user prompt as context ("asides"). */ private _pendingNextTurnMessages; private _retryCoordinator; private _logger; private _bashRunner; private _extensionRunner; private _slashCommandExecutor; private readonly _extensionEventBridge; private _resourceLoader; /** Injected theme for HTML-export custom-tool rendering (U2: no modes import). */ private _theme?; /** Debug event verbosity level. */ private _debugLevel; private _dbg; private _customTools; private _staticCustomTools; private _mcpToolsFactory?; private _soulManagerFactory?; private _baseToolRegistry; /** CC-style Agent tool — recreated on each _buildRuntime() */ private _agentTool?; /** Factory for creating child sessions (injected via config to avoid sdk.ts cycle) */ private _createSessionFactory?; /** Shared InProcessSubAgentBackend for session tracking (SendMessage routing, CC §XI) */ private _subAgentBackend?; private _cwd; private _extensionRunnerRef?; private _soulManager?; private _lastSoulInjection?; /** * Idempotency guard for the one-shot MCP capabilities hint CustomMessage. * Set after the first warmupMcpTools() persists the hint so a reload that * re-warms MCP doesn't append the hint a second time within the same * session. Reset on /clear and similar destructive operations; for * simplicity we leave it sticky here — appending the same hint twice is * harmless (it's just slightly more verbose context), but skipping is * tidier. */ private _mcpCapabilitiesInjected; private _initialActiveToolNames?; private _baseToolsOverride?; private _extensionUIContext?; private _extensionCommandContextActions?; private _extensionShutdownHandler?; private _extensionErrorListener?; private _extensionErrorUnsubscriber?; private _modelRegistry; private _agentDir; private _baseSystemPrompt; private readonly _modelController; private readonly _compactionController; private readonly _sessionTreeController; private readonly _lifecycleController; private readonly _toolOrchestrator; private readonly _toolRuntimeController; constructor(config: AgentSessionConfig); /** Model registry for API key resolution and model discovery */ get modelRegistry(): ModelRegistry; get cwd(): string; get agentDir(): string; /** * Return all currently available slash-like commands for the session. * Includes built-in commands, extension commands, prompt templates, and skills. */ getSlashCommands(): SessionSlashCommandDescriptor[]; /** * Try to execute an extension slash command directly. * Returns true when a matching extension command was found, even if it failed internally. */ tryExecuteExtensionCommand(text: string): Promise; executeSlashCommand(text: string): Promise; setSlashCommandExecutor(executor: SlashCommandExecutor | undefined): void; /** Emit an event to all listeners */ private _emit; private _emitDebug; private _lastAssistantMessage; /** Internal handler for agent events - shared by subscribe and reconnect */ private _handleAgentEvent; /** Extract text content from a message */ private _getUserMessageText; /** Find the last assistant message in agent state (including aborted ones) */ private _findLastAssistantMessage; /** * Subscribe to agent events. * Session persistence is handled internally (saves messages on message_end). * Multiple listeners can be added. Returns unsubscribe function for this listener. */ subscribe(listener: AgentSessionEventListener): () => void; /** * Temporarily disconnect from agent events. * User listeners are preserved and will receive events again after resubscribe(). * Used internally during operations that need to pause event processing. */ private _disconnectFromAgent; /** * Reconnect to agent events after _disconnectFromAgent(). * Preserves all existing listeners. */ private _reconnectToAgent; /** * Remove all listeners and disconnect from agent. * Call this when completely done with the session. */ dispose(): void; /** Full agent state */ get state(): AgentState; /** Current model (may be undefined if not yet selected) */ get model(): Model | undefined; /** Current thinking level */ get thinkingLevel(): ThinkingLevel; /** Current effective agent loop framework. */ get agentLoopFramework(): AgentLoopFramework; /** Whether agent is currently streaming a response */ get isStreaming(): boolean; /** Current effective system prompt (includes any per-turn extension modifications) */ get systemPrompt(): string; /** Shared Soul manager used by this session, if Soul is enabled. */ get soulManager(): unknown | undefined; /** Current retry attempt (0 if not retrying) */ get retryAttempt(): number; /** * Get the names of currently active tools. * Returns the names of tools currently set on the agent. */ getActiveToolNames(): string[]; /** * Get all configured tools with name, description, and parameter schema. */ getAllTools(): ToolInfo[]; /** * Set active tools by name. * Only tools in the registry can be enabled. Unknown tool names are ignored. * Also rebuilds the system prompt to reflect the new tool set. * Changes take effect on the next agent turn. */ setActiveToolsByName(toolNames: string[]): void; /** Whether auto-compaction is currently running */ get isCompacting(): boolean; /** All messages including custom types like BashExecutionMessage */ get messages(): AgentMessage[]; /** Current steering mode */ get steeringMode(): "all" | "one-at-a-time"; /** Current follow-up mode */ get followUpMode(): "all" | "one-at-a-time"; /** Current session file path, or undefined if sessions are disabled */ get sessionFile(): string | undefined; /** Current session ID */ get sessionId(): string; /** Current session display name, if set */ get sessionName(): string | undefined; /** Scoped models for cycling (from --models flag) */ get scopedModels(): ReadonlyArray<{ model: Model; thinkingLevel: ThinkingLevel; }>; /** Update scoped models for cycling */ setScopedModels(scopedModels: Array<{ model: Model; thinkingLevel: ThinkingLevel; }>): void; /** File-based prompt templates */ get promptTemplates(): ReadonlyArray; private _rebuildSystemPrompt; private _getActiveBaseToolNames; private _generateSoulInjection; /** * Send a prompt to the agent. * - Handles extension commands (registered via api.registerCommand) immediately, even during streaming * - Expands file-based prompt templates by default * - During streaming, queues via steer() or followUp() based on streamingBehavior option * - Validates model and API key before sending (when not streaming) * @throws Error if streaming and no streamingBehavior specified * @throws Error if no model selected or no API key available (when not streaming) */ prompt(text: string, options?: PromptOptions): Promise; /** * Try to execute an extension command. Returns true if command was found and executed. * * Delegates to ExtensionRunner.invokeCommand() so command dispatch, error * routing (emitError), and telemetry (ext_command_events) all happen in one * place rather than being scattered across modes. */ private _tryExecuteExtensionCommand; /** * Expand skill commands (/skill:name args) to their full content. * Returns the expanded text, or the original text if not a skill command or skill not found. * Emits errors via extension runner if file read fails. */ private _expandSkillCommand; /** * Queue a steering message to interrupt the agent mid-run. * Delivered after current tool execution, skips remaining tools. * Expands skill commands and prompt templates. Errors on extension commands. * @param images Optional image attachments to include with the message * @throws Error if text is an extension command */ steer(text: string, images?: ImageContent[]): Promise; /** * Queue a follow-up message to be processed after the agent finishes. * Delivered only when agent has no more tool calls or steering messages. * Expands skill commands and prompt templates. Errors on extension commands. * @param images Optional image attachments to include with the message * @throws Error if text is an extension command */ followUp(text: string, images?: ImageContent[]): Promise; /** * Internal: Queue a steering message (already expanded, no extension command check). */ private _queueSteer; /** * Internal: Queue a follow-up message (already expanded, no extension command check). */ private _queueFollowUp; /** * Throw an error if the text is an extension command. */ private _throwIfExtensionCommand; /** * Send a custom message to the session. Creates a CustomMessageEntry. * * Handles three cases: * - Streaming: queues message, processed when loop pulls from queue * - Not streaming + triggerTurn: appends to state/session, starts new turn * - Not streaming + no trigger: appends to state/session, no turn * * @param message Custom message with customType, content, display, details * @param options.triggerTurn If true and not streaming, triggers a new LLM turn * @param options.deliverAs Delivery mode: "steer", "followUp", or "nextTurn" */ sendCustomMessage(message: Pick, "customType" | "content" | "display" | "details">, options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn"; }): Promise; /** * 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. * * @param content User message content (string or content array) * @param options.deliverAs Delivery mode when streaming: "steer" or "followUp" */ sendUserMessage(content: string | (TextContent | ImageContent | DocumentContent)[], options?: { deliverAs?: "steer" | "followUp"; }): Promise; /** * Clear all queued messages and return them. * Useful for restoring to editor when user aborts. * @returns Object with steering and followUp arrays */ clearQueue(): { steering: string[]; followUp: string[]; }; /** Number of pending messages (includes both steering and follow-up) */ get pendingMessageCount(): number; /** Get pending steering messages (read-only) */ getSteeringMessages(): readonly string[]; /** Get pending follow-up messages (read-only) */ getFollowUpMessages(): readonly string[]; get resourceLoader(): ResourceLoader; /** * Abort current operation and wait for agent to become idle. */ abort(): Promise; /** * Start a new session, optionally with initial messages and parent tracking. * Clears all messages and starts a new session. * Listeners are preserved and will continue receiving events. * @param options.parentSession - Optional parent session path for tracking * @param options.setup - Optional callback to initialize session (e.g., append messages) * @returns true if completed, false if cancelled by extension */ newSession(options?: { parentSession?: string; setup?: (sessionManager: SessionManager) => Promise; }): Promise; /** Set model directly. @throws if no API key available. */ setModel(model: Model): Promise; /** Cycle to next/previous model. @returns new model info, or undefined if only one. */ cycleModel(direction?: "forward" | "backward"): Promise; /** Set thinking level, clamped to model capabilities; persists on change. */ setThinkingLevel(level: ThinkingLevel): void; /** Set the session-level agent loop framework override. */ setAgentLoopFramework(framework: AgentLoopFrameworkInput | undefined): void; /** Update runtime loop policy options for subsequent turns. */ setLoopPolicy(options: Partial): void; /** Cycle to next thinking level. @returns new level, or undefined if unsupported. */ cycleThinkingLevel(): ThinkingLevel | undefined; /** Thinking levels available for the current model. */ getAvailableThinkingLevels(): ThinkingLevel[]; /** Whether the current model supports xhigh thinking level. */ supportsXhighThinking(): boolean; /** Whether the current model supports thinking/reasoning. */ supportsThinking(): boolean; /** * Set steering message mode. * Saves to settings. */ setSteeringMode(mode: "all" | "one-at-a-time"): void; /** * Set follow-up message mode. * Saves to settings. */ setFollowUpMode(mode: "all" | "one-at-a-time"): void; /** Current theme name. */ getTheme(): string | undefined; /** Set theme. Saves to settings. */ setTheme(theme: string): void; /** Whether images are rendered in terminal. */ getShowImages(): boolean; /** Show or hide images in terminal. Saves to settings. */ setShowImages(show: boolean): void; /** Whether token usage stats are shown in footer. */ getShowTokenStats(): boolean; /** Show or hide token usage stats in footer. Saves to settings. */ setShowTokenStats(enabled: boolean): void; /** Whether tool execution trace (including edit diffs) is shown in chat. */ getShowWorkingTrace(): boolean; /** Show or hide tool execution trace (including edit diffs) in chat. Saves to settings. */ setShowWorkingTrace(enabled: boolean): void; /** Whether NanoMem search/recall/alignment traces are shown in chat. */ getShowMemoryTrace(): boolean; /** Show or hide NanoMem traces in chat. Saves to settings. */ setShowMemoryTrace(enabled: boolean): void; /** Whether buddy pet is displayed. */ getBuddyEnabled(): boolean; /** Enable or disable buddy pet. Saves to settings. */ setBuddyEnabled(enabled: boolean): void; /** Buddy species index. */ getBuddySpecies(): number; /** Set buddy species index. Saves to settings. */ setBuddySpecies(species: number): void; /** Whether presence feature is enabled. */ getPresenceEnabled(): boolean; /** Enable or disable presence. Saves to settings. */ setPresenceEnabled(enabled: boolean): void; /** Whether hardware cursor is shown. */ getShowHardwareCursor(): boolean; /** Show or hide hardware cursor. Saves to settings. */ setShowHardwareCursor(enabled: boolean): void; /** Whether empty rows are cleared when content shrinks. */ getClearOnShrink(): boolean; /** Enable or disable clear-on-shrink. Saves to settings. */ setClearOnShrink(enabled: boolean): void; /** Whether startup banner is suppressed. */ getQuietStartup(): boolean; /** Enable or disable quiet startup. Saves to settings. */ setQuietStartup(quiet: boolean): void; /** Whether thinking blocks are hidden in output. */ getHideThinkingBlock(): boolean; /** Show or hide thinking blocks. Saves to settings. */ setHideThinkingBlock(hide: boolean): void; /** Double-escape key action. */ getDoubleEscapeAction(): "fork" | "tree" | "none"; /** Set double-escape key action. Saves to settings. */ setDoubleEscapeAction(action: "fork" | "tree" | "none"): void; /** Editor horizontal padding (0-3). */ getEditorPaddingX(): number; /** Set editor horizontal padding (0-3). Saves to settings. */ setEditorPaddingX(padding: number): void; /** Max visible autocomplete suggestions (3-20). */ getAutocompleteMaxVisible(): number; /** Set max visible autocomplete suggestions (3-20). Saves to settings. */ setAutocompleteMaxVisible(maxVisible: number): void; /** Code block indent string. */ getCodeBlockIndent(): string; /** Default model provider name. */ getDefaultProvider(): string | undefined; /** Set default model provider. Saves to settings. */ setDefaultProvider(provider: string): void; /** Default model ID. */ getDefaultModel(): string | undefined; /** Set default model ID. Saves to settings. */ setDefaultModel(modelId: string): void; /** Set both default provider and model atomically. Saves to settings. */ setDefaultModelAndProvider(provider: string, modelId: string): void; /** Thinking token budgets per level. */ getThinkingBudgets(): import("../platform/config/settings-manager.js").ThinkingBudgetsSettings | undefined; /** Enabled model patterns (undefined = all). */ getEnabledModels(): string[] | undefined; /** Set enabled model patterns (undefined = all). Saves to settings. */ setEnabledModels(patterns: string[] | undefined): void; /** Whether images are auto-resized for model compatibility. */ getImageAutoResize(): boolean; /** Enable or disable image auto-resize. Saves to settings. */ setImageAutoResize(enabled: boolean): void; /** Whether all images are blocked from being sent to LLM. */ getBlockImages(): boolean; /** Block or unblock images from being sent to LLM. Saves to settings. */ setBlockImages(blocked: boolean): void; /** Shell executable path. */ getShellPath(): string | undefined; /** Set shell executable path. Saves to settings. */ setShellPath(path: string | undefined): void; /** Shell command prefix (e.g., wrapper). */ getShellCommandPrefix(): string | undefined; /** Set shell command prefix. Saves to settings. */ setShellCommandPrefix(prefix: string | undefined): void; /** Auto-update mode. */ getAutoUpdate(): "always" | "prompt" | "never"; /** Set auto-update mode. Saves to settings. */ setAutoUpdate(mode: "always" | "prompt" | "never"): void; /** Whether skill slash commands are enabled. */ getEnableSkillCommands(): boolean; /** Enable or disable skill slash commands. Saves to settings. */ setEnableSkillCommands(enabled: boolean): void; /** * Manually compact the session context. * Aborts current agent operation first. * @param customInstructions Optional instructions for the compaction summary */ compact(customInstructions?: string): Promise; /** * Cancel in-progress compaction (manual or auto). */ abortCompaction(): void; /** * Cancel in-progress branch summarization. */ abortBranchSummary(): void; /** * Check if compaction is needed and run it. * Called after agent_end and before prompt submission. * * Two cases: * 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry * 2. Threshold: Context over threshold, compact, NO auto-retry (user continues manually) * * @param assistantMessage The assistant message to check * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true */ private _checkCompaction; private _recoverModelErrorInLoop; /** * Internal: Run auto-compaction with events. */ private _runAutoCompaction; /** * Toggle auto-compaction setting. */ setAutoCompactionEnabled(enabled: boolean): void; /** Whether auto-compaction is enabled */ get autoCompactionEnabled(): boolean; bindExtensions(bindings: ExtensionBindings): Promise; private extendResourcesFromExtensions; private buildExtensionResourcePaths; private getExtensionSourceLabel; private _applyExtensionBindings; private _bindExtensionCore; private _buildRuntime; /** * Run the MCP tools factory and merge the result into `_customTools`. * Shared by reload() and warmupMcpTools(). Does NOT rebuild the runtime — * the caller decides when to call _buildRuntime() (reload batches it with the * soul refresh; warmup rebuilds on its own). * @returns number of MCP tools now loaded. */ private _refreshMcpTools; /** * Load MCP tools and merge them into the live runtime WITHOUT a full reload. * * Startup no longer blocks on MCP server spawn/handshake (which can take many * seconds — npx-based default servers measured ~20s). Interactive mode calls * this fire-and-forget once the UI is ready; one-shot modes (print/acp/rpc) * await it before their first turn (createAgentSession does this internally * unless `deferMcpInit` is set). No-op when MCP is disabled. * * Emits `sdk:mcp_ready` so the UI can surface a status line. */ warmupMcpTools(): Promise; reload(): Promise; /** Create the RetryCoordinator host adapter. */ private _createRetryHost; /** * Cancel in-progress retry. */ abortRetry(): void; /** * Wait for any in-progress retry to complete. * Returns immediately if no retry is in progress. */ private waitForRetry; /** Whether auto-retry is currently in progress */ get isRetrying(): boolean; /** Whether auto-retry is enabled */ get autoRetryEnabled(): boolean; /** * Toggle auto-retry setting. */ setAutoRetryEnabled(enabled: boolean): void; /** * Execute a bash command. * Adds result to agent context and session. * @param command The bash command to execute * @param onChunk Optional streaming callback for output * @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix) * @param options.operations Custom BashOperations for remote execution */ executeBash(command: string, onChunk?: (chunk: string) => void, options?: { excludeFromContext?: boolean; operations?: BashOperations; }): Promise; /** * Record a bash execution result in session history. * Used by executeBash and by extensions that handle bash execution themselves. */ recordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean; }): void; /** * Cancel running bash command. */ abortBash(): void; /** Whether a bash command is currently running */ get isBashRunning(): boolean; /** Whether there are pending bash messages waiting to be flushed */ get hasPendingBashMessages(): boolean; /** * Switch to a different session file. * Aborts current operation, loads messages, restores model/thinking. * Listeners are preserved and will continue receiving events. * @returns true if switch completed, false if cancelled by extension */ switchSession(sessionPath: string): Promise; /** * Set a display name for the current session. */ setSessionName(name: string): void; /** * Tag the current session with labels (e.g., "important", "bug-fix"). */ tagSession(tags: string[]): void; /** * Get the current session tags. */ getSessionTags(): string[]; /** * Create a fork from a specific entry. * Emits before_fork/fork session events to extensions. * * @param entryId ID of the entry to fork from * @returns Object with: * - selectedText: The text of the selected user message (for editor pre-fill) * - cancelled: True if an extension cancelled the fork */ fork(entryId: string): Promise<{ selectedText: string; cancelled: boolean; }>; /** * Navigate to a different node in the session tree. * Unlike fork() which creates a new session file, this stays in the same file. * * @param targetId The entry ID to navigate to * @param options.summarize Whether user wants to summarize abandoned branch * @param options.customInstructions Custom instructions for summarizer * @param options.replaceInstructions If true, customInstructions replaces the default prompt * @param options.label Label to attach to the branch summary entry * @returns Result with editorText (if user message) and cancelled status */ navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string; }): Promise<{ editorText?: string; cancelled: boolean; aborted?: boolean; summaryEntry?: BranchSummaryEntry; }>; /** * Get all user messages from session for fork selector. */ getUserMessagesForForking(): Array<{ entryId: string; text: string; }>; private _extractUserMessageText; /** * Get session statistics. */ getSessionStats(): SessionStats; getContextUsage(): ContextUsage | undefined; /** * Export session to HTML. * @param outputPath Optional output path (defaults to session directory) * @returns Path to exported file */ exportToHtml(outputPath?: string): Promise; /** * List sessions for the current project directory. * Returns session metadata sorted by last modified time (newest first). */ listSessions(onProgress?: SessionListProgress): Promise; /** * List all sessions across all project directories. * Returns session metadata sorted by last modified time (newest first). */ listAllSessions(onProgress?: SessionListProgress): Promise; /** Total cost in USD for this session. */ getTotalCost(): number; /** Total token usage breakdown for this session. */ getTotalTokens(): { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; }; /** Tool call count for this session. */ getToolCallCount(): number; /** * Get text content of last assistant message. * Useful for /copy command. * @returns Text content, or undefined if no assistant message exists */ getLastAssistantText(): string | undefined; /** * Check if extensions have handlers for a specific event type. */ hasExtensionHandlers(eventType: string): boolean; /** * Get the extension runner (for setting UI context and error handlers). */ get extensionRunner(): ExtensionRunner | undefined; }