import type { ApprovalDecision, AgentEvent, AgentQuestionAnswer, AgentRequest, AgentRuntimeStatus, BrowserTabId, RuntimeConversationCompactInput, RuntimeConversationCompactResult, RuntimeNativeSnapshot } from '../../shared/contracts' import type { ConversationSubagentActivity, ConversationMessage, ConversationToolActivity } from '../../shared/assistant-contracts' export type RuntimeApprovalRequest = { scopeKey: string title: string description: string toolName?: string argumentSummary?: string allowPermanent?: boolean } export type RuntimeAuthorizer = ( request: RuntimeApprovalRequest, signal?: AbortSignal ) => Promise export type RuntimeGeneratedImageEvent = { requestId: string type: 'generated-image' mimeType: 'image/png' | 'image/jpeg' | 'image/webp' data: string title: string imageContextNotice?: ConversationMessage['imageContextNotice'] } export type RuntimeModelUsageEvent = { requestId: string type: 'model-usage' callId: string runtime: 'model' | 'continue' | 'opencode' | 'deepseek-harness' provider: string model: string inputTokens: number outputTokens: number cacheReadTokens: number cacheWriteTokens: number reportedTotalTokens?: number } export type RuntimePublicEvent = | AgentEvent | RuntimeGeneratedImageEvent | RuntimeModelUsageEvent export type RemoteSemanticEventProvenance = { source: 'remote-semantic-transcript' bindingId: string operationId: string semanticSequence: string eventIndex: number } export type RemoteSemanticRuntimeEvent = RuntimePublicEvent & { remoteProvenance: RemoteSemanticEventProvenance } export type RemoteSemanticCheckpointEvent = { requestId: string type: 'remote-semantic-checkpoint' remoteProvenance: RemoteSemanticEventProvenance } export type RuntimeEvent = | RuntimePublicEvent | RemoteSemanticCheckpointEvent export type RuntimeConversationCompactOutcome = { result: RuntimeConversationCompactResult usageEvents?: RuntimeModelUsageEvent[] } export interface AgentRuntime { /** A workspace facade whose sessions are owned by a shared local Runtime. */ readonly sharedProcess?: boolean readonly hasRetainedSessions?: boolean readonly runtimeId?: AgentRuntimeStatus['id'] readonly requiresToolApproval: boolean readonly supportsToolExecution: boolean /** Whether request-scoped GoodBuddy data tools can reach this runtime. */ readonly supportsScopedDataTools?: boolean /** * Whether `trustedInstructions` reach the model's system layer for every * turn. Runtimes without this guarantee receive them inside the prompt. */ readonly consumesTrustedInstructions?: boolean readonly capability?: 'chat' | 'image-generation' getStatus(): Promise testConnection?(): Promise getNativeSnapshot?(workspace?: string): Promise compactConversation?( request: RuntimeConversationCompactInput, signal: AbortSignal ): Promise run( request: AgentExecutionRequest, signal: AbortSignal, authorize?: RuntimeAuthorizer ): AsyncGenerator respondToQuestion?( questionId: string, answers?: AgentQuestionAnswer[] ): Promise releaseConversation?(conversationId: string): Promise /** * Stop Main-process admission during a normal application exit. Runtimes * that implement this hook may intentionally leave remote work owned by * another process running after Desktop disconnects. */ detachForApplicationExit?(): void | Promise dispose(): Promise } export type AgentImage = { name: string mediaType: 'image/png' | 'image/jpeg' data: string } export type RemoteRecoveredTool = ConversationToolActivity & { callId: string } export type RemoteRecoveredSubagent = ConversationSubagentActivity export type AgentExecutionRequest = AgentRequest & { /** Resolved Main-side workspace, never taken from the current UI selection. */ executionWorkspace?: string images?: AgentImage[] imageContextNotice?: ConversationMessage['imageContextNotice'] /** Main-process-only recursion guard for direct-model programming delegation. */ directModelDelegationDepth?: 0 | 1 /** Main-process-only instructions placed in the model system layer. */ trustedInstructions?: string /** Main-process-only request-scoped authorization for built-in data tools. */ knowledgeCapabilityToken?: string storyGraphBinding?: import('./knowledge-mcp-gateway').StoryGraphRemoteBinding imageToolBinding?: ImageToolBinding /** Main-process-only browser tab fixed for this request. */ browserTabId?: BrowserTabId /** * Main-process recovery cursor for an Agent-owned semantic prompt. * It is never sent as prompt content and is ignored by local runtimes. */ remoteSemanticAfterSequence?: string /** Recovery may attach an accepted Agent prompt but must never replay it. */ remoteRecoveryOnly?: boolean /** Main-only durable tool state used to merge partial recovery updates. */ remoteRecoveredTools?: readonly RemoteRecoveredTool[] /** Derived from committed task events, including text before disconnect. */ remoteHasResponseTextAfterToolFailure?: boolean /** Main-only durable native subagent state for partial recovery updates. */ remoteRecoveredSubagents?: readonly RemoteRecoveredSubagent[] } import type { ImageToolBinding } from './image-tool-binding'