/**
 * AgentSession - Core abstraction for agent lifecycle and session management.
 *
 * This class is shared between all run modes (interactive, print, rpc).
 * It encapsulates:
 * - AgentController state access
 * - Event subscription with automatic session persistence
 * - Model and thinking level management
 * - Compaction (manual and auto)
 * - Bash execution
 * - Session switching and branching
 *
 * Modes use this class and add their own I/O layer on top.
 */
import type { ImageContent, Model, TextContent } from '../ai/types.js';
import type { AgentApprovalState } from '../contracts/agent-approval.js';
import type { AgentModelRegistry } from '../contracts/agent-model.js';
import type { RuntimeResourceLoader } from '../contracts/agent-resources.js';
import type { RuntimeSessionStore } from '../contracts/agent-session-store.js';
import type { AgentSettingsStore } from '../contracts/agent-settings.js';
import type { AgentController, AgentLoopEvent, AgentMessage, AgentState, ThinkingLevel, ToolDefinition } from '../core/index.js';
import type { RuntimePermissionPolicy } from '../core/permission-policy.js';
import { type CompactionCompleteFn, type CompactionResult } from '../core/session/compaction/index.js';
import type { ExtensionRunner } from './extensions/runner.js';
import type { ContextUsage, ExtensionSessionSetupStore, InputSource } from './extensions/types.js';
import { type FileUploadData } from './file-uploads.js';
import type { CustomMessage } from './messages.js';
import type { PromptTemplate } from './resources/prompt-templates.js';
import { type AutonomousState, type ConsumedPendingRefresh, type PendingRefresh } from './session/autonomous-workflow.js';
import { type ForkResult, type NavigateTreeResult } from './session/branch-manager.js';
import { type ExtensionBindings } from './session/extension-lifecycle.js';
import { type ModelCycleResult } from './session/session-models.js';
import { type SessionStats } from './session/session-stats.js';
import { type ToolInfo } from './session/tool-registry.js';
import { type ToolSummaryDiagnostic } from './session/tool-summary-emitter.js';
export declare class LoginRequiredError extends Error {
    /** Construct a LoginRequiredError with an optional human-readable message. */
    constructor(message?: string);
}
export { parseSkillBlock, type ParsedSkillBlock } from './resources/skill-block.js';
export interface AgentSessionSettingsStore extends AgentSettingsStore {
    disableSkill?(name: string): void;
    getShowCacheTokens?(): boolean;
    getTheme?(): string | undefined;
    isSkillDisabled?(name: string): boolean;
    setToolSummariesEnabled?(enabled: boolean): void;
}
/** Session-specific events that extend the core AgentLoopEvent */
export type AgentSessionEvent = AgentLoopEvent | {
    type: 'auto_compaction_start';
    reason: 'threshold' | 'overflow';
} | {
    type: 'auto_compaction_end';
    result: CompactionResult | undefined;
    aborted: boolean;
    willRetry: boolean;
    errorMessage?: string;
} | {
    type: 'recovery_start';
    category: string;
    attempt: number;
    maxAttempts: number;
    delayMs: number;
    errorMessage: string;
} | {
    type: 'recovery_end';
    category: string;
    success: boolean;
    attempt: number;
    finalError?: string;
} | {
    type: 'recovery_fallback';
    category: string;
    fallbackModel: string;
} | {
    type: 'hard_limit_reached';
    reason: string;
} | {
    type: 'tool_summary';
    toolCallId: string;
    summary: string;
};
/** Listener function for agent session events */
export type AgentSessionEventListener = (event: AgentSessionEvent) => void;
export interface AgentSessionConfig {
    agent: AgentController;
    sessionManager: RuntimeSessionStore;
    settingsManager: AgentSessionSettingsStore;
    approvalState: AgentApprovalState;
    cwd: string;
    /** Resource loader for skills, prompts, context files, and internal prompt injection */
    resourceLoader: RuntimeResourceLoader;
    /** Tools registered outside extensions */
    tools?: ToolDefinition[];
    /** Optional hook to rebuild runtime tools during reload(). */
    reloadTools?: () => Promise<{
        tools: ToolDefinition[];
        warnings: string[];
    }>;
    /** Exact tool names to register initially */
    initialToolNames?: string[];
    /** Optional initial mode name used to seed runtime permission policy. */
    initialModeName?: string;
    /** Optional fixed permission policy for isolated runtimes such as subagents. */
    initialPermissionPolicy?: RuntimePermissionPolicy;
    /** Model registry for API key resolution and model discovery */
    modelRegistry: AgentModelRegistry;
    fastModeAllowed?: boolean;
    fastModeDisabledReason?: FastModeDisabledReason;
    /** Mutable ref used by AgentController to access the current ExtensionRunner */
    extensionRunnerRef?: {
        current?: ExtensionRunner;
    };
    prePromptContext?: () => Promise<{
        text: string;
        details?: unknown;
    } | null>;
    compactionComplete?: CompactionCompleteFn;
    budgetLimits?: {
        maxTurns?: number;
        maxToolUses?: number;
        maxTokens?: number;
    };
    /** When true, allow tool summaries on this session surface. Disabled in print/subagent flows. */
    enableToolSummaries?: boolean;
    observability?: {
        setSessionId?: (sessionId: string) => void;
        info?: (input: {
            module: string;
            event: string;
            data?: Record<string, unknown>;
        }) => void;
    };
}
export type FastModeDisabledReason = 'login' | 'team';
export type { ExtensionBindings } from './session/extension-lifecycle.js';
/** 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). Defaults to "steer". */
    streamingBehavior?: 'steer' | 'followUp';
    /** Source of input for extension input event handlers. Defaults to "interactive". */
    source?: InputSource;
}
export type { ModelCycleResult } from './session/session-models.js';
export type { SessionStats } from './session/session-stats.js';
export declare class AgentSession {
    readonly agent: AgentController;
    readonly sessionManager: RuntimeSessionStore;
    readonly settingsManager: AgentSessionSettingsStore;
    readonly approvalState: AgentApprovalState;
    private _unsubscribeAgent?;
    private _eventListeners;
    private _agentEventQueue;
    private _queueTracker;
    /** Messages queued to be included with the next user prompt as context ("asides"). */
    private _pendingNextTurnMessages;
    private _compaction;
    private _branches;
    private _recovery;
    private _budgetContinuation;
    private _budgetLimits?;
    private _pendingRefresh;
    private _autonomousState;
    private _turnIndex;
    private _persistence;
    private _pendingImmediateRunAgentMetadata?;
    private _resourceLoader;
    private _prePromptContext?;
    /** Details from the last prePromptContext call (e.g. { workbooks: string[] }). Read by TUI for annotations. */
    lastPrePromptDetails?: unknown;
    private readonly _sessionState;
    /** Session-scoped file upload metadata. */
    private _fileUploads;
    private _collabClient;
    private _sheetPool;
    private _collabAwareness;
    private _collabSync;
    private _modelRegistry;
    /** Fire-and-forget tool-call summary generation. */
    private _summaryEmitter;
    private _toolSummaryDiagnostics;
    private _observability?;
    private _tools;
    private _models;
    private _fastModeAllowed;
    private _fastModeDisabledReason;
    private _extensions;
    private _compactionActions;
    private _compactionTriggerDeps;
    private _errorRecoveryActions;
    /** Wire up subsystems (tools, models, extensions, compaction, recovery) from a session config. */
    constructor(config: AgentSessionConfig);
    /** Model registry for API key resolution and model discovery */
    get modelRegistry(): AgentModelRegistry;
    /** Return a snapshot of the most recent tool-summary emitter diagnostics. */
    getToolSummaryDiagnostics(): ToolSummaryDiagnostic[];
    /** Active runtime permission policy applied to tool calls in this session. */
    get permissionPolicy(): RuntimePermissionPolicy;
    /** Emit an event to all listeners */
    private _emit;
    /**
     * Remove the last errored assistant message and its synthetic error
     * toolResult messages from agent state. When a streaming call fails
     * mid-response, agent-loop appends [assistant(error), toolResult, ...]
     * — this removes the entire group so retries start from a clean state.
     */
    private _removeLastErrorGroup;
    /** Internal handler for agent events - shared by subscribe and reconnect */
    private _handleAgentLoopEvent;
    /** True when the assistant message indicates the conversation has overflowed the model context. */
    private _checkContextOverflow;
    /** On agent_end, eagerly arm the recovery retry promise before queued event processing runs. */
    private _createRetryPromiseForAgentEnd;
    /** Find the last assistant message in a transcript, scanning from the tail. */
    private _findLastAssistantInMessages;
    /** Attach a budget-related note to a tool result so the model sees the limit context. */
    private _appendBudgetAnnotationToToolResult;
    /** Serialized handler for each agent-loop event: persistence, extensions, compaction, recovery. */
    private _processAgentLoopEvent;
    /**
     * Run stop hooks from extensions after agent_end, before retry/compaction.
     * Returns true if a hook triggered continuation (caller should return early).
     */
    private _runStopHooks;
    /**
     * Explicit execution limits for bounded contexts such as sub-agents.
     *
     * The main `/budget ...` product path does not use hidden settings-driven limits.
     */
    private _getExecutionBudgetLimits;
    /** 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;
    /**
     * Wait for any in-flight suggestion generation to complete.
     * Call before process exit to avoid dangling promises.
     */
    awaitPendingSuggestions(): Promise<void>;
    /** Full agent state */
    get state(): AgentState;
    /** Currently selected model for this session, if any. */
    get model(): Model<any> | undefined;
    /** Current thinking level */
    get thinkingLevel(): ThinkingLevel;
    get isFastModeEnabled(): boolean;
    get isFastModeAllowed(): boolean;
    get fastModeDisabledReason(): FastModeDisabledReason | undefined;
    get isFastModeAvailable(): boolean;
    setFastModeAllowed(allowed: boolean, reason?: FastModeDisabledReason): void;
    setFastModeEnabled(enabled: boolean): void;
    toggleFastMode(): boolean;
    /** Whether agent is currently streaming a response */
    get isStreaming(): boolean;
    /** Current effective system prompt (includes any per-turn extension modifications) */
    get systemPrompt(): string;
    /** Current retry attempt (0 if not retrying) */
    get retryAttempt(): number;
    /** Session-scoped file uploads. */
    get fileUploads(): readonly FileUploadData[];
    /**
     * Merge new file uploads into session state, deduplicating by name.
     */
    addFileUploads(files: FileUploadData[]): void;
    /**
     * Get the names of currently active tools.
     * Delegates to ToolRegistry (single source of truth).
     */
    getToolNames(): string[];
    /** Get all available tools with name, description, and parameter schema. */
    get tools(): readonly ToolDefinition[];
    /** Get all available 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.
     */
    replaceToolsByName(toolNames: string[]): void;
    /** Switch the session into a new agent mode (tool surface, system prompt, optional name). */
    applyMode(toolNames: string[], systemPrompt: string, modeName?: string): void;
    /** Whether compaction (manual or auto) is currently running */
    get isCompacting(): boolean;
    /** Set a pending context refresh query (consumed after the current agent loop ends). */
    setPendingRefresh(refresh: PendingRefresh): void;
    /** Consume and return the pending refresh payload, or null if none. */
    consumePendingRefresh(): ConsumedPendingRefresh | null;
    /** Read-only view of the current autonomous-run state, or null if not autonomous. */
    get autonomousState(): Readonly<AutonomousState> | null;
    /** Begin an autonomous run with the given task, switching the session into autonomous mode. */
    startAutonomous(task: string): Promise<void>;
    /** Stage a pending session refresh (mode/model swap) to be applied on the next prompt. */
    preparePendingRefresh(refresh: PendingRefresh): Promise<void>;
    /** Drop any active autonomous-run state and resume normal interactive flow. */
    clearAutonomousState(): void;
    /** 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;
    /** File-based prompt templates */
    get promptTemplates(): ReadonlyArray<PromptTemplate>;
    /**
     * Send a prompt to the agent.
     * - Expands file-based prompt templates by default
     * - During streaming, queues via steer() by default, or followUp() when requested
     * - Validates model and API key before sending (when not streaming)
     * @throws Error if no model selected or no API key available (when not streaming)
     */
    prompt(text: string, options?: PromptOptions): Promise<void>;
    /** Rewrite skill commands (/skill:name args) to selected-skill markers. */
    private _expandSkillCommand;
    /** Mutate the autonomous state record, persisting it to the session manager. */
    private _setAutonomousState;
    /** Reload autonomous-run state from the persisted session header on resume. */
    private _restoreAutonomousStateFromSession;
    /** Wrap a user prompt with autonomous-run framing before sending it to the model. */
    private _prepareAutonomousPrompt;
    /**
     * Queue a steering message to interrupt the agent mid-run.
     * Delivered after current tool execution, skips remaining tools.
     * Expands skill commands and prompt templates.
     * @param images Optional image attachments to include with the message
     */
    steer(text: string, images?: ImageContent[]): Promise<void>;
    /**
     * 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.
     * @param images Optional image attachments to include with the message
     */
    followUp(text: string, images?: ImageContent[]): Promise<void>;
    /** Resolve raw prompt text + images into the final agent-input shape (skills, autonomous, etc.). */
    private _preparePromptInput;
    /** Enqueue a steering message to be delivered before the next assistant response. */
    private _queueSteer;
    /** Enqueue a follow-up message to be delivered after the current turn completes. */
    private _queueFollowUp;
    /**
     * 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<T = unknown>(message: Pick<CustomMessage<T>, 'customType' | 'content' | 'display' | 'details'>, options?: {
        triggerTurn?: boolean;
        deliverAs?: 'steer' | 'followUp' | 'nextTurn';
    }): Promise<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.
     *
     * @param content User message content (string or content array)
     * @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
     */
    sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
        deliverAs?: 'steer' | 'followUp';
    }): Promise<void>;
    /**
     * 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[];
    /** Resource loader for skills, prompts, and context files used by this session. */
    get resourceLoader(): RuntimeResourceLoader;
    /** Active collaboration client when the session is part of a collab room, otherwise null. */
    get collabClient(): import('./collab/collab-client.js').CollabClient | null;
    /** Attach or detach the collaboration client for this session. */
    set collabClient(client: import('./collab/collab-client.js').CollabClient | null);
    /** Sheet-engine pool currently bound to this session, or null if unbound. */
    get sheetPool(): import('./new-sheet/sheet-engine.js').SheetEnginePool | null;
    /** Attach or detach the sheet-engine pool used by new-sheet flows. */
    set sheetPool(pool: import('./new-sheet/sheet-engine.js').SheetEnginePool | null);
    /** Awareness layer for the active collab session (peer cursors, presence), or null. */
    get collabAwareness(): import('./collab/awareness.js').CollabAwareness | null;
    /** Attach or detach the collab awareness layer. */
    set collabAwareness(awareness: import('./collab/awareness.js').CollabAwareness | null);
    /** Collab document sync controller for this session, or null if not in a room. */
    get collabSync(): import('./collab/collab-sync.js').CollabSync | null;
    /** Attach or detach the collab document sync controller. */
    set collabSync(sync: import('./collab/collab-sync.js').CollabSync | null);
    /**
     * Abort current operation and wait for agent to become idle.
     */
    abort(): Promise<void>;
    /**
     * 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: ExtensionSessionSetupStore) => Promise<void>;
        preserveAutonomous?: boolean;
    }): Promise<boolean>;
    /** Switch the session's active LLM to `model`, persisting the change. */
    setModel(model: Model<any>): Promise<void>;
    /** Cycle to the next configured model and report the switch result. */
    cycleModel(direction?: 'forward' | 'backward'): Promise<ModelCycleResult | undefined>;
    /** Set the model's reasoning/thinking level for subsequent turns. */
    setThinkingLevel(level: ThinkingLevel): void;
    /** Advance to the next thinking level supported by the active model. */
    cycleThinkingLevel(): ThinkingLevel | undefined;
    /** List the thinking levels supported by the active model. */
    getAvailableThinkingLevels(): ThinkingLevel[];
    /** True if the active model supports the extra-high thinking level. */
    supportsXhighThinking(): boolean;
    /** True if the active model exposes any thinking/reasoning configuration. */
    supportsThinking(): boolean;
    /** Check compaction decision and trigger if needed. */
    private _triggerCompactionIfNeeded;
    /** Run a manual compaction pass over the conversation, optionally with custom instructions. */
    compact(customInstructions?: string): Promise<CompactionResult>;
    /** Cancel any in-flight compaction run. */
    abortCompaction(): void;
    /** Auto-compaction is always enabled */
    get autoCompactionEnabled(): boolean;
    /** Bind UI/host integration callbacks for the extension runtime. */
    bindExtensions(bindings: ExtensionBindings): Promise<void>;
    /** Reload extensions, skills, prompts, and themes; returns any non-fatal warnings. */
    reload(): Promise<{
        warnings: string[];
    }>;
    /** Cancel in-progress recovery. */
    abortRetry(): void;
    /** Whether error recovery is currently in progress */
    get isRetrying(): boolean;
    /** Whether auto-retry is enabled */
    get autoRetryEnabled(): boolean;
    /** Toggle auto-retry setting. */
    setAutoRetryEnabled(enabled: boolean): void;
    /**
     * 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<boolean>;
    /**
     * Set a display name for the current session.
     */
    setSessionName(name: string): void;
    /**
     * Create a fork from a specific entry.
     */
    fork(entryId: string): Promise<ForkResult>;
    /**
     * Navigate to a different node in the session tree.
     * Unlike fork() which creates a new session file, this stays in the same file.
     */
    navigateTree(targetId: string, options?: {
        label?: string;
    }): NavigateTreeResult;
    /**
     * Get all user messages from session for fork selector.
     */
    getUserMessagesForForking(): Array<{
        entryId: string;
        text: string;
    }>;
    /**
     * Get session statistics.
     */
    getSessionStats(): SessionStats;
    /** Estimate token usage and remaining context budget for the current conversation. */
    getContextUsage(): ContextUsage | 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;
}
//# sourceMappingURL=agent-session.d.ts.map