@devicai/ui 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cjs/api/client.js +7 -0
  2. package/dist/cjs/api/client.js.map +1 -1
  3. package/dist/cjs/api/types.js +10 -0
  4. package/dist/cjs/api/types.js.map +1 -1
  5. package/dist/cjs/components/AICommandBar/AICommandBar.js +2 -1
  6. package/dist/cjs/components/AICommandBar/AICommandBar.js.map +1 -1
  7. package/dist/cjs/components/AICommandBar/useAICommandBar.js +4 -2
  8. package/dist/cjs/components/AICommandBar/useAICommandBar.js.map +1 -1
  9. package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js +2 -1
  10. package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
  11. package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js +4 -1
  12. package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
  13. package/dist/cjs/components/ChatDrawer/ChatDrawer.js +10 -3
  14. package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
  15. package/dist/cjs/components/ChatDrawer/ChatInput.js +138 -20
  16. package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -1
  17. package/dist/cjs/components/ChatDrawer/ChatMessages.js +24 -3
  18. package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
  19. package/dist/cjs/components/ChatDrawer/pastedText.js +64 -0
  20. package/dist/cjs/components/ChatDrawer/pastedText.js.map +1 -0
  21. package/dist/cjs/hooks/useDevicChat.js +9 -1
  22. package/dist/cjs/hooks/useDevicChat.js.map +1 -1
  23. package/dist/cjs/provider/DevicProvider.js +3 -1
  24. package/dist/cjs/provider/DevicProvider.js.map +1 -1
  25. package/dist/cjs/styles.css +1 -1
  26. package/dist/esm/api/client.d.ts +5 -0
  27. package/dist/esm/api/client.js +7 -0
  28. package/dist/esm/api/client.js.map +1 -1
  29. package/dist/esm/api/types.d.ts +24 -5
  30. package/dist/esm/api/types.js +9 -1
  31. package/dist/esm/api/types.js.map +1 -1
  32. package/dist/esm/components/AICommandBar/AICommandBar.js +2 -1
  33. package/dist/esm/components/AICommandBar/AICommandBar.js.map +1 -1
  34. package/dist/esm/components/AICommandBar/AICommandBar.types.d.ts +5 -0
  35. package/dist/esm/components/AICommandBar/useAICommandBar.d.ts +2 -0
  36. package/dist/esm/components/AICommandBar/useAICommandBar.js +4 -2
  37. package/dist/esm/components/AICommandBar/useAICommandBar.js.map +1 -1
  38. package/dist/esm/components/AIGenerationButton/AIGenerationButton.js +2 -1
  39. package/dist/esm/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
  40. package/dist/esm/components/AIGenerationButton/AIGenerationButton.types.d.ts +5 -0
  41. package/dist/esm/components/AIGenerationButton/useAIGenerationButton.d.ts +2 -0
  42. package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js +4 -1
  43. package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
  44. package/dist/esm/components/ChatDrawer/ChatDrawer.js +10 -3
  45. package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
  46. package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +23 -0
  47. package/dist/esm/components/ChatDrawer/ChatInput.d.ts +1 -1
  48. package/dist/esm/components/ChatDrawer/ChatInput.js +138 -20
  49. package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -1
  50. package/dist/esm/components/ChatDrawer/ChatMessages.js +24 -3
  51. package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
  52. package/dist/esm/components/ChatDrawer/pastedText.d.ts +30 -0
  53. package/dist/esm/components/ChatDrawer/pastedText.js +59 -0
  54. package/dist/esm/components/ChatDrawer/pastedText.js.map +1 -0
  55. package/dist/esm/hooks/useDevicChat.d.ts +8 -0
  56. package/dist/esm/hooks/useDevicChat.js +9 -1
  57. package/dist/esm/hooks/useDevicChat.js.map +1 -1
  58. package/dist/esm/provider/DevicProvider.d.ts +1 -1
  59. package/dist/esm/provider/DevicProvider.js +3 -1
  60. package/dist/esm/provider/DevicProvider.js.map +1 -1
  61. package/dist/esm/provider/types.d.ts +10 -0
  62. package/dist/esm/styles.css +1 -1
  63. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessages.js","sources":["../../../../../src/components/ChatDrawer/ChatMessages.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from \"react\";\nimport Markdown from \"markdown-to-jsx\";\nimport { MessageActions } from \"../Feedback\";\nimport { HandoffSubagentWidget } from \"./HandoffSubagentWidget\";\nimport { ReferenceChip } from \"./ReferenceChip\";\nimport type { ChatMessagesProps, SuggestedMessage } from \"./ChatDrawer.types\";\nimport type { ChatMessage, ToolGroupConfig, ToolGroupCall } from \"../../api/types\";\nimport type { FeedbackState } from \"../Feedback\";\nimport { segmentToolCalls } from \"../../utils/toolGroups\";\nimport { DevicApiClient } from \"../../api/client\";\nimport \"../Feedback/Feedback.css\";\n\n/**\n * Format timestamp to readable time\n */\nfunction formatTime(timestamp: number): string {\n return new Date(timestamp).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nfunction MicGlyph(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n </svg>\n );\n}\n\nfunction PlayGlyph(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n );\n}\n\nfunction PauseGlyph(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </svg>\n );\n}\n\n/**\n * Compact playback control shown on user messages that were dictated by voice\n * (i.e. carry a `transcriptId`). The source audio URL is resolved lazily on the\n * first play via GET /api/v1/whisper/:transcriptId, so listing a conversation\n * never triggers extra requests until the user actually wants to listen.\n */\nfunction TranscriptPlayback({\n transcriptId,\n apiKey,\n baseUrl,\n}: {\n transcriptId: string;\n apiKey?: string;\n baseUrl?: string;\n}): JSX.Element {\n const [isPlaying, setIsPlaying] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const audioUrlRef = useRef<string | null>(null);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n };\n }, []);\n\n const resolveAudio = async (): Promise<HTMLAudioElement | null> => {\n if (audioRef.current) return audioRef.current;\n let url = audioUrlRef.current;\n if (!url) {\n if (!apiKey) {\n setError(\"Unavailable\");\n return null;\n }\n setIsLoading(true);\n setError(null);\n try {\n const client = new DevicApiClient({\n apiKey,\n baseUrl: baseUrl || \"https://api.devic.ai\",\n });\n const transcript = await client.getTranscript(transcriptId);\n url = transcript.audioUrl || null;\n audioUrlRef.current = url;\n } catch {\n setError(\"Audio unavailable\");\n return null;\n } finally {\n setIsLoading(false);\n }\n }\n if (!url) {\n setError(\"Audio unavailable\");\n return null;\n }\n const audio = new Audio(url);\n audio.onplay = () => setIsPlaying(true);\n audio.onpause = () => setIsPlaying(false);\n audio.onended = () => setIsPlaying(false);\n audio.onerror = () => {\n setError(\"Playback failed\");\n setIsPlaying(false);\n };\n audioRef.current = audio;\n return audio;\n };\n\n const toggle = async () => {\n if (isPlaying && audioRef.current) {\n audioRef.current.pause();\n return;\n }\n const audio = await resolveAudio();\n if (audio) {\n try {\n await audio.play();\n } catch {\n setError(\"Playback failed\");\n }\n }\n };\n\n return (\n <div\n className=\"devic-transcript-playback\"\n data-playing={isPlaying ? \"true\" : \"false\"}\n title=\"Dictated by voice\"\n >\n <button\n type=\"button\"\n className=\"devic-transcript-btn\"\n onClick={toggle}\n disabled={isLoading}\n aria-label={isPlaying ? \"Pause recording\" : \"Play recording\"}\n >\n {isLoading ? (\n <span className=\"devic-transcript-spinner\" aria-hidden=\"true\" />\n ) : isPlaying ? (\n <PauseGlyph />\n ) : (\n <PlayGlyph />\n )}\n </button>\n <span className=\"devic-transcript-icon\" aria-hidden=\"true\">\n <MicGlyph />\n </span>\n <span className=\"devic-transcript-label\">\n {error || \"Voice message\"}\n </span>\n </div>\n );\n}\n\n/**\n * Groups consecutive tool-call assistant messages (no text content)\n * into { toolMessages, isActive } groups, interleaved with regular messages.\n */\nfunction groupMessages(\n messages: ChatMessage[],\n isLoading: boolean,\n): Array<\n | { type: \"message\"; message: ChatMessage }\n | { type: \"toolGroup\"; toolMessages: ChatMessage[]; isActive: boolean }\n> {\n const result: Array<\n | { type: \"message\"; message: ChatMessage }\n | { type: \"toolGroup\"; toolMessages: ChatMessage[]; isActive: boolean }\n > = [];\n\n let currentToolGroup: ChatMessage[] = [];\n\n const flushToolGroup = (isActive: boolean) => {\n if (currentToolGroup.length > 0) {\n result.push({\n type: \"toolGroup\",\n toolMessages: [...currentToolGroup],\n isActive,\n });\n currentToolGroup = [];\n }\n };\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n\n // Skip developer, system and tool response messages\n if (msg.role === \"developer\" || msg.role === \"system\" || msg.role === \"tool\") {\n continue;\n }\n\n const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;\n const hasText = !!msg.content?.message;\n const hasFiles = msg.content?.files && msg.content.files.length > 0;\n\n if (hasToolCalls) {\n // If message has both text and tool_calls, show text first\n if (hasText || hasFiles) {\n // Flush any prior tool group before inserting the text message\n const remainingMeaningful = messages\n .slice(i + 1)\n .some(\n (m) =>\n (m.role === \"assistant\" && m.content?.message) ||\n m.role === \"user\",\n );\n flushToolGroup(isLoading && !remainingMeaningful);\n result.push({ type: \"message\", message: msg });\n }\n // Always accumulate the tool call\n currentToolGroup.push(msg);\n } else {\n // Regular message → flush any accumulated tool group first\n const remainingMeaningful = messages\n .slice(i)\n .some(\n (m) =>\n (m.role === \"assistant\" && m.content?.message) || m.role === \"user\",\n );\n flushToolGroup(isLoading && !remainingMeaningful);\n\n if (hasText || hasFiles) {\n result.push({ type: \"message\", message: msg });\n }\n }\n }\n\n // Flush remaining tool group (is active if still loading)\n flushToolGroup(isLoading);\n\n return result;\n}\n\n/**\n * Collapsible tool actions group\n */\nfunction ToolGroup({\n toolMessages,\n isActive,\n allMessages,\n toolRenderers,\n toolIcons,\n toolGroups,\n handedOffSubThreadId,\n onHandoffCompleted,\n handoffWidgetRenderer,\n apiKey,\n baseUrl,\n}: {\n toolMessages: ChatMessage[];\n isActive: boolean;\n allMessages?: ChatMessage[];\n toolRenderers?: Record<string, (input: any, output: any) => React.ReactNode>;\n toolIcons?: Record<string, React.ReactNode>;\n toolGroups?: ToolGroupConfig[];\n handedOffSubThreadId?: string;\n onHandoffCompleted?: () => void;\n handoffWidgetRenderer?: ChatMessagesProps[\"handoffWidgetRenderer\"];\n apiKey?: string;\n baseUrl?: string;\n}): JSX.Element {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const shouldCollapse = toolMessages.length > 3 && !isActive;\n\n // Auto-collapse when transitioning from active to completed\n const wasActiveRef = useRef(isActive);\n useEffect(() => {\n if (wasActiveRef.current && !isActive && toolMessages.length > 3) {\n setIsCollapsed(true);\n }\n wasActiveRef.current = isActive;\n }, [isActive, toolMessages.length]);\n\n const lastIndex = toolMessages.length - 1;\n\n const renderToolItem = (\n msg: ChatMessage,\n opts: { active?: boolean; showSpinner?: boolean },\n ) => {\n const toolCall = msg.tool_calls?.[0];\n const toolName = toolCall?.function?.name;\n const summaryText =\n msg.summary || toolName || (opts.active ? \"Processing...\" : \"Completed\");\n\n // Render HandoffSubagentWidget for hand_off_subagent tool calls\n if (toolName === \"hand_off_subagent\" && toolCall && allMessages) {\n const subThreadId = extractSubThreadId(\n toolCall.id,\n allMessages,\n handedOffSubThreadId,\n );\n if (subThreadId) {\n return (\n <HandoffSubagentWidget\n subThreadId={subThreadId}\n onCompleted={onHandoffCompleted}\n renderWidget={handoffWidgetRenderer}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n );\n }\n }\n\n // Custom renderer for completed tools\n if (!opts.active && toolName && toolRenderers?.[toolName] && allMessages) {\n const toolResponse = allMessages.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCall!.id,\n );\n let input: any = {};\n try {\n input = JSON.parse(toolCall!.function.arguments);\n } catch {}\n const output =\n toolResponse?.content?.data ||\n toolResponse?.content?.message ||\n toolResponse?.content;\n return toolRenderers[toolName](input, output);\n }\n\n const icon = opts.showSpinner ? (\n <SpinnerIcon />\n ) : (\n (toolName && toolIcons?.[toolName]) || <ToolDoneIcon />\n );\n\n return (\n <>\n <span className=\"devic-tool-activity-icon\">{icon}</span>\n <span\n className={`devic-tool-activity-text ${opts.active ? \"devic-glow-text\" : \"\"}`}\n >\n {summaryText}\n </span>\n </>\n );\n };\n\n /** Resolve a ChatMessage into a ToolGroupCall */\n const resolveToolGroupCall = (msg: ChatMessage): ToolGroupCall | null => {\n const toolCall = msg.tool_calls?.[0];\n if (!toolCall) return null;\n const toolName = toolCall.function?.name;\n let input: any = {};\n try {\n input = JSON.parse(toolCall.function.arguments);\n } catch {}\n const toolResponse = allMessages?.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCall.id,\n );\n const output =\n toolResponse?.content?.data ||\n toolResponse?.content?.message ||\n toolResponse?.content;\n return { name: toolName, input, output, toolCallId: toolCall.id };\n };\n\n /** Render completed tool messages, applying toolGroups segmentation when configured */\n const renderCompletedItems = (msgs: ChatMessage[]) => {\n if (!toolGroups || toolGroups.length === 0) {\n return msgs.map((msg) => (\n <div key={msg.uid} className=\"devic-tool-activity\">\n {renderToolItem(msg, {})}\n </div>\n ));\n }\n\n // Build ToolGroupCall array for completed messages\n const calls: Array<{ msg: ChatMessage; call: ToolGroupCall }> = [];\n for (const msg of msgs) {\n const call = resolveToolGroupCall(msg);\n if (call) {\n calls.push({ msg, call });\n }\n }\n\n const segments = segmentToolCalls(\n calls.map((c) => c.call),\n toolGroups,\n );\n\n const elements: React.ReactNode[] = [];\n let callIdx = 0;\n\n for (const segment of segments) {\n if (segment.type === \"group\") {\n const groupKey = segment.calls\n .map((c) => c.toolCallId)\n .join(\"-\");\n elements.push(\n <div key={`tg-group-${groupKey}`} className=\"devic-tool-activity devic-tool-activity--grouped\">\n {segment.config.renderer(segment.calls)}\n </div>,\n );\n callIdx += segment.calls.length;\n } else {\n const entry = calls[callIdx];\n elements.push(\n <div key={entry.msg.uid} className=\"devic-tool-activity\">\n {renderToolItem(entry.msg, {})}\n </div>,\n );\n callIdx += 1;\n }\n }\n\n return elements;\n };\n\n // If active, show all items; last one gets the glow treatment\n if (isActive) {\n // For active groups: render all completed items with grouping, then render the active (last) item individually\n const completedMessages = toolMessages.slice(0, lastIndex);\n const lastMsg = toolMessages[lastIndex];\n\n return (\n <div className=\"devic-tool-group\">\n {completedMessages.length > 0 && renderCompletedItems(completedMessages)}\n <div\n key={lastMsg.uid}\n className=\"devic-tool-activity devic-tool-activity--active\"\n >\n {renderToolItem(lastMsg, { active: true, showSpinner: true })}\n </div>\n </div>\n );\n }\n\n // Completed: collapse if > 3 actions\n if (shouldCollapse && isCollapsed) {\n return (\n <div className=\"devic-tool-group\">\n <button\n className=\"devic-tool-collapse-btn\"\n onClick={() => setIsCollapsed(false)}\n type=\"button\"\n >\n <ToolDoneIcon />\n <span>{toolMessages.length} actions</span>\n <ChevronDownIcon />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"devic-tool-group\">\n {shouldCollapse && (\n <button\n className=\"devic-tool-collapse-btn\"\n onClick={() => setIsCollapsed(true)}\n type=\"button\"\n >\n <span>{toolMessages.length} actions</span>\n <ChevronUpIcon />\n </button>\n )}\n <div className=\"devic-tool-group-items\" data-expanded=\"true\">\n {renderCompletedItems(toolMessages)}\n </div>\n </div>\n );\n}\n\n/**\n * Messages list component\n */\nconst markdownOverrides = {\n table: {\n component: ({ children, ...props }: any) =>\n React.createElement(\n \"div\",\n { className: \"markdown-table\" },\n React.createElement(\"table\", props, children),\n ),\n },\n};\n\n/**\n * Extract subthread ID from a hand_off_subagent tool call.\n * Checks the tool response in allMessages first, then falls back to handedOffSubThreadId.\n */\nfunction extractSubThreadId(\n toolCallId: string,\n allMessages: ChatMessage[],\n handedOffSubThreadId?: string,\n): string | null {\n // Look for the tool response message\n const toolResponse = allMessages.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCallId,\n );\n if (toolResponse) {\n const content = toolResponse.content?.data || toolResponse.content;\n if (content && typeof content === \"object\" && \"subthreadId\" in content) {\n return (content as any).subthreadId;\n }\n if (content && typeof content === \"object\" && \"subThreadId\" in content) {\n return (content as any).subThreadId;\n }\n }\n // Fall back to active handoff subthread ID\n return handedOffSubThreadId || null;\n}\n\nexport function ChatMessages({\n messages,\n allMessages,\n isLoading,\n welcomeMessage,\n suggestedMessages,\n onSuggestedClick,\n toolRenderers,\n toolIcons,\n loadingIndicator,\n showFeedback = true,\n feedbackMap,\n onFeedback,\n handedOffSubThreadId,\n onHandoffCompleted,\n handoffWidgetRenderer,\n toolGroups,\n userMessageRenderer,\n assistantMessageRenderer,\n apiKey,\n baseUrl,\n pendingInlineWidgets,\n onSubmitWidget,\n onCancelWidget,\n}: ChatMessagesProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const prevLengthRef = useRef(messages.length);\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n if (containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n prevLengthRef.current = messages.length;\n }, [messages.length, isLoading]);\n\n const grouped = groupMessages(messages, isLoading);\n\n // Show loading dots only if there's no active tool group at the end\n const lastGroup = grouped[grouped.length - 1];\n const showLoadingDots =\n isLoading && !(lastGroup?.type === \"toolGroup\" && lastGroup.isActive);\n\n return (\n <div className=\"devic-messages-container\" ref={containerRef}>\n {messages.length === 0 &&\n !isLoading &&\n (welcomeMessage || suggestedMessages?.length) && (\n <div className=\"devic-welcome\">\n {welcomeMessage && (\n <p className=\"devic-welcome-text\">{welcomeMessage}</p>\n )}\n {suggestedMessages && suggestedMessages.length > 0 && (\n <div className=\"devic-suggested-messages\">\n {suggestedMessages.map((msg, idx) => {\n const isObject = typeof msg === \"object\" && msg !== null;\n const content = isObject ? (msg as SuggestedMessage).content : msg;\n const message = isObject ? (msg as SuggestedMessage).message : (msg as string);\n return (\n <button\n key={idx}\n className=\"devic-suggested-btn\"\n onClick={() => onSuggestedClick?.(message)}\n >\n {content}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n {grouped.map((item) => {\n if (item.type === \"toolGroup\") {\n return (\n <ToolGroup\n key={`tg-${item.toolMessages[0].uid}`}\n toolMessages={item.toolMessages}\n isActive={item.isActive}\n allMessages={allMessages}\n toolRenderers={toolRenderers}\n toolIcons={toolIcons}\n toolGroups={toolGroups}\n handedOffSubThreadId={handedOffSubThreadId}\n onHandoffCompleted={onHandoffCompleted}\n handoffWidgetRenderer={handoffWidgetRenderer}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n );\n }\n\n const message = item.message;\n const rawText = message.content?.message;\n const hasFiles =\n message.content?.files && message.content.files.length > 0;\n const isAssistant = message.role === \"assistant\";\n const currentFeedback = feedbackMap?.get(message.uid) || \"none\";\n\n // Extract reference chips from user messages (sent by AIElementWrapper).\n // The ChatDrawer prefixes user messages with:\n // Elemento referenciado: \"label1\", \"label2\"\\n\\n<actual message>\n // We render the labels as chips and only display the actual message\n // text inside the bubble.\n const parsed = !isAssistant && rawText\n ? parseReferencedPrefix(rawText)\n : null;\n const messageText = parsed ? parsed.cleanContent : rawText;\n const refLabels = parsed ? parsed.references : [];\n\n // A custom bubble renderer (per role) fully replaces the default\n // markdown rendering of the message text.\n const bubbleRenderer = isAssistant\n ? assistantMessageRenderer\n : userMessageRenderer;\n\n return (\n <div\n key={message.uid}\n className=\"devic-message\"\n data-role={message.role}\n >\n {refLabels.length > 0 && (\n <div className=\"devic-message-references\">\n {refLabels.map((lbl, i) => (\n <ReferenceChip key={i} label={lbl} variant=\"message\" />\n ))}\n </div>\n )}\n <div className=\"devic-message-bubble\">\n {messageText ? (\n bubbleRenderer ? (\n bubbleRenderer({\n message,\n content: messageText,\n role: isAssistant ? \"assistant\" : \"user\",\n references: refLabels,\n })\n ) : (\n <Markdown options={{ overrides: markdownOverrides }}>\n {messageText}\n </Markdown>\n )\n ) : null}\n {hasFiles && (\n <div className=\"devic-message-files\">\n {message.content!.files!.map((file, fileIdx) => (\n <div key={fileIdx} className=\"devic-message-file\">\n <FileIcon />\n <span>{file.name}</span>\n </div>\n ))}\n </div>\n )}\n {!isAssistant && message.transcriptId && (\n <TranscriptPlayback\n transcriptId={message.transcriptId}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n )}\n </div>\n <div className=\"devic-message-footer\">\n <span className=\"devic-message-time\">\n {formatTime(message.timestamp)}\n </span>\n {isAssistant && showFeedback && onFeedback && (\n <MessageActions\n messageId={message.uid}\n messageContent={messageText}\n currentFeedback={currentFeedback as FeedbackState}\n onFeedback={onFeedback}\n showCopy={true}\n showFeedback={true}\n />\n )}\n </div>\n </div>\n );\n })}\n\n {pendingInlineWidgets && pendingInlineWidgets.length > 0 && (\n <div className=\"devic-inline-widgets\">\n {pendingInlineWidgets.map((wc) => {\n const WidgetComponent = wc.widget.component;\n return (\n <div\n key={wc.toolCall.id}\n className=\"devic-inline-widget\"\n data-tool-name={wc.toolName}\n >\n <WidgetComponent\n toolCall={wc.toolCall}\n params={wc.params}\n submit={(response) => onSubmitWidget?.(wc.toolCall.id, response)}\n cancel={(reason) => onCancelWidget?.(wc.toolCall.id, reason)}\n />\n </div>\n );\n })}\n </div>\n )}\n\n {showLoadingDots &&\n (loadingIndicator ? (\n <div className=\"devic-loading\">{loadingIndicator}</div>\n ) : (\n <div className=\"devic-loading\">\n <span className=\"devic-loading-dot\"></span>\n <span className=\"devic-loading-dot\"></span>\n <span className=\"devic-loading-dot\"></span>\n </div>\n ))}\n </div>\n );\n}\n\n/* ── Icons ── */\n\nfunction SpinnerIcon(): JSX.Element {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n className=\"devic-spinner\"\n >\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n );\n}\n\nfunction ToolDoneIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n );\n}\n\nfunction ChevronDownIcon(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6,9 12,15 18,9\" />\n </svg>\n );\n}\n\nfunction ChevronUpIcon(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6,15 12,9 18,15\" />\n </svg>\n );\n}\n\nfunction FileIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14,2 14,8 20,8\" />\n </svg>\n );\n}\n\n/**\n * Extracts the \"Elemento referenciado: ...\" prefix that ChatDrawer prepends\n * to user messages when AIElementWrapper references are active. Returns the\n * parsed labels and the message text without the prefix. Returns null when\n * the content does not start with the prefix.\n */\nconst REFERENCE_PREFIX_RE =\n /^Elemento referenciado: ((?:\"[^\"]+\")(?:, \"[^\"]+\")*)\\n\\n([\\s\\S]*)$/;\n\nfunction parseReferencedPrefix(\n content: string\n): { references: string[]; cleanContent: string } | null {\n const m = content.match(REFERENCE_PREFIX_RE);\n if (!m) return null;\n const labels = (m[1].match(/\"([^\"]+)\"/g) || []).map((s) =>\n s.slice(1, -1)\n );\n return { references: labels, cleanContent: m[2] };\n}\n"],"names":["_jsxs","_jsx","useState","useRef","useEffect","client","DevicApiClient","toolGroups","HandoffSubagentWidget","_Fragment","segmentToolCalls","ReferenceChip","MessageActions"],"mappings":"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"}
1
+ {"version":3,"file":"ChatMessages.js","sources":["../../../../../src/components/ChatDrawer/ChatMessages.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from \"react\";\nimport Markdown from \"markdown-to-jsx\";\nimport { MessageActions } from \"../Feedback\";\nimport { HandoffSubagentWidget } from \"./HandoffSubagentWidget\";\nimport { ReferenceChip } from \"./ReferenceChip\";\nimport type { ChatMessagesProps, SuggestedMessage } from \"./ChatDrawer.types\";\nimport type { ChatMessage, ToolGroupConfig, ToolGroupCall } from \"../../api/types\";\nimport { normalizeMessageFile } from \"../../api/types\";\nimport type { FeedbackState } from \"../Feedback\";\nimport { segmentToolCalls } from \"../../utils/toolGroups\";\nimport { DevicApiClient } from \"../../api/client\";\nimport {\n parsePastedBlocks,\n pastedPreview,\n pastedLineCount,\n type PastedText,\n} from \"./pastedText\";\nimport \"../Feedback/Feedback.css\";\n\n/**\n * Format timestamp to readable time\n */\nfunction formatTime(timestamp: number): string {\n return new Date(timestamp).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nfunction MicGlyph(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n </svg>\n );\n}\n\nfunction PlayGlyph(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n );\n}\n\nfunction PauseGlyph(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </svg>\n );\n}\n\n/**\n * Compact playback control shown on user messages that were dictated by voice\n * (i.e. carry a `transcriptId`). The source audio URL is resolved lazily on the\n * first play via GET /api/v1/whisper/:transcriptId, so listing a conversation\n * never triggers extra requests until the user actually wants to listen.\n */\nfunction TranscriptPlayback({\n transcriptId,\n apiKey,\n baseUrl,\n}: {\n transcriptId: string;\n apiKey?: string;\n baseUrl?: string;\n}): JSX.Element {\n const [isPlaying, setIsPlaying] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const audioUrlRef = useRef<string | null>(null);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n };\n }, []);\n\n const resolveAudio = async (): Promise<HTMLAudioElement | null> => {\n if (audioRef.current) return audioRef.current;\n let url = audioUrlRef.current;\n if (!url) {\n if (!apiKey) {\n setError(\"Unavailable\");\n return null;\n }\n setIsLoading(true);\n setError(null);\n try {\n const client = new DevicApiClient({\n apiKey,\n baseUrl: baseUrl || \"https://api.devic.ai\",\n });\n const transcript = await client.getTranscript(transcriptId);\n url = transcript.audioUrl || null;\n audioUrlRef.current = url;\n } catch {\n setError(\"Audio unavailable\");\n return null;\n } finally {\n setIsLoading(false);\n }\n }\n if (!url) {\n setError(\"Audio unavailable\");\n return null;\n }\n const audio = new Audio(url);\n audio.onplay = () => setIsPlaying(true);\n audio.onpause = () => setIsPlaying(false);\n audio.onended = () => setIsPlaying(false);\n audio.onerror = () => {\n setError(\"Playback failed\");\n setIsPlaying(false);\n };\n audioRef.current = audio;\n return audio;\n };\n\n const toggle = async () => {\n if (isPlaying && audioRef.current) {\n audioRef.current.pause();\n return;\n }\n const audio = await resolveAudio();\n if (audio) {\n try {\n await audio.play();\n } catch {\n setError(\"Playback failed\");\n }\n }\n };\n\n return (\n <div\n className=\"devic-transcript-playback\"\n data-playing={isPlaying ? \"true\" : \"false\"}\n title=\"Dictated by voice\"\n >\n <button\n type=\"button\"\n className=\"devic-transcript-btn\"\n onClick={toggle}\n disabled={isLoading}\n aria-label={isPlaying ? \"Pause recording\" : \"Play recording\"}\n >\n {isLoading ? (\n <span className=\"devic-transcript-spinner\" aria-hidden=\"true\" />\n ) : isPlaying ? (\n <PauseGlyph />\n ) : (\n <PlayGlyph />\n )}\n </button>\n <span className=\"devic-transcript-icon\" aria-hidden=\"true\">\n <MicGlyph />\n </span>\n <span className=\"devic-transcript-label\">\n {error || \"Voice message\"}\n </span>\n </div>\n );\n}\n\n/**\n * Groups consecutive tool-call assistant messages (no text content)\n * into { toolMessages, isActive } groups, interleaved with regular messages.\n */\nfunction groupMessages(\n messages: ChatMessage[],\n isLoading: boolean,\n): Array<\n | { type: \"message\"; message: ChatMessage }\n | { type: \"toolGroup\"; toolMessages: ChatMessage[]; isActive: boolean }\n> {\n const result: Array<\n | { type: \"message\"; message: ChatMessage }\n | { type: \"toolGroup\"; toolMessages: ChatMessage[]; isActive: boolean }\n > = [];\n\n let currentToolGroup: ChatMessage[] = [];\n\n const flushToolGroup = (isActive: boolean) => {\n if (currentToolGroup.length > 0) {\n result.push({\n type: \"toolGroup\",\n toolMessages: [...currentToolGroup],\n isActive,\n });\n currentToolGroup = [];\n }\n };\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n\n // Skip developer, system and tool response messages\n if (msg.role === \"developer\" || msg.role === \"system\" || msg.role === \"tool\") {\n continue;\n }\n\n const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;\n const hasText = !!msg.content?.message;\n const hasFiles = msg.content?.files && msg.content.files.length > 0;\n\n if (hasToolCalls) {\n // If message has both text and tool_calls, show text first\n if (hasText || hasFiles) {\n // Flush any prior tool group before inserting the text message\n const remainingMeaningful = messages\n .slice(i + 1)\n .some(\n (m) =>\n (m.role === \"assistant\" && m.content?.message) ||\n m.role === \"user\",\n );\n flushToolGroup(isLoading && !remainingMeaningful);\n result.push({ type: \"message\", message: msg });\n }\n // Always accumulate the tool call\n currentToolGroup.push(msg);\n } else {\n // Regular message → flush any accumulated tool group first\n const remainingMeaningful = messages\n .slice(i)\n .some(\n (m) =>\n (m.role === \"assistant\" && m.content?.message) || m.role === \"user\",\n );\n flushToolGroup(isLoading && !remainingMeaningful);\n\n if (hasText || hasFiles) {\n result.push({ type: \"message\", message: msg });\n }\n }\n }\n\n // Flush remaining tool group (is active if still loading)\n flushToolGroup(isLoading);\n\n return result;\n}\n\n/**\n * Collapsible tool actions group\n */\nfunction ToolGroup({\n toolMessages,\n isActive,\n allMessages,\n toolRenderers,\n toolIcons,\n toolGroups,\n handedOffSubThreadId,\n onHandoffCompleted,\n handoffWidgetRenderer,\n apiKey,\n baseUrl,\n}: {\n toolMessages: ChatMessage[];\n isActive: boolean;\n allMessages?: ChatMessage[];\n toolRenderers?: Record<string, (input: any, output: any) => React.ReactNode>;\n toolIcons?: Record<string, React.ReactNode>;\n toolGroups?: ToolGroupConfig[];\n handedOffSubThreadId?: string;\n onHandoffCompleted?: () => void;\n handoffWidgetRenderer?: ChatMessagesProps[\"handoffWidgetRenderer\"];\n apiKey?: string;\n baseUrl?: string;\n}): JSX.Element {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const shouldCollapse = toolMessages.length > 3 && !isActive;\n\n // Auto-collapse when transitioning from active to completed\n const wasActiveRef = useRef(isActive);\n useEffect(() => {\n if (wasActiveRef.current && !isActive && toolMessages.length > 3) {\n setIsCollapsed(true);\n }\n wasActiveRef.current = isActive;\n }, [isActive, toolMessages.length]);\n\n const lastIndex = toolMessages.length - 1;\n\n const renderToolItem = (\n msg: ChatMessage,\n opts: { active?: boolean; showSpinner?: boolean },\n ) => {\n const toolCall = msg.tool_calls?.[0];\n const toolName = toolCall?.function?.name;\n const summaryText =\n msg.summary || toolName || (opts.active ? \"Processing...\" : \"Completed\");\n\n // Render HandoffSubagentWidget for hand_off_subagent tool calls\n if (toolName === \"hand_off_subagent\" && toolCall && allMessages) {\n const subThreadId = extractSubThreadId(\n toolCall.id,\n allMessages,\n handedOffSubThreadId,\n );\n if (subThreadId) {\n return (\n <HandoffSubagentWidget\n subThreadId={subThreadId}\n onCompleted={onHandoffCompleted}\n renderWidget={handoffWidgetRenderer}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n );\n }\n }\n\n // Custom renderer for completed tools\n if (!opts.active && toolName && toolRenderers?.[toolName] && allMessages) {\n const toolResponse = allMessages.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCall!.id,\n );\n let input: any = {};\n try {\n input = JSON.parse(toolCall!.function.arguments);\n } catch {}\n const output =\n toolResponse?.content?.data ||\n toolResponse?.content?.message ||\n toolResponse?.content;\n return toolRenderers[toolName](input, output);\n }\n\n const icon = opts.showSpinner ? (\n <SpinnerIcon />\n ) : (\n (toolName && toolIcons?.[toolName]) || <ToolDoneIcon />\n );\n\n return (\n <>\n <span className=\"devic-tool-activity-icon\">{icon}</span>\n <span\n className={`devic-tool-activity-text ${opts.active ? \"devic-glow-text\" : \"\"}`}\n >\n {summaryText}\n </span>\n </>\n );\n };\n\n /** Resolve a ChatMessage into a ToolGroupCall */\n const resolveToolGroupCall = (msg: ChatMessage): ToolGroupCall | null => {\n const toolCall = msg.tool_calls?.[0];\n if (!toolCall) return null;\n const toolName = toolCall.function?.name;\n let input: any = {};\n try {\n input = JSON.parse(toolCall.function.arguments);\n } catch {}\n const toolResponse = allMessages?.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCall.id,\n );\n const output =\n toolResponse?.content?.data ||\n toolResponse?.content?.message ||\n toolResponse?.content;\n return { name: toolName, input, output, toolCallId: toolCall.id };\n };\n\n /** Render completed tool messages, applying toolGroups segmentation when configured */\n const renderCompletedItems = (msgs: ChatMessage[]) => {\n if (!toolGroups || toolGroups.length === 0) {\n return msgs.map((msg) => (\n <div key={msg.uid} className=\"devic-tool-activity\">\n {renderToolItem(msg, {})}\n </div>\n ));\n }\n\n // Build ToolGroupCall array for completed messages\n const calls: Array<{ msg: ChatMessage; call: ToolGroupCall }> = [];\n for (const msg of msgs) {\n const call = resolveToolGroupCall(msg);\n if (call) {\n calls.push({ msg, call });\n }\n }\n\n const segments = segmentToolCalls(\n calls.map((c) => c.call),\n toolGroups,\n );\n\n const elements: React.ReactNode[] = [];\n let callIdx = 0;\n\n for (const segment of segments) {\n if (segment.type === \"group\") {\n const groupKey = segment.calls\n .map((c) => c.toolCallId)\n .join(\"-\");\n elements.push(\n <div key={`tg-group-${groupKey}`} className=\"devic-tool-activity devic-tool-activity--grouped\">\n {segment.config.renderer(segment.calls)}\n </div>,\n );\n callIdx += segment.calls.length;\n } else {\n const entry = calls[callIdx];\n elements.push(\n <div key={entry.msg.uid} className=\"devic-tool-activity\">\n {renderToolItem(entry.msg, {})}\n </div>,\n );\n callIdx += 1;\n }\n }\n\n return elements;\n };\n\n // If active, show all items; last one gets the glow treatment\n if (isActive) {\n // For active groups: render all completed items with grouping, then render the active (last) item individually\n const completedMessages = toolMessages.slice(0, lastIndex);\n const lastMsg = toolMessages[lastIndex];\n\n return (\n <div className=\"devic-tool-group\">\n {completedMessages.length > 0 && renderCompletedItems(completedMessages)}\n <div\n key={lastMsg.uid}\n className=\"devic-tool-activity devic-tool-activity--active\"\n >\n {renderToolItem(lastMsg, { active: true, showSpinner: true })}\n </div>\n </div>\n );\n }\n\n // Completed: collapse if > 3 actions\n if (shouldCollapse && isCollapsed) {\n return (\n <div className=\"devic-tool-group\">\n <button\n className=\"devic-tool-collapse-btn\"\n onClick={() => setIsCollapsed(false)}\n type=\"button\"\n >\n <ToolDoneIcon />\n <span>{toolMessages.length} actions</span>\n <ChevronDownIcon />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"devic-tool-group\">\n {shouldCollapse && (\n <button\n className=\"devic-tool-collapse-btn\"\n onClick={() => setIsCollapsed(true)}\n type=\"button\"\n >\n <span>{toolMessages.length} actions</span>\n <ChevronUpIcon />\n </button>\n )}\n <div className=\"devic-tool-group-items\" data-expanded=\"true\">\n {renderCompletedItems(toolMessages)}\n </div>\n </div>\n );\n}\n\n/**\n * Messages list component\n */\nconst markdownOverrides = {\n table: {\n component: ({ children, ...props }: any) =>\n React.createElement(\n \"div\",\n { className: \"markdown-table\" },\n React.createElement(\"table\", props, children),\n ),\n },\n};\n\n/**\n * Extract subthread ID from a hand_off_subagent tool call.\n * Checks the tool response in allMessages first, then falls back to handedOffSubThreadId.\n */\nfunction extractSubThreadId(\n toolCallId: string,\n allMessages: ChatMessage[],\n handedOffSubThreadId?: string,\n): string | null {\n // Look for the tool response message\n const toolResponse = allMessages.find(\n (m) => m.role === \"tool\" && m.tool_call_id === toolCallId,\n );\n if (toolResponse) {\n const content = toolResponse.content?.data || toolResponse.content;\n if (content && typeof content === \"object\" && \"subthreadId\" in content) {\n return (content as any).subthreadId;\n }\n if (content && typeof content === \"object\" && \"subThreadId\" in content) {\n return (content as any).subThreadId;\n }\n }\n // Fall back to active handoff subthread ID\n return handedOffSubThreadId || null;\n}\n\nexport function ChatMessages({\n messages,\n allMessages,\n isLoading,\n welcomeMessage,\n suggestedMessages,\n onSuggestedClick,\n toolRenderers,\n toolIcons,\n loadingIndicator,\n showFeedback = true,\n feedbackMap,\n onFeedback,\n handedOffSubThreadId,\n onHandoffCompleted,\n handoffWidgetRenderer,\n toolGroups,\n userMessageRenderer,\n assistantMessageRenderer,\n apiKey,\n baseUrl,\n pendingInlineWidgets,\n onSubmitWidget,\n onCancelWidget,\n}: ChatMessagesProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const prevLengthRef = useRef(messages.length);\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n if (containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n prevLengthRef.current = messages.length;\n }, [messages.length, isLoading]);\n\n const grouped = groupMessages(messages, isLoading);\n\n // Show loading dots only if there's no active tool group at the end\n const lastGroup = grouped[grouped.length - 1];\n const showLoadingDots =\n isLoading && !(lastGroup?.type === \"toolGroup\" && lastGroup.isActive);\n\n return (\n <div className=\"devic-messages-container\" ref={containerRef}>\n {messages.length === 0 &&\n !isLoading &&\n (welcomeMessage || suggestedMessages?.length) && (\n <div className=\"devic-welcome\">\n {welcomeMessage && (\n <p className=\"devic-welcome-text\">{welcomeMessage}</p>\n )}\n {suggestedMessages && suggestedMessages.length > 0 && (\n <div className=\"devic-suggested-messages\">\n {suggestedMessages.map((msg, idx) => {\n const isObject = typeof msg === \"object\" && msg !== null;\n const content = isObject ? (msg as SuggestedMessage).content : msg;\n const message = isObject ? (msg as SuggestedMessage).message : (msg as string);\n return (\n <button\n key={idx}\n className=\"devic-suggested-btn\"\n onClick={() => onSuggestedClick?.(message)}\n >\n {content}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n {grouped.map((item) => {\n if (item.type === \"toolGroup\") {\n return (\n <ToolGroup\n key={`tg-${item.toolMessages[0].uid}`}\n toolMessages={item.toolMessages}\n isActive={item.isActive}\n allMessages={allMessages}\n toolRenderers={toolRenderers}\n toolIcons={toolIcons}\n toolGroups={toolGroups}\n handedOffSubThreadId={handedOffSubThreadId}\n onHandoffCompleted={onHandoffCompleted}\n handoffWidgetRenderer={handoffWidgetRenderer}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n );\n }\n\n const message = item.message;\n const rawText = message.content?.message;\n const hasFiles =\n message.content?.files && message.content.files.length > 0;\n const isAssistant = message.role === \"assistant\";\n const currentFeedback = feedbackMap?.get(message.uid) || \"none\";\n\n // Extract reference chips from user messages (sent by AIElementWrapper).\n // The ChatDrawer prefixes user messages with:\n // Elemento referenciado: \"label1\", \"label2\"\\n\\n<actual message>\n // We render the labels as chips and only display the actual message\n // text inside the bubble.\n const parsed = !isAssistant && rawText\n ? parseReferencedPrefix(rawText)\n : null;\n const messageText = parsed ? parsed.cleanContent : rawText;\n const refLabels = parsed ? parsed.references : [];\n\n // Long pasted text travels inside the message but is shown as a card,\n // so the bubble renders what the user actually typed. Runs after the\n // reference prefix, which ChatDrawer prepends to the composed message.\n const pasted = !isAssistant && messageText\n ? parsePastedBlocks(messageText)\n : null;\n const bodyText = pasted ? pasted.cleanContent : messageText;\n const pastedBlocks = pasted ? pasted.blocks : [];\n\n // A custom bubble renderer (per role) fully replaces the default\n // markdown rendering of the message text.\n const bubbleRenderer = isAssistant\n ? assistantMessageRenderer\n : userMessageRenderer;\n\n return (\n <div\n key={message.uid}\n className=\"devic-message\"\n data-role={message.role}\n >\n {refLabels.length > 0 && (\n <div className=\"devic-message-references\">\n {refLabels.map((lbl, i) => (\n <ReferenceChip key={i} label={lbl} variant=\"message\" />\n ))}\n </div>\n )}\n <div className=\"devic-message-bubble\">\n {pastedBlocks.length > 0 && (\n <div className=\"devic-message-pasted\">\n {pastedBlocks.map((block) => (\n <PastedBlockCard key={block.id} block={block} />\n ))}\n </div>\n )}\n {bodyText ? (\n bubbleRenderer ? (\n bubbleRenderer({\n message,\n content: bodyText,\n role: isAssistant ? \"assistant\" : \"user\",\n references: refLabels,\n })\n ) : (\n <Markdown options={{ overrides: markdownOverrides }}>\n {bodyText}\n </Markdown>\n )\n ) : null}\n {hasFiles && (\n <div className=\"devic-message-files\">\n {message.content!.files!.map((raw, fileIdx) => {\n const file = normalizeMessageFile(raw);\n return file.type === \"image\" && file.url ? (\n <a\n key={fileIdx}\n className=\"devic-message-file-image\"\n href={file.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <img src={file.url} alt={file.name} />\n </a>\n ) : (\n <div key={fileIdx} className=\"devic-message-file\">\n <FileIcon />\n <span>{file.name}</span>\n </div>\n );\n })}\n </div>\n )}\n {!isAssistant && message.transcriptId && (\n <TranscriptPlayback\n transcriptId={message.transcriptId}\n apiKey={apiKey}\n baseUrl={baseUrl}\n />\n )}\n </div>\n <div className=\"devic-message-footer\">\n <span className=\"devic-message-time\">\n {formatTime(message.timestamp)}\n </span>\n {isAssistant && showFeedback && onFeedback && (\n <MessageActions\n messageId={message.uid}\n messageContent={messageText}\n currentFeedback={currentFeedback as FeedbackState}\n onFeedback={onFeedback}\n showCopy={true}\n showFeedback={true}\n />\n )}\n </div>\n </div>\n );\n })}\n\n {pendingInlineWidgets && pendingInlineWidgets.length > 0 && (\n <div className=\"devic-inline-widgets\">\n {pendingInlineWidgets.map((wc) => {\n const WidgetComponent = wc.widget.component;\n return (\n <div\n key={wc.toolCall.id}\n className=\"devic-inline-widget\"\n data-tool-name={wc.toolName}\n >\n <WidgetComponent\n toolCall={wc.toolCall}\n params={wc.params}\n submit={(response) => onSubmitWidget?.(wc.toolCall.id, response)}\n cancel={(reason) => onCancelWidget?.(wc.toolCall.id, reason)}\n />\n </div>\n );\n })}\n </div>\n )}\n\n {showLoadingDots &&\n (loadingIndicator ? (\n <div className=\"devic-loading\">{loadingIndicator}</div>\n ) : (\n <div className=\"devic-loading\">\n <span className=\"devic-loading-dot\"></span>\n <span className=\"devic-loading-dot\"></span>\n <span className=\"devic-loading-dot\"></span>\n </div>\n ))}\n </div>\n );\n}\n\n/* ── Icons ── */\n\nfunction SpinnerIcon(): JSX.Element {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n className=\"devic-spinner\"\n >\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n );\n}\n\nfunction ToolDoneIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n );\n}\n\nfunction ChevronDownIcon(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6,9 12,15 18,9\" />\n </svg>\n );\n}\n\nfunction ChevronUpIcon(): JSX.Element {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6,15 12,9 18,15\" />\n </svg>\n );\n}\n\nfunction FileIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14,2 14,8 20,8\" />\n </svg>\n );\n}\n\n/**\n * Extracts the \"Elemento referenciado: ...\" prefix that ChatDrawer prepends\n * to user messages when AIElementWrapper references are active. Returns the\n * parsed labels and the message text without the prefix. Returns null when\n * the content does not start with the prefix.\n */\nconst REFERENCE_PREFIX_RE =\n /^Elemento referenciado: ((?:\"[^\"]+\")(?:, \"[^\"]+\")*)\\n\\n([\\s\\S]*)$/;\n\nfunction parseReferencedPrefix(\n content: string\n): { references: string[]; cleanContent: string } | null {\n const m = content.match(REFERENCE_PREFIX_RE);\n if (!m) return null;\n const labels = (m[1].match(/\"([^\"]+)\"/g) || []).map((s) =>\n s.slice(1, -1)\n );\n return { references: labels, cleanContent: m[2] };\n}\n\n/**\n * A block of pasted text inside a sent message: collapsed to a card by default,\n * expandable to read the whole thing without leaving the thread.\n */\nfunction PastedBlockCard({ block }: { block: PastedText }): JSX.Element {\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div className=\"devic-pasted-card\" data-expanded={expanded ? \"true\" : \"false\"}>\n <button\n type=\"button\"\n className=\"devic-pasted-card-toggle\"\n onClick={() => setExpanded((prev) => !prev)}\n aria-expanded={expanded}\n >\n {expanded ? (\n <pre className=\"devic-pasted-card-full\">{block.text}</pre>\n ) : (\n <p className=\"devic-pasted-card-preview\">{pastedPreview(block.text)}</p>\n )}\n <span className=\"devic-pasted-card-footer\">\n <span className=\"devic-pasted-card-badge\">PASTED</span>\n <span className=\"devic-pasted-card-meta\">\n {pastedLineCount(block.text)} lines · {expanded ? \"collapse\" : \"expand\"}\n </span>\n </span>\n </button>\n </div>\n );\n}\n"],"names":["_jsxs","_jsx","useState","useRef","useEffect","client","DevicApiClient","toolGroups","HandoffSubagentWidget","_Fragment","segmentToolCalls","parsePastedBlocks","ReferenceChip","normalizeMessageFile","MessageActions","pastedPreview","pastedLineCount"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Shared contract for long blocks of pasted text.
5
+ *
6
+ * A long paste is shown in the prompt box as an attachment card instead of
7
+ * flooding the textarea, but its content still reaches the model in full: on
8
+ * send it is prepended to the message inside a <pasted-text> block. The thread
9
+ * parses those blocks back out so the bubble shows a card too, rather than
10
+ * thousands of lines of raw text.
11
+ *
12
+ * Both sides of that round-trip live here so they can never drift apart.
13
+ */
14
+ /**
15
+ * A pasted block could itself contain the literal closing tag (pasting this
16
+ * very file, say), which would truncate the block when parsed back. Escaping it
17
+ * on the way out keeps the round-trip exact and still reads as the intended
18
+ * text to the model.
19
+ */
20
+ const CLOSING_TAG = '</pasted-text>';
21
+ const ESCAPED_CLOSING_TAG = '<\\/pasted-text>';
22
+ const PASTED_BLOCK_RE = /<pasted-text id="([^"]*)">\n([\s\S]*?)\n<\/pasted-text>/g;
23
+ /** Serialize a pasted block for the message sent to the assistant. */
24
+ function toPastedBlock({ id, text }) {
25
+ const escaped = text.split(CLOSING_TAG).join(ESCAPED_CLOSING_TAG);
26
+ return `<pasted-text id="${id}">\n${escaped}\n${CLOSING_TAG}`;
27
+ }
28
+ /**
29
+ * Pull the pasted blocks out of a user message, returning them alongside the
30
+ * message with those blocks removed. Returns null when there are none, so
31
+ * callers can keep rendering untouched messages exactly as before.
32
+ */
33
+ function parsePastedBlocks(content) {
34
+ const blocks = [];
35
+ const cleanContent = content
36
+ .replace(PASTED_BLOCK_RE, (_match, id, text) => {
37
+ blocks.push({
38
+ id,
39
+ text: text.split(ESCAPED_CLOSING_TAG).join(CLOSING_TAG),
40
+ });
41
+ return '';
42
+ })
43
+ .trim();
44
+ if (blocks.length === 0)
45
+ return null;
46
+ return { blocks, cleanContent };
47
+ }
48
+ /** Short, single-line-ish excerpt shown on the collapsed card. */
49
+ function pastedPreview(text, maxChars = 160) {
50
+ const collapsed = text.replace(/\s+/g, ' ').trim();
51
+ return collapsed.length > maxChars
52
+ ? `${collapsed.slice(0, maxChars)}…`
53
+ : collapsed;
54
+ }
55
+ /** Line count shown on the card, mirroring how editors report a selection. */
56
+ function pastedLineCount(text) {
57
+ return text.split('\n').length;
58
+ }
59
+
60
+ exports.parsePastedBlocks = parsePastedBlocks;
61
+ exports.pastedLineCount = pastedLineCount;
62
+ exports.pastedPreview = pastedPreview;
63
+ exports.toPastedBlock = toPastedBlock;
64
+ //# sourceMappingURL=pastedText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pastedText.js","sources":["../../../../../src/components/ChatDrawer/pastedText.ts"],"sourcesContent":["/**\n * Shared contract for long blocks of pasted text.\n *\n * A long paste is shown in the prompt box as an attachment card instead of\n * flooding the textarea, but its content still reaches the model in full: on\n * send it is prepended to the message inside a <pasted-text> block. The thread\n * parses those blocks back out so the bubble shows a card too, rather than\n * thousands of lines of raw text.\n *\n * Both sides of that round-trip live here so they can never drift apart.\n */\n\nexport interface PastedText {\n id: string;\n text: string;\n}\n\n/**\n * A pasted block could itself contain the literal closing tag (pasting this\n * very file, say), which would truncate the block when parsed back. Escaping it\n * on the way out keeps the round-trip exact and still reads as the intended\n * text to the model.\n */\nconst CLOSING_TAG = '</pasted-text>';\nconst ESCAPED_CLOSING_TAG = '<\\\\/pasted-text>';\n\nconst PASTED_BLOCK_RE = /<pasted-text id=\"([^\"]*)\">\\n([\\s\\S]*?)\\n<\\/pasted-text>/g;\n\n/** Serialize a pasted block for the message sent to the assistant. */\nexport function toPastedBlock({ id, text }: PastedText): string {\n const escaped = text.split(CLOSING_TAG).join(ESCAPED_CLOSING_TAG);\n return `<pasted-text id=\"${id}\">\\n${escaped}\\n${CLOSING_TAG}`;\n}\n\n/**\n * Pull the pasted blocks out of a user message, returning them alongside the\n * message with those blocks removed. Returns null when there are none, so\n * callers can keep rendering untouched messages exactly as before.\n */\nexport function parsePastedBlocks(\n content: string\n): { blocks: PastedText[]; cleanContent: string } | null {\n const blocks: PastedText[] = [];\n const cleanContent = content\n .replace(PASTED_BLOCK_RE, (_match, id: string, text: string) => {\n blocks.push({\n id,\n text: text.split(ESCAPED_CLOSING_TAG).join(CLOSING_TAG),\n });\n return '';\n })\n .trim();\n\n if (blocks.length === 0) return null;\n return { blocks, cleanContent };\n}\n\n/** Short, single-line-ish excerpt shown on the collapsed card. */\nexport function pastedPreview(text: string, maxChars = 160): string {\n const collapsed = text.replace(/\\s+/g, ' ').trim();\n return collapsed.length > maxChars\n ? `${collapsed.slice(0, maxChars)}…`\n : collapsed;\n}\n\n/** Line count shown on the card, mirroring how editors report a selection. */\nexport function pastedLineCount(text: string): number {\n return text.split('\\n').length;\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;AAUG;AAOH;;;;;AAKG;AACH,MAAM,WAAW,GAAG,gBAAgB;AACpC,MAAM,mBAAmB,GAAG,kBAAkB;AAE9C,MAAM,eAAe,GAAG,0DAA0D;AAElF;SACgB,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,EAAc,EAAA;AACpD,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;AACjE,IAAA,OAAO,oBAAoB,EAAE,CAAA,IAAA,EAAO,OAAO,CAAA,EAAA,EAAK,WAAW,EAAE;AAC/D;AAEA;;;;AAIG;AACG,SAAU,iBAAiB,CAC/B,OAAe,EAAA;IAEf,MAAM,MAAM,GAAiB,EAAE;IAC/B,MAAM,YAAY,GAAG;SAClB,OAAO,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,EAAU,EAAE,IAAY,KAAI;QAC7D,MAAM,CAAC,IAAI,CAAC;YACV,EAAE;YACF,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;AACxD,SAAA,CAAC;AACF,QAAA,OAAO,EAAE;AACX,IAAA,CAAC;AACA,SAAA,IAAI,EAAE;AAET,IAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,IAAI;AACpC,IAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE;AACjC;AAEA;SACgB,aAAa,CAAC,IAAY,EAAE,QAAQ,GAAG,GAAG,EAAA;AACxD,IAAA,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;AAClD,IAAA,OAAO,SAAS,CAAC,MAAM,GAAG;UACtB,CAAA,EAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA,CAAA;UAC/B,SAAS;AACf;AAEA;AACM,SAAU,eAAe,CAAC,IAAY,EAAA;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;AAChC;;;;;;;"}
@@ -31,7 +31,7 @@ var useModelInterface = require('./useModelInterface.js');
31
31
  * ```
32
32
  */
33
33
  function useDevicChat(options) {
34
- const { assistantId, chatUid: initialChatUid, apiKey: propsApiKey, baseUrl: propsBaseUrl, tenantId, tenantMetadata, subtenantId, subtenantMetadata, enabledTools, modelInterfaceTools = [], pollingInterval = 1000, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onFileUpload, debug: propsDebug, } = options;
34
+ const { assistantId, chatUid: initialChatUid, apiKey: propsApiKey, baseUrl: propsBaseUrl, tenantId, tenantMetadata, subtenantId, subtenantMetadata, tags, enabledTools, modelInterfaceTools = [], pollingInterval = 1000, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onFileUpload, debug: propsDebug, } = options;
35
35
  // Get context (may be null if not wrapped in provider)
36
36
  const context = DevicContext.useOptionalDevicContext();
37
37
  // Resolve configuration
@@ -44,6 +44,8 @@ function useDevicChat(options) {
44
44
  ...context?.subtenantMetadata,
45
45
  ...subtenantMetadata,
46
46
  };
47
+ // Provider tags + hook tags, deduped. Per-message tags are merged at send time.
48
+ const resolvedTags = React.useMemo(() => Array.from(new Set([...(context?.tags ?? []), ...(tags ?? [])])), [context?.tags, tags]);
47
49
  const debug = propsDebug ?? context?.debug ?? false;
48
50
  const log = React.useMemo(() => logger.createLogger(debug), [debug]);
49
51
  const logRef = React.useRef(log);
@@ -388,6 +390,11 @@ function useDevicChat(options) {
388
390
  },
389
391
  tenantId: resolvedTenantId,
390
392
  ...(resolvedSubtenantId && { subtenantId: resolvedSubtenantId }),
393
+ // Conversation tags: provider + hook + per-message, deduped
394
+ ...(() => {
395
+ const merged = Array.from(new Set([...resolvedTags, ...(sendOptions?.tags ?? [])]));
396
+ return merged.length > 0 ? { tags: merged } : {};
397
+ })(),
391
398
  enabledTools,
392
399
  // Include model interface tools if any
393
400
  ...(toolSchemas.length > 0 && { tools: toolSchemas }),
@@ -435,6 +442,7 @@ function useDevicChat(options) {
435
442
  resolvedTenantMetadata,
436
443
  resolvedSubtenantId,
437
444
  resolvedSubtenantMetadata,
445
+ resolvedTags,
438
446
  toolSchemas,
439
447
  onMessageSent,
440
448
  onFileUpload,
@@ -1 +1 @@
1
- {"version":3,"file":"useDevicChat.js","sources":["../../../../src/hooks/useDevicChat.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useOptionalDevicContext } from '../provider';\nimport type { TenantMetadata, SubtenantMetadata } from '../provider';\nimport { DevicApiClient, DevicApiError } from '../api/client';\nimport { usePolling } from './usePolling';\nimport { useModelInterface, type PendingWidgetCall } from './useModelInterface';\nimport { createLogger } from '../utils/logger';\nimport type {\n ChatMessage,\n ChatFile,\n ModelInterfaceTool,\n RealtimeChatHistory,\n RealtimeStatus,\n TenantLimitExceeded,\n} from '../api/types';\n\nexport interface UseDevicChatOptions {\n /**\n * Assistant identifier\n */\n assistantId: string;\n\n /**\n * Existing chat UID to continue a conversation\n */\n chatUid?: string;\n\n /**\n * API key (overrides provider context)\n */\n apiKey?: string;\n\n /**\n * Base URL (overrides provider context)\n */\n baseUrl?: string;\n\n /**\n * Tenant ID for multi-tenant environments\n */\n tenantId?: string;\n\n /**\n * Tenant metadata (e.g. { name, email, imageUrl })\n */\n tenantMetadata?: TenantMetadata;\n\n /**\n * Subtenant ID identifying a user/entity inside the tenant\n */\n subtenantId?: string;\n\n /**\n * Subtenant metadata (e.g. { id, name, email, imageUrl })\n */\n subtenantMetadata?: SubtenantMetadata;\n\n /**\n * Tools enabled from the assistant's configured tool groups\n */\n enabledTools?: string[];\n\n /**\n * Client-side tools for model interface protocol\n */\n modelInterfaceTools?: ModelInterfaceTool[];\n\n /**\n * Polling interval for async mode (ms)\n * @default 1000\n */\n pollingInterval?: number;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: ChatMessage) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: ChatMessage) => void;\n\n /**\n * Callback when a tool is called\n */\n onToolCall?: (toolName: string, params: any) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when a new chat is created\n */\n onChatCreated?: (chatUid: string) => void;\n\n /**\n * Custom file upload handler. When provided, replaces the default\n * upload to Devic API. Receives the raw File objects and must return\n * an array of ChatFile with downloadUrl set.\n */\n onFileUpload?: (files: File[]) => Promise<ChatFile[]>;\n\n /**\n * Enable debug logging to the browser console.\n * Overrides the provider-level debug setting when provided.\n * @default false\n */\n debug?: boolean;\n}\n\nexport interface UseDevicChatResult {\n /**\n * Current chat messages\n */\n messages: ChatMessage[];\n\n /**\n * Current chat UID\n */\n chatUid: string | null;\n\n /**\n * Whether a message is being processed\n */\n isLoading: boolean;\n\n /**\n * Current status\n */\n status: RealtimeStatus | 'idle';\n\n /**\n * Last error\n */\n error: Error | null;\n\n /**\n * Set when the last message was blocked by a tenant/subtenant usage limit\n * (HTTP 429 / realtime status `limit_exceeded`). Carries the blocking rule,\n * current vs. limit and when the window resets. `null` while not limited.\n * Cleared when a new message is sent or the chat is cleared.\n */\n limitExceeded: TenantLimitExceeded | null;\n\n /**\n * Whether the assistant has handed off to a subagent\n */\n handedOff: boolean;\n\n /**\n * The subthread ID when a handoff is active\n */\n handedOffSubThreadId: string | null;\n\n /**\n * Send a message\n */\n sendMessage: (\n message: string,\n options?: {\n files?: File[];\n metadata?: Record<string, any>;\n /** Id of a speech-to-text transcript that seeded this message. */\n transcriptId?: string;\n }\n ) => Promise<void>;\n\n /**\n * Clear the chat and start a new conversation\n */\n clearChat: () => void;\n\n /**\n * Load an existing chat\n */\n loadChat: (chatUid: string) => Promise<void>;\n\n /**\n * Called when the handoff subagent completes.\n * Triggers reload of full chat content.\n */\n onHandoffCompleted: () => void;\n\n /**\n * Stop the current conversation processing (client-side only).\n * Stops polling and resets loading state.\n */\n stopChat: () => void;\n\n /**\n * Pending tool calls that require user interaction via a response widget\n */\n pendingWidgetCalls: PendingWidgetCall[];\n\n /**\n * Submit a response for a pending widget tool call.\n * Sends the response to the API and resumes the conversation.\n */\n submitWidgetResponse: (toolCallId: string, response: any) => Promise<void>;\n\n /**\n * Cancel a pending widget tool call.\n * Sends an error response so the model can continue.\n */\n cancelWidgetCall: (toolCallId: string, reason?: string) => Promise<void>;\n}\n\n/**\n * Main hook for managing chat with a Devic assistant\n *\n * @example\n * ```tsx\n * const {\n * messages,\n * isLoading,\n * sendMessage,\n * } = useDevicChat({\n * assistantId: 'my-assistant',\n * modelInterfaceTools: [\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ],\n * onMessageReceived: (msg) => console.log('Received:', msg),\n * });\n * ```\n */\nexport function useDevicChat(options: UseDevicChatOptions): UseDevicChatResult {\n const {\n assistantId,\n chatUid: initialChatUid,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n enabledTools,\n modelInterfaceTools = [],\n pollingInterval = 1000,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onFileUpload,\n debug: propsDebug,\n } = options;\n\n // Get context (may be null if not wrapped in provider)\n const context = useOptionalDevicContext();\n\n // Resolve configuration\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedTenantMetadata = { ...context?.tenantMetadata, ...tenantMetadata };\n const resolvedSubtenantId = subtenantId || context?.subtenantId;\n const resolvedSubtenantMetadata = {\n ...context?.subtenantMetadata,\n ...subtenantMetadata,\n };\n const debug = propsDebug ?? context?.debug ?? false;\n const log = useMemo(() => createLogger(debug), [debug]);\n const logRef = useRef(log);\n logRef.current = log;\n\n // State\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [chatUid, setChatUid] = useState<string | null>(initialChatUid || null);\n const [isLoading, setIsLoading] = useState(false);\n const [status, setStatus] = useState<RealtimeStatus | 'idle'>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [limitExceeded, setLimitExceeded] = useState<TenantLimitExceeded | null>(\n null\n );\n\n // Handoff state\n const [handedOff, setHandedOff] = useState(false);\n const [handedOffSubThreadId, setHandedOffSubThreadId] = useState<string | null>(null);\n const handoffPollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Polling state\n const [shouldPoll, setShouldPoll] = useState(false);\n\n // Keep a ref to chatUid so async callbacks always read the latest value\n const chatUidRef = useRef(chatUid);\n chatUidRef.current = chatUid;\n\n // Refs for callbacks\n const onMessageReceivedRef = useRef(onMessageReceived);\n const onErrorRef = useRef(onError);\n const onChatCreatedRef = useRef(onChatCreated);\n\n useEffect(() => {\n onMessageReceivedRef.current = onMessageReceived;\n onErrorRef.current = onError;\n onChatCreatedRef.current = onChatCreated;\n });\n\n // Create API client\n const clientRef = useRef<DevicApiClient | null>(null);\n if (!clientRef.current && apiKey) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl });\n }\n\n // Update client config if it changes\n useEffect(() => {\n if (clientRef.current && apiKey) {\n clientRef.current.setConfig({ apiKey, baseUrl });\n }\n }, [apiKey, baseUrl]);\n\n // Resume chat state based on realtime status.\n // Called after loading chat history to detect in-progress conversations.\n const resumeFromRealtimeStatus = useCallback(\n async (targetChatUid: string) => {\n if (!clientRef.current) return;\n try {\n const realtime = await clientRef.current.getRealtimeHistory(assistantId, targetChatUid);\n logRef.current.log('[useDevicChat] resumeFromRealtimeStatus:', realtime.status);\n\n // Update messages with realtime data (may be fresher than static history)\n if (realtime.chatHistory?.length) {\n setMessages(realtime.chatHistory);\n }\n setStatus(realtime.status);\n\n if (realtime.status === 'processing') {\n // Chat is still processing — resume polling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'waiting_for_tool_response') {\n // Chat is waiting for tool response — resume polling to trigger tool handling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'handed_off') {\n // Chat has an active handoff\n setIsLoading(true);\n setHandedOff(true);\n const subThreadId = realtime.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Resuming handoff state:', { subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n } else {\n // completed or error — just stop\n setIsLoading(false);\n }\n } catch (err) {\n // If realtime fetch fails (e.g. chat has no realtime entry), just stay idle\n logRef.current.warn('[useDevicChat] resumeFromRealtimeStatus failed:', err);\n setIsLoading(false);\n }\n },\n [assistantId]\n );\n\n // Load initial chat history if chatUid prop is provided\n // This runs once on mount (or when initialChatUid changes) to fetch existing conversation\n const initialChatLoadedRef = useRef(false);\n useEffect(() => {\n if (initialChatUid && clientRef.current && !initialChatLoadedRef.current) {\n initialChatLoadedRef.current = true;\n\n const loadInitialChat = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const history = await clientRef.current!.getChatHistory(\n assistantId,\n initialChatUid,\n { tenantId: resolvedTenantId }\n );\n setMessages(history.chatContent);\n setChatUid(initialChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(initialChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n };\n\n loadInitialChat();\n }\n }, [initialChatUid, assistantId, resolvedTenantId, resumeFromRealtimeStatus]);\n\n // Model interface hook\n const {\n toolSchemas,\n handleToolCalls,\n extractPendingToolCalls,\n } = useModelInterface({\n tools: modelInterfaceTools,\n onToolExecute: onToolCall,\n });\n\n // Pending widget calls awaiting user interaction\n const [pendingWidgetCalls, setPendingWidgetCalls] = useState<PendingWidgetCall[]>([]);\n const pendingWidgetCallsRef = useRef<PendingWidgetCall[]>([]);\n useEffect(() => {\n pendingWidgetCallsRef.current = pendingWidgetCalls;\n }, [pendingWidgetCalls]);\n\n // Polling hook - uses callbacks for side effects, return value not needed\n logRef.current.log('[useDevicChat] Render - shouldPoll:', shouldPoll, 'chatUid:', chatUid);\n usePolling(\n shouldPoll ? chatUid : null,\n async () => {\n logRef.current.log('[useDevicChat] fetchFn called, chatUid:', chatUid);\n if (!clientRef.current || !chatUid) {\n throw new Error('Cannot poll without client or chatUid');\n }\n const result = await clientRef.current.getRealtimeHistory(assistantId, chatUid);\n logRef.current.log('[useDevicChat] getRealtimeHistory result:', result);\n return result;\n },\n {\n interval: pollingInterval,\n enabled: shouldPoll,\n stopStatuses: [\n 'completed',\n 'error',\n 'waiting_for_tool_response',\n 'handed_off',\n 'limit_exceeded',\n ],\n onUpdate: async (data: RealtimeChatHistory) => {\n logRef.current.log('[useDevicChat] onUpdate called, status:', data.status);\n\n // Merge realtime data with optimistic messages.\n // When a server user message matches an optimistic one by text, adopt the\n // optimistic uid so React's key stays stable (avoids unmount/remount flicker).\n setMessages((prev) => {\n const normalize = (t?: string) => (t ?? '').trim();\n const optimisticUserByText = new Map(\n prev\n .filter((m) => m.role === 'user' && m.uid.startsWith('temp-'))\n .map((m) => [normalize(m.content?.message), m.uid])\n );\n\n const adoptedTempUids = new Set<string>();\n const merged = data.chatHistory.map((m) => {\n if (m.role === 'user') {\n const tempUid = optimisticUserByText.get(normalize(m.content?.message));\n if (tempUid) {\n adoptedTempUids.add(tempUid);\n return { ...m, uid: tempUid };\n }\n }\n return m;\n });\n\n const mergedUIDs = new Set(merged.map((m) => m.uid));\n const optimistic = prev.filter(\n (m) => !mergedUIDs.has(m.uid) && !adoptedTempUids.has(m.uid)\n );\n\n return [...merged, ...optimistic];\n });\n setStatus(data.status);\n\n // Notify about new messages\n const lastMessage = data.chatHistory[data.chatHistory.length - 1];\n if (lastMessage && lastMessage.role === 'assistant') {\n onMessageReceivedRef.current?.(lastMessage);\n }\n\n // Handle model interface - check for pending tool calls\n if (data.status === 'waiting_for_tool_response' || data.pendingToolCalls?.length) {\n await handlePendingToolCalls(data);\n }\n },\n onStop: (data) => {\n logRef.current.log('[useDevicChat] onStop called, status:', data?.status);\n setShouldPoll(false);\n\n if (data?.status === 'limit_exceeded') {\n // The message was blocked by a tenant/subtenant usage limit before\n // reaching the LLM. Surface the details so the UI can show a banner.\n setIsLoading(false);\n const details: TenantLimitExceeded = data.limitExceeded || {\n message: 'Usage limit reached.',\n };\n setLimitExceeded(details);\n const err = new Error(\n details.message || 'Usage limit reached.'\n ) as Error & { errorType?: string; details?: TenantLimitExceeded };\n err.errorType = 'TENANT_LIMIT_EXCEEDED';\n err.details = details;\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'error') {\n setIsLoading(false);\n const err = new Error('Chat processing failed');\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'completed') {\n setIsLoading(false);\n } else if (data?.status === 'handed_off') {\n // Subagent is working — keep isLoading true so the UI stays in loading state.\n // Set handoff state directly from the realtime status.\n setHandedOff(true);\n\n const subThreadId = data.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Handoff state set:', { handedOff: true, subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n }\n // Note: waiting_for_tool_response is handled in onUpdate to avoid double execution\n },\n onError: (err) => {\n logRef.current.error('[useDevicChat] onError called:', err);\n setError(err);\n setIsLoading(false);\n setShouldPoll(false);\n onErrorRef.current?.(err);\n },\n debug,\n }\n );\n\n // Handle pending tool calls from model interface\n const handlePendingToolCalls = useCallback(\n async (data: RealtimeChatHistory) => {\n if (!clientRef.current || !chatUid) return;\n\n // Get pending tool calls\n const pendingCalls = data.pendingToolCalls || extractPendingToolCalls(data.chatHistory);\n\n if (pendingCalls.length === 0) return;\n\n try {\n // Execute client-side tools (partitioned into immediate responses and widget-driven)\n const { responses, widgetCalls } = await handleToolCalls(pendingCalls);\n\n // Queue widget-driven tool calls for user interaction\n if (widgetCalls.length > 0) {\n const existingIds = new Set(pendingWidgetCallsRef.current.map((c) => c.toolCall.id));\n const deduped = widgetCalls.filter((c) => !existingIds.has(c.toolCall.id));\n const next = [...pendingWidgetCallsRef.current, ...deduped];\n pendingWidgetCallsRef.current = next;\n setPendingWidgetCalls(next);\n // Stop polling while we wait for the user to submit the widget response.\n // The widget submission will re-trigger polling via submitWidgetResponse.\n setShouldPoll(false);\n setIsLoading(false);\n }\n\n if (responses.length > 0) {\n // Send tool responses back to the API\n await clientRef.current.sendToolResponses(assistantId, chatUid, responses);\n\n // Only resume polling if no widgets are blocking\n if (widgetCalls.length === 0) {\n setShouldPoll(true);\n setIsLoading(true);\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [chatUid, assistantId, handleToolCalls, extractPendingToolCalls]\n );\n\n // Send a message\n const sendMessage = useCallback(\n async (\n message: string,\n sendOptions?: {\n files?: File[];\n metadata?: Record<string, any>;\n transcriptId?: string;\n }\n ) => {\n if (!clientRef.current) {\n const err = new Error(\n 'API client not configured. Please provide an API key.'\n );\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n setLimitExceeded(null);\n setStatus('processing');\n\n // Add user message optimistically (show file names before upload)\n const userMessage: ChatMessage = {\n uid: `temp-${Date.now()}`,\n role: 'user',\n content: {\n message,\n files: sendOptions?.files?.map((f) => ({\n name: f.name,\n url: '',\n type: f.type.split('/')[0] || 'other',\n })),\n },\n timestamp: Date.now(),\n ...(sendOptions?.transcriptId && {\n transcriptId: sendOptions.transcriptId,\n }),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n onMessageSent?.(userMessage);\n\n try {\n // Upload files if provided\n let uploadedFiles: ChatFile[] | undefined;\n if (sendOptions?.files && sendOptions.files.length > 0) {\n logRef.current.log('[useDevicChat] Uploading files...');\n if (onFileUpload) {\n // Use custom upload handler\n uploadedFiles = await onFileUpload(sendOptions.files);\n } else {\n // Default: upload via Devic API\n const uploadResults = await Promise.all(\n sendOptions.files.map((file) => clientRef.current!.uploadFile(file))\n );\n uploadedFiles = uploadResults.map((r) => ({\n name: r.name,\n downloadUrl: r.downloadUrl,\n fileType: r.fileType as ChatFile['fileType'],\n }));\n }\n logRef.current.log('[useDevicChat] Files uploaded:', uploadedFiles);\n\n // Update optimistic message with download URLs\n setMessages((prev) =>\n prev.map((m) =>\n m.uid === userMessage.uid\n ? {\n ...m,\n content: {\n ...m.content,\n files: uploadedFiles!.map((f) => ({\n name: f.name,\n url: f.downloadUrl || '',\n type: f.fileType || 'other',\n })),\n },\n }\n : m\n )\n );\n }\n\n // Build request DTO\n const hasSubtenantMetadata =\n resolvedSubtenantMetadata &&\n Object.keys(resolvedSubtenantMetadata).length > 0;\n const dto = {\n message,\n chatUid: chatUid || undefined,\n files: uploadedFiles,\n metadata: {\n ...resolvedTenantMetadata,\n ...(hasSubtenantMetadata && {\n subtenantMetadata: resolvedSubtenantMetadata,\n }),\n ...sendOptions?.metadata,\n },\n tenantId: resolvedTenantId,\n ...(resolvedSubtenantId && { subtenantId: resolvedSubtenantId }),\n enabledTools,\n // Include model interface tools if any\n ...(toolSchemas.length > 0 && { tools: toolSchemas }),\n // Link to the speech-to-text transcript that seeded this message, if any\n ...(sendOptions?.transcriptId && { transcriptId: sendOptions.transcriptId }),\n };\n\n // Send message in async mode\n logRef.current.log('[useDevicChat] Sending message async...');\n const response = await clientRef.current.sendMessageAsync(assistantId, dto);\n logRef.current.log('[useDevicChat] sendMessageAsync response:', response);\n\n // Update chat UID if this is a new chat\n if (response.chatUid && response.chatUid !== chatUid) {\n logRef.current.log('[useDevicChat] Setting chatUid:', response.chatUid);\n setChatUid(response.chatUid);\n onChatCreatedRef.current?.(response.chatUid);\n }\n\n // Start polling for results\n logRef.current.log('[useDevicChat] Setting shouldPoll to true');\n setShouldPoll(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n // A synchronous usage-limit block surfaces as HTTP 429 /\n // TENANT_LIMIT_EXCEEDED (sync send path). Async sends surface it via the\n // realtime `limit_exceeded` status instead — both are handled.\n if (\n err instanceof DevicApiError &&\n (err.statusCode === 429 || err.errorType === 'TENANT_LIMIT_EXCEEDED')\n ) {\n const details: TenantLimitExceeded =\n (err.details as TenantLimitExceeded) || { message: err.message };\n if (!details.message) details.message = err.message;\n setLimitExceeded(details);\n }\n\n setError(error);\n setIsLoading(false);\n setStatus('error');\n onErrorRef.current?.(error);\n\n // Remove optimistic user message on error\n setMessages((prev) => prev.filter((m) => m.uid !== userMessage.uid));\n }\n },\n [\n chatUid,\n assistantId,\n enabledTools,\n resolvedTenantId,\n resolvedTenantMetadata,\n resolvedSubtenantId,\n resolvedSubtenantMetadata,\n toolSchemas,\n onMessageSent,\n onFileUpload,\n ]\n );\n\n // Clear chat\n const clearChat = useCallback(() => {\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setMessages([]);\n setChatUid(null);\n setIsLoading(false);\n setStatus('idle');\n setError(null);\n setLimitExceeded(null);\n pendingWidgetCallsRef.current = [];\n setPendingWidgetCalls([]);\n }, []);\n\n // Load existing chat\n const loadChat = useCallback(\n async (loadChatUid: string) => {\n if (!clientRef.current) {\n const err = new Error('API client not configured');\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n // Reset any active polling/handoff state from previous conversation\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n pendingWidgetCallsRef.current = [];\n setPendingWidgetCalls([]);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const history = await clientRef.current.getChatHistory(\n assistantId,\n loadChatUid,\n { tenantId: resolvedTenantId }\n );\n\n setMessages(history.chatContent);\n setChatUid(loadChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(loadChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n },\n [assistantId, resolvedTenantId, resumeFromRealtimeStatus]\n );\n\n // Handoff polling: while handedOff is true, poll the realtime endpoint every 5s\n // to detect when the parent thread is no longer in handed_off state.\n useEffect(() => {\n if (!handedOff || !chatUid || !clientRef.current) return;\n\n const pollHandoff = async () => {\n try {\n const realtime = await clientRef.current!.getRealtimeHistory(assistantId, chatUid!);\n logRef.current.log('[useDevicChat] Handoff poll - realtime status:', realtime.status);\n if (realtime.status !== 'handed_off') {\n // Handoff completed — clear handoff state and resume main polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n // Resume main polling to pick up the parent thread's continuation\n setShouldPoll(true);\n }\n } catch {}\n };\n\n handoffPollRef.current = setInterval(pollHandoff, 5000);\n return () => {\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n };\n }, [handedOff, chatUid, assistantId]);\n\n // Called by HandoffSubagentWidget when the subthread reaches a terminal state\n const onHandoffCompleted = useCallback(() => {\n logRef.current.log('[useDevicChat] onHandoffCompleted called');\n // Clear the handoff polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n // Clear handoff state and resume main polling\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n setShouldPoll(true);\n }, []);\n\n // Submit a response for a pending widget tool call\n const submitWidgetResponse = useCallback(\n async (toolCallId: string, response: any) => {\n const uid = chatUidRef.current;\n if (!clientRef.current || !uid) return;\n\n // Check pending widgets via ref (state updates are async)\n const current = pendingWidgetCallsRef.current;\n const found = current.some((c) => c.toolCall.id === toolCallId);\n if (!found) return;\n\n // Remove the widget call from pending list\n const remaining = current.filter((c) => c.toolCall.id !== toolCallId);\n pendingWidgetCallsRef.current = remaining;\n setPendingWidgetCalls(remaining);\n\n try {\n logRef.current.log('[useDevicChat] sending widget tool response', toolCallId);\n await clientRef.current.sendToolResponses(assistantId, uid, [\n { tool_call_id: toolCallId, content: response, role: 'tool' },\n ]);\n // Resume polling only if no more widget calls are blocking\n if (remaining.length === 0) {\n setShouldPoll(true);\n setIsLoading(true);\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logRef.current.error('[useDevicChat] submitWidgetResponse failed', error);\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [assistantId]\n );\n\n // Cancel a pending widget tool call (sends an error response to the model)\n const cancelWidgetCall = useCallback(\n async (toolCallId: string, reason?: string) => {\n await submitWidgetResponse(toolCallId, {\n error: reason || 'User cancelled the tool call',\n });\n },\n [submitWidgetResponse]\n );\n\n // Stop current conversation — calls the server-side stop endpoint\n // then stops polling and resets loading state.\n const stopChat = useCallback(async () => {\n const uid = chatUidRef.current;\n logRef.current.log('[useDevicChat] stopChat called, chatUid:', uid);\n if (clientRef.current && uid) {\n try {\n await clientRef.current.stopChat(assistantId, uid);\n logRef.current.log('[useDevicChat] stopChat API call succeeded');\n } catch (err) {\n logRef.current.warn('[useDevicChat] stopChat API call failed:', err);\n }\n }\n setShouldPoll(false);\n setIsLoading(false);\n setStatus('idle');\n }, [assistantId]);\n\n return {\n messages,\n chatUid,\n isLoading,\n status,\n error,\n limitExceeded,\n handedOff,\n handedOffSubThreadId,\n sendMessage,\n clearChat,\n loadChat,\n onHandoffCompleted,\n stopChat,\n pendingWidgetCalls,\n submitWidgetResponse,\n cancelWidgetCall,\n };\n}\n"],"names":["useOptionalDevicContext","useMemo","createLogger","useRef","useState","useEffect","DevicApiClient","useCallback","useModelInterface","usePolling","DevicApiError"],"mappings":"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"}
1
+ {"version":3,"file":"useDevicChat.js","sources":["../../../../src/hooks/useDevicChat.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useOptionalDevicContext } from '../provider';\nimport type { TenantMetadata, SubtenantMetadata } from '../provider';\nimport { DevicApiClient, DevicApiError } from '../api/client';\nimport { usePolling } from './usePolling';\nimport { useModelInterface, type PendingWidgetCall } from './useModelInterface';\nimport { createLogger } from '../utils/logger';\nimport type {\n ChatMessage,\n ChatFile,\n ModelInterfaceTool,\n RealtimeChatHistory,\n RealtimeStatus,\n TenantLimitExceeded,\n} from '../api/types';\n\nexport interface UseDevicChatOptions {\n /**\n * Assistant identifier\n */\n assistantId: string;\n\n /**\n * Existing chat UID to continue a conversation\n */\n chatUid?: string;\n\n /**\n * API key (overrides provider context)\n */\n apiKey?: string;\n\n /**\n * Base URL (overrides provider context)\n */\n baseUrl?: string;\n\n /**\n * Tenant ID for multi-tenant environments\n */\n tenantId?: string;\n\n /**\n * Tenant metadata (e.g. { name, email, imageUrl })\n */\n tenantMetadata?: TenantMetadata;\n\n /**\n * Subtenant ID identifying a user/entity inside the tenant\n */\n subtenantId?: string;\n\n /**\n * Subtenant metadata (e.g. { id, name, email, imageUrl })\n */\n subtenantMetadata?: SubtenantMetadata;\n\n /**\n * Tags applied to the conversation. Sent as the top-level `tags` of each\n * message (distinct from metadata). Falls back to the DevicProvider's `tags`\n * and is merged (deduped) with any per-message tags passed to `sendMessage`.\n */\n tags?: string[];\n\n /**\n * Tools enabled from the assistant's configured tool groups\n */\n enabledTools?: string[];\n\n /**\n * Client-side tools for model interface protocol\n */\n modelInterfaceTools?: ModelInterfaceTool[];\n\n /**\n * Polling interval for async mode (ms)\n * @default 1000\n */\n pollingInterval?: number;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: ChatMessage) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: ChatMessage) => void;\n\n /**\n * Callback when a tool is called\n */\n onToolCall?: (toolName: string, params: any) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when a new chat is created\n */\n onChatCreated?: (chatUid: string) => void;\n\n /**\n * Custom file upload handler. When provided, replaces the default\n * upload to Devic API. Receives the raw File objects and must return\n * an array of ChatFile with downloadUrl set.\n */\n onFileUpload?: (files: File[]) => Promise<ChatFile[]>;\n\n /**\n * Enable debug logging to the browser console.\n * Overrides the provider-level debug setting when provided.\n * @default false\n */\n debug?: boolean;\n}\n\nexport interface UseDevicChatResult {\n /**\n * Current chat messages\n */\n messages: ChatMessage[];\n\n /**\n * Current chat UID\n */\n chatUid: string | null;\n\n /**\n * Whether a message is being processed\n */\n isLoading: boolean;\n\n /**\n * Current status\n */\n status: RealtimeStatus | 'idle';\n\n /**\n * Last error\n */\n error: Error | null;\n\n /**\n * Set when the last message was blocked by a tenant/subtenant usage limit\n * (HTTP 429 / realtime status `limit_exceeded`). Carries the blocking rule,\n * current vs. limit and when the window resets. `null` while not limited.\n * Cleared when a new message is sent or the chat is cleared.\n */\n limitExceeded: TenantLimitExceeded | null;\n\n /**\n * Whether the assistant has handed off to a subagent\n */\n handedOff: boolean;\n\n /**\n * The subthread ID when a handoff is active\n */\n handedOffSubThreadId: string | null;\n\n /**\n * Send a message\n */\n sendMessage: (\n message: string,\n options?: {\n files?: File[];\n metadata?: Record<string, any>;\n /** Id of a speech-to-text transcript that seeded this message. */\n transcriptId?: string;\n /** Per-message tags, merged (deduped) with the resolved conversation tags. */\n tags?: string[];\n }\n ) => Promise<void>;\n\n /**\n * Clear the chat and start a new conversation\n */\n clearChat: () => void;\n\n /**\n * Load an existing chat\n */\n loadChat: (chatUid: string) => Promise<void>;\n\n /**\n * Called when the handoff subagent completes.\n * Triggers reload of full chat content.\n */\n onHandoffCompleted: () => void;\n\n /**\n * Stop the current conversation processing (client-side only).\n * Stops polling and resets loading state.\n */\n stopChat: () => void;\n\n /**\n * Pending tool calls that require user interaction via a response widget\n */\n pendingWidgetCalls: PendingWidgetCall[];\n\n /**\n * Submit a response for a pending widget tool call.\n * Sends the response to the API and resumes the conversation.\n */\n submitWidgetResponse: (toolCallId: string, response: any) => Promise<void>;\n\n /**\n * Cancel a pending widget tool call.\n * Sends an error response so the model can continue.\n */\n cancelWidgetCall: (toolCallId: string, reason?: string) => Promise<void>;\n}\n\n/**\n * Main hook for managing chat with a Devic assistant\n *\n * @example\n * ```tsx\n * const {\n * messages,\n * isLoading,\n * sendMessage,\n * } = useDevicChat({\n * assistantId: 'my-assistant',\n * modelInterfaceTools: [\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ],\n * onMessageReceived: (msg) => console.log('Received:', msg),\n * });\n * ```\n */\nexport function useDevicChat(options: UseDevicChatOptions): UseDevicChatResult {\n const {\n assistantId,\n chatUid: initialChatUid,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n tags,\n enabledTools,\n modelInterfaceTools = [],\n pollingInterval = 1000,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onFileUpload,\n debug: propsDebug,\n } = options;\n\n // Get context (may be null if not wrapped in provider)\n const context = useOptionalDevicContext();\n\n // Resolve configuration\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedTenantMetadata = { ...context?.tenantMetadata, ...tenantMetadata };\n const resolvedSubtenantId = subtenantId || context?.subtenantId;\n const resolvedSubtenantMetadata = {\n ...context?.subtenantMetadata,\n ...subtenantMetadata,\n };\n // Provider tags + hook tags, deduped. Per-message tags are merged at send time.\n const resolvedTags = useMemo(\n () => Array.from(new Set([...(context?.tags ?? []), ...(tags ?? [])])),\n [context?.tags, tags]\n );\n const debug = propsDebug ?? context?.debug ?? false;\n const log = useMemo(() => createLogger(debug), [debug]);\n const logRef = useRef(log);\n logRef.current = log;\n\n // State\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [chatUid, setChatUid] = useState<string | null>(initialChatUid || null);\n const [isLoading, setIsLoading] = useState(false);\n const [status, setStatus] = useState<RealtimeStatus | 'idle'>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [limitExceeded, setLimitExceeded] = useState<TenantLimitExceeded | null>(\n null\n );\n\n // Handoff state\n const [handedOff, setHandedOff] = useState(false);\n const [handedOffSubThreadId, setHandedOffSubThreadId] = useState<string | null>(null);\n const handoffPollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Polling state\n const [shouldPoll, setShouldPoll] = useState(false);\n\n // Keep a ref to chatUid so async callbacks always read the latest value\n const chatUidRef = useRef(chatUid);\n chatUidRef.current = chatUid;\n\n // Refs for callbacks\n const onMessageReceivedRef = useRef(onMessageReceived);\n const onErrorRef = useRef(onError);\n const onChatCreatedRef = useRef(onChatCreated);\n\n useEffect(() => {\n onMessageReceivedRef.current = onMessageReceived;\n onErrorRef.current = onError;\n onChatCreatedRef.current = onChatCreated;\n });\n\n // Create API client\n const clientRef = useRef<DevicApiClient | null>(null);\n if (!clientRef.current && apiKey) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl });\n }\n\n // Update client config if it changes\n useEffect(() => {\n if (clientRef.current && apiKey) {\n clientRef.current.setConfig({ apiKey, baseUrl });\n }\n }, [apiKey, baseUrl]);\n\n // Resume chat state based on realtime status.\n // Called after loading chat history to detect in-progress conversations.\n const resumeFromRealtimeStatus = useCallback(\n async (targetChatUid: string) => {\n if (!clientRef.current) return;\n try {\n const realtime = await clientRef.current.getRealtimeHistory(assistantId, targetChatUid);\n logRef.current.log('[useDevicChat] resumeFromRealtimeStatus:', realtime.status);\n\n // Update messages with realtime data (may be fresher than static history)\n if (realtime.chatHistory?.length) {\n setMessages(realtime.chatHistory);\n }\n setStatus(realtime.status);\n\n if (realtime.status === 'processing') {\n // Chat is still processing — resume polling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'waiting_for_tool_response') {\n // Chat is waiting for tool response — resume polling to trigger tool handling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'handed_off') {\n // Chat has an active handoff\n setIsLoading(true);\n setHandedOff(true);\n const subThreadId = realtime.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Resuming handoff state:', { subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n } else {\n // completed or error — just stop\n setIsLoading(false);\n }\n } catch (err) {\n // If realtime fetch fails (e.g. chat has no realtime entry), just stay idle\n logRef.current.warn('[useDevicChat] resumeFromRealtimeStatus failed:', err);\n setIsLoading(false);\n }\n },\n [assistantId]\n );\n\n // Load initial chat history if chatUid prop is provided\n // This runs once on mount (or when initialChatUid changes) to fetch existing conversation\n const initialChatLoadedRef = useRef(false);\n useEffect(() => {\n if (initialChatUid && clientRef.current && !initialChatLoadedRef.current) {\n initialChatLoadedRef.current = true;\n\n const loadInitialChat = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const history = await clientRef.current!.getChatHistory(\n assistantId,\n initialChatUid,\n { tenantId: resolvedTenantId }\n );\n setMessages(history.chatContent);\n setChatUid(initialChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(initialChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n };\n\n loadInitialChat();\n }\n }, [initialChatUid, assistantId, resolvedTenantId, resumeFromRealtimeStatus]);\n\n // Model interface hook\n const {\n toolSchemas,\n handleToolCalls,\n extractPendingToolCalls,\n } = useModelInterface({\n tools: modelInterfaceTools,\n onToolExecute: onToolCall,\n });\n\n // Pending widget calls awaiting user interaction\n const [pendingWidgetCalls, setPendingWidgetCalls] = useState<PendingWidgetCall[]>([]);\n const pendingWidgetCallsRef = useRef<PendingWidgetCall[]>([]);\n useEffect(() => {\n pendingWidgetCallsRef.current = pendingWidgetCalls;\n }, [pendingWidgetCalls]);\n\n // Polling hook - uses callbacks for side effects, return value not needed\n logRef.current.log('[useDevicChat] Render - shouldPoll:', shouldPoll, 'chatUid:', chatUid);\n usePolling(\n shouldPoll ? chatUid : null,\n async () => {\n logRef.current.log('[useDevicChat] fetchFn called, chatUid:', chatUid);\n if (!clientRef.current || !chatUid) {\n throw new Error('Cannot poll without client or chatUid');\n }\n const result = await clientRef.current.getRealtimeHistory(assistantId, chatUid);\n logRef.current.log('[useDevicChat] getRealtimeHistory result:', result);\n return result;\n },\n {\n interval: pollingInterval,\n enabled: shouldPoll,\n stopStatuses: [\n 'completed',\n 'error',\n 'waiting_for_tool_response',\n 'handed_off',\n 'limit_exceeded',\n ],\n onUpdate: async (data: RealtimeChatHistory) => {\n logRef.current.log('[useDevicChat] onUpdate called, status:', data.status);\n\n // Merge realtime data with optimistic messages.\n // When a server user message matches an optimistic one by text, adopt the\n // optimistic uid so React's key stays stable (avoids unmount/remount flicker).\n setMessages((prev) => {\n const normalize = (t?: string) => (t ?? '').trim();\n const optimisticUserByText = new Map(\n prev\n .filter((m) => m.role === 'user' && m.uid.startsWith('temp-'))\n .map((m) => [normalize(m.content?.message), m.uid])\n );\n\n const adoptedTempUids = new Set<string>();\n const merged = data.chatHistory.map((m) => {\n if (m.role === 'user') {\n const tempUid = optimisticUserByText.get(normalize(m.content?.message));\n if (tempUid) {\n adoptedTempUids.add(tempUid);\n return { ...m, uid: tempUid };\n }\n }\n return m;\n });\n\n const mergedUIDs = new Set(merged.map((m) => m.uid));\n const optimistic = prev.filter(\n (m) => !mergedUIDs.has(m.uid) && !adoptedTempUids.has(m.uid)\n );\n\n return [...merged, ...optimistic];\n });\n setStatus(data.status);\n\n // Notify about new messages\n const lastMessage = data.chatHistory[data.chatHistory.length - 1];\n if (lastMessage && lastMessage.role === 'assistant') {\n onMessageReceivedRef.current?.(lastMessage);\n }\n\n // Handle model interface - check for pending tool calls\n if (data.status === 'waiting_for_tool_response' || data.pendingToolCalls?.length) {\n await handlePendingToolCalls(data);\n }\n },\n onStop: (data) => {\n logRef.current.log('[useDevicChat] onStop called, status:', data?.status);\n setShouldPoll(false);\n\n if (data?.status === 'limit_exceeded') {\n // The message was blocked by a tenant/subtenant usage limit before\n // reaching the LLM. Surface the details so the UI can show a banner.\n setIsLoading(false);\n const details: TenantLimitExceeded = data.limitExceeded || {\n message: 'Usage limit reached.',\n };\n setLimitExceeded(details);\n const err = new Error(\n details.message || 'Usage limit reached.'\n ) as Error & { errorType?: string; details?: TenantLimitExceeded };\n err.errorType = 'TENANT_LIMIT_EXCEEDED';\n err.details = details;\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'error') {\n setIsLoading(false);\n const err = new Error('Chat processing failed');\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'completed') {\n setIsLoading(false);\n } else if (data?.status === 'handed_off') {\n // Subagent is working — keep isLoading true so the UI stays in loading state.\n // Set handoff state directly from the realtime status.\n setHandedOff(true);\n\n const subThreadId = data.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Handoff state set:', { handedOff: true, subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n }\n // Note: waiting_for_tool_response is handled in onUpdate to avoid double execution\n },\n onError: (err) => {\n logRef.current.error('[useDevicChat] onError called:', err);\n setError(err);\n setIsLoading(false);\n setShouldPoll(false);\n onErrorRef.current?.(err);\n },\n debug,\n }\n );\n\n // Handle pending tool calls from model interface\n const handlePendingToolCalls = useCallback(\n async (data: RealtimeChatHistory) => {\n if (!clientRef.current || !chatUid) return;\n\n // Get pending tool calls\n const pendingCalls = data.pendingToolCalls || extractPendingToolCalls(data.chatHistory);\n\n if (pendingCalls.length === 0) return;\n\n try {\n // Execute client-side tools (partitioned into immediate responses and widget-driven)\n const { responses, widgetCalls } = await handleToolCalls(pendingCalls);\n\n // Queue widget-driven tool calls for user interaction\n if (widgetCalls.length > 0) {\n const existingIds = new Set(pendingWidgetCallsRef.current.map((c) => c.toolCall.id));\n const deduped = widgetCalls.filter((c) => !existingIds.has(c.toolCall.id));\n const next = [...pendingWidgetCallsRef.current, ...deduped];\n pendingWidgetCallsRef.current = next;\n setPendingWidgetCalls(next);\n // Stop polling while we wait for the user to submit the widget response.\n // The widget submission will re-trigger polling via submitWidgetResponse.\n setShouldPoll(false);\n setIsLoading(false);\n }\n\n if (responses.length > 0) {\n // Send tool responses back to the API\n await clientRef.current.sendToolResponses(assistantId, chatUid, responses);\n\n // Only resume polling if no widgets are blocking\n if (widgetCalls.length === 0) {\n setShouldPoll(true);\n setIsLoading(true);\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [chatUid, assistantId, handleToolCalls, extractPendingToolCalls]\n );\n\n // Send a message\n const sendMessage = useCallback(\n async (\n message: string,\n sendOptions?: {\n files?: File[];\n metadata?: Record<string, any>;\n transcriptId?: string;\n tags?: string[];\n }\n ) => {\n if (!clientRef.current) {\n const err = new Error(\n 'API client not configured. Please provide an API key.'\n );\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n setLimitExceeded(null);\n setStatus('processing');\n\n // Add user message optimistically (show file names before upload)\n const userMessage: ChatMessage = {\n uid: `temp-${Date.now()}`,\n role: 'user',\n content: {\n message,\n files: sendOptions?.files?.map((f) => ({\n name: f.name,\n url: '',\n type: f.type.split('/')[0] || 'other',\n })),\n },\n timestamp: Date.now(),\n ...(sendOptions?.transcriptId && {\n transcriptId: sendOptions.transcriptId,\n }),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n onMessageSent?.(userMessage);\n\n try {\n // Upload files if provided\n let uploadedFiles: ChatFile[] | undefined;\n if (sendOptions?.files && sendOptions.files.length > 0) {\n logRef.current.log('[useDevicChat] Uploading files...');\n if (onFileUpload) {\n // Use custom upload handler\n uploadedFiles = await onFileUpload(sendOptions.files);\n } else {\n // Default: upload via Devic API\n const uploadResults = await Promise.all(\n sendOptions.files.map((file) => clientRef.current!.uploadFile(file))\n );\n uploadedFiles = uploadResults.map((r) => ({\n name: r.name,\n downloadUrl: r.downloadUrl,\n fileType: r.fileType as ChatFile['fileType'],\n }));\n }\n logRef.current.log('[useDevicChat] Files uploaded:', uploadedFiles);\n\n // Update optimistic message with download URLs\n setMessages((prev) =>\n prev.map((m) =>\n m.uid === userMessage.uid\n ? {\n ...m,\n content: {\n ...m.content,\n files: uploadedFiles!.map((f) => ({\n name: f.name,\n url: f.downloadUrl || '',\n type: f.fileType || 'other',\n })),\n },\n }\n : m\n )\n );\n }\n\n // Build request DTO\n const hasSubtenantMetadata =\n resolvedSubtenantMetadata &&\n Object.keys(resolvedSubtenantMetadata).length > 0;\n const dto = {\n message,\n chatUid: chatUid || undefined,\n files: uploadedFiles,\n metadata: {\n ...resolvedTenantMetadata,\n ...(hasSubtenantMetadata && {\n subtenantMetadata: resolvedSubtenantMetadata,\n }),\n ...sendOptions?.metadata,\n },\n tenantId: resolvedTenantId,\n ...(resolvedSubtenantId && { subtenantId: resolvedSubtenantId }),\n // Conversation tags: provider + hook + per-message, deduped\n ...(() => {\n const merged = Array.from(\n new Set([...resolvedTags, ...(sendOptions?.tags ?? [])])\n );\n return merged.length > 0 ? { tags: merged } : {};\n })(),\n enabledTools,\n // Include model interface tools if any\n ...(toolSchemas.length > 0 && { tools: toolSchemas }),\n // Link to the speech-to-text transcript that seeded this message, if any\n ...(sendOptions?.transcriptId && { transcriptId: sendOptions.transcriptId }),\n };\n\n // Send message in async mode\n logRef.current.log('[useDevicChat] Sending message async...');\n const response = await clientRef.current.sendMessageAsync(assistantId, dto);\n logRef.current.log('[useDevicChat] sendMessageAsync response:', response);\n\n // Update chat UID if this is a new chat\n if (response.chatUid && response.chatUid !== chatUid) {\n logRef.current.log('[useDevicChat] Setting chatUid:', response.chatUid);\n setChatUid(response.chatUid);\n onChatCreatedRef.current?.(response.chatUid);\n }\n\n // Start polling for results\n logRef.current.log('[useDevicChat] Setting shouldPoll to true');\n setShouldPoll(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n // A synchronous usage-limit block surfaces as HTTP 429 /\n // TENANT_LIMIT_EXCEEDED (sync send path). Async sends surface it via the\n // realtime `limit_exceeded` status instead — both are handled.\n if (\n err instanceof DevicApiError &&\n (err.statusCode === 429 || err.errorType === 'TENANT_LIMIT_EXCEEDED')\n ) {\n const details: TenantLimitExceeded =\n (err.details as TenantLimitExceeded) || { message: err.message };\n if (!details.message) details.message = err.message;\n setLimitExceeded(details);\n }\n\n setError(error);\n setIsLoading(false);\n setStatus('error');\n onErrorRef.current?.(error);\n\n // Remove optimistic user message on error\n setMessages((prev) => prev.filter((m) => m.uid !== userMessage.uid));\n }\n },\n [\n chatUid,\n assistantId,\n enabledTools,\n resolvedTenantId,\n resolvedTenantMetadata,\n resolvedSubtenantId,\n resolvedSubtenantMetadata,\n resolvedTags,\n toolSchemas,\n onMessageSent,\n onFileUpload,\n ]\n );\n\n // Clear chat\n const clearChat = useCallback(() => {\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setMessages([]);\n setChatUid(null);\n setIsLoading(false);\n setStatus('idle');\n setError(null);\n setLimitExceeded(null);\n pendingWidgetCallsRef.current = [];\n setPendingWidgetCalls([]);\n }, []);\n\n // Load existing chat\n const loadChat = useCallback(\n async (loadChatUid: string) => {\n if (!clientRef.current) {\n const err = new Error('API client not configured');\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n // Reset any active polling/handoff state from previous conversation\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n pendingWidgetCallsRef.current = [];\n setPendingWidgetCalls([]);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const history = await clientRef.current.getChatHistory(\n assistantId,\n loadChatUid,\n { tenantId: resolvedTenantId }\n );\n\n setMessages(history.chatContent);\n setChatUid(loadChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(loadChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n },\n [assistantId, resolvedTenantId, resumeFromRealtimeStatus]\n );\n\n // Handoff polling: while handedOff is true, poll the realtime endpoint every 5s\n // to detect when the parent thread is no longer in handed_off state.\n useEffect(() => {\n if (!handedOff || !chatUid || !clientRef.current) return;\n\n const pollHandoff = async () => {\n try {\n const realtime = await clientRef.current!.getRealtimeHistory(assistantId, chatUid!);\n logRef.current.log('[useDevicChat] Handoff poll - realtime status:', realtime.status);\n if (realtime.status !== 'handed_off') {\n // Handoff completed — clear handoff state and resume main polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n // Resume main polling to pick up the parent thread's continuation\n setShouldPoll(true);\n }\n } catch {}\n };\n\n handoffPollRef.current = setInterval(pollHandoff, 5000);\n return () => {\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n };\n }, [handedOff, chatUid, assistantId]);\n\n // Called by HandoffSubagentWidget when the subthread reaches a terminal state\n const onHandoffCompleted = useCallback(() => {\n logRef.current.log('[useDevicChat] onHandoffCompleted called');\n // Clear the handoff polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n // Clear handoff state and resume main polling\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n setShouldPoll(true);\n }, []);\n\n // Submit a response for a pending widget tool call\n const submitWidgetResponse = useCallback(\n async (toolCallId: string, response: any) => {\n const uid = chatUidRef.current;\n if (!clientRef.current || !uid) return;\n\n // Check pending widgets via ref (state updates are async)\n const current = pendingWidgetCallsRef.current;\n const found = current.some((c) => c.toolCall.id === toolCallId);\n if (!found) return;\n\n // Remove the widget call from pending list\n const remaining = current.filter((c) => c.toolCall.id !== toolCallId);\n pendingWidgetCallsRef.current = remaining;\n setPendingWidgetCalls(remaining);\n\n try {\n logRef.current.log('[useDevicChat] sending widget tool response', toolCallId);\n await clientRef.current.sendToolResponses(assistantId, uid, [\n { tool_call_id: toolCallId, content: response, role: 'tool' },\n ]);\n // Resume polling only if no more widget calls are blocking\n if (remaining.length === 0) {\n setShouldPoll(true);\n setIsLoading(true);\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logRef.current.error('[useDevicChat] submitWidgetResponse failed', error);\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [assistantId]\n );\n\n // Cancel a pending widget tool call (sends an error response to the model)\n const cancelWidgetCall = useCallback(\n async (toolCallId: string, reason?: string) => {\n await submitWidgetResponse(toolCallId, {\n error: reason || 'User cancelled the tool call',\n });\n },\n [submitWidgetResponse]\n );\n\n // Stop current conversation — calls the server-side stop endpoint\n // then stops polling and resets loading state.\n const stopChat = useCallback(async () => {\n const uid = chatUidRef.current;\n logRef.current.log('[useDevicChat] stopChat called, chatUid:', uid);\n if (clientRef.current && uid) {\n try {\n await clientRef.current.stopChat(assistantId, uid);\n logRef.current.log('[useDevicChat] stopChat API call succeeded');\n } catch (err) {\n logRef.current.warn('[useDevicChat] stopChat API call failed:', err);\n }\n }\n setShouldPoll(false);\n setIsLoading(false);\n setStatus('idle');\n }, [assistantId]);\n\n return {\n messages,\n chatUid,\n isLoading,\n status,\n error,\n limitExceeded,\n handedOff,\n handedOffSubThreadId,\n sendMessage,\n clearChat,\n loadChat,\n onHandoffCompleted,\n stopChat,\n pendingWidgetCalls,\n submitWidgetResponse,\n cancelWidgetCall,\n };\n}\n"],"names":["useOptionalDevicContext","useMemo","createLogger","useRef","useState","useEffect","DevicApiClient","useCallback","useModelInterface","usePolling","DevicApiError"],"mappings":"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"}