@firtoz/chat-agent 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat-agent-base.ts"],"names":[],"mappings":"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","file":"chunk-G5P5JXRF.js","sourcesContent":["import { exhaustiveGuard } from \"@firtoz/maybe-error\";\nimport { OpenRouter } from \"@openrouter/sdk\";\n\n// OpenRouter SDK message types (simplified for our use)\ntype ORToolCall = {\n\tid: string;\n\ttype: \"function\";\n\tfunction: { name: string; arguments: string };\n} & Record<string, unknown>;\n\ntype ORSystemMessage = { role: \"system\"; content: string };\ntype ORUserMessage = { role: \"user\"; content: string };\ntype ORAssistantMessage = {\n\trole: \"assistant\";\n\tcontent?: string | null;\n\ttoolCalls?: ORToolCall[];\n};\ntype ORToolMessage = { role: \"tool\"; content: string; toolCallId: string };\ntype OpenRouterMessage =\n\t| ORSystemMessage\n\t| ORUserMessage\n\t| ORAssistantMessage\n\t| ORToolMessage;\n\nimport {\n\tAgent,\n\ttype AgentContext,\n\ttype Connection,\n\ttype ConnectionContext,\n} from \"agents\";\nimport {\n\ttype AssistantMessage,\n\ttype ChatMessage,\n\tisAssistantMessage,\n\ttype ServerMessage,\n\tsafeParseClientMessage,\n\ttype TokenUsage,\n\ttype ToolCall,\n\ttype ToolCallDelta,\n\ttype ToolDefinition,\n\ttype ToolMessage,\n\ttype UserMessage,\n\ttype SendMessagePayload,\n} from \"./chat-messages\";\n\n// Re-export types for external use\nexport type {\n\tAssistantMessage,\n\tChatMessage,\n\tClientMessage,\n\tServerMessage,\n\tTokenUsage,\n\tToolCall,\n\tToolDefinition,\n\tToolMessage,\n\tUserMessage,\n\tToolNeedsApprovalFn,\n\tSendMessagePayload,\n\tSendMessageTrigger,\n\tToolApprovalResponsePayload,\n\tToolApprovalRequestMessage,\n} from \"./chat-messages\";\nexport { defineTool } from \"./chat-messages\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default system prompt - override getSystemPrompt() to customize */\nconst DEFAULT_SYSTEM_PROMPT = \"You are a helpful AI assistant.\";\n\n/** Number of chunks to buffer before flushing to SQLite */\nconst CHUNK_BUFFER_SIZE = 10;\n/** Maximum buffer size to prevent memory issues */\nconst CHUNK_BUFFER_MAX_SIZE = 100;\n/** Maximum age for a \"streaming\" stream before considering it stale (5 minutes) */\nconst STREAM_STALE_THRESHOLD_MS = 5 * 60 * 1000;\n/** Cleanup interval for old streams (10 minutes) */\nconst CLEANUP_INTERVAL_MS = 10 * 60 * 1000;\n/** Age threshold for cleaning up completed streams (24 hours) */\nconst CLEANUP_AGE_THRESHOLD_MS = 24 * 60 * 60 * 1000;\n\n/** Default max length for persisted tool message `content` (characters) */\nconst DEFAULT_MAX_TOOL_CONTENT_CHARS = 200_000;\n\n/** OpenAI stream keys on each tool_calls[] element (camelCase or snake_case) */\nconst STREAM_TOOL_TOP_KEYS = new Set([\"index\", \"id\", \"type\", \"function\"]);\n\nfunction getRawToolCallDeltaEntry(\n\tchunk: unknown,\n\tindex: number,\n): Record<string, unknown> | undefined {\n\tconst c = chunk as {\n\t\tchoices?: Array<{ delta?: Record<string, unknown> }>;\n\t};\n\tconst delta = c.choices?.[0]?.delta;\n\tif (!delta) {\n\t\treturn undefined;\n\t}\n\tconst list = (delta.tool_calls ?? delta.toolCalls) as unknown;\n\tif (!Array.isArray(list) || index < 0 || index >= list.length) {\n\t\treturn undefined;\n\t}\n\tconst raw = list[index];\n\tif (!raw || typeof raw !== \"object\") {\n\t\treturn undefined;\n\t}\n\treturn raw as Record<string, unknown>;\n}\n\nfunction extractProviderMetadataFromRawToolPart(\n\traw: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n\tconst meta: Record<string, unknown> = {};\n\tfor (const [k, v] of Object.entries(raw)) {\n\t\tif (STREAM_TOOL_TOP_KEYS.has(k)) {\n\t\t\tcontinue;\n\t\t}\n\t\tmeta[k] = v;\n\t}\n\tconst fn = raw.function;\n\tif (fn && typeof fn === \"object\" && !Array.isArray(fn)) {\n\t\tconst f = fn as Record<string, unknown>;\n\t\tconst fnExtra: Record<string, unknown> = {};\n\t\tfor (const [k, v] of Object.entries(f)) {\n\t\t\tif (k === \"name\" || k === \"arguments\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfnExtra[k] = v;\n\t\t}\n\t\tif (Object.keys(fnExtra).length > 0) {\n\t\t\tmeta.function = fnExtra;\n\t\t}\n\t}\n\treturn Object.keys(meta).length > 0 ? meta : undefined;\n}\n\ntype PendingClientToolAutoContinue = {\n\tconnection: Connection;\n\ttoolCallId: string;\n\ttoolName: string;\n\toutput: unknown;\n};\n\ntype PendingToolApproval = {\n\tresolve: (approved: boolean) => void;\n};\n\n// ============================================================================\n// ChatAgent Class\n// ============================================================================\n\n/**\n * ChatAgentBase - Abstract base class for AI chat agents\n *\n * Features:\n * - DB-agnostic SQLite persistence in Durable Objects\n * - Resumable streaming with chunk buffering (like @cloudflare/ai-chat)\n * - Broadcast of stream and history updates to all WebSocket connections (multi-tab)\n * - Serialized chat turns + batched client tool auto-continue\n * - OpenRouter via Cloudflare AI Gateway\n *\n * Subclasses must implement database operations via abstract methods.\n *\n * @template Env - Environment bindings type (must include OPENROUTER_API_KEY, optionally AI Gateway config)\n */\nexport abstract class ChatAgentBase<\n\tEnv extends Cloudflare.Env & {\n\t\tOPENROUTER_API_KEY: string;\n\t} = Cloudflare.Env & { OPENROUTER_API_KEY: string },\n> extends Agent<Env> {\n\t/** In-memory cache of messages */\n\tmessages: ChatMessage[] = [];\n\n\t/**\n\t * When set, oldest messages are deleted from storage after each save so only the last N remain.\n\t * Does not change what is sent to the model unless you prune separately.\n\t */\n\tprotected maxPersistedMessages?: number;\n\n\t/** Map of message IDs to AbortControllers for request cancellation */\n\tprivate _abortControllers: Map<string, AbortController> = new Map();\n\n\t/** Currently active stream ID */\n\tprivate _activeStreamId: string | null = null;\n\t/** Message ID being streamed */\n\tprivate _activeMessageId: string | null = null;\n\t/** True only while the OpenRouter async iterator for the active stream is running */\n\tprivate _openRouterStreamLive = false;\n\t/** Current chunk index for active stream */\n\tprivate _streamChunkIndex = 0;\n\t/** Buffer for chunks pending write */\n\tprivate _chunkBuffer: Array<{\n\t\tstreamId: string;\n\t\tcontent: string;\n\t\tindex: number;\n\t}> = [];\n\t/** Lock for flush operations */\n\tprivate _isFlushingChunks = false;\n\t/** Last cleanup timestamp */\n\tprivate _lastCleanupTime = 0;\n\n\t/** Client-registered tools (tools defined at runtime from frontend) */\n\tprivate _clientTools: Map<\n\t\tstring,\n\t\t{ name: string; description?: string; parameters?: Record<string, unknown> }\n\t> = new Map();\n\n\t/** FIFO serialization of chat turns (user sends, tool continuations, etc.) */\n\tprivate _turnTail: Promise<void> = Promise.resolve();\n\t/** Bumped by {@link resetTurnState} to ignore stale async work */\n\tprivate _turnGeneration = 0;\n\n\t/** Connection id that last queued an auto-continue after client tools (for multi-tab hints) */\n\tprivate _continuationOriginConnectionId: string | null = null;\n\n\tprivate _pendingClientToolAutoContinue: PendingClientToolAutoContinue[] = [];\n\tprivate _clientToolAutoContinueFlushScheduled = false;\n\n\t/** Human-in-the-loop: server tools awaiting `toolApprovalResponse` (not queued — avoids deadlock). */\n\tprivate _pendingToolApprovals: Map<string, PendingToolApproval> = new Map();\n\n\t// ============================================================================\n\t// Constructor - Following @cloudflare/ai-chat pattern\n\t// ============================================================================\n\n\tconstructor(ctx: AgentContext, env: Env) {\n\t\tsuper(ctx, env);\n\n\t\t// Initialize database (subclass-specific)\n\t\tthis.dbInitialize();\n\n\t\t// Load messages from DB\n\t\tthis.messages = this.dbLoadMessages();\n\n\t\t// Restore any active stream from a previous session (never live after restore)\n\t\tthis._restoreActiveStream();\n\t\tthis._openRouterStreamLive = false;\n\n\t\t// Wrap onConnect to handle stream resumption\n\t\tconst _onConnect = this.onConnect.bind(this);\n\t\tthis.onConnect = async (\n\t\t\tconnection: Connection,\n\t\t\tconnCtx: ConnectionContext,\n\t\t) => {\n\t\t\tif (this._activeStreamId && this._activeMessageId) {\n\t\t\t\tthis._notifyStreamResuming(connection);\n\t\t\t}\n\t\t\treturn _onConnect(connection, connCtx);\n\t\t};\n\t}\n\n\t// ============================================================================\n\t// Abstract Database Methods - Subclasses must implement\n\t// ============================================================================\n\n\t/**\n\t * Initialize database and run migrations\n\t * Called once during constructor\n\t */\n\tprotected abstract dbInitialize(): void;\n\n\t/**\n\t * Load all messages from database\n\t * @returns Array of chat messages ordered by createdAt\n\t */\n\tprotected abstract dbLoadMessages(): ChatMessage[];\n\n\t/**\n\t * Save or update a message in database\n\t * @param msg - The message to save\n\t */\n\tprotected abstract dbSaveMessage(msg: ChatMessage): void;\n\n\t/**\n\t * Clear all data (messages, streams, chunks)\n\t */\n\tprotected abstract dbClearAll(): void;\n\n\t/**\n\t * Find an active streaming session\n\t * @returns Stream info or null if none active\n\t */\n\tprotected abstract dbFindActiveStream(): {\n\t\tid: string;\n\t\tmessageId: string;\n\t\tcreatedAt: Date;\n\t} | null;\n\n\t/**\n\t * Delete a stream and all its chunks\n\t * @param streamId - The stream to delete\n\t */\n\tprotected abstract dbDeleteStreamWithChunks(streamId: string): void;\n\n\t/**\n\t * Create a new stream metadata entry\n\t * @param streamId - Unique stream identifier\n\t * @param messageId - Associated message ID\n\t */\n\tprotected abstract dbInsertStreamMetadata(\n\t\tstreamId: string,\n\t\tmessageId: string,\n\t): void;\n\n\t/**\n\t * Update stream status to completed or error\n\t * @param streamId - The stream to update\n\t * @param status - New status\n\t */\n\tprotected abstract dbUpdateStreamStatus(\n\t\tstreamId: string,\n\t\tstatus: \"completed\" | \"error\",\n\t): void;\n\n\t/**\n\t * Delete old completed streams older than cutoff\n\t * @param cutoffMs - Timestamp in milliseconds\n\t */\n\tprotected abstract dbDeleteOldCompletedStreams(cutoffMs: number): void;\n\n\t/**\n\t * Find the maximum chunk index for a stream\n\t * @param streamId - The stream to query\n\t * @returns Max chunk index or null if no chunks\n\t */\n\tprotected abstract dbFindMaxChunkIndex(streamId: string): number | null;\n\n\t/**\n\t * Insert multiple stream chunks\n\t * @param chunks - Array of chunks to insert\n\t */\n\tprotected abstract dbInsertChunks(\n\t\tchunks: Array<{\n\t\t\tid: string;\n\t\t\tstreamId: string;\n\t\t\tcontent: string;\n\t\t\tchunkIndex: number;\n\t\t}>,\n\t): void;\n\n\t/**\n\t * Get all chunks for a stream, ordered by index\n\t * @param streamId - The stream to query\n\t * @returns Array of chunk content strings\n\t */\n\tprotected abstract dbGetChunks(streamId: string): string[];\n\n\t/**\n\t * Delete all chunks for a stream\n\t * @param streamId - The stream to clean up\n\t */\n\tprotected abstract dbDeleteChunks(streamId: string): void;\n\n\t/**\n\t * Whether stream metadata or chunks exist for this stream id\n\t */\n\tprotected abstract dbIsStreamKnown(streamId: string): boolean;\n\n\t/**\n\t * Delete oldest messages until at most `maxMessages` rows remain\n\t */\n\tprotected abstract dbTrimMessagesToMax(maxMessages: number): void;\n\n\t/**\n\t * Replace all chat messages (used for client sync / regenerate). Implementations should delete existing rows then insert.\n\t */\n\tprotected abstract dbReplaceAllMessages(messages: ChatMessage[]): void;\n\n\t// ============================================================================\n\t// Persistence hooks (override in subclasses)\n\t// ============================================================================\n\n\t/**\n\t * Transform a message immediately before it is written to storage.\n\t * Default: return the message unchanged.\n\t */\n\tprotected sanitizeMessageForPersistence(msg: ChatMessage): ChatMessage {\n\t\treturn msg;\n\t}\n\n\t// ============================================================================\n\t// Turn coordination (subclasses / host code)\n\t// ============================================================================\n\n\t/**\n\t * Resolves after all queued turns have finished and no OpenRouter stream is active.\n\t */\n\tprotected waitUntilStable(): Promise<void> {\n\t\treturn this._turnTail.then(async () => {\n\t\t\twhile (this._openRouterStreamLive) {\n\t\t\t\tawait new Promise((r) => queueMicrotask(r));\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Abort in-flight generation, clear pending client tool auto-continue batch, and invalidate queued async work.\n\t * Call from custom clear handlers; {@link clearHistory} path also resets state.\n\t */\n\tprotected resetTurnState(): void {\n\t\tthis._turnGeneration++;\n\t\tthis._pendingClientToolAutoContinue = [];\n\t\tthis._clientToolAutoContinueFlushScheduled = false;\n\t\tthis._continuationOriginConnectionId = null;\n\t\tfor (const p of this._pendingToolApprovals.values()) {\n\t\t\tp.resolve(false);\n\t\t}\n\t\tthis._pendingToolApprovals.clear();\n\t\tfor (const id of [...this._abortControllers.keys()]) {\n\t\t\tthis._cancelRequest(id);\n\t\t}\n\t}\n\n\t/**\n\t * True when the last assistant message still has tool calls without matching tool role replies.\n\t */\n\tprotected hasPendingInteraction(): boolean {\n\t\tif (this._pendingToolApprovals.size > 0) {\n\t\t\treturn true;\n\t\t}\n\t\tconst last = this.messages[this.messages.length - 1];\n\t\tif (!last || last.role !== \"assistant\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (!last.toolCalls?.length) {\n\t\t\treturn false;\n\t\t}\n\t\tconst pending = new Set(last.toolCalls.map((t) => t.id));\n\t\tfor (const m of this.messages) {\n\t\t\tif (m.role === \"tool\" && pending.has(m.toolCallId)) {\n\t\t\t\tpending.delete(m.toolCallId);\n\t\t\t}\n\t\t}\n\t\treturn pending.size > 0;\n\t}\n\n\t// ============================================================================\n\t// Message Persistence\n\t// ============================================================================\n\n\tprivate _persistMessage(msg: ChatMessage): void {\n\t\tconst sanitized = this.sanitizeMessageForPersistence(msg);\n\t\tconst stored = this._maybeTruncateToolMessageContent(sanitized);\n\t\tthis.dbSaveMessage(stored);\n\t\tconst max = this.maxPersistedMessages;\n\t\tif (typeof max === \"number\" && max > 0) {\n\t\t\tthis.dbTrimMessagesToMax(max);\n\t\t\tthis.messages = this.dbLoadMessages();\n\t\t}\n\t}\n\n\tprivate _maybeTruncateToolMessageContent(msg: ChatMessage): ChatMessage {\n\t\tif (msg.role !== \"tool\") {\n\t\t\treturn msg;\n\t\t}\n\t\tconst content = msg.content;\n\t\tif (content.length <= DEFAULT_MAX_TOOL_CONTENT_CHARS) {\n\t\t\treturn msg;\n\t\t}\n\t\tconst truncated =\n\t\t\tcontent.slice(0, DEFAULT_MAX_TOOL_CONTENT_CHARS) +\n\t\t\t`\\n… [truncated ${content.length - DEFAULT_MAX_TOOL_CONTENT_CHARS} chars for storage]`;\n\t\treturn { ...msg, content: truncated };\n\t}\n\n\tprivate _clearMessages(): void {\n\t\tthis.resetTurnState();\n\t\tthis.dbClearAll();\n\t\tthis._activeStreamId = null;\n\t\tthis._activeMessageId = null;\n\t\tthis._streamChunkIndex = 0;\n\t\tthis._chunkBuffer = [];\n\t\tthis.messages = [];\n\t}\n\n\t// ============================================================================\n\t// Stream Restoration (following @cloudflare/ai-chat pattern)\n\t// ============================================================================\n\n\t/**\n\t * Restore active stream state if the agent was restarted during streaming.\n\t * Called during construction to recover any interrupted streams.\n\t */\n\tprivate _restoreActiveStream(): void {\n\t\tconst stream = this.dbFindActiveStream();\n\t\tif (!stream) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst streamAge = Date.now() - stream.createdAt.getTime();\n\n\t\t// Delete stale streams\n\t\tif (streamAge > STREAM_STALE_THRESHOLD_MS) {\n\t\t\tthis.dbDeleteStreamWithChunks(stream.id);\n\t\t\tconsole.warn(\n\t\t\t\t`[ChatAgent] Deleted stale stream ${stream.id} (age: ${Math.round(streamAge / 1000)}s)`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tthis._activeStreamId = stream.id;\n\t\tthis._activeMessageId = stream.messageId;\n\n\t\t// Get the last chunk index\n\t\tconst maxIndex = this.dbFindMaxChunkIndex(stream.id);\n\t\tthis._streamChunkIndex = maxIndex != null ? maxIndex + 1 : 0;\n\t}\n\n\t/**\n\t * Notify a connection about an active stream that can be resumed.\n\t */\n\tprivate _notifyStreamResuming(connection: Connection): void {\n\t\tif (!this._activeStreamId || !this._activeMessageId) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._sendTo(connection, {\n\t\t\ttype: \"streamResuming\",\n\t\t\tid: this._activeMessageId,\n\t\t\tstreamId: this._activeStreamId,\n\t\t});\n\t}\n\n\t// ============================================================================\n\t// Stream Chunk Management\n\t// ============================================================================\n\n\tprivate _storeChunk(streamId: string, content: string): void {\n\t\t// Force flush if buffer is at max\n\t\tif (this._chunkBuffer.length >= CHUNK_BUFFER_MAX_SIZE) {\n\t\t\tthis._flushChunkBuffer();\n\t\t}\n\n\t\tthis._chunkBuffer.push({\n\t\t\tstreamId,\n\t\t\tcontent,\n\t\t\tindex: this._streamChunkIndex++,\n\t\t});\n\n\t\t// Flush when buffer reaches threshold\n\t\tif (this._chunkBuffer.length >= CHUNK_BUFFER_SIZE) {\n\t\t\tthis._flushChunkBuffer();\n\t\t}\n\t}\n\n\tprivate _flushChunkBuffer(): void {\n\t\tif (this._isFlushingChunks || this._chunkBuffer.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isFlushingChunks = true;\n\t\ttry {\n\t\t\tconst chunks = this._chunkBuffer;\n\t\t\tthis._chunkBuffer = [];\n\n\t\t\t// Convert to format expected by dbInsertChunks\n\t\t\tconst chunksToInsert = chunks.map((chunk) => ({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tstreamId: chunk.streamId,\n\t\t\t\tcontent: chunk.content,\n\t\t\t\tchunkIndex: chunk.index,\n\t\t\t}));\n\n\t\t\tthis.dbInsertChunks(chunksToInsert);\n\t\t} finally {\n\t\t\tthis._isFlushingChunks = false;\n\t\t}\n\t}\n\n\tprivate _startStream(messageId: string): string {\n\t\t// Flush any pending chunks from previous streams\n\t\tthis._flushChunkBuffer();\n\n\t\tconst streamId = crypto.randomUUID();\n\t\tthis._activeStreamId = streamId;\n\t\tthis._activeMessageId = messageId;\n\t\tthis._streamChunkIndex = 0;\n\n\t\tthis.dbInsertStreamMetadata(streamId, messageId);\n\n\t\treturn streamId;\n\t}\n\n\t/**\n\t * Complete stream with a full message (supports tool calls)\n\t */\n\tprivate _completeStreamWithMessage(\n\t\tstreamId: string,\n\t\tmessage: AssistantMessage,\n\t): void {\n\t\t// Flush any pending chunks\n\t\tthis._flushChunkBuffer();\n\n\t\tthis.dbUpdateStreamStatus(streamId, \"completed\");\n\n\t\t// Save the complete message\n\t\tthis._persistMessage(message);\n\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\tthis.messages.push(message);\n\t\t}\n\n\t\t// Clean up stream chunks\n\t\tthis.dbDeleteChunks(streamId);\n\n\t\tthis._activeStreamId = null;\n\t\tthis._activeMessageId = null;\n\t\tthis._streamChunkIndex = 0;\n\n\t\t// Periodically clean up old streams\n\t\tthis._maybeCleanupOldStreams();\n\t}\n\n\tprivate _markStreamError(streamId: string): void {\n\t\tthis._flushChunkBuffer();\n\n\t\tthis.dbUpdateStreamStatus(streamId, \"error\");\n\n\t\tthis._activeStreamId = null;\n\t\tthis._activeMessageId = null;\n\t\tthis._streamChunkIndex = 0;\n\t}\n\n\t/**\n\t * Clean up old completed streams periodically.\n\t */\n\tprivate _maybeCleanupOldStreams(): void {\n\t\tconst now = Date.now();\n\t\tif (now - this._lastCleanupTime < CLEANUP_INTERVAL_MS) {\n\t\t\treturn;\n\t\t}\n\t\tthis._lastCleanupTime = now;\n\n\t\tconst cutoffMs = now - CLEANUP_AGE_THRESHOLD_MS;\n\t\tthis.dbDeleteOldCompletedStreams(cutoffMs);\n\t}\n\n\tprivate _getStreamChunks(streamId: string): string[] {\n\t\t// Flush first to ensure all chunks are persisted\n\t\tthis._flushChunkBuffer();\n\n\t\treturn this.dbGetChunks(streamId);\n\t}\n\n\t/**\n\t * Finalize a stream that has buffered chunks but no live OpenRouter reader (e.g. after DO restart).\n\t */\n\tprivate _finalizeOrphanedStreamFromChunks(streamId: string): void {\n\t\tif (this._activeStreamId !== streamId || !this._activeMessageId) {\n\t\t\treturn;\n\t\t}\n\t\tconst messageId = this._activeMessageId;\n\t\tconst chunks = this._getStreamChunks(streamId);\n\t\tconst text = chunks.join(\"\");\n\t\tconst assistantMessage: AssistantMessage = {\n\t\t\tid: messageId,\n\t\t\trole: \"assistant\",\n\t\t\tcontent: text.length > 0 ? text : null,\n\t\t\tcreatedAt: Date.now(),\n\t\t};\n\t\tthis._completeStreamWithMessage(streamId, assistantMessage);\n\t\tthis._broadcast({\n\t\t\ttype: \"messageEnd\",\n\t\t\tid: messageId,\n\t\t\tcreatedAt: assistantMessage.createdAt,\n\t\t});\n\t}\n\n\t// ============================================================================\n\t// Abort Controller Management\n\t// ============================================================================\n\n\tprivate _getAbortSignal(id: string): AbortSignal {\n\t\tlet controller = this._abortControllers.get(id);\n\t\tif (!controller) {\n\t\t\tcontroller = new AbortController();\n\t\t\tthis._abortControllers.set(id, controller);\n\t\t}\n\t\treturn controller.signal;\n\t}\n\n\tprivate _cancelRequest(id: string): void {\n\t\tconst controller = this._abortControllers.get(id);\n\t\tif (controller) {\n\t\t\tcontroller.abort();\n\t\t\tthis._abortControllers.delete(id);\n\t\t}\n\t}\n\n\tprivate _removeAbortController(id: string): void {\n\t\tthis._abortControllers.delete(id);\n\t}\n\n\t// ============================================================================\n\t// Broadcasting\n\t// ============================================================================\n\n\tprivate _broadcast(msg: ServerMessage): void {\n\t\tthis.broadcast(JSON.stringify(msg));\n\t}\n\n\tprivate _sendTo(connection: Connection, msg: ServerMessage): void {\n\t\tconnection.send(JSON.stringify(msg));\n\t}\n\n\tprivate _enqueueTurn(fn: () => Promise<void>): Promise<void> {\n\t\tconst run = this._turnTail.then(fn);\n\t\tthis._turnTail = run.then(\n\t\t\t() => {},\n\t\t\t() => {},\n\t\t);\n\t\treturn run;\n\t}\n\n\tprivate _resolveToolApproval(approvalId: string, approved: boolean): void {\n\t\tconst pending = this._pendingToolApprovals.get(approvalId);\n\t\tif (!pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis._pendingToolApprovals.delete(approvalId);\n\t\tpending.resolve(approved);\n\t}\n\n\tprivate _mergeProviderMetadata(\n\t\ta: Record<string, unknown> | undefined,\n\t\tb: Record<string, unknown> | undefined,\n\t): Record<string, unknown> | undefined {\n\t\tif (!a && !b) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { ...(a ?? {}), ...(b ?? {}) };\n\t}\n\n\tprivate _replaceMessagesFromClient(\n\t\tmessages: ReadonlyArray<ChatMessage>,\n\t): void {\n\t\tthis.resetTurnState();\n\t\tthis._flushChunkBuffer();\n\t\tif (this._activeStreamId) {\n\t\t\tthis.dbDeleteStreamWithChunks(this._activeStreamId);\n\t\t}\n\t\tthis._activeStreamId = null;\n\t\tthis._activeMessageId = null;\n\t\tthis._streamChunkIndex = 0;\n\t\tthis._chunkBuffer = [];\n\t\tthis.dbReplaceAllMessages([...messages]);\n\t\tthis.messages = [...messages];\n\t}\n\n\t// ============================================================================\n\t// OpenRouter Integration\n\t// ============================================================================\n\n\tprivate _getOpenRouter(): OpenRouter {\n\t\t// Use AI Gateway if configured, otherwise use OpenRouter directly\n\t\tconst envWithGateway = this.env as Env & {\n\t\t\tCLOUDFLARE_ACCOUNT_ID?: string;\n\t\t\tAI_GATEWAY_NAME?: string;\n\t\t\tAI_GATEWAY_TOKEN?: string;\n\t\t};\n\n\t\tconst serverURL =\n\t\t\tenvWithGateway.CLOUDFLARE_ACCOUNT_ID && envWithGateway.AI_GATEWAY_NAME\n\t\t\t\t? `https://gateway.ai.cloudflare.com/v1/${envWithGateway.CLOUDFLARE_ACCOUNT_ID}/${envWithGateway.AI_GATEWAY_NAME}/openrouter`\n\t\t\t\t: undefined;\n\n\t\treturn new OpenRouter({\n\t\t\tapiKey: this.env.OPENROUTER_API_KEY,\n\t\t\t...(serverURL && { serverURL }),\n\t\t});\n\t}\n\n\t// ============================================================================\n\t// WebSocket Handlers\n\t// ============================================================================\n\n\tasync onConnect(connection: Connection, _ctx: ConnectionContext) {\n\t\tthis._sendTo(connection, { type: \"history\", messages: this.messages });\n\t}\n\n\tasync onClose(\n\t\tconnection: Connection,\n\t\t_code: number,\n\t\t_reason: string,\n\t\t_wasClean: boolean,\n\t): Promise<void> {\n\t\tif (this._continuationOriginConnectionId === connection.id) {\n\t\t\tthis._continuationOriginConnectionId = null;\n\t\t}\n\t}\n\n\tasync onMessage(connection: Connection, message: string) {\n\t\tconst data = safeParseClientMessage(message);\n\n\t\tif (!data) {\n\t\t\tconsole.error(\"Invalid client message:\", message);\n\t\t\tthis._sendTo(connection, {\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: \"Invalid message format\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tswitch (data.type) {\n\t\t\t\tcase \"getHistory\":\n\t\t\t\t\tthis._sendTo(connection, {\n\t\t\t\t\t\ttype: \"history\",\n\t\t\t\t\t\tmessages: this.messages,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"clearHistory\":\n\t\t\t\t\tawait this._enqueueTurn(async () => {\n\t\t\t\t\t\tthis._clearMessages();\n\t\t\t\t\t\tthis._broadcast({ type: \"history\", messages: [] });\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"sendMessage\":\n\t\t\t\t\tawait this._enqueueTurn(async () => {\n\t\t\t\t\t\tthis._continuationOriginConnectionId = connection.id;\n\t\t\t\t\t\tawait this._handleSendMessagePayload(data);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"toolApprovalResponse\":\n\t\t\t\t\tthis._resolveToolApproval(data.approvalId, data.approved);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"resumeStream\":\n\t\t\t\t\tthis._handleResumeStream(data.streamId);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"cancelRequest\":\n\t\t\t\t\tthis._cancelRequest(data.id);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\tawait this._handleToolResultMessage(\n\t\t\t\t\t\tconnection,\n\t\t\t\t\t\tdata.toolCallId,\n\t\t\t\t\t\tdata.toolName,\n\t\t\t\t\t\tdata.output,\n\t\t\t\t\t\tdata.autoContinue ?? false,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"registerTools\":\n\t\t\t\t\tawait this._enqueueTurn(async () => {\n\t\t\t\t\t\tthis._registerClientTools(\n\t\t\t\t\t\t\tconnection,\n\t\t\t\t\t\t\tdata.tools as ReadonlyArray<{\n\t\t\t\t\t\t\t\tname: string;\n\t\t\t\t\t\t\t\tdescription?: string;\n\t\t\t\t\t\t\t\tparameters?: Record<string, unknown>;\n\t\t\t\t\t\t\t}>,\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveGuard(data);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\"Error processing message:\", err);\n\t\t\tthis._broadcast({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: \"Failed to process message\",\n\t\t\t});\n\t\t}\n\t}\n\n\t// ============================================================================\n\t// Chat Message Handling\n\t// ============================================================================\n\n\t/**\n\t * Get the system prompt for the AI\n\t * Override this method to customize the AI's behavior\n\t */\n\tprotected getSystemPrompt(): string {\n\t\treturn DEFAULT_SYSTEM_PROMPT;\n\t}\n\n\t/**\n\t * Get the AI model to use\n\t * Override this method to use a different model\n\t */\n\tprotected getModel(): string {\n\t\treturn \"anthropic/claude-sonnet-4.5\";\n\t}\n\n\t/**\n\t * Get available tools for the AI\n\t * Override this method to provide custom tools\n\t */\n\tprotected getTools(): ToolDefinition[] {\n\t\treturn [];\n\t}\n\n\tprivate async _handleSendMessagePayload(\n\t\tdata: SendMessagePayload,\n\t): Promise<void> {\n\t\tconst trigger = data.trigger ?? \"submit-message\";\n\t\tif (trigger === \"regenerate-message\") {\n\t\t\tthis._replaceMessagesFromClient(data.messages ?? []);\n\t\t\tawait this._generateAIResponse();\n\t\t\treturn;\n\t\t}\n\t\tif (data.messages && data.messages.length > 0) {\n\t\t\tthis._replaceMessagesFromClient(data.messages);\n\t\t}\n\t\tconst content = data.content;\n\t\tif (content !== undefined && content !== \"\") {\n\t\t\tconst userMessage: UserMessage = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent,\n\t\t\t\tcreatedAt: Date.now(),\n\t\t\t};\n\t\t\tthis._persistMessage(userMessage);\n\t\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\t\tthis.messages.push(userMessage);\n\t\t\t}\n\t\t}\n\t\tconst last = this.messages[this.messages.length - 1];\n\t\tif (!last || last.role !== \"user\") {\n\t\t\tthis._broadcast({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Cannot generate: conversation must end with a user message (sync `messages` and/or send `content`).\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tawait this._generateAIResponse();\n\t}\n\n\tprivate async _handleToolResultMessage(\n\t\tconnection: Connection,\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\toutput: unknown,\n\t\tautoContinue: boolean,\n\t): Promise<void> {\n\t\tif (!autoContinue) {\n\t\t\tawait this._enqueueTurn(async () => {\n\t\t\t\tawait this._applyClientToolResult(connection, toolCallId, output);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis._pendingClientToolAutoContinue.push({\n\t\t\tconnection,\n\t\t\ttoolCallId,\n\t\t\ttoolName,\n\t\t\toutput,\n\t\t});\n\t\tthis._scheduleClientToolAutoContinueFlush();\n\t}\n\n\tprivate _scheduleClientToolAutoContinueFlush(): void {\n\t\tif (this._clientToolAutoContinueFlushScheduled) {\n\t\t\treturn;\n\t\t}\n\t\tthis._clientToolAutoContinueFlushScheduled = true;\n\t\tqueueMicrotask(() => {\n\t\t\tthis._clientToolAutoContinueFlushScheduled = false;\n\t\t\tconst batch = this._pendingClientToolAutoContinue.splice(0);\n\t\t\tif (batch.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid this._enqueueTurn(async () => {\n\t\t\t\tconst origin = batch[0]?.connection;\n\t\t\t\tif (origin) {\n\t\t\t\t\tthis._continuationOriginConnectionId = origin.id;\n\t\t\t\t}\n\t\t\t\tfor (const item of batch) {\n\t\t\t\t\tawait this._applyClientToolResult(\n\t\t\t\t\t\titem.connection,\n\t\t\t\t\t\titem.toolCallId,\n\t\t\t\t\t\titem.output,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait this._generateAIResponse();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate async _applyClientToolResult(\n\t\t_connection: Connection,\n\t\ttoolCallId: string,\n\t\toutput: unknown,\n\t): Promise<void> {\n\t\tconst assistantMsg = this.messages.find(\n\t\t\t(m) =>\n\t\t\t\tisAssistantMessage(m) &&\n\t\t\t\tm.toolCalls?.some((tc: ToolCall) => tc.id === toolCallId),\n\t\t) as AssistantMessage | undefined;\n\n\t\tif (!assistantMsg) {\n\t\t\tconsole.warn(\n\t\t\t\t`[ChatAgent] Tool result for unknown tool call: ${toolCallId}`,\n\t\t\t);\n\t\t\tthis._broadcast({ type: \"error\", message: \"Tool call not found\" });\n\t\t\treturn;\n\t\t}\n\n\t\tconst toolMessage: ToolMessage = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\trole: \"tool\",\n\t\t\ttoolCallId,\n\t\t\tcontent: JSON.stringify(output),\n\t\t\tcreatedAt: Date.now(),\n\t\t};\n\n\t\tthis._persistMessage(toolMessage);\n\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\tthis.messages.push(toolMessage);\n\t\t}\n\t\tthis._broadcast({ type: \"messageUpdated\", message: toolMessage });\n\t}\n\n\t/**\n\t * Generate AI response (can be called for initial message or after tool results)\n\t */\n\tprivate async _generateAIResponse(): Promise<void> {\n\t\tconst generation = this._turnGeneration;\n\t\tconst assistantId = crypto.randomUUID();\n\t\tconst streamId = this._startStream(assistantId);\n\t\tconst abortSignal = this._getAbortSignal(assistantId);\n\n\t\tthis._broadcast({ type: \"messageStart\", id: assistantId, streamId });\n\n\t\tconst runStream = async (): Promise<void> => {\n\t\t\tlet fullContent = \"\";\n\t\t\tlet usage: TokenUsage | undefined;\n\n\t\t\tconst toolCallsInProgress: Map<\n\t\t\t\tnumber,\n\t\t\t\t{\n\t\t\t\t\tid: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\targuments: string;\n\t\t\t\t\tproviderMetadata?: Record<string, unknown>;\n\t\t\t\t}\n\t\t\t> = new Map();\n\n\t\t\tconst openRouter = this._getOpenRouter();\n\t\t\tconst toolsMap = this._getToolsMap();\n\t\t\tconst tools = Array.from(toolsMap.values());\n\t\t\tconst apiMessages = this._buildApiMessages();\n\n\t\t\tconst envWithGateway = this.env as Env & { AI_GATEWAY_TOKEN?: string };\n\t\t\tconst headers = envWithGateway.AI_GATEWAY_TOKEN\n\t\t\t\t? {\n\t\t\t\t\t\t\"cf-aig-authorization\": `Bearer ${envWithGateway.AI_GATEWAY_TOKEN}`,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\t\tconst stream = await openRouter.chat.send(\n\t\t\t\t{\n\t\t\t\t\tmodel: this.getModel(),\n\t\t\t\t\tmessages: apiMessages,\n\t\t\t\t\tstream: true,\n\t\t\t\t\t...(tools.length > 0 && { tools }),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t...(headers && { headers }),\n\t\t\t\t\tsignal: abortSignal,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tthis._openRouterStreamLive = true;\n\t\t\ttry {\n\t\t\t\tfor await (const chunk of stream) {\n\t\t\t\t\tif (generation !== this._turnGeneration) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (abortSignal.aborted) {\n\t\t\t\t\t\tthrow new Error(\"Request cancelled\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst delta = chunk.choices?.[0]?.delta;\n\n\t\t\t\t\tif (delta?.content) {\n\t\t\t\t\t\tfullContent += delta.content;\n\t\t\t\t\t\tthis._storeChunk(streamId, delta.content);\n\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\ttype: \"messageChunk\",\n\t\t\t\t\t\t\tid: assistantId,\n\t\t\t\t\t\t\tchunk: delta.content,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (delta?.toolCalls) {\n\t\t\t\t\t\tfor (const toolCallDelta of delta.toolCalls) {\n\t\t\t\t\t\t\tconst index = toolCallDelta.index;\n\n\t\t\t\t\t\t\tif (!toolCallsInProgress.has(index)) {\n\t\t\t\t\t\t\t\ttoolCallsInProgress.set(index, {\n\t\t\t\t\t\t\t\t\tid: toolCallDelta.id || \"\",\n\t\t\t\t\t\t\t\t\tname: toolCallDelta.function?.name || \"\",\n\t\t\t\t\t\t\t\t\targuments: \"\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst tcRow = toolCallsInProgress.get(index);\n\t\t\t\t\t\t\tif (tcRow) {\n\t\t\t\t\t\t\t\tif (toolCallDelta.id) {\n\t\t\t\t\t\t\t\t\ttcRow.id = toolCallDelta.id;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (toolCallDelta.function?.name) {\n\t\t\t\t\t\t\t\t\ttcRow.name = toolCallDelta.function.name;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (toolCallDelta.function?.arguments) {\n\t\t\t\t\t\t\t\t\ttcRow.arguments += toolCallDelta.function.arguments;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst rawEntry = getRawToolCallDeltaEntry(chunk, index);\n\t\t\t\t\t\t\t\tconst extra = rawEntry\n\t\t\t\t\t\t\t\t\t? extractProviderMetadataFromRawToolPart(rawEntry)\n\t\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t\t\tif (extra) {\n\t\t\t\t\t\t\t\t\ttcRow.providerMetadata = this._mergeProviderMetadata(\n\t\t\t\t\t\t\t\t\t\ttcRow.providerMetadata,\n\t\t\t\t\t\t\t\t\t\textra,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst deltaMsg: ToolCallDelta = {\n\t\t\t\t\t\t\t\tindex: toolCallDelta.index,\n\t\t\t\t\t\t\t\tid: toolCallDelta.id,\n\t\t\t\t\t\t\t\ttype: toolCallDelta.type as \"function\" | undefined,\n\t\t\t\t\t\t\t\tfunction: toolCallDelta.function\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tname: toolCallDelta.function.name,\n\t\t\t\t\t\t\t\t\t\t\targuments: toolCallDelta.function.arguments,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t\t...(tcRow?.providerMetadata &&\n\t\t\t\t\t\t\t\t\tObject.keys(tcRow.providerMetadata).length > 0 && {\n\t\t\t\t\t\t\t\t\t\tproviderMetadata: tcRow.providerMetadata,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\t\ttype: \"toolCallDelta\",\n\t\t\t\t\t\t\t\tid: assistantId,\n\t\t\t\t\t\t\t\tdelta: deltaMsg,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (chunk.usage) {\n\t\t\t\t\t\tusage = {\n\t\t\t\t\t\t\tprompt_tokens: chunk.usage.promptTokens ?? 0,\n\t\t\t\t\t\t\tcompletion_tokens: chunk.usage.completionTokens ?? 0,\n\t\t\t\t\t\t\ttotal_tokens: chunk.usage.totalTokens ?? 0,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst finalToolCalls: ToolCall[] = [];\n\t\t\t\tfor (const [, tc] of toolCallsInProgress) {\n\t\t\t\t\tif (tc.id && tc.name) {\n\t\t\t\t\t\tconst toolCall: ToolCall = {\n\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\tname: tc.name,\n\t\t\t\t\t\t\t\targuments: tc.arguments,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t...(tc.providerMetadata &&\n\t\t\t\t\t\t\t\tObject.keys(tc.providerMetadata).length > 0 && {\n\t\t\t\t\t\t\t\t\tproviderMetadata: tc.providerMetadata,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tfinalToolCalls.push(toolCall);\n\n\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: assistantId,\n\t\t\t\t\t\t\ttoolCall,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst assistantMessage: AssistantMessage = {\n\t\t\t\t\tid: assistantId,\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: fullContent || null,\n\t\t\t\t\ttoolCalls: finalToolCalls.length > 0 ? finalToolCalls : undefined,\n\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t};\n\n\t\t\t\tthis._completeStreamWithMessage(streamId, assistantMessage);\n\t\t\t\tthis._removeAbortController(assistantId);\n\n\t\t\t\tthis._broadcast({\n\t\t\t\t\ttype: \"messageEnd\",\n\t\t\t\t\tid: assistantId,\n\t\t\t\t\ttoolCalls: finalToolCalls.length > 0 ? finalToolCalls : undefined,\n\t\t\t\t\tcreatedAt: assistantMessage.createdAt,\n\t\t\t\t\t...(usage && { usage }),\n\t\t\t\t});\n\n\t\t\t\tif (finalToolCalls.length > 0) {\n\t\t\t\t\tconst hasServerTools =\n\t\t\t\t\t\tawait this._executeServerSideTools(finalToolCalls);\n\t\t\t\t\tif (hasServerTools) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"OpenRouter error:\", err);\n\t\t\t\tthis._markStreamError(streamId);\n\t\t\t\tthis._removeAbortController(assistantId);\n\t\t\t\tthis._broadcast({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage:\n\t\t\t\t\t\terr instanceof Error ? err.message : \"Failed to get AI response\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tthis._openRouterStreamLive = false;\n\t\t\t}\n\t\t};\n\n\t\tawait this.experimental_waitUntil(runStream);\n\t}\n\n\t/**\n\t * Build API messages from our message history\n\t */\n\tprivate _buildApiMessages(): OpenRouterMessage[] {\n\t\tconst result: OpenRouterMessage[] = [\n\t\t\t{ role: \"system\", content: this.getSystemPrompt() } as ORSystemMessage,\n\t\t];\n\n\t\tfor (const msg of this.messages) {\n\t\t\tswitch (msg.role) {\n\t\t\t\tcase \"user\":\n\t\t\t\t\tresult.push({ role: \"user\", content: msg.content } as ORUserMessage);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"assistant\": {\n\t\t\t\t\tconst assistantMsg = msg;\n\t\t\t\t\tconst orMsg: ORAssistantMessage = {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: assistantMsg.content,\n\t\t\t\t\t\t...(assistantMsg.toolCalls && {\n\t\t\t\t\t\t\ttoolCalls: assistantMsg.toolCalls.map((tc) => {\n\t\t\t\t\t\t\t\tconst call: ORToolCall = {\n\t\t\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\t\tname: tc.function.name,\n\t\t\t\t\t\t\t\t\t\targuments: tc.function.arguments,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tconst meta = tc.providerMetadata;\n\t\t\t\t\t\t\t\tif (meta) {\n\t\t\t\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\t\t\t\tid: _i,\n\t\t\t\t\t\t\t\t\t\ttype: _t,\n\t\t\t\t\t\t\t\t\t\tfunction: _fn,\n\t\t\t\t\t\t\t\t\t\t...rest\n\t\t\t\t\t\t\t\t\t} = meta as Record<string, unknown>;\n\t\t\t\t\t\t\t\t\tObject.assign(call, rest);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn call;\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t\tresult.push(orMsg);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"tool\": {\n\t\t\t\t\tconst toolMsg = msg;\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trole: \"tool\",\n\t\t\t\t\t\tcontent: toolMsg.content,\n\t\t\t\t\t\ttoolCallId: toolMsg.toolCallId,\n\t\t\t\t\t} as ORToolMessage);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveGuard(msg);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Build a map of tool definitions by name for quick lookup\n\t */\n\tprivate _getToolsMap(): Map<string, ToolDefinition> {\n\t\tconst tools = this.getTools();\n\t\tconst map = new Map(tools.map((t) => [t.function.name, t]));\n\n\t\tfor (const [name, tool] of this._clientTools) {\n\t\t\tif (!map.has(name)) {\n\t\t\t\tconst toolDef: ToolDefinition = {\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tif (tool.description !== undefined) {\n\t\t\t\t\ttoolDef.function.description = tool.description;\n\t\t\t\t}\n\t\t\t\tif (tool.parameters !== undefined) {\n\t\t\t\t\ttoolDef.function.parameters = tool.parameters;\n\t\t\t\t}\n\t\t\t\tmap.set(name, toolDef);\n\t\t\t}\n\t\t}\n\n\t\treturn map;\n\t}\n\n\t/**\n\t * Register tools from the client at runtime\n\t */\n\tprivate _registerClientTools(\n\t\t_connection: Connection,\n\t\ttools: ReadonlyArray<{\n\t\t\tname: string;\n\t\t\tdescription?: string;\n\t\t\tparameters?: Record<string, unknown>;\n\t\t}>,\n\t): void {\n\t\tfor (const tool of tools) {\n\t\t\tconst entry: {\n\t\t\t\tname: string;\n\t\t\t\tdescription?: string;\n\t\t\t\tparameters?: Record<string, unknown>;\n\t\t\t} = {\n\t\t\t\tname: tool.name,\n\t\t\t};\n\t\t\tif (tool.description !== undefined) {\n\t\t\t\tentry.description = tool.description;\n\t\t\t}\n\t\t\tif (tool.parameters !== undefined) {\n\t\t\t\tentry.parameters = tool.parameters;\n\t\t\t}\n\t\t\tthis._clientTools.set(tool.name, entry);\n\t\t\tconsole.log(`[ChatAgent] Registered client tool: ${tool.name}`);\n\t\t}\n\n\t\tthis._broadcast({\n\t\t\ttype: \"history\",\n\t\t\tmessages: this.messages,\n\t\t});\n\t}\n\n\t/**\n\t * Execute server-side tools and continue the conversation\n\t */\n\tprivate async _executeServerSideTools(\n\t\ttoolCalls: ToolCall[],\n\t): Promise<boolean> {\n\t\tconst toolsMap = this._getToolsMap();\n\t\tlet executedServerTools = false;\n\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tconst toolDef = toolsMap.get(toolCall.function.name);\n\n\t\t\tif (!toolDef) {\n\t\t\t\tthis._broadcast({\n\t\t\t\t\ttype: \"toolError\",\n\t\t\t\t\terrorType: \"not_found\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.function.name,\n\t\t\t\t\tmessage: `Tool \"${toolCall.function.name}\" not found`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!toolDef.execute) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\texecutedServerTools = true;\n\n\t\t\ttry {\n\t\t\t\tlet args: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\targs = toolCall.function.arguments\n\t\t\t\t\t\t? JSON.parse(toolCall.function.arguments)\n\t\t\t\t\t\t: {};\n\t\t\t\t} catch (parseErr) {\n\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\ttype: \"toolError\",\n\t\t\t\t\t\terrorType: \"input\",\n\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\ttoolName: toolCall.function.name,\n\t\t\t\t\t\tmessage: `Invalid JSON arguments: ${parseErr instanceof Error ? parseErr.message : \"Parse error\"}`,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (toolDef.needsApproval) {\n\t\t\t\t\tconst needApproval = await toolDef.needsApproval(args);\n\t\t\t\t\tif (needApproval) {\n\t\t\t\t\t\tconst approvalId = crypto.randomUUID();\n\t\t\t\t\t\tconst approved = await new Promise<boolean>((resolve) => {\n\t\t\t\t\t\t\tthis._pendingToolApprovals.set(approvalId, { resolve });\n\t\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\t\ttype: \"toolApprovalRequest\",\n\t\t\t\t\t\t\t\tapprovalId,\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\ttoolName: toolCall.function.name,\n\t\t\t\t\t\t\t\targuments: toolCall.function.arguments,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!approved) {\n\t\t\t\t\t\t\tconst errorMsg = \"Tool execution rejected by user\";\n\t\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\t\ttype: \"toolError\",\n\t\t\t\t\t\t\t\terrorType: \"output\",\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\ttoolName: toolCall.function.name,\n\t\t\t\t\t\t\t\tmessage: errorMsg,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst rejectedMessage: ToolMessage = {\n\t\t\t\t\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\t\t\t\t\trole: \"tool\",\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\tcontent: JSON.stringify({\n\t\t\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\t\t\trejected: true,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tthis._persistMessage(rejectedMessage);\n\t\t\t\t\t\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\t\t\t\t\t\tthis.messages.push(rejectedMessage);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._broadcast({\n\t\t\t\t\t\t\t\ttype: \"messageUpdated\",\n\t\t\t\t\t\t\t\tmessage: rejectedMessage,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[ChatAgent] Executing server tool: ${toolCall.function.name}`,\n\t\t\t\t\targs,\n\t\t\t\t);\n\n\t\t\t\tconst result = await toolDef.execute(args);\n\n\t\t\t\tconst toolMessage: ToolMessage = {\n\t\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tcontent: JSON.stringify(result),\n\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t};\n\n\t\t\t\tthis._persistMessage(toolMessage);\n\t\t\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\t\t\tthis.messages.push(toolMessage);\n\t\t\t\t}\n\n\t\t\t\tthis._broadcast({ type: \"messageUpdated\", message: toolMessage });\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[ChatAgent] Server tool completed: ${toolCall.function.name}`,\n\t\t\t\t\tresult,\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ChatAgent] Server tool error: ${toolCall.function.name}`,\n\t\t\t\t\terr,\n\t\t\t\t);\n\n\t\t\t\tconst errorMsg =\n\t\t\t\t\terr instanceof Error ? err.message : \"Tool execution failed\";\n\t\t\t\tthis._broadcast({\n\t\t\t\t\ttype: \"toolError\",\n\t\t\t\t\terrorType: \"output\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.function.name,\n\t\t\t\t\tmessage: errorMsg,\n\t\t\t\t});\n\n\t\t\t\tconst errorMessage: ToolMessage = {\n\t\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tcontent: JSON.stringify({ error: errorMsg }),\n\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t};\n\n\t\t\t\tthis._persistMessage(errorMessage);\n\t\t\t\tif (typeof this.maxPersistedMessages !== \"number\") {\n\t\t\t\t\tthis.messages.push(errorMessage);\n\t\t\t\t}\n\t\t\t\tthis._broadcast({\n\t\t\t\t\ttype: \"messageUpdated\",\n\t\t\t\t\tmessage: errorMessage,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (executedServerTools) {\n\t\t\tawait this._generateAIResponse();\n\t\t}\n\n\t\treturn executedServerTools;\n\t}\n\n\tprivate _handleResumeStream(streamId: string): void {\n\t\tif (!this.dbIsStreamKnown(streamId)) {\n\t\t\tthis._broadcast({\n\t\t\t\ttype: \"streamResume\",\n\t\t\t\tstreamId,\n\t\t\t\tchunks: [],\n\t\t\t\tdone: true,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst chunks = this._getStreamChunks(streamId);\n\t\tconst isLive =\n\t\t\tthis._openRouterStreamLive && this._activeStreamId === streamId;\n\n\t\tthis._broadcast({\n\t\t\ttype: \"streamResume\",\n\t\t\tstreamId,\n\t\t\tchunks,\n\t\t\tdone: !isLive,\n\t\t});\n\n\t\tif (!isLive && this._activeStreamId === streamId) {\n\t\t\tthis._finalizeOrphanedStreamFromChunks(streamId);\n\t\t}\n\t}\n\n\t// ============================================================================\n\t// Cleanup\n\t// ============================================================================\n\n\tasync destroy(): Promise<void> {\n\t\tfor (const controller of this._abortControllers.values()) {\n\t\t\tcontroller.abort();\n\t\t}\n\t\tthis._abortControllers.clear();\n\n\t\tthis._flushChunkBuffer();\n\n\t\tawait super.destroy();\n\t}\n}\n"]}
@@ -0,0 +1,292 @@
1
+ import * as z from 'zod/v4';
2
+
3
+ // src/chat-messages.ts
4
+ var JSONSchemaSchema = z.record(z.string(), z.unknown());
5
+ var ToolDefinitionSchema = z.object({
6
+ type: z.literal("function"),
7
+ function: z.object({
8
+ name: z.string(),
9
+ description: z.string().optional(),
10
+ parameters: JSONSchemaSchema.optional(),
11
+ strict: z.boolean().optional()
12
+ })
13
+ });
14
+ var ToolCallSchema = z.object({
15
+ id: z.string(),
16
+ type: z.literal("function"),
17
+ function: z.object({
18
+ name: z.string(),
19
+ arguments: z.string()
20
+ // JSON string
21
+ }),
22
+ /**
23
+ * Opaque provider-specific fields from the upstream stream (e.g. Gemini / Anthropic extras).
24
+ * Forwarded on the wire when calling the model again after tool results.
25
+ */
26
+ providerMetadata: z.record(z.string(), z.unknown()).optional()
27
+ });
28
+ var ToolCallDeltaSchema = z.object({
29
+ index: z.number(),
30
+ id: z.string().optional(),
31
+ type: z.literal("function").optional(),
32
+ function: z.object({
33
+ name: z.string().optional(),
34
+ arguments: z.string().optional()
35
+ }).optional(),
36
+ providerMetadata: z.record(z.string(), z.unknown()).optional()
37
+ });
38
+ var ToolResultSchema = z.object({
39
+ toolCallId: z.string(),
40
+ output: z.unknown()
41
+ // Can be any JSON-serializable value
42
+ });
43
+ var UserMessageSchema = z.object({
44
+ id: z.string(),
45
+ role: z.literal("user"),
46
+ content: z.string(),
47
+ createdAt: z.number()
48
+ });
49
+ var AssistantMessageSchema = z.object({
50
+ id: z.string(),
51
+ role: z.literal("assistant"),
52
+ content: z.string().nullable(),
53
+ // null when only tool calls
54
+ toolCalls: z.array(ToolCallSchema).optional(),
55
+ createdAt: z.number()
56
+ });
57
+ var ToolMessageSchema = z.object({
58
+ id: z.string(),
59
+ role: z.literal("tool"),
60
+ toolCallId: z.string(),
61
+ content: z.string(),
62
+ // JSON stringified result
63
+ createdAt: z.number()
64
+ });
65
+ var ChatMessageSchema = z.discriminatedUnion("role", [
66
+ UserMessageSchema,
67
+ AssistantMessageSchema,
68
+ ToolMessageSchema
69
+ ]);
70
+ var TokenUsageSchema = z.object({
71
+ prompt_tokens: z.number(),
72
+ completion_tokens: z.number(),
73
+ total_tokens: z.number()
74
+ });
75
+ var SendMessageTriggerSchema = z.enum([
76
+ "submit-message",
77
+ "regenerate-message"
78
+ ]);
79
+ var ClientMessageSchema = z.discriminatedUnion("type", [
80
+ z.object({
81
+ type: z.literal("sendMessage"),
82
+ content: z.string().optional(),
83
+ /** Full conversation snapshot; used with `regenerate-message` or to reconcile before a new user turn */
84
+ messages: z.array(ChatMessageSchema).optional(),
85
+ trigger: SendMessageTriggerSchema.optional()
86
+ }).superRefine((data, ctx) => {
87
+ const trigger = data.trigger ?? "submit-message";
88
+ if (trigger === "regenerate-message") {
89
+ if (!data.messages || data.messages.length === 0) {
90
+ ctx.addIssue({
91
+ code: z.ZodIssueCode.custom,
92
+ message: "sendMessage with trigger regenerate-message requires non-empty messages"
93
+ });
94
+ }
95
+ } else {
96
+ const hasContent = data.content !== void 0 && data.content !== "";
97
+ const messagesEndWithUser = !!data.messages && data.messages.length > 0 && data.messages[data.messages.length - 1].role === "user";
98
+ if (!hasContent && !messagesEndWithUser) {
99
+ ctx.addIssue({
100
+ code: z.ZodIssueCode.custom,
101
+ message: "sendMessage requires non-empty content, or messages ending with a user message"
102
+ });
103
+ }
104
+ }
105
+ }),
106
+ z.object({
107
+ type: z.literal("clearHistory")
108
+ }),
109
+ z.object({
110
+ type: z.literal("getHistory")
111
+ }),
112
+ z.object({
113
+ type: z.literal("resumeStream"),
114
+ streamId: z.string()
115
+ }),
116
+ z.object({
117
+ type: z.literal("cancelRequest"),
118
+ id: z.string()
119
+ }),
120
+ // Tool result from client-side tool execution
121
+ z.object({
122
+ type: z.literal("toolResult"),
123
+ toolCallId: z.string(),
124
+ toolName: z.string(),
125
+ output: z.unknown(),
126
+ // If true, server should continue the conversation after tool result
127
+ autoContinue: z.boolean().optional()
128
+ }),
129
+ z.object({
130
+ type: z.literal("toolApprovalResponse"),
131
+ approvalId: z.string(),
132
+ approved: z.boolean()
133
+ }),
134
+ // Register client-defined tools at runtime
135
+ z.object({
136
+ type: z.literal("registerTools"),
137
+ tools: z.array(
138
+ z.object({
139
+ name: z.string(),
140
+ description: z.string().optional(),
141
+ parameters: JSONSchemaSchema.optional()
142
+ })
143
+ )
144
+ })
145
+ ]);
146
+ var ServerMessageSchema = z.discriminatedUnion("type", [
147
+ // Full message history
148
+ z.object({
149
+ type: z.literal("history"),
150
+ messages: z.array(ChatMessageSchema)
151
+ }),
152
+ // Stream start
153
+ z.object({
154
+ type: z.literal("messageStart"),
155
+ id: z.string(),
156
+ streamId: z.string()
157
+ }),
158
+ // Text content chunk
159
+ z.object({
160
+ type: z.literal("messageChunk"),
161
+ id: z.string(),
162
+ chunk: z.string()
163
+ }),
164
+ // Tool call streaming delta
165
+ z.object({
166
+ type: z.literal("toolCallDelta"),
167
+ id: z.string(),
168
+ delta: ToolCallDeltaSchema
169
+ }),
170
+ // Tool call complete (full tool call ready for execution)
171
+ z.object({
172
+ type: z.literal("toolCall"),
173
+ id: z.string(),
174
+ // message id
175
+ toolCall: ToolCallSchema
176
+ }),
177
+ // Stream end
178
+ z.object({
179
+ type: z.literal("messageEnd"),
180
+ id: z.string(),
181
+ // Final message state (with tool calls if any)
182
+ toolCalls: z.array(ToolCallSchema).optional(),
183
+ createdAt: z.number(),
184
+ usage: TokenUsageSchema.optional()
185
+ }),
186
+ // Stream resumption
187
+ z.object({
188
+ type: z.literal("streamResume"),
189
+ streamId: z.string(),
190
+ chunks: z.array(z.string()),
191
+ done: z.boolean()
192
+ }),
193
+ z.object({
194
+ type: z.literal("streamResuming"),
195
+ id: z.string(),
196
+ streamId: z.string()
197
+ }),
198
+ // Message updated (e.g., tool result applied)
199
+ z.object({
200
+ type: z.literal("messageUpdated"),
201
+ message: ChatMessageSchema
202
+ }),
203
+ // General error
204
+ z.object({
205
+ type: z.literal("error"),
206
+ message: z.string()
207
+ }),
208
+ // Tool input error (arguments validation failed)
209
+ z.object({
210
+ type: z.literal("toolError"),
211
+ errorType: z.enum(["input", "output", "not_found"]),
212
+ toolCallId: z.string(),
213
+ toolName: z.string(),
214
+ message: z.string()
215
+ }),
216
+ z.object({
217
+ type: z.literal("toolApprovalRequest"),
218
+ approvalId: z.string(),
219
+ toolCallId: z.string(),
220
+ toolName: z.string(),
221
+ arguments: z.string()
222
+ })
223
+ ]);
224
+ function parseClientMessage(json) {
225
+ const data = JSON.parse(json);
226
+ return ClientMessageSchema.parse(data);
227
+ }
228
+ function safeParseClientMessage(json) {
229
+ try {
230
+ const data = JSON.parse(json);
231
+ const result = ClientMessageSchema.safeParse(data);
232
+ return result.success ? result.data : null;
233
+ } catch {
234
+ return null;
235
+ }
236
+ }
237
+ function parseServerMessage(json) {
238
+ const data = JSON.parse(json);
239
+ return ServerMessageSchema.parse(data);
240
+ }
241
+ function safeParseServerMessage(json) {
242
+ try {
243
+ const data = JSON.parse(json);
244
+ const result = ServerMessageSchema.safeParse(data);
245
+ return result.success ? result.data : null;
246
+ } catch {
247
+ return null;
248
+ }
249
+ }
250
+ function isClientMessage(data) {
251
+ return ClientMessageSchema.safeParse(data).success;
252
+ }
253
+ function isServerMessage(data) {
254
+ return ServerMessageSchema.safeParse(data).success;
255
+ }
256
+ function isUserMessage(msg) {
257
+ return msg.role === "user";
258
+ }
259
+ function isAssistantMessage(msg) {
260
+ return msg.role === "assistant";
261
+ }
262
+ function isToolMessage(msg) {
263
+ return msg.role === "tool";
264
+ }
265
+ function hasToolCalls(msg) {
266
+ return !!msg.toolCalls && msg.toolCalls.length > 0;
267
+ }
268
+ function parseToolArguments(toolCall) {
269
+ return JSON.parse(toolCall.function.arguments);
270
+ }
271
+ function defineTool(config) {
272
+ const tool = {
273
+ type: "function",
274
+ function: {
275
+ name: config.name,
276
+ description: config.description,
277
+ parameters: config.parameters,
278
+ strict: config.strict
279
+ }
280
+ };
281
+ if (config.execute) {
282
+ tool.execute = config.execute;
283
+ }
284
+ if (config.needsApproval) {
285
+ tool.needsApproval = config.needsApproval;
286
+ }
287
+ return tool;
288
+ }
289
+
290
+ export { AssistantMessageSchema, ChatMessageSchema, ClientMessageSchema, JSONSchemaSchema, SendMessageTriggerSchema, ServerMessageSchema, TokenUsageSchema, ToolCallDeltaSchema, ToolCallSchema, ToolDefinitionSchema, ToolMessageSchema, ToolResultSchema, UserMessageSchema, defineTool, hasToolCalls, isAssistantMessage, isClientMessage, isServerMessage, isToolMessage, isUserMessage, parseClientMessage, parseServerMessage, parseToolArguments, safeParseClientMessage, safeParseServerMessage };
291
+ //# sourceMappingURL=chunk-OEX3D4WL.js.map
292
+ //# sourceMappingURL=chunk-OEX3D4WL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat-messages.ts"],"names":[],"mappings":"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","file":"chunk-OEX3D4WL.js","sourcesContent":["import * as z from \"zod/v4\";\n\n// ============================================================================\n// Tool Definitions (for sending to OpenRouter)\n// ============================================================================\n\n/**\n * JSON Schema for tool parameters (subset of JSON Schema 7)\n */\nexport const JSONSchemaSchema = z.record(z.string(), z.unknown());\n\nexport type JSONSchema = z.infer<typeof JSONSchemaSchema>;\n\n/**\n * Tool definition following OpenAI/OpenRouter format\n * The schema is for wire format (no execute function)\n */\nexport const ToolDefinitionSchema = z.object({\n\ttype: z.literal(\"function\"),\n\tfunction: z.object({\n\t\tname: z.string(),\n\t\tdescription: z.string().optional(),\n\t\tparameters: JSONSchemaSchema.optional(),\n\t\tstrict: z.boolean().optional(),\n\t}),\n});\n\n/**\n * Execute function signature for server-side tools\n * Takes parsed arguments, returns JSON-serializable result\n */\n// biome-ignore lint/suspicious/noExplicitAny: Tool execute functions need flexible typing\nexport type ToolExecuteFunction = (args: any) => unknown | Promise<unknown>;\n\n/**\n * Tool definition with optional execute function for server-side execution\n * - If `execute` is provided: server runs it automatically and continues\n * - If `execute` is omitted: tool call is sent to client for execution\n */\nexport type ToolNeedsApprovalFn = (\n\targs: Record<string, unknown>,\n) => boolean | Promise<boolean>;\n\nexport type ToolDefinition = z.infer<typeof ToolDefinitionSchema> & {\n\t/** Optional server-side execute function. If omitted, tool call goes to client. */\n\texecute?: ToolExecuteFunction;\n\t/**\n\t * When `execute` is set, if this returns true the server waits for a client\n\t * `toolApprovalResponse` before running `execute` (human-in-the-loop).\n\t */\n\tneedsApproval?: ToolNeedsApprovalFn;\n};\n\n// ============================================================================\n// Tool Calls (from AI responses)\n// ============================================================================\n\n/**\n * A tool call from the AI (complete, after streaming)\n */\nexport const ToolCallSchema = z.object({\n\tid: z.string(),\n\ttype: z.literal(\"function\"),\n\tfunction: z.object({\n\t\tname: z.string(),\n\t\targuments: z.string(), // JSON string\n\t}),\n\t/**\n\t * Opaque provider-specific fields from the upstream stream (e.g. Gemini / Anthropic extras).\n\t * Forwarded on the wire when calling the model again after tool results.\n\t */\n\tproviderMetadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ToolCall = z.infer<typeof ToolCallSchema>;\n\n/**\n * Tool call delta during streaming\n */\nexport const ToolCallDeltaSchema = z.object({\n\tindex: z.number(),\n\tid: z.string().optional(),\n\ttype: z.literal(\"function\").optional(),\n\tfunction: z\n\t\t.object({\n\t\t\tname: z.string().optional(),\n\t\t\targuments: z.string().optional(),\n\t\t})\n\t\t.optional(),\n\tproviderMetadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ToolCallDelta = z.infer<typeof ToolCallDeltaSchema>;\n\n// ============================================================================\n// Tool Results (from client execution)\n// ============================================================================\n\n/**\n * Tool result from client-side execution\n */\nexport const ToolResultSchema = z.object({\n\ttoolCallId: z.string(),\n\toutput: z.unknown(), // Can be any JSON-serializable value\n});\n\nexport type ToolResult = z.infer<typeof ToolResultSchema>;\n\n// ============================================================================\n// Chat Message Schema (supports text + tool calls)\n// ============================================================================\n\n/**\n * User message\n */\nexport const UserMessageSchema = z.object({\n\tid: z.string(),\n\trole: z.literal(\"user\"),\n\tcontent: z.string(),\n\tcreatedAt: z.number(),\n});\n\nexport type UserMessage = z.infer<typeof UserMessageSchema>;\n\n/**\n * Assistant message - can have content, tool calls, or both\n */\nexport const AssistantMessageSchema = z.object({\n\tid: z.string(),\n\trole: z.literal(\"assistant\"),\n\tcontent: z.string().nullable(), // null when only tool calls\n\ttoolCalls: z.array(ToolCallSchema).optional(),\n\tcreatedAt: z.number(),\n});\n\nexport type AssistantMessage = z.infer<typeof AssistantMessageSchema>;\n\n/**\n * Tool response message (sent back to AI after tool execution)\n */\nexport const ToolMessageSchema = z.object({\n\tid: z.string(),\n\trole: z.literal(\"tool\"),\n\ttoolCallId: z.string(),\n\tcontent: z.string(), // JSON stringified result\n\tcreatedAt: z.number(),\n});\n\nexport type ToolMessage = z.infer<typeof ToolMessageSchema>;\n\n/**\n * Union of all chat message types\n */\nexport const ChatMessageSchema = z.discriminatedUnion(\"role\", [\n\tUserMessageSchema,\n\tAssistantMessageSchema,\n\tToolMessageSchema,\n]);\n\nexport type ChatMessage = z.infer<typeof ChatMessageSchema>;\n\n// ============================================================================\n// Token Usage Schema\n// ============================================================================\n\nexport const TokenUsageSchema = z.object({\n\tprompt_tokens: z.number(),\n\tcompletion_tokens: z.number(),\n\ttotal_tokens: z.number(),\n});\n\nexport type TokenUsage = z.infer<typeof TokenUsageSchema>;\n\n// ============================================================================\n// Client → Server Messages (Discriminated Union)\n// ============================================================================\n\nexport const SendMessageTriggerSchema = z.enum([\n\t\"submit-message\",\n\t\"regenerate-message\",\n]);\n\nexport type SendMessageTrigger = z.infer<typeof SendMessageTriggerSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"sendMessage\"),\n\t\t\tcontent: z.string().optional(),\n\t\t\t/** Full conversation snapshot; used with `regenerate-message` or to reconcile before a new user turn */\n\t\t\tmessages: z.array(ChatMessageSchema).optional(),\n\t\t\ttrigger: SendMessageTriggerSchema.optional(),\n\t\t})\n\t\t.superRefine((data, ctx) => {\n\t\t\tconst trigger = data.trigger ?? \"submit-message\";\n\t\t\tif (trigger === \"regenerate-message\") {\n\t\t\t\tif (!data.messages || data.messages.length === 0) {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"sendMessage with trigger regenerate-message requires non-empty messages\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst hasContent = data.content !== undefined && data.content !== \"\";\n\t\t\t\tconst messagesEndWithUser =\n\t\t\t\t\t!!data.messages &&\n\t\t\t\t\tdata.messages.length > 0 &&\n\t\t\t\t\tdata.messages[data.messages.length - 1].role === \"user\";\n\t\t\t\tif (!hasContent && !messagesEndWithUser) {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"sendMessage requires non-empty content, or messages ending with a user message\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}),\n\tz.object({\n\t\ttype: z.literal(\"clearHistory\"),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"getHistory\"),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"resumeStream\"),\n\t\tstreamId: z.string(),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"cancelRequest\"),\n\t\tid: z.string(),\n\t}),\n\t// Tool result from client-side tool execution\n\tz.object({\n\t\ttype: z.literal(\"toolResult\"),\n\t\ttoolCallId: z.string(),\n\t\ttoolName: z.string(),\n\t\toutput: z.unknown(),\n\t\t// If true, server should continue the conversation after tool result\n\t\tautoContinue: z.boolean().optional(),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"toolApprovalResponse\"),\n\t\tapprovalId: z.string(),\n\t\tapproved: z.boolean(),\n\t}),\n\t// Register client-defined tools at runtime\n\tz.object({\n\t\ttype: z.literal(\"registerTools\"),\n\t\ttools: z.array(\n\t\t\tz.object({\n\t\t\t\tname: z.string(),\n\t\t\t\tdescription: z.string().optional(),\n\t\t\t\tparameters: JSONSchemaSchema.optional(),\n\t\t\t}),\n\t\t),\n\t}),\n]);\n\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\n// Individual message types for convenience\nexport type SendMessagePayload = Extract<\n\tClientMessage,\n\t{ type: \"sendMessage\" }\n>;\nexport type ClearHistoryPayload = Extract<\n\tClientMessage,\n\t{ type: \"clearHistory\" }\n>;\nexport type GetHistoryPayload = Extract<ClientMessage, { type: \"getHistory\" }>;\nexport type ResumeStreamPayload = Extract<\n\tClientMessage,\n\t{ type: \"resumeStream\" }\n>;\nexport type CancelRequestPayload = Extract<\n\tClientMessage,\n\t{ type: \"cancelRequest\" }\n>;\nexport type ToolResultPayload = Extract<ClientMessage, { type: \"toolResult\" }>;\nexport type ToolApprovalResponsePayload = Extract<\n\tClientMessage,\n\t{ type: \"toolApprovalResponse\" }\n>;\nexport type RegisterToolsPayload = Extract<\n\tClientMessage,\n\t{ type: \"registerTools\" }\n>;\n\n// ============================================================================\n// Server → Client Messages (Discriminated Union)\n// ============================================================================\n\nexport const ServerMessageSchema = z.discriminatedUnion(\"type\", [\n\t// Full message history\n\tz.object({\n\t\ttype: z.literal(\"history\"),\n\t\tmessages: z.array(ChatMessageSchema),\n\t}),\n\t// Stream start\n\tz.object({\n\t\ttype: z.literal(\"messageStart\"),\n\t\tid: z.string(),\n\t\tstreamId: z.string(),\n\t}),\n\t// Text content chunk\n\tz.object({\n\t\ttype: z.literal(\"messageChunk\"),\n\t\tid: z.string(),\n\t\tchunk: z.string(),\n\t}),\n\t// Tool call streaming delta\n\tz.object({\n\t\ttype: z.literal(\"toolCallDelta\"),\n\t\tid: z.string(),\n\t\tdelta: ToolCallDeltaSchema,\n\t}),\n\t// Tool call complete (full tool call ready for execution)\n\tz.object({\n\t\ttype: z.literal(\"toolCall\"),\n\t\tid: z.string(), // message id\n\t\ttoolCall: ToolCallSchema,\n\t}),\n\t// Stream end\n\tz.object({\n\t\ttype: z.literal(\"messageEnd\"),\n\t\tid: z.string(),\n\t\t// Final message state (with tool calls if any)\n\t\ttoolCalls: z.array(ToolCallSchema).optional(),\n\t\tcreatedAt: z.number(),\n\t\tusage: TokenUsageSchema.optional(),\n\t}),\n\t// Stream resumption\n\tz.object({\n\t\ttype: z.literal(\"streamResume\"),\n\t\tstreamId: z.string(),\n\t\tchunks: z.array(z.string()),\n\t\tdone: z.boolean(),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"streamResuming\"),\n\t\tid: z.string(),\n\t\tstreamId: z.string(),\n\t}),\n\t// Message updated (e.g., tool result applied)\n\tz.object({\n\t\ttype: z.literal(\"messageUpdated\"),\n\t\tmessage: ChatMessageSchema,\n\t}),\n\t// General error\n\tz.object({\n\t\ttype: z.literal(\"error\"),\n\t\tmessage: z.string(),\n\t}),\n\t// Tool input error (arguments validation failed)\n\tz.object({\n\t\ttype: z.literal(\"toolError\"),\n\t\terrorType: z.enum([\"input\", \"output\", \"not_found\"]),\n\t\ttoolCallId: z.string(),\n\t\ttoolName: z.string(),\n\t\tmessage: z.string(),\n\t}),\n\tz.object({\n\t\ttype: z.literal(\"toolApprovalRequest\"),\n\t\tapprovalId: z.string(),\n\t\ttoolCallId: z.string(),\n\t\ttoolName: z.string(),\n\t\targuments: z.string(),\n\t}),\n]);\n\nexport type ServerMessage = z.infer<typeof ServerMessageSchema>;\n\n// Individual message types for convenience\nexport type HistoryMessage = Extract<ServerMessage, { type: \"history\" }>;\nexport type MessageStartMessage = Extract<\n\tServerMessage,\n\t{ type: \"messageStart\" }\n>;\nexport type MessageChunkMessage = Extract<\n\tServerMessage,\n\t{ type: \"messageChunk\" }\n>;\nexport type ToolCallDeltaMessage = Extract<\n\tServerMessage,\n\t{ type: \"toolCallDelta\" }\n>;\nexport type ToolCallMessage = Extract<ServerMessage, { type: \"toolCall\" }>;\nexport type MessageEndMessage = Extract<ServerMessage, { type: \"messageEnd\" }>;\nexport type StreamResumeMessage = Extract<\n\tServerMessage,\n\t{ type: \"streamResume\" }\n>;\nexport type StreamResumingMessage = Extract<\n\tServerMessage,\n\t{ type: \"streamResuming\" }\n>;\nexport type MessageUpdatedMessage = Extract<\n\tServerMessage,\n\t{ type: \"messageUpdated\" }\n>;\nexport type ErrorMessage = Extract<ServerMessage, { type: \"error\" }>;\nexport type ToolErrorMessage = Extract<ServerMessage, { type: \"toolError\" }>;\nexport type ToolApprovalRequestMessage = Extract<\n\tServerMessage,\n\t{ type: \"toolApprovalRequest\" }\n>;\n\n// ============================================================================\n// Parsing Helpers\n// ============================================================================\n\n/**\n * Parse and validate a client message from JSON string\n * @throws ZodError if validation fails\n */\nexport function parseClientMessage(json: string): ClientMessage {\n\tconst data = JSON.parse(json);\n\treturn ClientMessageSchema.parse(data);\n}\n\n/**\n * Safely parse a client message, returning null on failure\n */\nexport function safeParseClientMessage(json: string): ClientMessage | null {\n\ttry {\n\t\tconst data = JSON.parse(json);\n\t\tconst result = ClientMessageSchema.safeParse(data);\n\t\treturn result.success ? result.data : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse and validate a server message from JSON string\n * @throws ZodError if validation fails\n */\nexport function parseServerMessage(json: string): ServerMessage {\n\tconst data = JSON.parse(json);\n\treturn ServerMessageSchema.parse(data);\n}\n\n/**\n * Safely parse a server message, returning null on failure\n */\nexport function safeParseServerMessage(json: string): ServerMessage | null {\n\ttry {\n\t\tconst data = JSON.parse(json);\n\t\tconst result = ServerMessageSchema.safeParse(data);\n\t\treturn result.success ? result.data : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isClientMessage(data: unknown): data is ClientMessage {\n\treturn ClientMessageSchema.safeParse(data).success;\n}\n\nexport function isServerMessage(data: unknown): data is ServerMessage {\n\treturn ServerMessageSchema.safeParse(data).success;\n}\n\nexport function isUserMessage(msg: ChatMessage): msg is UserMessage {\n\treturn msg.role === \"user\";\n}\n\nexport function isAssistantMessage(msg: ChatMessage): msg is AssistantMessage {\n\treturn msg.role === \"assistant\";\n}\n\nexport function isToolMessage(msg: ChatMessage): msg is ToolMessage {\n\treturn msg.role === \"tool\";\n}\n\nexport function hasToolCalls(msg: AssistantMessage): boolean {\n\treturn !!msg.toolCalls && msg.toolCalls.length > 0;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Parse tool call arguments from JSON string\n */\nexport function parseToolArguments<T = unknown>(toolCall: ToolCall): T {\n\treturn JSON.parse(toolCall.function.arguments) as T;\n}\n\n/**\n * Create a tool definition helper\n *\n * @example Server-side tool (executes automatically on server)\n * ```ts\n * defineTool({\n * name: \"get_weather\",\n * description: \"Get current weather\",\n * parameters: { type: \"object\", properties: { location: { type: \"string\" } } },\n * execute: async (args) => {\n * const weather = await fetchWeather(args.location);\n * return { temp: weather.temp, conditions: weather.desc };\n * }\n * })\n * ```\n *\n * @example Client-side tool (sent to client for execution)\n * ```ts\n * defineTool({\n * name: \"get_user_location\",\n * description: \"Get user's current location\",\n * parameters: { type: \"object\", properties: {} },\n * // No execute function - client handles this\n * })\n * ```\n */\nexport function defineTool(config: {\n\tname: string;\n\tdescription?: string;\n\tparameters?: JSONSchema;\n\tstrict?: boolean;\n\t/** Server-side execute function. If omitted, tool call goes to client. */\n\texecute?: ToolExecuteFunction;\n\t/** If set with `execute`, client must approve before the server runs `execute`. */\n\tneedsApproval?: ToolNeedsApprovalFn;\n}): ToolDefinition {\n\tconst tool: ToolDefinition = {\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: config.name,\n\t\t\tdescription: config.description,\n\t\t\tparameters: config.parameters,\n\t\t\tstrict: config.strict,\n\t\t},\n\t};\n\tif (config.execute) {\n\t\ttool.execute = config.execute;\n\t}\n\tif (config.needsApproval) {\n\t\ttool.needsApproval = config.needsApproval;\n\t}\n\treturn tool;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { ChatAgentBase } from './chat-agent-base.js';
2
+ export { AssistantMessage, CancelRequestPayload, ChatMessage, ClearHistoryPayload, ClientMessage, ErrorMessage, GetHistoryPayload, HistoryMessage, JSONSchema, MessageChunkMessage, MessageEndMessage, MessageStartMessage, MessageUpdatedMessage, RegisterToolsPayload, ResumeStreamPayload, SendMessagePayload, SendMessageTrigger, ServerMessage, StreamResumeMessage, StreamResumingMessage, TokenUsage, ToolApprovalRequestMessage, ToolApprovalResponsePayload, ToolCall, ToolCallDelta, ToolCallDeltaMessage, ToolCallMessage, ToolDefinition, ToolErrorMessage, ToolMessage, ToolNeedsApprovalFn, ToolResult, ToolResultPayload, UserMessage, defineTool, hasToolCalls, isAssistantMessage, isClientMessage, isServerMessage, isToolMessage, isUserMessage, parseClientMessage, parseServerMessage, parseToolArguments, safeParseClientMessage, safeParseServerMessage } from './chat-messages.js';
3
+ import 'agents';
4
+ import 'zod/v4';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { ChatAgentBase } from './chunk-G5P5JXRF.js';
2
+ export { defineTool, hasToolCalls, isAssistantMessage, isClientMessage, isServerMessage, isToolMessage, isUserMessage, parseClientMessage, parseServerMessage, parseToolArguments, safeParseClientMessage, safeParseServerMessage } from './chunk-OEX3D4WL.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/package.json CHANGED
@@ -1,24 +1,29 @@
1
1
  {
2
2
  "name": "@firtoz/chat-agent",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Wire protocol, tools, and ChatAgentBase for Cloudflare Durable Objects with OpenRouter (use @firtoz/chat-agent-drizzle or @firtoz/chat-agent-sql for persistence)",
5
- "main": "./src/index.ts",
6
- "module": "./src/index.ts",
7
- "types": "./src/index.ts",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "types": "./src/index.ts",
11
- "import": "./src/index.ts",
12
- "require": "./src/index.ts"
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
13
  }
14
14
  },
15
15
  "files": [
16
+ "dist/**/*.js",
17
+ "dist/**/*.js.map",
18
+ "dist/**/*.d.ts",
16
19
  "src/**/*.ts",
17
20
  "!src/**/*.test.ts",
18
21
  "README.md"
19
22
  ],
20
23
  "scripts": {
21
- "typecheck": "tsc --noEmit -p ./tsconfig.json",
24
+ "build": "tsup",
25
+ "prepack": "bun run build",
26
+ "typecheck": "tsgo --noEmit -p ./tsconfig.json",
22
27
  "lint": "biome check --write src",
23
28
  "lint:ci": "biome ci src",
24
29
  "test": "bun test",
@@ -47,9 +52,9 @@
47
52
  "url": "https://github.com/firtoz/fullstack-toolkit/issues"
48
53
  },
49
54
  "peerDependencies": {
50
- "@cloudflare/workers-types": "^4.20260317.1",
51
- "@openrouter/sdk": "^0.9.11",
52
- "agents": "^0.8.1"
55
+ "@cloudflare/workers-types": "^4.20260329.1",
56
+ "@openrouter/sdk": "^0.10.2",
57
+ "agents": "^0.8.7"
53
58
  },
54
59
  "engines": {
55
60
  "node": ">=18.0.0"
@@ -62,7 +67,7 @@
62
67
  "typescript": "^6.0.2"
63
68
  },
64
69
  "dependencies": {
65
- "@firtoz/maybe-error": "^1.5.2",
70
+ "@firtoz/maybe-error": "^1.6.0",
66
71
  "zod": "^4.3.6"
67
72
  }
68
73
  }