@tanstack/ai-devtools-core 0.2.1 → 0.2.3

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.
Files changed (29) hide show
  1. package/README.md +1 -0
  2. package/dist/esm/components/ConversationDetails.js +74 -1
  3. package/dist/esm/components/ConversationDetails.js.map +1 -1
  4. package/dist/esm/components/conversation/ActivityEventsTab.d.ts +8 -0
  5. package/dist/esm/components/conversation/ActivityEventsTab.js +72 -0
  6. package/dist/esm/components/conversation/ActivityEventsTab.js.map +1 -0
  7. package/dist/esm/components/conversation/ConversationHeader.js +109 -66
  8. package/dist/esm/components/conversation/ConversationHeader.js.map +1 -1
  9. package/dist/esm/components/conversation/ConversationTabs.d.ts +1 -1
  10. package/dist/esm/components/conversation/ConversationTabs.js +107 -3
  11. package/dist/esm/components/conversation/ConversationTabs.js.map +1 -1
  12. package/dist/esm/components/conversation/MessageCard.js +83 -28
  13. package/dist/esm/components/conversation/MessageCard.js.map +1 -1
  14. package/dist/esm/components/conversation/index.d.ts +1 -0
  15. package/dist/esm/store/ai-context.d.ts +19 -2
  16. package/dist/esm/store/ai-context.js +528 -262
  17. package/dist/esm/store/ai-context.js.map +1 -1
  18. package/dist/esm/styles/use-styles.d.ts +7 -0
  19. package/dist/esm/styles/use-styles.js +65 -1
  20. package/dist/esm/styles/use-styles.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/components/ConversationDetails.tsx +70 -1
  23. package/src/components/conversation/ActivityEventsTab.tsx +57 -0
  24. package/src/components/conversation/ConversationHeader.tsx +52 -36
  25. package/src/components/conversation/ConversationTabs.tsx +121 -2
  26. package/src/components/conversation/MessageCard.tsx +45 -10
  27. package/src/components/conversation/index.ts +1 -0
  28. package/src/store/ai-context.tsx +783 -418
  29. package/src/styles/use-styles.ts +65 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ai-context.js","sources":["../../../src/store/ai-context.tsx"],"sourcesContent":["import { batch, createContext, onCleanup, onMount, useContext } from 'solid-js'\nimport { createStore, produce } from 'solid-js/store'\nimport { aiEventClient } from '@tanstack/ai/event-client'\nimport type { ParentComponent } from 'solid-js'\n\ninterface MessagePart {\n type: 'text' | 'tool-call' | 'tool-result'\n content?: string\n toolCallId?: string\n toolName?: string\n arguments?: string\n state?: string\n output?: unknown\n error?: string\n}\n\nexport interface ToolCall {\n id: string\n name: string\n arguments: string\n state: string\n result?: unknown\n approvalRequired?: boolean\n approvalId?: string\n /** Duration of tool execution in milliseconds */\n duration?: number\n}\n\ninterface TokenUsage {\n promptTokens: number\n completionTokens: number\n totalTokens: number\n}\n\nexport interface Message {\n id: string\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string\n timestamp: number\n parts?: Array<MessagePart>\n toolCalls?: Array<ToolCall>\n /** Consolidated chunks - consecutive same-type chunks are merged into one entry */\n chunks?: Array<Chunk>\n /** Total number of raw chunks received (before consolidation) */\n totalChunkCount?: number\n model?: string\n usage?: TokenUsage\n thinkingContent?: string\n /** Source of the message: 'client' for aggregated client-side data, 'server' for individual server chunks */\n source?: 'client' | 'server'\n}\n\n/**\n * Consolidated chunk - represents one or more raw chunks of the same type.\n * Consecutive content/thinking chunks are merged into a single entry with accumulated content.\n */\nexport interface Chunk {\n id: string\n type:\n | 'content'\n | 'tool_call'\n | 'tool_result'\n | 'done'\n | 'error'\n | 'approval'\n | 'thinking'\n timestamp: number\n messageId?: string\n /** Accumulated content from all merged chunks */\n content?: string\n /** The last delta received (kept for debugging) */\n delta?: string\n toolName?: string\n toolCallId?: string\n finishReason?: string\n error?: string\n approvalId?: string\n input?: unknown\n /** Tool arguments for tool_call chunks */\n arguments?: string\n /** Tool result data for tool_result chunks */\n result?: unknown\n /** Duration in ms for tool execution */\n duration?: number\n /** Number of raw chunks that were merged into this consolidated chunk */\n chunkCount: number\n}\n\nexport interface SummarizeOperation {\n id: string\n model: string\n inputLength: number\n outputLength?: number\n duration?: number\n timestamp: number\n status: 'started' | 'completed'\n}\n\nexport interface Conversation {\n id: string\n type: 'client' | 'server'\n label: string\n messages: Array<Message>\n chunks: Array<Chunk>\n model?: string\n provider?: string\n status: 'active' | 'completed' | 'error'\n startedAt: number\n completedAt?: number\n usage?: TokenUsage\n iterationCount?: number\n toolNames?: Array<string>\n options?: Record<string, unknown>\n providerOptions?: Record<string, unknown>\n /** Flags for which operation types this conversation has */\n hasChat?: boolean\n hasSummarize?: boolean\n /** Summarize operations in this conversation */\n summaries?: Array<SummarizeOperation>\n}\n\ninterface AIStoreState {\n conversations: Record<string, Conversation>\n activeConversationId: string | null\n}\n\ninterface AIContextValue {\n state: AIStoreState\n clearAllConversations: () => void\n selectConversation: (id: string) => void\n}\n\nconst AIContext = createContext<AIContextValue>()\n\nexport function useAIStore(): AIContextValue {\n const context = useContext(AIContext)\n if (!context) {\n throw new Error('useAIStore must be used within an AIProvider')\n }\n return context\n}\n\nexport const AIProvider: ParentComponent = (props) => {\n const [state, setState] = createStore<AIStoreState>({\n conversations: {},\n activeConversationId: null,\n })\n\n const streamToConversation = new Map<string, string>()\n const requestToConversation = new Map<string, string>()\n\n // Batching system for high-frequency chunk updates with consolidated chunk merging\n // Stores: conversationId -> { chunks to merge, totalNewChunks count }\n const pendingConversationChunks = new Map<\n string,\n { chunks: Array<Chunk>; newChunkCount: number }\n >()\n // Stores: conversationId -> messageIndex -> { chunks to merge, totalNewChunks count }\n const pendingMessageChunks = new Map<\n string,\n Map<number, { chunks: Array<Chunk>; newChunkCount: number }>\n >()\n let batchScheduled = false\n\n function scheduleBatchFlush(): void {\n if (batchScheduled) return\n batchScheduled = true\n queueMicrotask(flushPendingChunks)\n }\n\n /** Check if a chunk type can be merged with consecutive same-type chunks */\n function isMergeableChunkType(type: Chunk['type']): boolean {\n return type === 'content' || type === 'thinking'\n }\n\n /** Merge pending chunks into existing chunks array, consolidating consecutive same-type chunks */\n function mergeChunks(existing: Array<Chunk>, pending: Array<Chunk>): void {\n for (const chunk of pending) {\n const lastChunk = existing[existing.length - 1]\n\n // If last chunk exists, is the same type, and both are mergeable types, merge them\n if (\n lastChunk &&\n lastChunk.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastChunk.messageId === chunk.messageId\n ) {\n // Merge: use the new chunk's content (it's already accumulated), update delta, increment count\n lastChunk.content = chunk.content || lastChunk.content\n lastChunk.delta = chunk.delta\n lastChunk.chunkCount += chunk.chunkCount\n } else {\n // Different type or not mergeable - add as new entry\n existing.push(chunk)\n }\n }\n }\n\n function flushPendingChunks(): void {\n batchScheduled = false\n\n batch(() => {\n // Flush conversation-level chunks\n for (const [\n conversationId,\n { chunks, newChunkCount },\n ] of pendingConversationChunks) {\n const conv = state.conversations[conversationId]\n if (conv) {\n setState(\n 'conversations',\n conversationId,\n 'chunks',\n produce((arr: Array<Chunk>) => {\n mergeChunks(arr, chunks)\n }),\n )\n }\n }\n pendingConversationChunks.clear()\n\n // Flush message-level chunks\n for (const [conversationId, messageMap] of pendingMessageChunks) {\n const conv = state.conversations[conversationId]\n if (!conv) continue\n\n for (const [messageIndex, { chunks, newChunkCount }] of messageMap) {\n const message = conv.messages[messageIndex]\n if (message) {\n // Update chunks array with merging\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'chunks',\n produce((arr: Array<Chunk> | undefined) => {\n if (!arr) {\n // First time - just set the chunks (they're already consolidated in pending)\n return chunks\n }\n mergeChunks(arr, chunks)\n return arr\n }),\n )\n // Update total chunk count\n const currentTotal = message.totalChunkCount || 0\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'totalChunkCount',\n currentTotal + newChunkCount,\n )\n }\n }\n }\n pendingMessageChunks.clear()\n })\n }\n\n function queueChunk(conversationId: string, chunk: Chunk): void {\n if (!pendingConversationChunks.has(conversationId)) {\n pendingConversationChunks.set(conversationId, {\n chunks: [],\n newChunkCount: 0,\n })\n }\n const pending = pendingConversationChunks.get(conversationId)!\n\n // Pre-merge in pending buffer to reduce array operations during flush\n const lastPending = pending.chunks[pending.chunks.length - 1]\n if (\n lastPending &&\n lastPending.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastPending.messageId === chunk.messageId\n ) {\n // Merge into pending buffer - only append delta (incremental content)\n // Use the new chunk's content as the accumulated content (it's already accumulated)\n lastPending.content = chunk.content || lastPending.content\n lastPending.delta = chunk.delta\n lastPending.chunkCount += chunk.chunkCount\n } else {\n pending.chunks.push(chunk)\n }\n pending.newChunkCount += chunk.chunkCount\n scheduleBatchFlush()\n }\n\n function queueMessageChunk(\n conversationId: string,\n messageIndex: number,\n chunk: Chunk,\n ): void {\n if (!pendingMessageChunks.has(conversationId)) {\n pendingMessageChunks.set(conversationId, new Map())\n }\n const messageMap = pendingMessageChunks.get(conversationId)!\n if (!messageMap.has(messageIndex)) {\n messageMap.set(messageIndex, { chunks: [], newChunkCount: 0 })\n }\n const pending = messageMap.get(messageIndex)!\n\n // Pre-merge in pending buffer\n const lastPending = pending.chunks[pending.chunks.length - 1]\n if (\n lastPending &&\n lastPending.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastPending.messageId === chunk.messageId\n ) {\n // Merge into pending buffer - only append delta (incremental content)\n // Use the new chunk's content as the accumulated content (it's already accumulated)\n lastPending.content = chunk.content || lastPending.content\n lastPending.delta = chunk.delta\n lastPending.chunkCount += chunk.chunkCount\n } else {\n pending.chunks.push(chunk)\n }\n pending.newChunkCount += chunk.chunkCount\n scheduleBatchFlush()\n }\n\n // Optimized helper functions using path-based updates\n function getOrCreateConversation(\n id: string,\n type: 'client' | 'server',\n label: string,\n ): void {\n if (!state.conversations[id]) {\n setState('conversations', id, {\n id,\n type,\n label,\n messages: [],\n chunks: [],\n status: 'active',\n startedAt: Date.now(),\n })\n if (!state.activeConversationId) {\n setState('activeConversationId', id)\n }\n }\n }\n\n function addMessage(conversationId: string, message: Message): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n conv.messages.length,\n message,\n )\n }\n\n function addChunkToMessage(conversationId: string, chunk: Chunk): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n if (chunk.messageId) {\n const messageIndex = conv.messages.findIndex(\n (msg) => msg.id === chunk.messageId,\n )\n\n if (messageIndex !== -1) {\n queueMessageChunk(conversationId, messageIndex, chunk)\n return\n } else {\n // Create new message with the chunk\n const newMessage: Message = {\n id: chunk.messageId,\n role: 'assistant',\n content: '',\n timestamp: chunk.timestamp,\n model: conv.model,\n chunks: [chunk],\n }\n setState(\n 'conversations',\n conversationId,\n 'messages',\n conv.messages.length,\n newMessage,\n )\n return\n }\n }\n\n // Find last assistant message\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (message && message.role === 'assistant') {\n queueMessageChunk(conversationId, i, chunk)\n return\n }\n }\n }\n\n function updateMessageUsage(\n conversationId: string,\n messageId: string | undefined,\n cumulativeUsage: TokenUsage,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n // Calculate the sum of usage from all previous messages (excluding the target message)\n let previousPromptTokens = 0\n let previousCompletionTokens = 0\n\n // Find the target message index\n let targetMessageIndex = -1\n if (messageId) {\n targetMessageIndex = conv.messages.findIndex(\n (msg) => msg.id === messageId,\n )\n } else {\n // Find last assistant message\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n if (conv.messages[i]?.role === 'assistant') {\n targetMessageIndex = i\n break\n }\n }\n }\n\n if (targetMessageIndex === -1) return\n\n // Sum up usage from all previous assistant messages\n for (let i = 0; i < targetMessageIndex; i++) {\n const msg = conv.messages[i]\n if (msg?.role === 'assistant' && msg.usage) {\n previousPromptTokens += msg.usage.promptTokens\n previousCompletionTokens += msg.usage.completionTokens\n }\n }\n\n // Calculate delta usage for this message\n const deltaUsage: TokenUsage = {\n promptTokens: Math.max(\n 0,\n cumulativeUsage.promptTokens - previousPromptTokens,\n ),\n completionTokens: Math.max(\n 0,\n cumulativeUsage.completionTokens - previousCompletionTokens,\n ),\n totalTokens: 0,\n }\n deltaUsage.totalTokens =\n deltaUsage.promptTokens + deltaUsage.completionTokens\n\n setState(\n 'conversations',\n conversationId,\n 'messages',\n targetMessageIndex,\n 'usage',\n deltaUsage,\n )\n }\n\n // Public actions\n function clearAllConversations() {\n setState('conversations', {})\n setState('activeConversationId', null)\n streamToConversation.clear()\n requestToConversation.clear()\n pendingConversationChunks.clear()\n pendingMessageChunks.clear()\n }\n\n function selectConversation(id: string) {\n setState('activeConversationId', id)\n }\n\n // Additional optimized helper functions\n function updateConversation(\n conversationId: string,\n updates: Partial<Conversation>,\n ): void {\n if (!state.conversations[conversationId]) return\n for (const [key, value] of Object.entries(updates)) {\n setState(\n 'conversations',\n conversationId,\n key as keyof Conversation,\n value as Conversation[keyof Conversation],\n )\n }\n }\n\n function updateMessage(\n conversationId: string,\n messageIndex: number,\n updates: Partial<Message>,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv || !conv.messages[messageIndex]) return\n for (const [key, value] of Object.entries(updates)) {\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n key as keyof Message,\n value as Message[keyof Message],\n )\n }\n }\n\n function updateToolCall(\n conversationId: string,\n messageIndex: number,\n toolCallIndex: number,\n updates: Partial<ToolCall>,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv?.messages[messageIndex]?.toolCalls?.[toolCallIndex]) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'toolCalls',\n toolCallIndex,\n produce((tc: ToolCall) => Object.assign(tc, updates)),\n )\n }\n\n function setToolCalls(\n conversationId: string,\n messageIndex: number,\n toolCalls: Array<ToolCall>,\n ): void {\n if (!state.conversations[conversationId]?.messages[messageIndex]) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'toolCalls',\n toolCalls,\n )\n }\n\n function addChunk(conversationId: string, chunk: Chunk): void {\n if (!state.conversations[conversationId]) return\n queueChunk(conversationId, chunk)\n }\n\n /**\n * For server conversations, ensure a message exists for the given messageId.\n * This creates a placeholder message that will be updated as chunks arrive.\n */\n function ensureMessageForChunk(\n conversationId: string,\n messageId: string | undefined,\n timestamp: number,\n ): void {\n if (!messageId) return\n const conv = state.conversations[conversationId]\n if (!conv || conv.type === 'client') return\n\n // Check if message already exists\n const existingMessage = conv.messages.find((m) => m.id === messageId)\n if (existingMessage) return\n\n // Create a new message for this messageId (server-side message)\n addMessage(conversationId, {\n id: messageId,\n role: 'assistant',\n content: '',\n timestamp,\n source: 'server',\n })\n }\n\n // Register all event listeners on mount\n onMount(() => {\n const cleanupFns: Array<() => void> = []\n\n // ============= Client Events =============\n\n cleanupFns.push(\n aiEventClient.on('client:created', (e) => {\n const clientId = e.payload.clientId\n getOrCreateConversation(\n clientId,\n 'client',\n `Client Chat (${clientId.substring(0, 8)})`,\n )\n updateConversation(clientId, { model: undefined, provider: 'Client' })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:message-sent', (e) => {\n const clientId = e.payload.clientId\n if (!state.conversations[clientId]) {\n getOrCreateConversation(\n clientId,\n 'client',\n `Client Chat (${clientId.substring(0, 8)})`,\n )\n }\n addMessage(clientId, {\n id: e.payload.messageId,\n role: 'user',\n content: e.payload.content,\n timestamp: e.payload.timestamp,\n source: 'client',\n })\n updateConversation(clientId, { status: 'active' })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:message-appended', (e) => {\n const clientId = e.payload.clientId\n const role = e.payload.role\n\n if (role === 'user') return\n if (!state.conversations[clientId]) return\n\n if (role === 'assistant') {\n addMessage(clientId, {\n id: e.payload.messageId,\n role: 'assistant',\n content: e.payload.contentPreview,\n timestamp: e.payload.timestamp,\n source: 'client',\n })\n } else if (role === 'tool') {\n // Tool result message from the LLM\n addMessage(clientId, {\n id: e.payload.messageId,\n role: 'tool',\n content: e.payload.contentPreview,\n timestamp: e.payload.timestamp,\n source: 'client',\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:loading-changed', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n status: e.payload.isLoading ? 'active' : 'completed',\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:stopped', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n status: 'completed',\n completedAt: e.payload.timestamp,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:messages-cleared', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n messages: [],\n chunks: [],\n usage: undefined,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:reloaded', (e) => {\n const clientId = e.payload.clientId\n const conv = state.conversations[clientId]\n if (conv) {\n updateConversation(clientId, {\n messages: conv.messages.slice(0, e.payload.fromMessageIndex),\n status: 'active',\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:error-changed', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId] && e.payload.error) {\n updateConversation(clientId, { status: 'error' })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:assistant-message-updated', (e) => {\n const clientId = e.payload.clientId\n const messageId = e.payload.messageId\n const content = e.payload.content\n\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n\n // Find message by ID anywhere in the list, not just the last one\n const messageIndex = conv.messages.findIndex(\n (m: Message) => m.id === messageId,\n )\n\n // Only update existing messages, don't create new ones\n // (client:message-appended is responsible for creating messages)\n if (messageIndex >= 0) {\n updateMessage(clientId, messageIndex, {\n content,\n model: conv.model,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:tool-call-updated', (e) => {\n const {\n clientId,\n messageId,\n toolCallId,\n toolName,\n state: toolCallState,\n arguments: args,\n } = e.payload as {\n clientId: string\n messageId: string\n toolCallId: string\n toolName: string\n state: string\n arguments: unknown\n timestamp: number\n }\n\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n const messageIndex = conv.messages.findIndex(\n (m: Message) => m.id === messageId,\n )\n if (messageIndex === -1) return\n\n const message = conv.messages[messageIndex]\n if (!message) return\n\n const toolCalls = message.toolCalls || []\n const existingToolIndex = toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n\n const toolCall: ToolCall = {\n id: toolCallId,\n name: toolName,\n arguments: JSON.stringify(args, null, 2),\n state: toolCallState,\n }\n\n if (existingToolIndex >= 0) {\n updateToolCall(clientId, messageIndex, existingToolIndex, toolCall)\n } else {\n setToolCalls(clientId, messageIndex, [...toolCalls, toolCall])\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:approval-requested', (e) => {\n const { clientId, messageId, toolCallId, approvalId } = e.payload\n\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n const messageIndex = conv.messages.findIndex((m) => m.id === messageId)\n if (messageIndex === -1) return\n\n const message = conv.messages[messageIndex]\n if (!message?.toolCalls) return\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === toolCallId,\n )\n if (toolCallIndex === -1) return\n\n updateToolCall(clientId, messageIndex, toolCallIndex, {\n approvalRequired: true,\n approvalId,\n state: 'approval-requested',\n })\n }),\n )\n\n // ============= Tool Events =============\n\n cleanupFns.push(\n aiEventClient.on('tool:result-added', (e) => {\n const {\n clientId,\n toolCallId,\n toolName,\n output,\n state: resultState,\n timestamp,\n } = e.payload\n\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n\n // Find the message with the tool call and update it\n for (\n let messageIndex = conv.messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = conv.messages[messageIndex]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n // Update the tool call state\n updateToolCall(clientId, messageIndex, toolCallIndex, {\n result: output,\n state: resultState === 'output-error' ? 'error' : 'complete',\n })\n\n // Also add a chunk to show the tool result in the chunks view\n const chunk: Chunk = {\n id: `chunk-tool-result-${toolCallId}-${Date.now()}`,\n type: 'tool_result',\n messageId: message.id,\n toolCallId,\n toolName,\n result: output,\n timestamp,\n chunkCount: 1,\n }\n addChunkToMessage(clientId, chunk)\n return\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tool:approval-responded', (e) => {\n const { clientId, toolCallId, approved } = e.payload\n\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n\n for (\n let messageIndex = conv.messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = conv.messages[messageIndex]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(clientId, messageIndex, toolCallIndex, {\n state: approved ? 'approved' : 'denied',\n approvalRequired: false,\n })\n return\n }\n }\n }),\n )\n\n // ============= Stream Events =============\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:content', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'content',\n messageId: e.payload.messageId,\n content: e.payload.content,\n delta: e.payload.delta,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:tool-call', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'tool_call',\n messageId: e.payload.messageId,\n toolCallId: e.payload.toolCallId,\n toolName: e.payload.toolName,\n arguments: e.payload.arguments,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:tool-result', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'tool_result',\n messageId: e.payload.messageId,\n toolCallId: e.payload.toolCallId,\n content: e.payload.result,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n // Also update the toolCalls array with the result\n if (conv && e.payload.toolCallId) {\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === e.payload.toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n result: e.payload.result,\n state: 'complete',\n })\n break\n }\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:thinking', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'thinking',\n messageId: e.payload.messageId,\n content: e.payload.content,\n delta: e.payload.delta,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n\n if (e.payload.messageId) {\n const messageIndex = conv.messages.findIndex(\n (msg) => msg.id === e.payload.messageId,\n )\n if (messageIndex !== -1) {\n updateMessage(conversationId, messageIndex, {\n thinkingContent: e.payload.content,\n })\n }\n }\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:done', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'done',\n messageId: e.payload.messageId,\n finishReason: e.payload.finishReason || undefined,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n if (e.payload.usage) {\n updateConversation(conversationId, { usage: e.payload.usage })\n updateMessageUsage(\n conversationId,\n e.payload.messageId,\n e.payload.usage,\n )\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n updateConversation(conversationId, {\n status: 'completed',\n completedAt: e.payload.timestamp,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:chunk:error', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'error',\n messageId: e.payload.messageId,\n error: e.payload.error,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n updateConversation(conversationId, {\n status: 'error',\n completedAt: e.payload.timestamp,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:ended', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n updateConversation(conversationId, {\n status: 'completed',\n completedAt: e.payload.timestamp,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('stream:approval-requested', (e) => {\n const {\n streamId,\n messageId,\n toolCallId,\n toolName,\n input,\n approvalId,\n timestamp,\n } = e.payload\n\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'approval',\n messageId: messageId,\n toolCallId,\n toolName,\n approvalId,\n input,\n timestamp,\n chunkCount: 1,\n }\n\n if (conv.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n addChunk(conversationId, chunk)\n }\n\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message) continue\n\n if (message.role === 'assistant' && message.toolCalls) {\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n approvalRequired: true,\n approvalId,\n state: 'approval-requested',\n })\n return\n }\n }\n }\n }),\n )\n\n // ============= Processor Events =============\n\n cleanupFns.push(\n aiEventClient.on('processor:text-updated', (e) => {\n const streamId = e.payload.streamId\n\n let conversationId = streamToConversation.get(streamId)\n\n if (!conversationId) {\n const activeClients = Object.values(state.conversations)\n .filter((c) => c.type === 'client' && c.status === 'active')\n .sort((a, b) => b.startedAt - a.startedAt)\n\n if (activeClients.length > 0 && activeClients[0]) {\n conversationId = activeClients[0].id\n streamToConversation.set(streamId, conversationId)\n }\n }\n\n if (!conversationId) return\n\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n // Only update existing assistant messages, don't create new ones\n // (client:message-appended is responsible for creating messages)\n const lastMessage = conv.messages[conv.messages.length - 1]\n if (lastMessage && lastMessage.role === 'assistant') {\n updateMessage(conversationId, conv.messages.length - 1, {\n content: e.payload.content,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('processor:tool-call-state-changed', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n const lastMessage = conv.messages[conv.messages.length - 1]\n\n if (lastMessage && lastMessage.role === 'assistant') {\n const toolCalls = lastMessage.toolCalls || []\n const existingToolIndex = toolCalls.findIndex(\n (t) => t.id === e.payload.toolCallId,\n )\n\n const toolCall: ToolCall = {\n id: e.payload.toolCallId,\n name: e.payload.toolName,\n arguments: JSON.stringify(e.payload.arguments, null, 2),\n state: e.payload.state,\n }\n\n if (existingToolIndex >= 0) {\n updateToolCall(\n conversationId,\n conv.messages.length - 1,\n existingToolIndex,\n toolCall,\n )\n } else {\n setToolCalls(conversationId, conv.messages.length - 1, [\n ...toolCalls,\n toolCall,\n ])\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('processor:tool-result-state-changed', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === e.payload.toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n result: e.payload.content,\n state: e.payload.error ? 'error' : e.payload.state,\n })\n return\n }\n }\n }),\n )\n\n // ============= Chat Events (for usage tracking) =============\n\n cleanupFns.push(\n aiEventClient.on('text:started', (e) => {\n const streamId = e.payload.streamId\n const model = e.payload.model\n const provider = e.payload.provider\n const clientId = e.payload.clientId\n\n if (clientId && state.conversations[clientId]) {\n streamToConversation.set(streamId, clientId)\n updateConversation(clientId, { status: 'active', ...e.payload })\n return\n }\n\n const activeClient = Object.values(state.conversations).find(\n (c) => c.type === 'client' && c.status === 'active' && !c.model,\n )\n\n if (activeClient) {\n streamToConversation.set(streamId, activeClient.id)\n updateConversation(activeClient.id, { ...e.payload })\n } else {\n const existingServerConv = Object.values(state.conversations).find(\n (c) => c.type === 'server' && c.model === model,\n )\n\n if (existingServerConv) {\n streamToConversation.set(streamId, existingServerConv.id)\n updateConversation(existingServerConv.id, {\n status: 'active',\n ...e.payload,\n })\n } else {\n const serverId = `server-${model}`\n getOrCreateConversation(serverId, 'server', `${model} Server`)\n streamToConversation.set(streamId, serverId)\n updateConversation(serverId, { ...e.payload })\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:completed', (e) => {\n const { requestId, usage } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (conversationId && state.conversations[conversationId]) {\n const updates: Partial<Conversation> = {\n status: 'completed',\n completedAt: e.payload.timestamp,\n }\n if (usage) {\n updates.usage = usage\n }\n updateConversation(conversationId, updates)\n if (usage) {\n updateMessageUsage(conversationId, e.payload.messageId, usage)\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:iteration', (e) => {\n const { requestId, iterationNumber } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (conversationId && state.conversations[conversationId]) {\n updateConversation(conversationId, {\n iterationCount: iterationNumber,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('usage:tokens', (e) => {\n const { requestId, usage, messageId } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (conversationId && state.conversations[conversationId]) {\n updateConversation(conversationId, { usage })\n updateMessageUsage(conversationId, messageId, usage)\n }\n }),\n )\n\n // ============= Tool Call Completed (with duration) =============\n\n cleanupFns.push(\n aiEventClient.on('tool:call-completed', (e) => {\n const {\n streamId,\n toolCallId,\n toolName,\n result,\n duration,\n messageId,\n timestamp,\n } = e.payload\n\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n\n // Add a tool_result chunk to show the result in the chunks view\n const chunk: Chunk = {\n id: `chunk-tool-result-${toolCallId}-${Date.now()}`,\n type: 'tool_result',\n messageId: messageId,\n toolCallId,\n toolName,\n result,\n duration,\n timestamp,\n chunkCount: 1,\n }\n\n // Add chunk to message if it's a client conversation, otherwise to conversation\n if (conv.type === 'client' && messageId) {\n const messageIndex = conv.messages.findIndex(\n (m) => m.id === messageId,\n )\n if (messageIndex !== -1) {\n queueMessageChunk(conversationId, messageIndex, chunk)\n } else {\n // If message not found, add to last assistant message\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n if (conv.messages[i]?.role === 'assistant') {\n queueMessageChunk(conversationId, i, chunk)\n break\n }\n }\n }\n } else {\n addChunk(conversationId, chunk)\n }\n\n // Update the tool call with duration\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n duration,\n result,\n })\n return\n }\n }\n }),\n )\n\n // ============= Summarize Events =============\n\n cleanupFns.push(\n aiEventClient.on('summarize:started', (e) => {\n const { requestId, model, inputLength, timestamp, clientId } = e.payload\n\n // Try to find an active conversation to attach to, or create a new one\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n // Find most recent active client conversation\n const activeClients = Object.values(state.conversations)\n .filter((c) => c.type === 'client' && c.status === 'active')\n .sort((a, b) => b.startedAt - a.startedAt)\n\n if (activeClients.length > 0 && activeClients[0]) {\n conversationId = activeClients[0].id\n } else {\n // Create a new conversation for summaries\n conversationId = `summarize-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Summarize (${model})`,\n )\n updateConversation(conversationId, { model })\n }\n }\n\n requestToConversation.set(requestId, conversationId)\n\n const summarizeOp: SummarizeOperation = {\n id: requestId,\n model,\n inputLength,\n timestamp,\n status: 'started',\n }\n\n const conv = state.conversations[conversationId]\n if (conv) {\n const summaries = conv.summaries || []\n setState('conversations', conversationId, 'summaries', [\n ...summaries,\n summarizeOp,\n ])\n setState('conversations', conversationId, 'hasSummarize', true)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('summarize:completed', (e) => {\n const { requestId, outputLength, duration } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n if (!conv.summaries) return\n\n const summaryIndex = conv.summaries.findIndex(\n (op) => op.id === requestId,\n )\n if (summaryIndex >= 0) {\n setState(\n 'conversations',\n conversationId,\n 'summaries',\n summaryIndex,\n produce((op: SummarizeOperation) => {\n op.duration = duration\n op.outputLength = outputLength\n op.status = 'completed'\n }),\n )\n }\n }),\n )\n\n // Cleanup all listeners on unmount\n onCleanup(() => {\n for (const cleanup of cleanupFns) {\n cleanup()\n }\n streamToConversation.clear()\n requestToConversation.clear()\n })\n })\n\n const contextValue: AIContextValue = {\n state,\n clearAllConversations,\n selectConversation,\n }\n\n return (\n <AIContext.Provider value={contextValue}>\n {props.children}\n </AIContext.Provider>\n )\n}\n"],"names":["AIContext","createContext","useAIStore","context","useContext","Error","AIProvider","props","state","setState","createStore","conversations","activeConversationId","streamToConversation","Map","requestToConversation","pendingConversationChunks","pendingMessageChunks","batchScheduled","scheduleBatchFlush","queueMicrotask","flushPendingChunks","isMergeableChunkType","type","mergeChunks","existing","pending","chunk","lastChunk","length","messageId","content","delta","chunkCount","push","batch","conversationId","chunks","newChunkCount","conv","produce","arr","clear","messageMap","messageIndex","message","messages","currentTotal","totalChunkCount","queueChunk","has","set","get","lastPending","queueMessageChunk","getOrCreateConversation","id","label","status","startedAt","Date","now","addMessage","addChunkToMessage","findIndex","msg","newMessage","role","timestamp","model","i","updateMessageUsage","cumulativeUsage","previousPromptTokens","previousCompletionTokens","targetMessageIndex","usage","promptTokens","completionTokens","deltaUsage","Math","max","totalTokens","clearAllConversations","selectConversation","updateConversation","updates","key","value","Object","entries","updateMessage","updateToolCall","toolCallIndex","toolCalls","tc","assign","setToolCalls","addChunk","ensureMessageForChunk","existingMessage","find","m","source","onMount","cleanupFns","aiEventClient","on","e","clientId","payload","substring","undefined","provider","contentPreview","isLoading","completedAt","slice","fromMessageIndex","error","toolCallId","toolName","toolCallState","arguments","args","existingToolIndex","t","toolCall","name","JSON","stringify","approvalId","approvalRequired","output","resultState","result","approved","streamId","random","thinkingContent","finishReason","input","activeClients","values","filter","c","sort","a","b","lastMessage","activeClient","existingServerConv","serverId","requestId","iterationNumber","iterationCount","duration","inputLength","summarizeOp","summaries","outputLength","summaryIndex","op","onCleanup","cleanup","contextValue","_$createComponent","Provider","children"],"mappings":"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"}
1
+ {"version":3,"file":"ai-context.js","sources":["../../../src/store/ai-context.tsx"],"sourcesContent":["import { batch, createContext, onCleanup, onMount, useContext } from 'solid-js'\nimport { createStore, produce } from 'solid-js/store'\nimport { aiEventClient } from '@tanstack/ai/event-client'\nimport type { ParentComponent } from 'solid-js'\n\ninterface MessagePart {\n type: 'text' | 'tool-call' | 'tool-result' | 'thinking'\n content?: string\n toolCallId?: string\n toolName?: string\n arguments?: string\n state?: string\n output?: unknown\n error?: string\n}\n\nexport interface ToolCall {\n id: string\n name: string\n arguments: string\n state: string\n result?: unknown\n approvalRequired?: boolean\n approvalId?: string\n /** Duration of tool execution in milliseconds */\n duration?: number\n}\n\ninterface TokenUsage {\n promptTokens: number\n completionTokens: number\n totalTokens: number\n}\n\nexport interface Message {\n id: string\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string\n timestamp: number\n parts?: Array<MessagePart>\n toolCalls?: Array<ToolCall>\n /** Consolidated chunks - consecutive same-type chunks are merged into one entry */\n chunks?: Array<Chunk>\n /** Total number of raw chunks received (before consolidation) */\n totalChunkCount?: number\n model?: string\n usage?: TokenUsage\n thinkingContent?: string\n /** Source of the message: 'client' for aggregated client-side data, 'server' for individual server chunks */\n source?: 'client' | 'server'\n}\n\n/**\n * Consolidated chunk - represents one or more raw chunks of the same type.\n * Consecutive content/thinking chunks are merged into a single entry with accumulated content.\n */\nexport interface Chunk {\n id: string\n type:\n | 'content'\n | 'tool_call'\n | 'tool_result'\n | 'done'\n | 'error'\n | 'approval'\n | 'thinking'\n timestamp: number\n messageId?: string\n /** Accumulated content from all merged chunks */\n content?: string\n /** The last delta received (kept for debugging) */\n delta?: string\n toolName?: string\n toolCallId?: string\n finishReason?: string\n error?: string\n approvalId?: string\n input?: unknown\n /** Tool arguments for tool_call chunks */\n arguments?: string\n /** Tool result data for tool_result chunks */\n result?: unknown\n /** Duration in ms for tool execution */\n duration?: number\n /** Number of raw chunks that were merged into this consolidated chunk */\n chunkCount: number\n /** Whether this is a client-side tool execution */\n isClientTool?: boolean\n}\n\nexport interface SummarizeOperation {\n id: string\n model: string\n inputLength: number\n outputLength?: number\n duration?: number\n timestamp: number\n status: 'started' | 'completed'\n}\n\nexport interface ActivityEvent {\n id: string\n name: string\n timestamp: number\n payload: unknown\n}\n\nexport interface Conversation {\n id: string\n type: 'client' | 'server'\n label: string\n messages: Array<Message>\n chunks: Array<Chunk>\n model?: string\n provider?: string\n status: 'active' | 'completed' | 'error'\n startedAt: number\n completedAt?: number\n usage?: TokenUsage\n iterationCount?: number\n toolNames?: Array<string>\n options?: Record<string, unknown>\n modelOptions?: Record<string, unknown>\n systemPrompts?: Array<string>\n /** Flags for which operation types this conversation has */\n hasChat?: boolean\n hasSummarize?: boolean\n hasImage?: boolean\n hasSpeech?: boolean\n hasTranscription?: boolean\n hasVideo?: boolean\n /** Summarize operations in this conversation */\n summaries?: Array<SummarizeOperation>\n imageEvents?: Array<ActivityEvent>\n speechEvents?: Array<ActivityEvent>\n transcriptionEvents?: Array<ActivityEvent>\n videoEvents?: Array<ActivityEvent>\n}\n\ninterface AIStoreState {\n conversations: Record<string, Conversation>\n activeConversationId: string | null\n}\n\ninterface AIContextValue {\n state: AIStoreState\n clearAllConversations: () => void\n selectConversation: (id: string) => void\n}\n\nconst AIContext = createContext<AIContextValue>()\n\nexport function useAIStore(): AIContextValue {\n const context = useContext(AIContext)\n if (!context) {\n throw new Error('useAIStore must be used within an AIProvider')\n }\n return context\n}\n\nexport const AIProvider: ParentComponent = (props) => {\n const [state, setState] = createStore<AIStoreState>({\n conversations: {},\n activeConversationId: null,\n })\n\n const streamToConversation = new Map<string, string>()\n const requestToConversation = new Map<string, string>()\n\n // Batching system for high-frequency chunk updates with consolidated chunk merging\n // Stores: conversationId -> { chunks to merge, totalNewChunks count }\n const pendingConversationChunks = new Map<\n string,\n { chunks: Array<Chunk>; newChunkCount: number }\n >()\n // Stores: conversationId -> messageIndex -> { chunks to merge, totalNewChunks count }\n const pendingMessageChunks = new Map<\n string,\n Map<number, { chunks: Array<Chunk>; newChunkCount: number }>\n >()\n let batchScheduled = false\n\n function scheduleBatchFlush(): void {\n if (batchScheduled) return\n batchScheduled = true\n queueMicrotask(flushPendingChunks)\n }\n\n /** Check if a chunk type can be merged with consecutive same-type chunks */\n function isMergeableChunkType(type: Chunk['type']): boolean {\n return type === 'content' || type === 'thinking'\n }\n\n /** Merge pending chunks into existing chunks array, consolidating consecutive same-type chunks */\n function mergeChunks(existing: Array<Chunk>, pending: Array<Chunk>): void {\n for (const chunk of pending) {\n const lastChunk = existing[existing.length - 1]\n\n // If last chunk exists, is the same type, and both are mergeable types, merge them\n if (\n lastChunk &&\n lastChunk.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastChunk.messageId === chunk.messageId\n ) {\n // Merge: use the new chunk's content (it's already accumulated), update delta, increment count\n lastChunk.content = chunk.content || lastChunk.content\n lastChunk.delta = chunk.delta\n lastChunk.chunkCount += chunk.chunkCount\n } else {\n // Different type or not mergeable - add as new entry\n existing.push(chunk)\n }\n }\n }\n\n function flushPendingChunks(): void {\n batchScheduled = false\n\n batch(() => {\n // Flush conversation-level chunks\n for (const [\n conversationId,\n { chunks, newChunkCount },\n ] of pendingConversationChunks) {\n const conv = state.conversations[conversationId]\n if (conv) {\n setState(\n 'conversations',\n conversationId,\n 'chunks',\n produce((arr: Array<Chunk>) => {\n mergeChunks(arr, chunks)\n }),\n )\n }\n }\n pendingConversationChunks.clear()\n\n // Flush message-level chunks\n for (const [conversationId, messageMap] of pendingMessageChunks) {\n const conv = state.conversations[conversationId]\n if (!conv) continue\n\n for (const [messageIndex, { chunks, newChunkCount }] of messageMap) {\n const message = conv.messages[messageIndex]\n if (message) {\n // Update chunks array with merging\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'chunks',\n produce((arr: Array<Chunk> | undefined) => {\n if (!arr) {\n // First time - just set the chunks (they're already consolidated in pending)\n return chunks\n }\n mergeChunks(arr, chunks)\n return arr\n }),\n )\n // Update total chunk count\n const currentTotal = message.totalChunkCount || 0\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'totalChunkCount',\n currentTotal + newChunkCount,\n )\n }\n }\n }\n pendingMessageChunks.clear()\n })\n }\n\n function queueChunk(conversationId: string, chunk: Chunk): void {\n if (!pendingConversationChunks.has(conversationId)) {\n pendingConversationChunks.set(conversationId, {\n chunks: [],\n newChunkCount: 0,\n })\n }\n const pending = pendingConversationChunks.get(conversationId)!\n\n // Pre-merge in pending buffer to reduce array operations during flush\n const lastPending = pending.chunks[pending.chunks.length - 1]\n if (\n lastPending &&\n lastPending.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastPending.messageId === chunk.messageId\n ) {\n // Merge into pending buffer - only append delta (incremental content)\n // Use the new chunk's content as the accumulated content (it's already accumulated)\n lastPending.content = chunk.content || lastPending.content\n lastPending.delta = chunk.delta\n lastPending.chunkCount += chunk.chunkCount\n } else {\n pending.chunks.push(chunk)\n }\n pending.newChunkCount += chunk.chunkCount\n scheduleBatchFlush()\n }\n\n function queueMessageChunk(\n conversationId: string,\n messageIndex: number,\n chunk: Chunk,\n ): void {\n if (!pendingMessageChunks.has(conversationId)) {\n pendingMessageChunks.set(conversationId, new Map())\n }\n const messageMap = pendingMessageChunks.get(conversationId)!\n if (!messageMap.has(messageIndex)) {\n messageMap.set(messageIndex, { chunks: [], newChunkCount: 0 })\n }\n const pending = messageMap.get(messageIndex)!\n\n // Pre-merge in pending buffer\n const lastPending = pending.chunks[pending.chunks.length - 1]\n if (\n lastPending &&\n lastPending.type === chunk.type &&\n isMergeableChunkType(chunk.type) &&\n lastPending.messageId === chunk.messageId\n ) {\n // Merge into pending buffer - only append delta (incremental content)\n // Use the new chunk's content as the accumulated content (it's already accumulated)\n lastPending.content = chunk.content || lastPending.content\n lastPending.delta = chunk.delta\n lastPending.chunkCount += chunk.chunkCount\n } else {\n pending.chunks.push(chunk)\n }\n pending.newChunkCount += chunk.chunkCount\n scheduleBatchFlush()\n }\n\n // Optimized helper functions using path-based updates\n function getOrCreateConversation(\n id: string,\n type: 'client' | 'server',\n label: string,\n ): void {\n if (!state.conversations[id]) {\n setState('conversations', id, {\n id,\n type,\n label,\n messages: [],\n chunks: [],\n imageEvents: [],\n speechEvents: [],\n transcriptionEvents: [],\n videoEvents: [],\n status: 'active',\n startedAt: Date.now(),\n })\n if (!state.activeConversationId) {\n setState('activeConversationId', id)\n }\n }\n }\n\n function addMessage(conversationId: string, message: Message): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n conv.messages.length,\n message,\n )\n }\n\n function addChunkToMessage(conversationId: string, chunk: Chunk): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n if (chunk.messageId) {\n const messageIndex = conv.messages.findIndex(\n (msg) => msg.id === chunk.messageId,\n )\n\n if (messageIndex !== -1) {\n queueMessageChunk(conversationId, messageIndex, chunk)\n return\n } else {\n // Create new message with the chunk\n const newMessage: Message = {\n id: chunk.messageId,\n role: 'assistant',\n content: '',\n timestamp: chunk.timestamp,\n model: conv.model,\n chunks: [chunk],\n }\n setState(\n 'conversations',\n conversationId,\n 'messages',\n conv.messages.length,\n newMessage,\n )\n return\n }\n }\n\n // Find last assistant message\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (message && message.role === 'assistant') {\n queueMessageChunk(conversationId, i, chunk)\n return\n }\n }\n\n // Fallback: add to conversation's main chunks array if no assistant message found\n addChunk(conversationId, chunk)\n }\n\n function updateMessageUsage(\n conversationId: string,\n messageId: string | undefined,\n cumulativeUsage: TokenUsage,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n // Calculate the sum of usage from all previous messages (excluding the target message)\n let previousPromptTokens = 0\n let previousCompletionTokens = 0\n\n // Find the target message index\n let targetMessageIndex = -1\n if (messageId) {\n targetMessageIndex = conv.messages.findIndex(\n (msg) => msg.id === messageId,\n )\n } else {\n // Find last assistant message\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n if (conv.messages[i]?.role === 'assistant') {\n targetMessageIndex = i\n break\n }\n }\n }\n\n if (targetMessageIndex === -1) return\n\n // Sum up usage from all previous assistant messages\n for (let i = 0; i < targetMessageIndex; i++) {\n const msg = conv.messages[i]\n if (msg?.role === 'assistant' && msg.usage) {\n previousPromptTokens += msg.usage.promptTokens\n previousCompletionTokens += msg.usage.completionTokens\n }\n }\n\n // Calculate delta usage for this message\n const deltaUsage: TokenUsage = {\n promptTokens: Math.max(\n 0,\n cumulativeUsage.promptTokens - previousPromptTokens,\n ),\n completionTokens: Math.max(\n 0,\n cumulativeUsage.completionTokens - previousCompletionTokens,\n ),\n totalTokens: 0,\n }\n deltaUsage.totalTokens =\n deltaUsage.promptTokens + deltaUsage.completionTokens\n\n setState(\n 'conversations',\n conversationId,\n 'messages',\n targetMessageIndex,\n 'usage',\n deltaUsage,\n )\n }\n\n // Public actions\n function clearAllConversations() {\n setState('conversations', {})\n setState('activeConversationId', null)\n streamToConversation.clear()\n requestToConversation.clear()\n pendingConversationChunks.clear()\n pendingMessageChunks.clear()\n }\n\n function selectConversation(id: string) {\n setState('activeConversationId', id)\n }\n\n // Additional optimized helper functions\n function updateConversation(\n conversationId: string,\n updates: Partial<Conversation>,\n ): void {\n if (!state.conversations[conversationId]) return\n for (const [key, value] of Object.entries(updates)) {\n setState(\n 'conversations',\n conversationId,\n key as keyof Conversation,\n value as Conversation[keyof Conversation],\n )\n }\n }\n\n function updateMessage(\n conversationId: string,\n messageIndex: number,\n updates: Partial<Message>,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv || !conv.messages[messageIndex]) return\n for (const [key, value] of Object.entries(updates)) {\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n key as keyof Message,\n value as Message[keyof Message],\n )\n }\n }\n\n function updateToolCall(\n conversationId: string,\n messageIndex: number,\n toolCallIndex: number,\n updates: Partial<ToolCall>,\n ): void {\n const conv = state.conversations[conversationId]\n if (!conv?.messages[messageIndex]?.toolCalls?.[toolCallIndex]) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'toolCalls',\n toolCallIndex,\n produce((tc: ToolCall) => Object.assign(tc, updates)),\n )\n }\n\n function setToolCalls(\n conversationId: string,\n messageIndex: number,\n toolCalls: Array<ToolCall>,\n ): void {\n if (!state.conversations[conversationId]?.messages[messageIndex]) return\n setState(\n 'conversations',\n conversationId,\n 'messages',\n messageIndex,\n 'toolCalls',\n toolCalls,\n )\n }\n\n function addChunk(conversationId: string, chunk: Chunk): void {\n if (!state.conversations[conversationId]) return\n queueChunk(conversationId, chunk)\n }\n\n function addActivityEvent(\n conversationId: string,\n activity:\n | 'imageEvents'\n | 'speechEvents'\n | 'transcriptionEvents'\n | 'videoEvents',\n event: ActivityEvent,\n ): void {\n if (!state.conversations[conversationId]) return\n\n setState(\n 'conversations',\n conversationId,\n activity,\n produce((events: Array<ActivityEvent> | undefined) => {\n if (!events) return [event]\n events.push(event)\n return events\n }),\n )\n\n const activityFlagMap: Record<typeof activity, keyof Conversation> = {\n imageEvents: 'hasImage',\n speechEvents: 'hasSpeech',\n transcriptionEvents: 'hasTranscription',\n videoEvents: 'hasVideo',\n }\n\n setState('conversations', conversationId, activityFlagMap[activity], true)\n }\n\n /**\n * For server conversations, ensure a message exists for the given messageId.\n * This creates a placeholder message that will be updated as chunks arrive.\n */\n function ensureMessageForChunk(\n conversationId: string,\n messageId: string | undefined,\n timestamp: number,\n ): void {\n if (!messageId) return\n const conv = state.conversations[conversationId]\n if (!conv || conv.type === 'client') return\n\n // Check if message already exists\n const existingMessage = conv.messages.find((m) => m.id === messageId)\n if (existingMessage) return\n\n // Create a new message for this messageId (server-side message)\n addMessage(conversationId, {\n id: messageId,\n role: 'assistant',\n content: '',\n timestamp,\n source: 'server',\n })\n }\n\n // Register all event listeners on mount\n onMount(() => {\n const cleanupFns: Array<() => void> = []\n\n // ============= Client Events =============\n\n cleanupFns.push(\n aiEventClient.on('client:created', (e) => {\n const clientId = e.payload.clientId\n getOrCreateConversation(\n clientId,\n 'client',\n `Client Chat (${clientId.substring(0, 8)})`,\n )\n updateConversation(clientId, { model: undefined, provider: 'Client' })\n }),\n )\n\n // ============= Message Events =============\n\n cleanupFns.push(\n aiEventClient.on('text:message:created', (e) => {\n const { clientId, streamId, messageId, role, content, timestamp } =\n e.payload\n const conversationId =\n clientId ||\n (streamId ? streamToConversation.get(streamId) : undefined)\n\n if (!conversationId) return\n if (role === 'tool' || role === 'system') return\n\n if (!state.conversations[conversationId]) {\n getOrCreateConversation(\n conversationId,\n clientId ? 'client' : 'server',\n clientId\n ? `Client Chat (${conversationId.substring(0, 8)})`\n : `Server Chat (${conversationId.substring(0, 8)})`,\n )\n }\n\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n const existingIndex = conv.messages.findIndex(\n (message) => message.id === messageId,\n )\n\n const parts = e.payload.parts?.map((part) => {\n if (part.type === 'text') {\n return { type: 'text', content: part.content } satisfies MessagePart\n }\n if (part.type === 'tool-call') {\n return {\n type: 'tool-call',\n toolCallId: part.id,\n toolName: part.name,\n arguments: part.arguments,\n state: part.state,\n output: part.output,\n content: part.approval\n ? JSON.stringify(part.approval)\n : undefined,\n } satisfies MessagePart\n }\n if (part.type === 'tool-result') {\n return {\n type: 'tool-result',\n toolCallId: part.toolCallId,\n content: part.content,\n state: part.state,\n error: part.error,\n } satisfies MessagePart\n }\n return {\n type: 'thinking',\n content: part.content,\n } satisfies MessagePart\n })\n\n const toolCalls = e.payload.toolCalls?.map((toolCall) => ({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n state: 'input-complete',\n }))\n\n const source = e.payload.source ?? (clientId ? 'client' : 'server')\n\n if (role === 'user' && conv.type === 'client' && source === 'server') {\n return\n }\n\n // Skip empty assistant messages from client - the real content comes from server\n if (\n role === 'assistant' &&\n source === 'client' &&\n !content &&\n (!toolCalls || toolCalls.length === 0)\n ) {\n return\n }\n\n const messagePayload: Message = {\n id: messageId,\n role,\n content,\n timestamp,\n parts,\n toolCalls,\n source,\n }\n\n if (existingIndex >= 0) {\n updateMessage(conversationId, existingIndex, messagePayload)\n } else {\n addMessage(conversationId, messagePayload)\n }\n\n updateConversation(conversationId, { status: 'active', hasChat: true })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:message:user', (e) => {\n const { clientId, streamId, messageId, content, timestamp } = e.payload\n const conversationId =\n clientId ||\n (streamId ? streamToConversation.get(streamId) : undefined)\n if (!conversationId) return\n\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n const existingIndex = conv.messages.findIndex(\n (message) => message.id === messageId,\n )\n\n if (existingIndex >= 0) return\n\n const source = e.payload.source ?? (clientId ? 'client' : 'server')\n\n if (conv.type === 'client' && source === 'server') {\n return\n }\n\n addMessage(conversationId, {\n id: messageId,\n role: 'user',\n content,\n timestamp,\n source,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:loading:changed', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n status: e.payload.isLoading ? 'active' : 'completed',\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:stopped', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n status: 'completed',\n completedAt: e.payload.timestamp,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:messages:cleared', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId]) {\n updateConversation(clientId, {\n messages: [],\n chunks: [],\n usage: undefined,\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:reloaded', (e) => {\n const clientId = e.payload.clientId\n const conv = state.conversations[clientId]\n if (conv) {\n updateConversation(clientId, {\n messages: conv.messages.slice(0, e.payload.fromMessageIndex),\n status: 'active',\n })\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('client:error:changed', (e) => {\n const clientId = e.payload.clientId\n if (state.conversations[clientId] && e.payload.error) {\n updateConversation(clientId, { status: 'error' })\n }\n }),\n )\n\n // ============= Tool Events =============\n\n cleanupFns.push(\n aiEventClient.on('tools:result:added', (e) => {\n const {\n clientId,\n toolCallId,\n toolName,\n output,\n state: resultState,\n timestamp,\n } = e.payload\n\n if (!clientId) return\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n\n // Always create a chunk for the tool result\n const chunk: Chunk = {\n id: `chunk-tool-result-${toolCallId}-${Date.now()}`,\n type: 'tool_result',\n toolCallId,\n toolName,\n result: output,\n timestamp,\n chunkCount: 1,\n isClientTool: true,\n }\n\n // Find the message with the tool call and update it\n for (\n let messageIndex = conv.messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = conv.messages[messageIndex]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n // Update the tool call state\n updateToolCall(clientId, messageIndex, toolCallIndex, {\n result: output,\n state: resultState === 'output-error' ? 'error' : 'complete',\n })\n\n // Add chunk with message ID\n chunk.messageId = message.id\n addChunkToMessage(clientId, chunk)\n return\n }\n }\n\n // If we couldn't find the message with toolCalls, still add the chunk\n // This handles cases where the message hasn't been processed yet\n // or the tool call is a client-only tool\n addChunkToMessage(clientId, chunk)\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tools:approval:responded', (e) => {\n const { clientId, toolCallId, approved } = e.payload\n\n if (!clientId) return\n if (!state.conversations[clientId]) return\n\n const conv = state.conversations[clientId]\n\n for (\n let messageIndex = conv.messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = conv.messages[messageIndex]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(clientId, messageIndex, toolCallIndex, {\n state: approved ? 'approved' : 'denied',\n approvalRequired: false,\n })\n return\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tools:call:updated', (e) => {\n const {\n clientId,\n streamId,\n messageId,\n toolCallId,\n toolName,\n state: toolCallState,\n arguments: args,\n } = e.payload\n\n const conversationId =\n clientId ||\n (streamId ? streamToConversation.get(streamId) : undefined)\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n const messageIndex = conv.messages.findIndex(\n (m: Message) => m.id === messageId,\n )\n if (messageIndex === -1) return\n\n const message = conv.messages[messageIndex]\n if (!message) return\n\n const toolCalls = message.toolCalls || []\n const existingToolIndex = toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n\n const toolCall: ToolCall = {\n id: toolCallId,\n name: toolName,\n arguments: args,\n state: toolCallState,\n }\n\n if (existingToolIndex >= 0) {\n updateToolCall(\n conversationId,\n messageIndex,\n existingToolIndex,\n toolCall,\n )\n } else {\n setToolCalls(conversationId, messageIndex, [...toolCalls, toolCall])\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tools:input:available', (e) => {\n const {\n streamId,\n messageId,\n toolCallId,\n toolName,\n input,\n timestamp,\n clientId,\n } = e.payload\n\n const conversationId =\n clientId ||\n (streamId ? streamToConversation.get(streamId) : undefined)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'tool_call',\n messageId: messageId,\n toolCallId,\n toolName,\n arguments: JSON.stringify(input),\n timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n addChunk(conversationId, chunk)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tools:call:completed', (e) => {\n const {\n streamId,\n toolCallId,\n toolName,\n result,\n duration,\n messageId,\n timestamp,\n clientId,\n } = e.payload\n\n const conversationId =\n clientId ||\n (streamId ? streamToConversation.get(streamId) : undefined)\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n\n const chunk: Chunk = {\n id: `chunk-tool-result-${toolCallId}-${Date.now()}`,\n type: 'tool_result',\n messageId: messageId,\n toolCallId,\n toolName,\n result,\n duration,\n timestamp,\n chunkCount: 1,\n }\n\n if (conv.type === 'client' && messageId) {\n const messageIndex = conv.messages.findIndex(\n (m) => m.id === messageId,\n )\n if (messageIndex !== -1) {\n queueMessageChunk(conversationId, messageIndex, chunk)\n } else {\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n if (conv.messages[i]?.role === 'assistant') {\n queueMessageChunk(conversationId, i, chunk)\n break\n }\n }\n }\n } else {\n addChunk(conversationId, chunk)\n }\n\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n duration,\n result,\n })\n return\n }\n }\n }),\n )\n\n // ============= Stream Events =============\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:content', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'content',\n messageId: e.payload.messageId,\n content: e.payload.content,\n delta: e.payload.delta,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n if (e.payload.messageId) {\n const messageIndex = conv?.messages.findIndex(\n (msg) => msg.id === e.payload.messageId,\n )\n if (messageIndex !== undefined && messageIndex >= 0) {\n updateMessage(conversationId, messageIndex, {\n content: e.payload.content,\n })\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:tool-call', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'tool_call',\n messageId: e.payload.messageId,\n toolCallId: e.payload.toolCallId,\n toolName: e.payload.toolName,\n arguments: e.payload.arguments,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n if (e.payload.messageId) {\n const messageIndex = conv?.messages.findIndex(\n (msg) => msg.id === e.payload.messageId,\n )\n if (messageIndex !== undefined && messageIndex >= 0) {\n const message = conv?.messages[messageIndex]\n if (!message) return\n\n const toolCalls = message.toolCalls || []\n const existingToolIndex = toolCalls.findIndex(\n (t: ToolCall) => t.id === e.payload.toolCallId,\n )\n\n const toolCall: ToolCall = {\n id: e.payload.toolCallId,\n name: e.payload.toolName,\n arguments: e.payload.arguments,\n state: 'input-streaming',\n }\n\n if (existingToolIndex >= 0) {\n updateToolCall(\n conversationId,\n messageIndex,\n existingToolIndex,\n toolCall,\n )\n } else {\n setToolCalls(conversationId, messageIndex, [\n ...toolCalls,\n toolCall,\n ])\n }\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:tool-result', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'tool_result',\n messageId: e.payload.messageId,\n toolCallId: e.payload.toolCallId,\n result: e.payload.result,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n // Also update the toolCalls array with the result\n if (conv && e.payload.toolCallId) {\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message?.toolCalls) continue\n\n const toolCallIndex = message.toolCalls.findIndex(\n (t) => t.id === e.payload.toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n result: e.payload.result,\n state: 'complete',\n })\n break\n }\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:thinking', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'thinking',\n messageId: e.payload.messageId,\n content: e.payload.content,\n delta: e.payload.delta,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n\n if (e.payload.messageId) {\n const messageIndex = conv.messages.findIndex(\n (msg) => msg.id === e.payload.messageId,\n )\n if (messageIndex !== -1) {\n updateMessage(conversationId, messageIndex, {\n thinkingContent: e.payload.content,\n })\n }\n }\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:done', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'done',\n messageId: e.payload.messageId,\n finishReason: e.payload.finishReason || undefined,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n if (e.payload.usage) {\n updateConversation(conversationId, { usage: e.payload.usage })\n updateMessageUsage(\n conversationId,\n e.payload.messageId,\n e.payload.usage,\n )\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n updateConversation(conversationId, {\n status: 'completed',\n completedAt: e.payload.timestamp,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:chunk:error', (e) => {\n const streamId = e.payload.streamId\n const conversationId = streamToConversation.get(streamId)\n if (!conversationId) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'error',\n messageId: e.payload.messageId,\n error: e.payload.error,\n timestamp: e.payload.timestamp,\n chunkCount: 1,\n }\n\n const conv = state.conversations[conversationId]\n if (conv?.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n ensureMessageForChunk(\n conversationId,\n e.payload.messageId,\n e.payload.timestamp,\n )\n addChunk(conversationId, chunk)\n }\n\n updateConversation(conversationId, {\n status: 'error',\n completedAt: e.payload.timestamp,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('tools:approval:requested', (e) => {\n const {\n streamId,\n messageId,\n toolCallId,\n toolName,\n input,\n approvalId,\n timestamp,\n clientId,\n } = e.payload\n\n const conversationId =\n clientId || streamToConversation.get(streamId) || ''\n if (!conversationId) return\n\n const conv = state.conversations[conversationId]\n if (!conv) return\n\n const chunk: Chunk = {\n id: `chunk-${Date.now()}-${Math.random()}`,\n type: 'approval',\n messageId: messageId,\n toolCallId,\n toolName,\n approvalId,\n input,\n timestamp,\n chunkCount: 1,\n }\n\n if (conv.type === 'client') {\n addChunkToMessage(conversationId, chunk)\n } else {\n addChunk(conversationId, chunk)\n }\n\n for (let i = conv.messages.length - 1; i >= 0; i--) {\n const message = conv.messages[i]\n if (!message) continue\n\n if (message.role === 'assistant' && message.toolCalls) {\n const toolCallIndex = message.toolCalls.findIndex(\n (t: ToolCall) => t.id === toolCallId,\n )\n if (toolCallIndex >= 0) {\n updateToolCall(conversationId, i, toolCallIndex, {\n approvalRequired: true,\n approvalId,\n state: 'approval-requested',\n })\n return\n }\n }\n }\n }),\n )\n\n // ============= Chat Events (for usage tracking) =============\n\n cleanupFns.push(\n aiEventClient.on('text:request:started', (e) => {\n const streamId = e.payload.streamId\n const model = e.payload.model\n const provider = e.payload.provider\n const clientId = e.payload.clientId\n\n if (clientId && state.conversations[clientId]) {\n streamToConversation.set(streamId, clientId)\n requestToConversation.set(e.payload.requestId, clientId)\n updateConversation(clientId, {\n status: 'active',\n ...e.payload,\n systemPrompts: e.payload.systemPrompts,\n hasChat: true,\n })\n return\n }\n\n const activeClient = Object.values(state.conversations).find(\n (c) => c.type === 'client' && c.status === 'active' && !c.model,\n )\n\n if (activeClient) {\n streamToConversation.set(streamId, activeClient.id)\n requestToConversation.set(e.payload.requestId, activeClient.id)\n updateConversation(activeClient.id, {\n ...e.payload,\n systemPrompts: e.payload.systemPrompts,\n hasChat: true,\n })\n } else {\n const existingServerConv = Object.values(state.conversations).find(\n (c) => c.type === 'server' && c.model === model,\n )\n\n if (existingServerConv) {\n streamToConversation.set(streamId, existingServerConv.id)\n requestToConversation.set(\n e.payload.requestId,\n existingServerConv.id,\n )\n updateConversation(existingServerConv.id, {\n status: 'active',\n ...e.payload,\n systemPrompts: e.payload.systemPrompts,\n hasChat: true,\n })\n } else {\n const serverId = `server-${model}`\n getOrCreateConversation(serverId, 'server', `${model} Server`)\n streamToConversation.set(streamId, serverId)\n requestToConversation.set(e.payload.requestId, serverId)\n updateConversation(serverId, {\n ...e.payload,\n systemPrompts: e.payload.systemPrompts,\n hasChat: true,\n })\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:request:completed', (e) => {\n const { requestId, usage } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (conversationId && state.conversations[conversationId]) {\n const updates: Partial<Conversation> = {\n status: 'completed',\n completedAt: e.payload.timestamp,\n }\n if (usage) {\n updates.usage = usage\n }\n updateConversation(conversationId, updates)\n if (usage) {\n updateMessageUsage(conversationId, e.payload.messageId, usage)\n }\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('text:usage', (e) => {\n const { requestId, usage, messageId } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (conversationId && state.conversations[conversationId]) {\n updateConversation(conversationId, { usage })\n updateMessageUsage(conversationId, messageId, usage)\n }\n }),\n )\n\n // ============= Summarize Events =============\n\n cleanupFns.push(\n aiEventClient.on('summarize:request:started', (e) => {\n const { requestId, model, inputLength, timestamp, clientId } = e.payload\n\n // Try to find an active conversation to attach to, or create a new one\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n // Find most recent active client conversation\n const activeClients = Object.values(state.conversations)\n .filter((c) => c.type === 'client' && c.status === 'active')\n .sort((a, b) => b.startedAt - a.startedAt)\n\n if (activeClients.length > 0 && activeClients[0]) {\n conversationId = activeClients[0].id\n } else {\n // Create a new conversation for summaries\n conversationId = `summarize-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Summarize (${model})`,\n )\n updateConversation(conversationId, { model })\n }\n }\n\n requestToConversation.set(requestId, conversationId)\n\n const summarizeOp: SummarizeOperation = {\n id: requestId,\n model,\n inputLength,\n timestamp,\n status: 'started',\n }\n\n const conv = state.conversations[conversationId]\n if (conv) {\n const summaries = conv.summaries || []\n setState('conversations', conversationId, 'summaries', [\n ...summaries,\n summarizeOp,\n ])\n setState('conversations', conversationId, 'hasSummarize', true)\n }\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('summarize:request:completed', (e) => {\n const { requestId, outputLength, duration } = e.payload\n\n const conversationId = requestToConversation.get(requestId)\n if (!conversationId || !state.conversations[conversationId]) return\n\n const conv = state.conversations[conversationId]\n if (!conv.summaries) return\n\n const summaryIndex = conv.summaries.findIndex(\n (op) => op.id === requestId,\n )\n if (summaryIndex >= 0) {\n setState(\n 'conversations',\n conversationId,\n 'summaries',\n summaryIndex,\n produce((op: SummarizeOperation) => {\n op.duration = duration\n op.outputLength = outputLength\n op.status = 'completed'\n }),\n )\n }\n }),\n )\n\n // ============= Image Events =============\n\n cleanupFns.push(\n aiEventClient.on('image:request:started', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `image-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Image (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'imageEvents', {\n id: requestId,\n name: 'image:request:started',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('image:request:completed', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `image-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Image (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'imageEvents', {\n id: requestId,\n name: 'image:request:completed',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('image:usage', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `image-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Image (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'imageEvents', {\n id: requestId,\n name: 'image:usage',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n // ============= Speech Events =============\n\n cleanupFns.push(\n aiEventClient.on('speech:request:started', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `speech-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Speech (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'speechEvents', {\n id: requestId,\n name: 'speech:request:started',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('speech:request:completed', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `speech-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Speech (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'speechEvents', {\n id: requestId,\n name: 'speech:request:completed',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('speech:usage', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `speech-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Speech (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'speechEvents', {\n id: requestId,\n name: 'speech:usage',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n // ============= Transcription Events =============\n\n cleanupFns.push(\n aiEventClient.on('transcription:request:started', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `transcription-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Transcription (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'transcriptionEvents', {\n id: requestId,\n name: 'transcription:request:started',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('transcription:request:completed', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `transcription-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Transcription (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'transcriptionEvents', {\n id: requestId,\n name: 'transcription:request:completed',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('transcription:usage', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `transcription-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Transcription (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'transcriptionEvents', {\n id: requestId,\n name: 'transcription:usage',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n // ============= Video Events =============\n\n cleanupFns.push(\n aiEventClient.on('video:request:started', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `video-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Video (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'videoEvents', {\n id: requestId,\n name: 'video:request:started',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('video:request:completed', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `video-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Video (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'videoEvents', {\n id: requestId,\n name: 'video:request:completed',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n cleanupFns.push(\n aiEventClient.on('video:usage', (e) => {\n const { requestId, clientId, timestamp } = e.payload\n\n let conversationId = clientId\n if (!conversationId || !state.conversations[conversationId]) {\n conversationId = `video-${requestId}`\n getOrCreateConversation(\n conversationId,\n 'server',\n `Video (${requestId.substring(0, 8)})`,\n )\n }\n\n addActivityEvent(conversationId, 'videoEvents', {\n id: requestId,\n name: 'video:usage',\n timestamp,\n payload: e.payload,\n })\n }),\n )\n\n // Cleanup all listeners on unmount\n onCleanup(() => {\n for (const cleanup of cleanupFns) {\n cleanup()\n }\n streamToConversation.clear()\n requestToConversation.clear()\n })\n })\n\n const contextValue: AIContextValue = {\n state,\n clearAllConversations,\n selectConversation,\n }\n\n return (\n <AIContext.Provider value={contextValue}>\n {props.children}\n </AIContext.Provider>\n )\n}\n"],"names":["AIContext","createContext","useAIStore","context","useContext","Error","AIProvider","props","state","setState","createStore","conversations","activeConversationId","streamToConversation","Map","requestToConversation","pendingConversationChunks","pendingMessageChunks","batchScheduled","scheduleBatchFlush","queueMicrotask","flushPendingChunks","isMergeableChunkType","type","mergeChunks","existing","pending","chunk","lastChunk","length","messageId","content","delta","chunkCount","push","batch","conversationId","chunks","newChunkCount","conv","produce","arr","clear","messageMap","messageIndex","message","messages","currentTotal","totalChunkCount","queueChunk","has","set","get","lastPending","queueMessageChunk","getOrCreateConversation","id","label","imageEvents","speechEvents","transcriptionEvents","videoEvents","status","startedAt","Date","now","addMessage","addChunkToMessage","findIndex","msg","newMessage","role","timestamp","model","i","addChunk","updateMessageUsage","cumulativeUsage","previousPromptTokens","previousCompletionTokens","targetMessageIndex","usage","promptTokens","completionTokens","deltaUsage","Math","max","totalTokens","clearAllConversations","selectConversation","updateConversation","updates","key","value","Object","entries","updateMessage","updateToolCall","toolCallIndex","toolCalls","tc","assign","setToolCalls","addActivityEvent","activity","event","events","activityFlagMap","ensureMessageForChunk","existingMessage","find","m","source","onMount","cleanupFns","aiEventClient","on","e","clientId","payload","substring","undefined","provider","streamId","existingIndex","parts","map","part","toolCallId","toolName","name","arguments","output","approval","JSON","stringify","error","toolCall","function","messagePayload","hasChat","isLoading","completedAt","slice","fromMessageIndex","resultState","result","isClientTool","t","approved","approvalRequired","toolCallState","args","existingToolIndex","input","random","duration","thinkingContent","finishReason","approvalId","requestId","systemPrompts","activeClient","values","c","existingServerConv","serverId","inputLength","activeClients","filter","sort","a","b","summarizeOp","summaries","outputLength","summaryIndex","op","onCleanup","cleanup","contextValue","_$createComponent","Provider","children"],"mappings":"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"}
@@ -88,8 +88,15 @@ export declare function useStyles(): import('solid-js').Accessor<{
88
88
  toolsList: string;
89
89
  toolBadge: string;
90
90
  jsonPreview: string;
91
+ collapsibleSection: string;
92
+ collapsibleSummary: string;
93
+ collapsibleContent: string;
94
+ systemPromptItem: string;
95
+ systemPromptIndex: string;
96
+ systemPromptText: string;
91
97
  tabsContainer: string;
92
98
  tabButtonActive: string;
99
+ tabButtonPulse: string;
93
100
  contentArea: string;
94
101
  emptyMessages: string;
95
102
  messagesList: string;
@@ -678,6 +678,54 @@ const stylesFactory = (theme) => {
678
678
  white-space: pre-wrap;
679
679
  word-break: break-word;
680
680
  `,
681
+ collapsibleSection: css`
682
+ margin-top: ${size[2]};
683
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
684
+ border-radius: ${border.radius.md};
685
+ overflow: hidden;
686
+ `,
687
+ collapsibleSummary: css`
688
+ cursor: pointer;
689
+ padding: ${size[2]} ${size[3]};
690
+ background: ${t(colors.gray[100], colors.darkGray[800])};
691
+ font-size: ${fontSize.xs};
692
+ font-weight: ${font.weight.medium};
693
+ color: ${t(colors.gray[700], colors.gray[300])};
694
+ user-select: none;
695
+ &:hover {
696
+ background: ${t(colors.gray[200], colors.darkGray[700])};
697
+ }
698
+ `,
699
+ collapsibleContent: css`
700
+ padding: ${size[3]};
701
+ background: ${t(colors.gray[50], colors.darkGray[900])};
702
+ font-size: ${fontSize.xs};
703
+ max-height: 300px;
704
+ overflow-y: auto;
705
+ `,
706
+ systemPromptItem: css`
707
+ display: flex;
708
+ gap: ${size[2]};
709
+ padding: ${size[2]};
710
+ margin-bottom: ${size[2]};
711
+ background: ${t(colors.gray[100], colors.darkGray[800])};
712
+ border-radius: ${border.radius.sm};
713
+ &:last-child {
714
+ margin-bottom: 0;
715
+ }
716
+ `,
717
+ systemPromptIndex: css`
718
+ font-weight: ${font.weight.semibold};
719
+ color: ${colors.purple[400]};
720
+ font-size: 10px;
721
+ flex-shrink: 0;
722
+ `,
723
+ systemPromptText: css`
724
+ color: ${t(colors.gray[700], colors.gray[300])};
725
+ white-space: pre-wrap;
726
+ word-break: break-word;
727
+ line-height: 1.4;
728
+ `,
681
729
  tabsContainer: css`
682
730
  display: flex;
683
731
  gap: ${size[2]};
@@ -689,10 +737,26 @@ const stylesFactory = (theme) => {
689
737
  color: ${colors.white};
690
738
  border-color: ${colors.pink[400]};
691
739
  `,
740
+ tabButtonPulse: css`
741
+ position: relative;
742
+ animation: activityPulse 1.4s ease-in-out infinite;
743
+ @keyframes activityPulse {
744
+ 0% {
745
+ box-shadow: 0 0 0 0 ${colors.pink[400]}55;
746
+ }
747
+ 70% {
748
+ box-shadow: 0 0 0 8px ${colors.pink[400]}00;
749
+ }
750
+ 100% {
751
+ box-shadow: 0 0 0 0 ${colors.pink[400]}00;
752
+ }
753
+ }
754
+ `,
692
755
  contentArea: css`
693
756
  flex: 1;
694
757
  overflow: auto;
695
758
  padding: ${size[3]};
759
+ padding-bottom: ${size[6]};
696
760
  `,
697
761
  emptyMessages: css`
698
762
  padding: ${size[6]};
@@ -710,7 +774,7 @@ const stylesFactory = (theme) => {
710
774
  overflow: hidden;
711
775
  `,
712
776
  messageCardUser: css`
713
- padding: ${size[4]};
777
+ padding: ${size[3]};
714
778
  border: 1.5px solid oklch(0.45 0.12 260);
715
779
  `,
716
780
  messageCardAssistant: css`