@devicai/ui 0.47.1 → 0.50.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.
- package/dist/cjs/api/assistantInfo.js.map +1 -1
- package/dist/cjs/api/client.js +56 -0
- package/dist/cjs/api/client.js.map +1 -1
- package/dist/cjs/api/types.js.map +1 -1
- package/dist/cjs/components/AICommandBar/AICommandBar.js.map +1 -1
- package/dist/cjs/components/AICommandBar/useAICommandBar.js.map +1 -1
- package/dist/cjs/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
- package/dist/cjs/components/AIElementWrapper/activeWrapperRegistry.js.map +1 -1
- package/dist/cjs/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
- package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
- package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +50 -4
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ConversationSelector.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ErrorBoundary.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js +2 -1
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/LimitBanner.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ReferenceChip.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ToolTimeline.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/UsageBar.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/pastedText.js.map +1 -1
- package/dist/cjs/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
- package/dist/cjs/components/Feedback/FeedbackModal.js.map +1 -1
- package/dist/cjs/components/Feedback/MessageActions.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationLogo.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js +22 -10
- package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsModal.js +36 -5
- package/dist/cjs/components/IntegrationsModal/IntegrationsModal.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js +43 -18
- package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/McpConnectForm.js +79 -0
- package/dist/cjs/components/IntegrationsModal/McpConnectForm.js.map +1 -0
- package/dist/cjs/components/IntegrationsModal/McpServersSection.js +234 -0
- package/dist/cjs/components/IntegrationsModal/McpServersSection.js.map +1 -0
- package/dist/cjs/components/IntegrationsModal/useIntegrations.js.map +1 -1
- package/dist/cjs/components/IntegrationsModal/useTenantMcp.js +107 -0
- package/dist/cjs/components/IntegrationsModal/useTenantMcp.js.map +1 -0
- package/dist/cjs/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
- package/dist/cjs/components/theme.js.map +1 -1
- package/dist/cjs/hooks/useDevicChat.js.map +1 -1
- package/dist/cjs/hooks/useModelInterface.js.map +1 -1
- package/dist/cjs/hooks/usePolling.js.map +1 -1
- package/dist/cjs/hooks/useSpeechRecording.js.map +1 -1
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/provider/DevicContext.js.map +1 -1
- package/dist/cjs/provider/DevicProvider.js.map +1 -1
- package/dist/cjs/provider/sharedSession.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/cjs/utils/avatar.js +60 -0
- package/dist/cjs/utils/avatar.js.map +1 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/logger.js.map +1 -1
- package/dist/cjs/utils/toolGroups.js.map +1 -1
- package/dist/esm/api/assistantInfo.js.map +1 -1
- package/dist/esm/api/client.d.ts +41 -1
- package/dist/esm/api/client.js +56 -0
- package/dist/esm/api/client.js.map +1 -1
- package/dist/esm/api/types.d.ts +103 -0
- package/dist/esm/api/types.js.map +1 -1
- package/dist/esm/components/AICommandBar/AICommandBar.js.map +1 -1
- package/dist/esm/components/AICommandBar/useAICommandBar.js.map +1 -1
- package/dist/esm/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
- package/dist/esm/components/AIElementWrapper/activeWrapperRegistry.js.map +1 -1
- package/dist/esm/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +50 -4
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ConversationSelector.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ErrorBoundary.js.map +1 -1
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js +2 -1
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/esm/components/ChatDrawer/LimitBanner.js.map +1 -1
- package/dist/esm/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ReferenceChip.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ToolTimeline.js.map +1 -1
- package/dist/esm/components/ChatDrawer/UsageBar.js.map +1 -1
- package/dist/esm/components/ChatDrawer/pastedText.js.map +1 -1
- package/dist/esm/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
- package/dist/esm/components/Feedback/FeedbackModal.js.map +1 -1
- package/dist/esm/components/Feedback/MessageActions.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationLogo.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.d.ts +17 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js +22 -10
- package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsModal.d.ts +8 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsModal.js +36 -5
- package/dist/esm/components/IntegrationsModal/IntegrationsModal.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.d.ts +22 -3
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js +44 -19
- package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/McpConnectForm.d.ts +42 -0
- package/dist/esm/components/IntegrationsModal/McpConnectForm.js +77 -0
- package/dist/esm/components/IntegrationsModal/McpConnectForm.js.map +1 -0
- package/dist/esm/components/IntegrationsModal/McpServersSection.d.ts +25 -0
- package/dist/esm/components/IntegrationsModal/McpServersSection.js +232 -0
- package/dist/esm/components/IntegrationsModal/McpServersSection.js.map +1 -0
- package/dist/esm/components/IntegrationsModal/index.d.ts +6 -0
- package/dist/esm/components/IntegrationsModal/useIntegrations.js.map +1 -1
- package/dist/esm/components/IntegrationsModal/useTenantMcp.d.ts +40 -0
- package/dist/esm/components/IntegrationsModal/useTenantMcp.js +105 -0
- package/dist/esm/components/IntegrationsModal/useTenantMcp.js.map +1 -0
- package/dist/esm/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
- package/dist/esm/components/theme.js.map +1 -1
- package/dist/esm/hooks/useDevicChat.js.map +1 -1
- package/dist/esm/hooks/useModelInterface.js.map +1 -1
- package/dist/esm/hooks/usePolling.js.map +1 -1
- package/dist/esm/hooks/useSpeechRecording.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/provider/DevicContext.js.map +1 -1
- package/dist/esm/provider/DevicProvider.js.map +1 -1
- package/dist/esm/provider/sharedSession.js.map +1 -1
- package/dist/esm/styles.css +1 -1
- package/dist/esm/utils/avatar.d.ts +18 -0
- package/dist/esm/utils/avatar.js +58 -0
- package/dist/esm/utils/avatar.js.map +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/logger.js.map +1 -1
- package/dist/esm/utils/toolGroups.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessages.js","sources":["../../../../../src/components/ChatDrawer/ChatMessages.tsx"],"sourcesContent":["import React, { useState, useEffect, useMemo, useRef } from \"react\";\nimport { useOptionalDevicContext } from \"../../provider\";\nimport Markdown from \"markdown-to-jsx\";\nimport { MessageActions } from \"../Feedback\";\nimport { HandoffSubagentWidget } from \"./HandoffSubagentWidget\";\nimport { ReferenceChip } from \"./ReferenceChip\";\nimport { RecalledMemoriesWidget } from \"./RecalledMemoriesWidget\";\nimport type { ChatMessagesProps, SuggestedMessage } from \"./ChatDrawer.types\";\nimport type { ChatMessage, RecalledMemoryRecord, 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// Backend finalizer tool for assistants configured with \"Require Tool Use to\n// Finish\". It carries the final answer in its `message` argument, which the\n// backend copies to content.message, so it renders as a plain assistant bubble\n// instead of a tool activity line. Agents have a same-named tool with a\n// different shape, but their timeline does not go through this component.\nconst FINISH_EXECUTION_TOOL = \"finish_execution\";\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 devicContext = useOptionalDevicContext();\n const getTenantSession = devicContext?.getTenantSession;\n const onSessionExpired = devicContext?.onSessionExpired;\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 && !getTenantSession) {\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 getTenantSession,\n onSessionExpired,\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 // `finish_execution` is not an action the assistant took, it is how the\n // backend delivers the final answer when the assistant is configured with\n // \"Require Tool Use to Finish\": the tool's `message` argument is copied to\n // content.message and rendered as the assistant bubble below. Showing it as\n // a tool activity line would just duplicate that bubble with plumbing.\n const visibleToolCalls = (msg.tool_calls || []).filter(\n (toolCall) => toolCall.function?.name !== FINISH_EXECUTION_TOOL,\n );\n const hasToolCalls = visibleToolCalls.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(\n visibleToolCalls.length === msg.tool_calls!.length\n ? msg\n : { ...msg, tool_calls: visibleToolCalls },\n );\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 pollingInterval,\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 pollingInterval?: number;\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 pollingInterval={pollingInterval}\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 pollingInterval,\n pendingInlineWidgets,\n onSubmitWidget,\n onCancelWidget,\n recalledMemories,\n recalledMemoriesRenderer,\n}: ChatMessagesProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const prevLengthRef = useRef(messages.length);\n\n // Anchor each recall record to the message that brought it in: the\n // assistant message carrying its memory tool call (toolCallId), or the\n // message the backend named (messageUid — matched against serverUid too,\n // since user messages may render under an adopted optimistic uid). Records\n // whose anchor is not on screen yet (the run is still producing it) go to\n // the pending group shown at the bottom while loading.\n const { recallsByAnchor, pendingRecalls } = useMemo(() => {\n const byAnchor = new Map<string, RecalledMemoryRecord[]>();\n const pending: RecalledMemoryRecord[] = [];\n for (const record of recalledMemories ?? []) {\n let anchor: string | undefined;\n if (record.toolCallId) {\n anchor = messages.find((m) =>\n m.tool_calls?.some((tc) => tc.id === record.toolCallId)\n )?.uid;\n }\n if (!anchor && record.messageUid) {\n anchor = messages.find(\n (m) =>\n m.uid === record.messageUid || m.serverUid === record.messageUid\n )?.uid;\n }\n if (anchor) {\n const list = byAnchor.get(anchor);\n if (list) list.push(record);\n else byAnchor.set(anchor, [record]);\n } else {\n pending.push(record);\n }\n }\n return { recallsByAnchor: byAnchor, pendingRecalls: pending };\n }, [recalledMemories, messages]);\n\n // The strip renders after the message (or tool group) that anchors it.\n const recallsFor = (uids: string[]): RecalledMemoryRecord[] =>\n uids.flatMap((uid) => recallsByAnchor.get(uid) ?? []);\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 const groupRecalls = recallsFor(\n item.toolMessages.map((m) => m.uid)\n );\n return (\n <React.Fragment key={`tg-${item.toolMessages[0].uid}`}>\n <ToolGroup\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 pollingInterval={pollingInterval}\n />\n {groupRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={groupRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\n />\n )}\n </React.Fragment>\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 const messageRecalls = recallsFor([message.uid]);\n\n return (\n <React.Fragment key={message.uid}>\n <div\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 {messageRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={messageRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\n />\n )}\n </React.Fragment>\n );\n })}\n\n {/* Recall events whose anchor message has not landed yet — shown while\n the run is in flight so the user sees what the assistant recalled\n before the first response arrives. */}\n {isLoading && pendingRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={pendingRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\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","useOptionalDevicContext","useState","useRef","useEffect","client","DevicApiClient","toolGroups","HandoffSubagentWidget","_Fragment","segmentToolCalls","useMemo","RecalledMemoriesWidget","parsePastedBlocks","ReferenceChip","normalizeMessageFile","MessageActions","pastedPreview","pastedLineCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatMessages.js","sources":["../../../../../src/components/ChatDrawer/ChatMessages.tsx"],"sourcesContent":["import React, { useState, useEffect, useMemo, useRef } from \"react\";\nimport { useOptionalDevicContext } from \"../../provider\";\nimport Markdown from \"markdown-to-jsx\";\nimport { MessageActions } from \"../Feedback\";\nimport { HandoffSubagentWidget } from \"./HandoffSubagentWidget\";\nimport { ReferenceChip } from \"./ReferenceChip\";\nimport { RecalledMemoriesWidget } from \"./RecalledMemoriesWidget\";\nimport type { ChatMessagesProps, SuggestedMessage } from \"./ChatDrawer.types\";\nimport type { ChatMessage, RecalledMemoryRecord, 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// Backend finalizer tool for assistants configured with \"Require Tool Use to\n// Finish\". It carries the final answer in its `message` argument, which the\n// backend copies to content.message, so it renders as a plain assistant bubble\n// instead of a tool activity line. Agents have a same-named tool with a\n// different shape, but their timeline does not go through this component.\nconst FINISH_EXECUTION_TOOL = \"finish_execution\";\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 devicContext = useOptionalDevicContext();\n const getTenantSession = devicContext?.getTenantSession;\n const onSessionExpired = devicContext?.onSessionExpired;\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 && !getTenantSession) {\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 getTenantSession,\n onSessionExpired,\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 // `finish_execution` is not an action the assistant took, it is how the\n // backend delivers the final answer when the assistant is configured with\n // \"Require Tool Use to Finish\": the tool's `message` argument is copied to\n // content.message and rendered as the assistant bubble below. Showing it as\n // a tool activity line would just duplicate that bubble with plumbing.\n const visibleToolCalls = (msg.tool_calls || []).filter(\n (toolCall) => toolCall.function?.name !== FINISH_EXECUTION_TOOL,\n );\n const hasToolCalls = visibleToolCalls.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(\n visibleToolCalls.length === msg.tool_calls!.length\n ? msg\n : { ...msg, tool_calls: visibleToolCalls },\n );\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 pollingInterval,\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 pollingInterval?: number;\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 pollingInterval={pollingInterval}\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 pollingInterval,\n pendingInlineWidgets,\n onSubmitWidget,\n onCancelWidget,\n recalledMemories,\n recalledMemoriesRenderer,\n}: ChatMessagesProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const prevLengthRef = useRef(messages.length);\n\n // Anchor each recall record to the message that brought it in: the\n // assistant message carrying its memory tool call (toolCallId), or the\n // message the backend named (messageUid — matched against serverUid too,\n // since user messages may render under an adopted optimistic uid). Records\n // whose anchor is not on screen yet (the run is still producing it) go to\n // the pending group shown at the bottom while loading.\n const { recallsByAnchor, pendingRecalls } = useMemo(() => {\n const byAnchor = new Map<string, RecalledMemoryRecord[]>();\n const pending: RecalledMemoryRecord[] = [];\n for (const record of recalledMemories ?? []) {\n let anchor: string | undefined;\n if (record.toolCallId) {\n anchor = messages.find((m) =>\n m.tool_calls?.some((tc) => tc.id === record.toolCallId)\n )?.uid;\n }\n if (!anchor && record.messageUid) {\n anchor = messages.find(\n (m) =>\n m.uid === record.messageUid || m.serverUid === record.messageUid\n )?.uid;\n }\n if (anchor) {\n const list = byAnchor.get(anchor);\n if (list) list.push(record);\n else byAnchor.set(anchor, [record]);\n } else {\n pending.push(record);\n }\n }\n return { recallsByAnchor: byAnchor, pendingRecalls: pending };\n }, [recalledMemories, messages]);\n\n // The strip renders after the message (or tool group) that anchors it.\n const recallsFor = (uids: string[]): RecalledMemoryRecord[] =>\n uids.flatMap((uid) => recallsByAnchor.get(uid) ?? []);\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 const groupRecalls = recallsFor(\n item.toolMessages.map((m) => m.uid)\n );\n return (\n <React.Fragment key={`tg-${item.toolMessages[0].uid}`}>\n <ToolGroup\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 pollingInterval={pollingInterval}\n />\n {groupRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={groupRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\n />\n )}\n </React.Fragment>\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 const messageRecalls = recallsFor([message.uid]);\n\n return (\n <React.Fragment key={message.uid}>\n <div\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 {messageRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={messageRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\n />\n )}\n </React.Fragment>\n );\n })}\n\n {/* Recall events whose anchor message has not landed yet — shown while\n the run is in flight so the user sees what the assistant recalled\n before the first response arrives. */}\n {isLoading && pendingRecalls.length > 0 && (\n <RecalledMemoriesWidget\n records={pendingRecalls}\n isLoading={isLoading}\n renderer={recalledMemoriesRenderer}\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","useOptionalDevicContext","useState","useRef","useEffect","client","DevicApiClient","toolGroups","HandoffSubagentWidget","_Fragment","segmentToolCalls","useMemo","RecalledMemoriesWidget","parsePastedBlocks","ReferenceChip","normalizeMessageFile","MessageActions","pastedPreview","pastedLineCount"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationSelector.js","sources":["../../../../../src/components/ChatDrawer/ConversationSelector.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport type { ConversationSummary } from '../../api/types';\nimport type { ConversationSelectorProps } from './ChatDrawer.types';\n\nconst PAGE_SIZE = 10;\n\nexport function ConversationSelector({\n assistantId,\n currentChatUid,\n onSelect,\n onNewChat,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId: propsTenantId,\n subtenantId: propsSubtenantId,\n conversationPreview,\n}: ConversationSelectorProps): JSX.Element {\n const context = useOptionalDevicContext();\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const tenantId = propsTenantId || context?.tenantId;\n const subtenantId = propsSubtenantId || context?.subtenantId;\n\n const [isOpen, setIsOpen] = useState(false);\n const [conversations, setConversations] = useState<ConversationSummary[]>([]);\n const [search, setSearch] = useState('');\n const [loading, setLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [firstMessages, setFirstMessages] = useState<Record<string, string | null>>({});\n const fetchedChatsRef = useRef<Set<string>>(new Set());\n const dropdownRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const clientRef = useRef<DevicApiClient | null>(null);\n const getTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n\n if (!clientRef.current && (apiKey || getTenantSession)) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n }\n\n // Update client config when props/context change\n useEffect(() => {\n if (clientRef.current) {\n clientRef.current.setConfig({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n } else if (apiKey || getTenantSession) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n }\n }, [apiKey, baseUrl, getTenantSession]);\n\n const fetchConversations = useCallback(async (offset = 0, append = false) => {\n if (!clientRef.current) return;\n if (offset === 0) {\n setLoading(true);\n } else {\n setLoadingMore(true);\n }\n try {\n const response = await clientRef.current.listConversations(assistantId, {\n tenantId,\n subtenantId,\n offset,\n limit: PAGE_SIZE,\n });\n setConversations((prev) => append ? [...prev, ...response.histories] : response.histories);\n setHasMore(offset + response.histories.length < response.total);\n } catch {\n // silently fail\n } finally {\n setLoading(false);\n setLoadingMore(false);\n }\n }, [assistantId, tenantId, subtenantId]);\n\n useEffect(() => {\n if (isOpen) {\n fetchConversations(0);\n }\n }, [isOpen, fetchConversations]);\n\n // Fetch conversations when currentChatUid changes so the selector label is correct\n useEffect(() => {\n if (currentChatUid && conversations.length === 0) {\n fetchConversations(0);\n }\n }, [currentChatUid, conversations.length, fetchConversations]);\n\n const handleLoadMore = useCallback(() => {\n if (!loadingMore && hasMore) {\n fetchConversations(conversations.length, true);\n }\n }, [loadingMore, hasMore, conversations.length, fetchConversations]);\n\n // Lazy-fetch first user message for unnamed conversations\n useEffect(() => {\n if (conversationPreview !== 'firstMessage' || !clientRef.current || !isOpen) return;\n const unnamed = conversations.filter((c) => !c.name && !fetchedChatsRef.current.has(c.chatUID));\n if (unnamed.length === 0) return;\n\n // Mark as loading (null = loading)\n unnamed.forEach((c) => fetchedChatsRef.current.add(c.chatUID));\n setFirstMessages((prev) => {\n const next = { ...prev };\n unnamed.forEach((c) => { next[c.chatUID] = null; });\n return next;\n });\n\n unnamed.forEach((conv) => {\n clientRef.current!.getChatHistory(assistantId, conv.chatUID, { tenantId }).then((history) => {\n const firstUserMsg = history.chatContent?.find((m) => m.role === 'user');\n const text = firstUserMsg?.content?.message || '';\n setFirstMessages((prev) => ({ ...prev, [conv.chatUID]: text || '' }));\n }).catch(() => {\n setFirstMessages((prev) => ({ ...prev, [conv.chatUID]: '' }));\n });\n });\n }, [conversations, isOpen, conversationPreview, assistantId, tenantId]);\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return;\n const handler = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [isOpen]);\n\n const getConversationLabel = (conv: ConversationSummary): string => {\n if (conv.name) return conv.name;\n if (conversationPreview === 'firstMessage') {\n const msg = firstMessages[conv.chatUID];\n if (msg === null) return '...';\n if (msg) return msg;\n }\n return formatDate(conv.creationTimestampMs);\n };\n\n const currentConv = conversations.find((c) => c.chatUID === currentChatUid);\n const currentName = currentConv\n ? getConversationLabel(currentConv)\n : 'New chat';\n\n const filtered = conversations.filter((c) => {\n if (!search) return true;\n const q = search.toLowerCase();\n if ((c.name || '').toLowerCase().includes(q)) return true;\n if (conversationPreview === 'firstMessage') {\n const msg = firstMessages[c.chatUID];\n if (msg && msg.toLowerCase().includes(q)) return true;\n }\n return false;\n });\n\n return (\n <div className=\"devic-conversation-selector\" ref={dropdownRef}>\n <button\n className=\"devic-conversation-selector-trigger\"\n onClick={() => setIsOpen(!isOpen)}\n type=\"button\"\n >\n <span className=\"devic-conversation-selector-label\">{currentName}</span>\n <ChevronIcon open={isOpen} />\n </button>\n\n {isOpen && (\n <div className=\"devic-conversation-dropdown\">\n <div className=\"devic-conversation-search-wrapper\">\n <input\n className=\"devic-conversation-search\"\n type=\"text\"\n placeholder=\"Search conversations...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n />\n </div>\n\n <div\n className=\"devic-conversation-list\"\n ref={listRef}\n >\n {loading && (\n <div className=\"devic-conversation-loading\">Loading...</div>\n )}\n {!loading && filtered.length === 0 && (\n <div className=\"devic-conversation-empty\">No conversations</div>\n )}\n {!loading &&\n filtered.map((conv) => (\n <button\n key={conv.chatUID}\n className=\"devic-conversation-item\"\n data-active={conv.chatUID === currentChatUid}\n type=\"button\"\n onClick={() => {\n onSelect(conv.chatUID);\n setIsOpen(false);\n }}\n >\n {conv.chatUID === currentChatUid && (\n <span className=\"devic-conversation-item-check\">\n <CheckIcon />\n </span>\n )}\n <span className=\"devic-conversation-item-name\">\n {getConversationLabel(conv)}\n </span>\n <span className=\"devic-conversation-item-date\">\n {formatDate(conv.lastEditTimestampMs || conv.creationTimestampMs)}\n </span>\n </button>\n ))}\n {loadingMore && (\n <div className=\"devic-conversation-loading\">Loading more...</div>\n )}\n {!loadingMore && hasMore && !loading && (\n <button\n className=\"devic-conversation-load-more\"\n type=\"button\"\n onClick={handleLoadMore}\n >\n Load more\n </button>\n )}\n </div>\n\n <button\n className=\"devic-conversation-new\"\n type=\"button\"\n onClick={() => {\n onNewChat();\n setIsOpen(false);\n }}\n >\n + Start a new chat\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction ChevronIcon({ open }: { open: boolean }): 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 style={{ transform: open ? 'rotate(180deg)' : undefined, transition: '0.2s' }}\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\nfunction CheckIcon(): JSX.Element {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n );\n}\n\nfunction formatDate(ms: number): string {\n const d = new Date(ms);\n const now = new Date();\n if (d.toDateString() === now.toDateString()) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n }\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });\n}\n"],"names":["useOptionalDevicContext","useState","useRef","DevicApiClient","useEffect","useCallback","_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConversationSelector.js","sources":["../../../../../src/components/ChatDrawer/ConversationSelector.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport type { ConversationSummary } from '../../api/types';\nimport type { ConversationSelectorProps } from './ChatDrawer.types';\n\nconst PAGE_SIZE = 10;\n\nexport function ConversationSelector({\n assistantId,\n currentChatUid,\n onSelect,\n onNewChat,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId: propsTenantId,\n subtenantId: propsSubtenantId,\n conversationPreview,\n}: ConversationSelectorProps): JSX.Element {\n const context = useOptionalDevicContext();\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const tenantId = propsTenantId || context?.tenantId;\n const subtenantId = propsSubtenantId || context?.subtenantId;\n\n const [isOpen, setIsOpen] = useState(false);\n const [conversations, setConversations] = useState<ConversationSummary[]>([]);\n const [search, setSearch] = useState('');\n const [loading, setLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [firstMessages, setFirstMessages] = useState<Record<string, string | null>>({});\n const fetchedChatsRef = useRef<Set<string>>(new Set());\n const dropdownRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const clientRef = useRef<DevicApiClient | null>(null);\n const getTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n\n if (!clientRef.current && (apiKey || getTenantSession)) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n }\n\n // Update client config when props/context change\n useEffect(() => {\n if (clientRef.current) {\n clientRef.current.setConfig({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n } else if (apiKey || getTenantSession) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl, getTenantSession, onSessionExpired });\n }\n }, [apiKey, baseUrl, getTenantSession]);\n\n const fetchConversations = useCallback(async (offset = 0, append = false) => {\n if (!clientRef.current) return;\n if (offset === 0) {\n setLoading(true);\n } else {\n setLoadingMore(true);\n }\n try {\n const response = await clientRef.current.listConversations(assistantId, {\n tenantId,\n subtenantId,\n offset,\n limit: PAGE_SIZE,\n });\n setConversations((prev) => append ? [...prev, ...response.histories] : response.histories);\n setHasMore(offset + response.histories.length < response.total);\n } catch {\n // silently fail\n } finally {\n setLoading(false);\n setLoadingMore(false);\n }\n }, [assistantId, tenantId, subtenantId]);\n\n useEffect(() => {\n if (isOpen) {\n fetchConversations(0);\n }\n }, [isOpen, fetchConversations]);\n\n // Fetch conversations when currentChatUid changes so the selector label is correct\n useEffect(() => {\n if (currentChatUid && conversations.length === 0) {\n fetchConversations(0);\n }\n }, [currentChatUid, conversations.length, fetchConversations]);\n\n const handleLoadMore = useCallback(() => {\n if (!loadingMore && hasMore) {\n fetchConversations(conversations.length, true);\n }\n }, [loadingMore, hasMore, conversations.length, fetchConversations]);\n\n // Lazy-fetch first user message for unnamed conversations\n useEffect(() => {\n if (conversationPreview !== 'firstMessage' || !clientRef.current || !isOpen) return;\n const unnamed = conversations.filter((c) => !c.name && !fetchedChatsRef.current.has(c.chatUID));\n if (unnamed.length === 0) return;\n\n // Mark as loading (null = loading)\n unnamed.forEach((c) => fetchedChatsRef.current.add(c.chatUID));\n setFirstMessages((prev) => {\n const next = { ...prev };\n unnamed.forEach((c) => { next[c.chatUID] = null; });\n return next;\n });\n\n unnamed.forEach((conv) => {\n clientRef.current!.getChatHistory(assistantId, conv.chatUID, { tenantId }).then((history) => {\n const firstUserMsg = history.chatContent?.find((m) => m.role === 'user');\n const text = firstUserMsg?.content?.message || '';\n setFirstMessages((prev) => ({ ...prev, [conv.chatUID]: text || '' }));\n }).catch(() => {\n setFirstMessages((prev) => ({ ...prev, [conv.chatUID]: '' }));\n });\n });\n }, [conversations, isOpen, conversationPreview, assistantId, tenantId]);\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return;\n const handler = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [isOpen]);\n\n const getConversationLabel = (conv: ConversationSummary): string => {\n if (conv.name) return conv.name;\n if (conversationPreview === 'firstMessage') {\n const msg = firstMessages[conv.chatUID];\n if (msg === null) return '...';\n if (msg) return msg;\n }\n return formatDate(conv.creationTimestampMs);\n };\n\n const currentConv = conversations.find((c) => c.chatUID === currentChatUid);\n const currentName = currentConv\n ? getConversationLabel(currentConv)\n : 'New chat';\n\n const filtered = conversations.filter((c) => {\n if (!search) return true;\n const q = search.toLowerCase();\n if ((c.name || '').toLowerCase().includes(q)) return true;\n if (conversationPreview === 'firstMessage') {\n const msg = firstMessages[c.chatUID];\n if (msg && msg.toLowerCase().includes(q)) return true;\n }\n return false;\n });\n\n return (\n <div className=\"devic-conversation-selector\" ref={dropdownRef}>\n <button\n className=\"devic-conversation-selector-trigger\"\n onClick={() => setIsOpen(!isOpen)}\n type=\"button\"\n >\n <span className=\"devic-conversation-selector-label\">{currentName}</span>\n <ChevronIcon open={isOpen} />\n </button>\n\n {isOpen && (\n <div className=\"devic-conversation-dropdown\">\n <div className=\"devic-conversation-search-wrapper\">\n <input\n className=\"devic-conversation-search\"\n type=\"text\"\n placeholder=\"Search conversations...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n />\n </div>\n\n <div\n className=\"devic-conversation-list\"\n ref={listRef}\n >\n {loading && (\n <div className=\"devic-conversation-loading\">Loading...</div>\n )}\n {!loading && filtered.length === 0 && (\n <div className=\"devic-conversation-empty\">No conversations</div>\n )}\n {!loading &&\n filtered.map((conv) => (\n <button\n key={conv.chatUID}\n className=\"devic-conversation-item\"\n data-active={conv.chatUID === currentChatUid}\n type=\"button\"\n onClick={() => {\n onSelect(conv.chatUID);\n setIsOpen(false);\n }}\n >\n {conv.chatUID === currentChatUid && (\n <span className=\"devic-conversation-item-check\">\n <CheckIcon />\n </span>\n )}\n <span className=\"devic-conversation-item-name\">\n {getConversationLabel(conv)}\n </span>\n <span className=\"devic-conversation-item-date\">\n {formatDate(conv.lastEditTimestampMs || conv.creationTimestampMs)}\n </span>\n </button>\n ))}\n {loadingMore && (\n <div className=\"devic-conversation-loading\">Loading more...</div>\n )}\n {!loadingMore && hasMore && !loading && (\n <button\n className=\"devic-conversation-load-more\"\n type=\"button\"\n onClick={handleLoadMore}\n >\n Load more\n </button>\n )}\n </div>\n\n <button\n className=\"devic-conversation-new\"\n type=\"button\"\n onClick={() => {\n onNewChat();\n setIsOpen(false);\n }}\n >\n + Start a new chat\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction ChevronIcon({ open }: { open: boolean }): 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 style={{ transform: open ? 'rotate(180deg)' : undefined, transition: '0.2s' }}\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\nfunction CheckIcon(): JSX.Element {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n );\n}\n\nfunction formatDate(ms: number): string {\n const d = new Date(ms);\n const now = new Date();\n if (d.toDateString() === now.toDateString()) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n }\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });\n}\n"],"names":["useOptionalDevicContext","useState","useRef","DevicApiClient","useEffect","useCallback","_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundary.js","sources":["../../../../../src/components/ChatDrawer/ErrorBoundary.tsx"],"sourcesContent":["import React, { Component } from 'react';\nimport type { ReactNode, ErrorInfo } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n}\n\nexport class ChatDrawerErrorBoundary extends Component<Props, State> {\n state: State = { hasError: false };\n\n static getDerivedStateFromError(): State {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n console.error('[devic-ui] ChatDrawer error:', error, info.componentStack);\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n return this.props.fallback ?? null;\n }\n return this.props.children;\n }\n}\n"],"names":["Component"],"mappings":";;;;AAYM,MAAO,uBAAwB,SAAQA,eAAuB,CAAA;AAApE,IAAA,WAAA,GAAA;;AACE,QAAA,IAAA,CAAA,KAAK,GAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;IAgBpC;AAdE,IAAA,OAAO,wBAAwB,GAAA;AAC7B,QAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3B;IAEA,iBAAiB,CAAC,KAAY,EAAE,IAAe,EAAA;QAC7C,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC;IAC3E;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI;QACpC;AACA,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ;IAC5B;AACD
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.js","sources":["../../../../../src/components/ChatDrawer/ErrorBoundary.tsx"],"sourcesContent":["import React, { Component } from 'react';\nimport type { ReactNode, ErrorInfo } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n}\n\nexport class ChatDrawerErrorBoundary extends Component<Props, State> {\n state: State = { hasError: false };\n\n static getDerivedStateFromError(): State {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n console.error('[devic-ui] ChatDrawer error:', error, info.componentStack);\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n return this.props.fallback ?? null;\n }\n return this.props.children;\n }\n}\n"],"names":["Component"],"mappings":";;;;AAYM,MAAO,uBAAwB,SAAQA,eAAuB,CAAA;AAApE,IAAA,WAAA,GAAA;;AACE,QAAA,IAAA,CAAA,KAAK,GAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;IAgBpC;AAdE,IAAA,OAAO,wBAAwB,GAAA;AAC7B,QAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3B;IAEA,iBAAiB,CAAC,KAAY,EAAE,IAAe,EAAA;QAC7C,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC;IAC3E;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI;QACpC;AACA,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ;IAC5B;AACD;;"}
|
|
@@ -8,6 +8,7 @@ var logger = require('../../utils/logger.js');
|
|
|
8
8
|
var types = require('../../api/types.js');
|
|
9
9
|
var ThreadStateTag = require('../ThreadStateTag/ThreadStateTag.js');
|
|
10
10
|
var usePolling = require('../../hooks/usePolling.js');
|
|
11
|
+
var avatar = require('../../utils/avatar.js');
|
|
11
12
|
|
|
12
13
|
const TERMINAL_STATES = [
|
|
13
14
|
types.AgentThreadState.COMPLETED,
|
|
@@ -143,7 +144,7 @@ function HandoffSubagentWidget({ subThreadId, onCompleted, apiKey, baseUrl, poll
|
|
|
143
144
|
if (renderWidget) {
|
|
144
145
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderWidget({ thread, agent, elapsedSeconds, isTerminal }) });
|
|
145
146
|
}
|
|
146
|
-
return (jsxRuntime.jsxs("div", { className: "devic-handoff-widget", children: [jsxRuntime.jsxs("div", { className: "devic-handoff-header", children: [jsxRuntime.jsx("div", { className: "devic-handoff-agent-avatar", children: agent?.imgUrl ? (jsxRuntime.jsx("img", { src: agent.imgUrl, alt: "", className: "devic-handoff-avatar-img" })) : (jsxRuntime.jsx(RobotFallbackIcon, {})) }), jsxRuntime.jsx("span", { className: "devic-handoff-agent-name", children: agent?.name || thread?.name || 'Subagent' })] }), thread?.state && (jsxRuntime.jsx("div", { className: "devic-handoff-state-row", children: jsxRuntime.jsx(ThreadStateTag.ThreadStateTag, { state: thread.state, threadId: thread._id || subThreadId, agentName: agent?.name || thread?.name || 'Subagent', pausedReason: thread.pausedReason, finishReason: thread.finishReason, pauseUntil: thread.pauseUntil, interactive: true, apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl }) })), totalTasks > 0 && (jsxRuntime.jsxs("div", { className: "devic-handoff-progress", children: [jsxRuntime.jsx("div", { className: "devic-handoff-progress-bar", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-fill", "data-status": thread?.state === types.AgentThreadState.FAILED ? 'error' : isTerminal ? 'success' : 'active', style: { width: `${taskPercentage}%` } }) }), jsxRuntime.jsxs("span", { className: "devic-handoff-progress-text", children: [completedTasks, "/", totalTasks] })] })), totalTasks === 0 && isProcessing && (jsxRuntime.jsx("div", { className: "devic-handoff-progress", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-bar", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-indeterminate" }) }) })), lastSummary && (jsxRuntime.jsx("div", { className: `devic-handoff-summary ${isProcessing ? 'devic-handoff-summary-active' : ''}`, children: lastSummary })), isProcessing && (jsxRuntime.jsxs("div", { className: "devic-handoff-elapsed", children: [jsxRuntime.jsx(ClockSmallIcon, {}), jsxRuntime.jsx("span", { children: formatElapsed(elapsedSeconds) })] }))] }));
|
|
147
|
+
return (jsxRuntime.jsxs("div", { className: "devic-handoff-widget", children: [jsxRuntime.jsxs("div", { className: "devic-handoff-header", children: [jsxRuntime.jsx("div", { className: "devic-handoff-agent-avatar", children: agent?.imgUrl || agent?._id ? (jsxRuntime.jsx("img", { src: agent.imgUrl || avatar.avatarUri(agent._id, agent.avatarStyle), alt: "", className: "devic-handoff-avatar-img" })) : (jsxRuntime.jsx(RobotFallbackIcon, {})) }), jsxRuntime.jsx("span", { className: "devic-handoff-agent-name", children: agent?.name || thread?.name || 'Subagent' })] }), thread?.state && (jsxRuntime.jsx("div", { className: "devic-handoff-state-row", children: jsxRuntime.jsx(ThreadStateTag.ThreadStateTag, { state: thread.state, threadId: thread._id || subThreadId, agentName: agent?.name || thread?.name || 'Subagent', pausedReason: thread.pausedReason, finishReason: thread.finishReason, pauseUntil: thread.pauseUntil, interactive: true, apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl }) })), totalTasks > 0 && (jsxRuntime.jsxs("div", { className: "devic-handoff-progress", children: [jsxRuntime.jsx("div", { className: "devic-handoff-progress-bar", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-fill", "data-status": thread?.state === types.AgentThreadState.FAILED ? 'error' : isTerminal ? 'success' : 'active', style: { width: `${taskPercentage}%` } }) }), jsxRuntime.jsxs("span", { className: "devic-handoff-progress-text", children: [completedTasks, "/", totalTasks] })] })), totalTasks === 0 && isProcessing && (jsxRuntime.jsx("div", { className: "devic-handoff-progress", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-bar", children: jsxRuntime.jsx("div", { className: "devic-handoff-progress-indeterminate" }) }) })), lastSummary && (jsxRuntime.jsx("div", { className: `devic-handoff-summary ${isProcessing ? 'devic-handoff-summary-active' : ''}`, children: lastSummary })), isProcessing && (jsxRuntime.jsxs("div", { className: "devic-handoff-elapsed", children: [jsxRuntime.jsx(ClockSmallIcon, {}), jsxRuntime.jsx("span", { children: formatElapsed(elapsedSeconds) })] }))] }));
|
|
147
148
|
}
|
|
148
149
|
/* ── Icons ── */
|
|
149
150
|
function RobotFallbackIcon() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandoffSubagentWidget.js","sources":["../../../../../src/components/ChatDrawer/HandoffSubagentWidget.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { AgentThreadState } from '../../api/types';\nimport type { AgentThreadDto, AgentDto } from '../../api/types';\nimport { ThreadStateTag } from '../ThreadStateTag';\nimport { resolvePollingInterval } from '../../hooks/usePolling';\nimport { createLogger } from '../../utils/logger';\n\nconst TERMINAL_STATES: AgentThreadState[] = [\n AgentThreadState.COMPLETED,\n AgentThreadState.FAILED,\n AgentThreadState.TERMINATED,\n];\n\n/**\n * The subagent runs for as long as it runs, so watching it does not need the\n * main conversation's rhythm. A configured `pollingInterval` still wins.\n */\nconst DEFAULT_POLL_INTERVAL_MS = 5000;\n\nexport interface HandoffSubagentWidgetProps {\n /**\n * The subthread ID to monitor\n */\n subThreadId: string;\n\n /**\n * Called when the subthread reaches a terminal state\n */\n onCompleted?: () => void;\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 * How often (ms) the subthread is polled while it runs. Overrides the\n * DevicProvider's `pollingInterval`. Values below 250 ms are clamped.\n * @default 5000\n */\n pollingInterval?: number;\n\n /**\n * Custom renderer to replace the entire widget content.\n * Receives the thread and agent data.\n */\n renderWidget?: (props: {\n thread: AgentThreadDto | null;\n agent: AgentDto | null;\n elapsedSeconds: number;\n isTerminal: boolean;\n }) => React.ReactNode;\n}\n\nfunction formatElapsed(seconds: number): string {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return m > 0 ? `${m}m ${s}s` : `${s}s`;\n}\n\nexport function HandoffSubagentWidget({\n subThreadId,\n onCompleted,\n apiKey,\n baseUrl,\n pollingInterval,\n renderWidget,\n}: HandoffSubagentWidgetProps): JSX.Element {\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedPollInterval = resolvePollingInterval(\n pollingInterval,\n context?.pollingInterval,\n DEFAULT_POLL_INTERVAL_MS\n );\n const debug = context?.debug ?? false;\n const log = useMemo(() => createLogger(debug), [debug]);\n\n const [thread, setThread] = useState<AgentThreadDto | null>(null);\n const [agent, setAgent] = useState<AgentDto | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\n\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const hasCalledCompleted = useRef(false);\n const startTimeRef = useRef(Date.now());\n\n const resolvedTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n const getClient = useCallback((): DevicApiClient | null => {\n if (!resolvedApiKey && !resolvedTenantSession) return null;\n return new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n });\n }, [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]);\n\n const fetchThread = useCallback(async () => {\n const client = getClient();\n if (!client) return;\n\n try {\n const data = await client.getThreadById(subThreadId, true);\n log.log('[HandoffSubagentWidget] Thread loaded:', {\n id: data._id,\n agentId: data.agentId,\n parentAgentId: data.parentAgentId,\n name: data.name,\n state: data.state,\n });\n setThread(data);\n\n if (\n data.state &&\n TERMINAL_STATES.includes(data.state) &&\n !hasCalledCompleted.current\n ) {\n hasCalledCompleted.current = true;\n onCompleted?.();\n }\n } catch (err) {\n log.error('[HandoffSubagentWidget] Error fetching thread:', err);\n }\n }, [subThreadId, getClient, onCompleted]);\n\n // Initial fetch + polling\n useEffect(() => {\n fetchThread();\n pollRef.current = setInterval(fetchThread, resolvedPollInterval);\n return () => {\n if (pollRef.current) clearInterval(pollRef.current);\n };\n }, [fetchThread, resolvedPollInterval]);\n\n // Fetch agent details once we have a thread with an agent ID\n const agentIdToFetch = thread?.agentId || thread?.parentAgentId;\n useEffect(() => {\n if (!agentIdToFetch || agent) return;\n const client = getClient();\n if (!client) {\n log.warn('[HandoffSubagentWidget] No API client available (missing apiKey?)');\n return;\n }\n\n log.log('[HandoffSubagentWidget] Fetching agent details for:', agentIdToFetch);\n client.getAgentDetails(agentIdToFetch).then((data) => {\n log.log('[HandoffSubagentWidget] Agent details loaded:', data?.name);\n setAgent(data);\n }).catch((err) => {\n log.warn('[HandoffSubagentWidget] Could not fetch agent details:', err);\n });\n }, [agentIdToFetch, agent, getClient]);\n\n // Stop polling on terminal state\n useEffect(() => {\n if (thread?.state && TERMINAL_STATES.includes(thread.state)) {\n if (pollRef.current) {\n clearInterval(pollRef.current);\n pollRef.current = null;\n }\n }\n }, [thread?.state]);\n\n // Elapsed timer\n useEffect(() => {\n startTimeRef.current = Date.now();\n timerRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\n }, 1000);\n return () => {\n if (timerRef.current) clearInterval(timerRef.current);\n };\n }, []);\n\n // Stop timer on terminal\n useEffect(() => {\n if (thread?.state && TERMINAL_STATES.includes(thread.state)) {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n }\n }, [thread?.state]);\n\n // Computed\n const isTerminal = !!(thread?.state && TERMINAL_STATES.includes(thread.state));\n const isProcessing = thread?.state === AgentThreadState.PROCESSING || thread?.state === AgentThreadState.HANDED_OFF;\n const totalTasks = thread?.tasks?.length || 0;\n const completedTasks = thread?.tasks?.filter((t) => t.completed).length || 0;\n const taskPercentage = totalTasks ? Math.round((completedTasks / totalTasks) * 100) : 0;\n\n const lastMessage = thread?.threadContent?.[thread.threadContent.length - 1];\n const lastSummary = lastMessage?.summary;\n\n // Custom renderer\n if (renderWidget) {\n return <>{renderWidget({ thread, agent, elapsedSeconds, isTerminal })}</>;\n }\n\n return (\n <div className=\"devic-handoff-widget\">\n {/* Header: Agent avatar + name */}\n <div className=\"devic-handoff-header\">\n <div className=\"devic-handoff-agent-avatar\">\n {agent?.imgUrl ? (\n <img src={agent.imgUrl} alt=\"\" className=\"devic-handoff-avatar-img\" />\n ) : (\n <RobotFallbackIcon />\n )}\n </div>\n <span className=\"devic-handoff-agent-name\">\n {agent?.name || thread?.name || 'Subagent'}\n </span>\n </div>\n\n {/* State tag */}\n {thread?.state && (\n <div className=\"devic-handoff-state-row\">\n <ThreadStateTag\n state={thread.state}\n threadId={thread._id || subThreadId}\n agentName={agent?.name || thread?.name || 'Subagent'}\n pausedReason={thread.pausedReason}\n finishReason={thread.finishReason}\n pauseUntil={thread.pauseUntil}\n interactive={true}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n />\n </div>\n )}\n\n {/* Progress bar */}\n {totalTasks > 0 && (\n <div className=\"devic-handoff-progress\">\n <div className=\"devic-handoff-progress-bar\">\n <div\n className=\"devic-handoff-progress-fill\"\n data-status={thread?.state === AgentThreadState.FAILED ? 'error' : isTerminal ? 'success' : 'active'}\n style={{ width: `${taskPercentage}%` }}\n />\n </div>\n <span className=\"devic-handoff-progress-text\">\n {completedTasks}/{totalTasks}\n </span>\n </div>\n )}\n\n {/* Indeterminate progress when no tasks */}\n {totalTasks === 0 && isProcessing && (\n <div className=\"devic-handoff-progress\">\n <div className=\"devic-handoff-progress-bar\">\n <div className=\"devic-handoff-progress-indeterminate\" />\n </div>\n </div>\n )}\n\n {/* Last message summary */}\n {lastSummary && (\n <div className={`devic-handoff-summary ${isProcessing ? 'devic-handoff-summary-active' : ''}`}>\n {lastSummary}\n </div>\n )}\n\n {/* Elapsed time */}\n {isProcessing && (\n <div className=\"devic-handoff-elapsed\">\n <ClockSmallIcon />\n <span>{formatElapsed(elapsedSeconds)}</span>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Icons ── */\n\nfunction RobotFallbackIcon(): JSX.Element {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"#999\">\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <circle cx=\"9\" cy=\"14\" r=\"2\" fill=\"#fff\" />\n <circle cx=\"15\" cy=\"14\" r=\"2\" fill=\"#fff\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"8\" stroke=\"#999\" strokeWidth=\"2\" />\n <circle cx=\"12\" cy=\"2\" r=\"1.5\" />\n </svg>\n );\n}\n\nfunction ClockSmallIcon(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12,6 12,12 16,14\" />\n </svg>\n );\n}\n"],"names":["AgentThreadState","useOptionalDevicContext","resolvePollingInterval","useMemo","createLogger","useState","useRef","useCallback","DevicApiClient","useEffect","_jsx","_Fragment","_jsxs","ThreadStateTag"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HandoffSubagentWidget.js","sources":["../../../../../src/components/ChatDrawer/HandoffSubagentWidget.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { AgentThreadState } from '../../api/types';\nimport type { AgentThreadDto, AgentDto } from '../../api/types';\nimport { ThreadStateTag } from '../ThreadStateTag';\nimport { resolvePollingInterval } from '../../hooks/usePolling';\nimport { createLogger } from '../../utils/logger';\nimport { avatarUri } from '../../utils/avatar';\n\nconst TERMINAL_STATES: AgentThreadState[] = [\n AgentThreadState.COMPLETED,\n AgentThreadState.FAILED,\n AgentThreadState.TERMINATED,\n];\n\n/**\n * The subagent runs for as long as it runs, so watching it does not need the\n * main conversation's rhythm. A configured `pollingInterval` still wins.\n */\nconst DEFAULT_POLL_INTERVAL_MS = 5000;\n\nexport interface HandoffSubagentWidgetProps {\n /**\n * The subthread ID to monitor\n */\n subThreadId: string;\n\n /**\n * Called when the subthread reaches a terminal state\n */\n onCompleted?: () => void;\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 * How often (ms) the subthread is polled while it runs. Overrides the\n * DevicProvider's `pollingInterval`. Values below 250 ms are clamped.\n * @default 5000\n */\n pollingInterval?: number;\n\n /**\n * Custom renderer to replace the entire widget content.\n * Receives the thread and agent data.\n */\n renderWidget?: (props: {\n thread: AgentThreadDto | null;\n agent: AgentDto | null;\n elapsedSeconds: number;\n isTerminal: boolean;\n }) => React.ReactNode;\n}\n\nfunction formatElapsed(seconds: number): string {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return m > 0 ? `${m}m ${s}s` : `${s}s`;\n}\n\nexport function HandoffSubagentWidget({\n subThreadId,\n onCompleted,\n apiKey,\n baseUrl,\n pollingInterval,\n renderWidget,\n}: HandoffSubagentWidgetProps): JSX.Element {\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedPollInterval = resolvePollingInterval(\n pollingInterval,\n context?.pollingInterval,\n DEFAULT_POLL_INTERVAL_MS\n );\n const debug = context?.debug ?? false;\n const log = useMemo(() => createLogger(debug), [debug]);\n\n const [thread, setThread] = useState<AgentThreadDto | null>(null);\n const [agent, setAgent] = useState<AgentDto | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\n\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const hasCalledCompleted = useRef(false);\n const startTimeRef = useRef(Date.now());\n\n const resolvedTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n const getClient = useCallback((): DevicApiClient | null => {\n if (!resolvedApiKey && !resolvedTenantSession) return null;\n return new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n });\n }, [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]);\n\n const fetchThread = useCallback(async () => {\n const client = getClient();\n if (!client) return;\n\n try {\n const data = await client.getThreadById(subThreadId, true);\n log.log('[HandoffSubagentWidget] Thread loaded:', {\n id: data._id,\n agentId: data.agentId,\n parentAgentId: data.parentAgentId,\n name: data.name,\n state: data.state,\n });\n setThread(data);\n\n if (\n data.state &&\n TERMINAL_STATES.includes(data.state) &&\n !hasCalledCompleted.current\n ) {\n hasCalledCompleted.current = true;\n onCompleted?.();\n }\n } catch (err) {\n log.error('[HandoffSubagentWidget] Error fetching thread:', err);\n }\n }, [subThreadId, getClient, onCompleted]);\n\n // Initial fetch + polling\n useEffect(() => {\n fetchThread();\n pollRef.current = setInterval(fetchThread, resolvedPollInterval);\n return () => {\n if (pollRef.current) clearInterval(pollRef.current);\n };\n }, [fetchThread, resolvedPollInterval]);\n\n // Fetch agent details once we have a thread with an agent ID\n const agentIdToFetch = thread?.agentId || thread?.parentAgentId;\n useEffect(() => {\n if (!agentIdToFetch || agent) return;\n const client = getClient();\n if (!client) {\n log.warn('[HandoffSubagentWidget] No API client available (missing apiKey?)');\n return;\n }\n\n log.log('[HandoffSubagentWidget] Fetching agent details for:', agentIdToFetch);\n client.getAgentDetails(agentIdToFetch).then((data) => {\n log.log('[HandoffSubagentWidget] Agent details loaded:', data?.name);\n setAgent(data);\n }).catch((err) => {\n log.warn('[HandoffSubagentWidget] Could not fetch agent details:', err);\n });\n }, [agentIdToFetch, agent, getClient]);\n\n // Stop polling on terminal state\n useEffect(() => {\n if (thread?.state && TERMINAL_STATES.includes(thread.state)) {\n if (pollRef.current) {\n clearInterval(pollRef.current);\n pollRef.current = null;\n }\n }\n }, [thread?.state]);\n\n // Elapsed timer\n useEffect(() => {\n startTimeRef.current = Date.now();\n timerRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\n }, 1000);\n return () => {\n if (timerRef.current) clearInterval(timerRef.current);\n };\n }, []);\n\n // Stop timer on terminal\n useEffect(() => {\n if (thread?.state && TERMINAL_STATES.includes(thread.state)) {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n }\n }, [thread?.state]);\n\n // Computed\n const isTerminal = !!(thread?.state && TERMINAL_STATES.includes(thread.state));\n const isProcessing = thread?.state === AgentThreadState.PROCESSING || thread?.state === AgentThreadState.HANDED_OFF;\n const totalTasks = thread?.tasks?.length || 0;\n const completedTasks = thread?.tasks?.filter((t) => t.completed).length || 0;\n const taskPercentage = totalTasks ? Math.round((completedTasks / totalTasks) * 100) : 0;\n\n const lastMessage = thread?.threadContent?.[thread.threadContent.length - 1];\n const lastSummary = lastMessage?.summary;\n\n // Custom renderer\n if (renderWidget) {\n return <>{renderWidget({ thread, agent, elapsedSeconds, isTerminal })}</>;\n }\n\n return (\n <div className=\"devic-handoff-widget\">\n {/* Header: Agent avatar + name */}\n <div className=\"devic-handoff-header\">\n <div className=\"devic-handoff-agent-avatar\">\n {/* The subagent's own face — uploaded, or generated from its id. The\n robot glyph is kept for the case where the hand-off names no\n agent at all, which is the only time there is nothing to draw. */}\n {agent?.imgUrl || agent?._id ? (\n <img\n src={agent.imgUrl || avatarUri(agent._id!, agent.avatarStyle)}\n alt=\"\"\n className=\"devic-handoff-avatar-img\"\n />\n ) : (\n <RobotFallbackIcon />\n )}\n </div>\n <span className=\"devic-handoff-agent-name\">\n {agent?.name || thread?.name || 'Subagent'}\n </span>\n </div>\n\n {/* State tag */}\n {thread?.state && (\n <div className=\"devic-handoff-state-row\">\n <ThreadStateTag\n state={thread.state}\n threadId={thread._id || subThreadId}\n agentName={agent?.name || thread?.name || 'Subagent'}\n pausedReason={thread.pausedReason}\n finishReason={thread.finishReason}\n pauseUntil={thread.pauseUntil}\n interactive={true}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n />\n </div>\n )}\n\n {/* Progress bar */}\n {totalTasks > 0 && (\n <div className=\"devic-handoff-progress\">\n <div className=\"devic-handoff-progress-bar\">\n <div\n className=\"devic-handoff-progress-fill\"\n data-status={thread?.state === AgentThreadState.FAILED ? 'error' : isTerminal ? 'success' : 'active'}\n style={{ width: `${taskPercentage}%` }}\n />\n </div>\n <span className=\"devic-handoff-progress-text\">\n {completedTasks}/{totalTasks}\n </span>\n </div>\n )}\n\n {/* Indeterminate progress when no tasks */}\n {totalTasks === 0 && isProcessing && (\n <div className=\"devic-handoff-progress\">\n <div className=\"devic-handoff-progress-bar\">\n <div className=\"devic-handoff-progress-indeterminate\" />\n </div>\n </div>\n )}\n\n {/* Last message summary */}\n {lastSummary && (\n <div className={`devic-handoff-summary ${isProcessing ? 'devic-handoff-summary-active' : ''}`}>\n {lastSummary}\n </div>\n )}\n\n {/* Elapsed time */}\n {isProcessing && (\n <div className=\"devic-handoff-elapsed\">\n <ClockSmallIcon />\n <span>{formatElapsed(elapsedSeconds)}</span>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Icons ── */\n\nfunction RobotFallbackIcon(): JSX.Element {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"#999\">\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <circle cx=\"9\" cy=\"14\" r=\"2\" fill=\"#fff\" />\n <circle cx=\"15\" cy=\"14\" r=\"2\" fill=\"#fff\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"8\" stroke=\"#999\" strokeWidth=\"2\" />\n <circle cx=\"12\" cy=\"2\" r=\"1.5\" />\n </svg>\n );\n}\n\nfunction ClockSmallIcon(): JSX.Element {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12,6 12,12 16,14\" />\n </svg>\n );\n}\n"],"names":["AgentThreadState","useOptionalDevicContext","resolvePollingInterval","useMemo","createLogger","useState","useRef","useCallback","DevicApiClient","useEffect","_jsx","_Fragment","_jsxs","avatarUri","ThreadStateTag"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LimitBanner.js","sources":["../../../../../src/components/ChatDrawer/LimitBanner.tsx"],"sourcesContent":["import React from 'react';\nimport type { TenantLimitExceeded } from '../../api/types';\n\nexport interface LimitBannerProps {\n limit: TenantLimitExceeded;\n}\n\nfunction resetText(resetsAt?: number): string | null {\n if (!resetsAt) return null;\n const ms = resetsAt - Date.now();\n if (ms <= 0) return 'You can try again now.';\n const mins = Math.round(ms / 60000);\n if (mins < 60) return `Resets in ${mins} minute${mins === 1 ? '' : 's'}.`;\n const hours = Math.round(mins / 60);\n if (hours < 48) return `Resets in ${hours} hour${hours === 1 ? '' : 's'}.`;\n const days = Math.round(hours / 24);\n return `Resets in ${days} day${days === 1 ? '' : 's'}.`;\n}\n\n/**\n * Default banner shown above the chat input when a message is blocked by a\n * tenant/subtenant usage limit. Antd-free — styled via `.devic-limit-banner*`.\n * Suppress it with `options.hideLimitBanner` or replace it with\n * `options.limitBannerRenderer`.\n */\nexport function LimitBanner({ limit }: LimitBannerProps): JSX.Element {\n const message = limit.message || 'Usage limit reached.';\n const reset = resetText(limit.resetsAt);\n return (\n <div className=\"devic-limit-banner\" role=\"alert\">\n <span className=\"devic-limit-banner-icon\" aria-hidden=\"true\">\n <WarningIcon />\n </span>\n <div className=\"devic-limit-banner-text\">\n <span className=\"devic-limit-banner-title\">{message}</span>\n {reset && <span className=\"devic-limit-banner-reset\">{reset}</span>}\n </div>\n </div>\n );\n}\n\nfunction WarningIcon(): 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\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n );\n}\n"],"names":["_jsxs","_jsx"],"mappings":";;;;AAOA,SAAS,SAAS,CAAC,QAAiB,EAAA;AAClC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;IAC1B,MAAM,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE;IAChC,IAAI,EAAE,IAAI,CAAC;AAAE,QAAA,OAAO,wBAAwB;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC;IACnC,IAAI,IAAI,GAAG,EAAE;AAAE,QAAA,OAAO,CAAA,UAAA,EAAa,IAAI,CAAA,OAAA,EAAU,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,EAAE;AAAE,QAAA,OAAO,CAAA,UAAA,EAAa,KAAK,CAAA,KAAA,EAAQ,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;AACnC,IAAA,OAAO,CAAA,UAAA,EAAa,IAAI,CAAA,IAAA,EAAO,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;AACzD;AAEA;;;;;AAKG;AACG,SAAU,WAAW,CAAC,EAAE,KAAK,EAAoB,EAAA;AACrD,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,sBAAsB;IACvD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC;IACvC,QACEA,yBAAK,SAAS,EAAC,oBAAoB,EAAC,IAAI,EAAC,OAAO,EAAA,QAAA,EAAA,CAC9CC,yBAAM,SAAS,EAAC,yBAAyB,EAAA,aAAA,EAAa,MAAM,YAC1DA,cAAA,CAAC,WAAW,EAAA,EAAA,CAAG,EAAA,CACV,EACPD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yBAAyB,aACtCC,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,0BAA0B,EAAA,QAAA,EAAE,OAAO,EAAA,CAAQ,EAC1D,KAAK,IAAIA,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,0BAA0B,EAAA,QAAA,EAAE,KAAK,EAAA,CAAQ,CAAA,EAAA,CAC/D,CAAA,EAAA,CACF;AAEV;AAEA,SAAS,WAAW,GAAA;AAClB,IAAA,QACED,eAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBC,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,0FAA0F,EAAA,CAAG,EACrGA,yBAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACvCA,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CACvC;AAEV
|
|
1
|
+
{"version":3,"file":"LimitBanner.js","sources":["../../../../../src/components/ChatDrawer/LimitBanner.tsx"],"sourcesContent":["import React from 'react';\nimport type { TenantLimitExceeded } from '../../api/types';\n\nexport interface LimitBannerProps {\n limit: TenantLimitExceeded;\n}\n\nfunction resetText(resetsAt?: number): string | null {\n if (!resetsAt) return null;\n const ms = resetsAt - Date.now();\n if (ms <= 0) return 'You can try again now.';\n const mins = Math.round(ms / 60000);\n if (mins < 60) return `Resets in ${mins} minute${mins === 1 ? '' : 's'}.`;\n const hours = Math.round(mins / 60);\n if (hours < 48) return `Resets in ${hours} hour${hours === 1 ? '' : 's'}.`;\n const days = Math.round(hours / 24);\n return `Resets in ${days} day${days === 1 ? '' : 's'}.`;\n}\n\n/**\n * Default banner shown above the chat input when a message is blocked by a\n * tenant/subtenant usage limit. Antd-free — styled via `.devic-limit-banner*`.\n * Suppress it with `options.hideLimitBanner` or replace it with\n * `options.limitBannerRenderer`.\n */\nexport function LimitBanner({ limit }: LimitBannerProps): JSX.Element {\n const message = limit.message || 'Usage limit reached.';\n const reset = resetText(limit.resetsAt);\n return (\n <div className=\"devic-limit-banner\" role=\"alert\">\n <span className=\"devic-limit-banner-icon\" aria-hidden=\"true\">\n <WarningIcon />\n </span>\n <div className=\"devic-limit-banner-text\">\n <span className=\"devic-limit-banner-title\">{message}</span>\n {reset && <span className=\"devic-limit-banner-reset\">{reset}</span>}\n </div>\n </div>\n );\n}\n\nfunction WarningIcon(): 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\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n );\n}\n"],"names":["_jsxs","_jsx"],"mappings":";;;;AAOA,SAAS,SAAS,CAAC,QAAiB,EAAA;AAClC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;IAC1B,MAAM,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE;IAChC,IAAI,EAAE,IAAI,CAAC;AAAE,QAAA,OAAO,wBAAwB;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC;IACnC,IAAI,IAAI,GAAG,EAAE;AAAE,QAAA,OAAO,CAAA,UAAA,EAAa,IAAI,CAAA,OAAA,EAAU,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,EAAE;AAAE,QAAA,OAAO,CAAA,UAAA,EAAa,KAAK,CAAA,KAAA,EAAQ,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;AACnC,IAAA,OAAO,CAAA,UAAA,EAAa,IAAI,CAAA,IAAA,EAAO,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;AACzD;AAEA;;;;;AAKG;AACG,SAAU,WAAW,CAAC,EAAE,KAAK,EAAoB,EAAA;AACrD,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,sBAAsB;IACvD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC;IACvC,QACEA,yBAAK,SAAS,EAAC,oBAAoB,EAAC,IAAI,EAAC,OAAO,EAAA,QAAA,EAAA,CAC9CC,yBAAM,SAAS,EAAC,yBAAyB,EAAA,aAAA,EAAa,MAAM,YAC1DA,cAAA,CAAC,WAAW,EAAA,EAAA,CAAG,EAAA,CACV,EACPD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yBAAyB,aACtCC,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,0BAA0B,EAAA,QAAA,EAAE,OAAO,EAAA,CAAQ,EAC1D,KAAK,IAAIA,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,0BAA0B,EAAA,QAAA,EAAE,KAAK,EAAA,CAAQ,CAAA,EAAA,CAC/D,CAAA,EAAA,CACF;AAEV;AAEA,SAAS,WAAW,GAAA;AAClB,IAAA,QACED,eAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBC,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,0FAA0F,EAAA,CAAG,EACrGA,yBAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACvCA,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CACvC;AAEV;;"}
|