import type { Peer } from 'crossws'; import type { PageContext, ClientToolDefinition, ServerToolMetadata, ConversationStateSnapshot, SelectedBlock } from '../../../shared/types.js'; import type { ServerPlan } from '../../server-tools/index.js'; export declare class Session { /** The single, immutable source of truth for the conversation. */ private history; pendingToolCalls: Map void; reject: (error: Error) => void; }>; abortController: AbortController | null; isProcessing: boolean; /** Names of eager tools sent to the LLM on every turn */ toolNames: string[]; /** Names of lazy tools held back until activated via load_tools */ lazyToolNames: string[]; /** Names of lazy tools that have been activated via load_tools */ activatedLazyTools: Set; /** Names of skills that have been loaded via load_skills */ loadedSkills: Set; /** Page context received from client on init */ pageContext?: PageContext; /** Current plan (null when no plan is active) */ plan: ServerPlan | null; /** Whether any real work (non-server tool calls) happened since the last plan step started */ planStepHasWork: boolean; /** Pending plan approval promise resolver */ pendingPlanApproval: { resolve: (approved: boolean) => void; } | null; /** Last generic tool definitions for transcript */ private lastTools; /** Last raw request payload for transcript (dev only) */ private lastDebugPayload; /** Bundled tool metadata map for server-side resolution */ private bundledToolMap; /** Cache for resolved JSON Schemas (Zod→JSON Schema is deterministic) */ private jsonSchemaCache; constructor(toolDefinitions: ServerToolMetadata[]); /** * Resolve a single tool name into a ClientToolDefinition. * Resolves from bundled metadata. Caches the JSON Schema conversion. */ resolveToolDefinition(name: string): ClientToolDefinition | undefined; /** * Resolve multiple tool names into ClientToolDefinition objects. * Skips names that cannot be resolved. */ resolveToolDefinitions(names: string[]): ClientToolDefinition[]; /** * Look up name + description for a tool. */ private getToolSummary; init(toolNames: string[], pageContext: PageContext): void; start(peer: Peer, prompt: string, apiKey: string, authSecret: string, selectedBlocks?: SelectedBlock[], autoLoadTools?: string[], autoLoadSkills?: string[], preSeededResults?: { toolName: string; params: Record; result: unknown; }[], autoExecuteTools?: { toolName: string; params: Record; }[], rollbackToUserMessageIndex?: number): void; /** * Remove the Nth real user turn (0-based) and every message after it. * "Real user turn" excludes tool-result relays. Throws if the index is * out of range — typically because the target turn has been pruned away. */ private truncateAtUserMessage; resolveToolResult(callId: string, result: { result: unknown; error?: string; skipLlmResponse?: boolean; }): void; cancel(peer: Peer): void; acceptChanges(peer: Peer, authSecret: string): void; rejectChanges(peer: Peer, authSecret: string): void; approvePlan(): void; rejectPlan(): void; getTranscript(peer: Peer): void; newConversation(peer: Peer, authSecret: string): void; cleanup(): void; /** * Build a persistence snapshot and send it to the client. */ sendConversationState(peer: Peer, authSecret: string): void; /** * Create an aggressively pruned snapshot of the current conversation * for client-side persistence. */ getConversationStateForPersistence(authSecret: string): ConversationStateSnapshot; /** * Restore conversation state from a client-provided snapshot. * Verifies HMAC integrity before loading. */ restoreConversation(state: ConversationStateSnapshot, authSecret: string): { success: boolean; reason?: string; }; /** * Convert the server plan to a client-facing plan (strips descriptions). */ private toClientPlan; /** * Build an ActivePlanContext from the current plan state, * or undefined if no plan step is in progress. */ private getActivePlanContext; /** * Wait for the user to approve or reject the plan. */ private waitForPlanApproval; private runAgentLoop; private waitForToolResult; /** * Build the context object passed to a server-side tool handler. `assistantContent` * is the live block array for the current turn — `commitMessagesEarly` flushes and * resets it in place, so it must be the same reference the stream loop appends to. */ private buildServerToolContext; /** * Dispatch a server-side tool: reject if unavailable, coerce + validate input, * run the handler. Returns the blocks to merge into the turn's results. */ private dispatchServerTool; /** * Dispatch a client-side tool: send the call to the peer and await its result. * An `agentMessage` on the result replaces the `label` in the payload fed back * to the LLM (the label is UI-only). Returns the tool_result block(s). */ /** * Validate an LLM-generated client tool call against its Zod `paramsSchema` * (the same schema the client parses with), server-side, before dispatching * to the peer. Returns an error string on a schema failure so the caller can * reject it silently. Unknown tools pass through (handled by normal dispatch). */ private validateClientToolInput; private dispatchClientTool; /** * Append a synthetic assistant `tool_use` + user `tool_result` message pair — * the shape used to inject pre-seeded results and to record auto-executed tool * calls before the LLM loop starts. */ private pushToolExchange; /** * Safely push a user message, merging with the last message if it's also a * user message — the LLM API rejects consecutive same-role messages. */ private safePushUserMessage; /** * Whether a tool's results go stale after a mutation — used by the live * projection's eager volatile eviction. Volatility is a property of the tool * definition, so it holds regardless of the current tool set. */ private volatileLookup; private buildTranscript; }