import type { AgentMessage } from "@f5-sales-demo/pi-agent-core"; import type { AssistantMessage, ImageContent, Message, UsageReport } from "@f5-sales-demo/pi-ai"; import type { Component, Container, Loader, Spacer, Text, TUI } from "@f5-sales-demo/pi-tui"; import type { KeybindingsManager } from "../config/keybindings"; import type { Settings } from "../config/settings"; import type { ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetContent, ExtensionWidgetOptions, } from "../extensibility/extensions"; import type { CompactOptions } from "../extensibility/extensions/types"; import type { MCPManager } from "../mcp"; import type { AgentSession, AgentSessionEvent } from "../session/agent-session"; import type { HistoryStorage } from "../session/history-storage"; import type { SessionContext, SessionManager } from "../session/session-manager"; import type { ExitPlanModeDetails, LspStartupServerInfo } from "../tools"; import type { AssistantMessageComponent } from "./components/assistant-message"; import type { BashExecutionComponent } from "./components/bash-execution"; import type { CustomEditor } from "./components/custom-editor"; import type { GutterBlock } from "./components/gutter-block"; import type { HookEditorComponent } from "./components/hook-editor"; import type { HookInputComponent } from "./components/hook-input"; import type { HookSelectorComponent } from "./components/hook-selector"; import type { PythonExecutionComponent } from "./components/python-execution"; import type { StatusLineComponent } from "./components/status-line"; import type { ToolExecutionHandle } from "./components/tool-execution"; import type { OAuthManualInputManager } from "./oauth-manual-input"; import type { Theme } from "./theme/theme"; export type CompactionQueuedMessage = { text: string; mode: "steer" | "followUp"; }; export type SubmittedUserInput = { text: string; images?: ImageContent[]; cancelled: boolean; started: boolean; }; export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned"; export type TodoItem = { id: string; content: string; status: TodoStatus; details?: string; }; export type TodoPhase = { id: string; name: string; tasks: TodoItem[]; }; export interface InteractiveModeContext { // UI access ui: TUI; chatContainer: Container; pendingMessagesContainer: Container; statusContainer: Container; todoContainer: Container; btwContainer: Container; editor: CustomEditor; editorContainer: Container; hookWidgetContainerAbove: Container; hookWidgetContainerBelow: Container; statusLine: StatusLineComponent; // Session access session: AgentSession; sessionManager: SessionManager; settings: Settings; keybindings: KeybindingsManager; agent: AgentSession["agent"]; historyStorage?: HistoryStorage; mcpManager?: MCPManager; lspServers?: LspStartupServerInfo[]; // State isInitialized: boolean; isBackgrounded: boolean; isBashMode: boolean; toolOutputExpanded: boolean; todoExpanded: boolean; planModeEnabled: boolean; planModePlanFilePath?: string; hideThinkingBlock: boolean; pendingImages: ImageContent[]; compactionQueuedMessages: CompactionQueuedMessage[]; pendingTools: Map; pendingBashComponents: BashExecutionComponent[]; bashComponent: BashExecutionComponent | undefined; pendingPythonComponents: PythonExecutionComponent[]; pythonComponent: PythonExecutionComponent | undefined; isPythonMode: boolean; streamingComponent: AssistantMessageComponent | undefined; streamingAssistantGutter: GutterBlock | undefined; streamingMessage: AssistantMessage | undefined; loadingAnimation: Loader | undefined; autoCompactionLoader: Loader | undefined; retryLoader: Loader | undefined; autoCompactionEscapeHandler?: () => void; retryEscapeHandler?: () => void; unsubscribe?: () => void; onInputCallback?: (input: SubmittedUserInput) => void; optimisticUserMessageSignature: string | undefined; lastSigintTime: number; lastEscapeTime: number; shutdownRequested: boolean; hookSelector: HookSelectorComponent | undefined; hookInput: HookInputComponent | undefined; hookEditor: HookEditorComponent | undefined; lastStatusSpacer: Spacer | undefined; lastStatusText: Text | undefined; fileSlashCommands: Set; skillCommands: Map; oauthManualInput: OAuthManualInputManager; todoPhases: TodoPhase[]; // Lifecycle init(): Promise; shutdown(): Promise; checkShutdownRequested(): Promise; // Extension UI integration setToolUIContext(uiContext: ExtensionUIContext, hasUI: boolean): void; initializeHookRunner(uiContext: ExtensionUIContext, hasUI: boolean): void; createBackgroundUiContext(): ExtensionUIContext; // Event handling handleBackgroundEvent(event: AgentSessionEvent): Promise; // UI helpers showStatus(message: string, options?: { dim?: boolean }): void; showError(message: string): void; showWarning(message: string): void; /** Instant, local check for whether a usable LLM provider is configured (no network). */ hasActiveLlmProvider(): boolean; clearEditor(): void; updatePendingMessagesDisplay(): void; queueCompactionMessage(text: string, mode: "steer" | "followUp"): void; flushCompactionQueue(options?: { willRetry?: boolean }): Promise; flushPendingBashComponents(): void; flushPendingModelSwitch(): Promise; setWorkingMessage(message?: string): void; applyPendingWorkingMessage(): void; ensureLoadingAnimation(): void; startPendingSubmission(input: { text: string; images?: ImageContent[] }): SubmittedUserInput; cancelPendingSubmission(): boolean; markPendingSubmissionStarted(input: SubmittedUserInput): boolean; finishPendingSubmission(input: SubmittedUserInput): void; isKnownSlashCommand(text: string): boolean; addMessageToChat(message: AgentMessage, options?: { populateHistory?: boolean }): void; renderSessionContext( sessionContext: SessionContext, options?: { updateFooter?: boolean; populateHistory?: boolean }, ): void; renderInitialMessages(): void; getUserMessageText(message: Message): string; findLastAssistantMessage(): AssistantMessage | undefined; extractAssistantText(message: AssistantMessage): string; updateEditorTopBorder(): void; updateEditorBorderColor(): void; rebuildChatFromMessages(): void; setTodos(todos: TodoItem[] | TodoPhase[]): void; reloadTodos(): Promise; toggleTodoExpansion(): void; // Command handling handleExportCommand(text: string): Promise; handleShareCommand(): Promise; handleCopyCommand(sub?: string): void; handleMediaCommand(text: string): void; handleSessionCommand(): Promise; handleJobsCommand(): Promise; handleUsageCommand(reports?: UsageReport[] | null): Promise; handleChangelogCommand(showFull?: boolean): Promise; handleHotkeysCommand(): void; handleToolsCommand(): void; handleDumpCommand(): void; handleDebugTranscriptCommand(): Promise; handleClearCommand(): Promise; handleForkCommand(): Promise; handleBashCommand(command: string, excludeFromContext?: boolean): Promise; handlePythonCommand(code: string, excludeFromContext?: boolean): Promise; handleMCPCommand(text: string): Promise; handleSSHCommand(text: string): Promise; handleCompactCommand(customInstructions?: string): Promise; handleHandoffCommand(customInstructions?: string): Promise; handleMoveCommand(targetPath: string): Promise; handleRenameCommand(title: string): Promise; handleMemoryCommand(text: string): Promise; handleSTTToggle(): Promise; executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise; openInBrowser(urlOrPath: string): void; refreshSlashCommandState(cwd?: string): Promise; // Selector handling showSettingsSelector(): void; showHistorySearch(): void; showExtensionsDashboard(): void; showAgentsDashboard(): void; showModelSelector(options?: { temporaryOnly?: boolean }): void; showPluginSelector(mode?: "install" | "uninstall"): void; showPluginDashboard(): void; showUserMessageSelector(): void; showTreeSelector(): void; showSessionSelector(): void; handleResumeSession(sessionPath: string): Promise; handleSessionDeleteCommand(): Promise; showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise; showHookConfirm(title: string, message: string): Promise; showDebugSelector(): void; showSessionObserver(): void; resetObserverRegistry(): void; refreshWelcomeAfterLogin(): Promise; // Input handling handleCtrlC(): void; handleCtrlD(): void; handleCtrlZ(): void; handleDequeue(): void; handleBackgroundCommand(): void; handleImagePaste(): Promise; handleBtwCommand(question: string): Promise; hasActiveBtw(): boolean; handleBtwEscape(): boolean; cycleThinkingLevel(): void; cycleRoleModel(options?: { temporary?: boolean }): Promise; toggleToolOutputExpansion(): void; setToolsExpanded(expanded: boolean): void; toggleThinkingBlockVisibility(): void; openExternalEditor(): void; registerExtensionShortcuts(): void; handlePlanModeCommand(initialPrompt?: string): Promise; handleExitPlanModeTool(details: ExitPlanModeDetails): Promise; // Hook UI methods initHooksAndCustomTools(): Promise; emitCustomToolSessionEvent( reason: "start" | "switch" | "branch" | "tree" | "shutdown", previousSessionFile?: string, ): Promise; setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void; setHookStatus(key: string, text: string | undefined): void; showHookSelector( title: string, options: string[], dialogOptions?: ExtensionUIDialogOptions, ): Promise; hideHookSelector(): void; showHookInput(title: string, placeholder?: string): Promise; hideHookInput(): void; showHookEditor( title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: { promptStyle?: boolean }, ): Promise; hideHookEditor(): void; showHookNotify(message: string, type?: "info" | "warning" | "error"): void; showHookCustom( factory: ( tui: TUI, theme: Theme, keybindings: KeybindingsManager, done: (result: T) => void, ) => (Component & { dispose?(): void }) | Promise, options?: { overlay?: boolean }, ): Promise; showExtensionError(extensionPath: string, error: string): void; showToolError(toolName: string, error: string): void; }