@devicai/ui 0.56.0 → 0.57.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/README.md +18 -5
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +2 -1
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatMessages.js +2 -2
- package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/CompactionWidget.js +13 -5
- package/dist/cjs/components/ChatDrawer/CompactionWidget.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +2 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +18 -0
- package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +1 -1
- package/dist/esm/components/ChatDrawer/ChatMessages.js +2 -2
- package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/esm/components/ChatDrawer/CompactionWidget.d.ts +20 -4
- package/dist/esm/components/ChatDrawer/CompactionWidget.js +13 -5
- package/dist/esm/components/ChatDrawer/CompactionWidget.js.map +1 -1
- package/dist/esm/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -366,16 +366,25 @@ paths and urls preserved verbatim — and reads that instead of the messages it
|
|
|
366
366
|
replaces. The messages themselves stay in the conversation and keep being
|
|
367
367
|
shown; only what the assistant receives changes.
|
|
368
368
|
|
|
369
|
-
The drawer draws a cut line at the exact point where that happens,
|
|
370
|
-
|
|
371
|
-
says so: it is a model call of its own, taken between two assistant
|
|
372
|
-
so without it the conversation just appears to have gone quiet.
|
|
369
|
+
The drawer draws a cut line at the exact point where that happens, with how
|
|
370
|
+
many messages were folded and the token counts. While a compaction is being
|
|
371
|
+
written it says so: it is a model call of its own, taken between two assistant
|
|
372
|
+
messages, so without it the conversation just appears to have gone quiet.
|
|
373
|
+
|
|
374
|
+
**The checkpoint's contents are not shown unless you ask for them.** What is
|
|
375
|
+
behind the marker is not metadata about the conversation but an account *of*
|
|
376
|
+
it — the goal the model inferred, the decisions it recorded and why, what it
|
|
377
|
+
believes is still pending, and the identifiers it lifted out verbatim. That is
|
|
378
|
+
useful to an operator debugging an assistant and rarely something to put in
|
|
379
|
+
front of the customer the conversation is with, so `expandableCompaction` is
|
|
380
|
+
off by default and opening it is your decision.
|
|
373
381
|
|
|
374
382
|
```tsx
|
|
375
383
|
<ChatDrawer
|
|
376
384
|
assistantId="my-assistant"
|
|
377
385
|
options={{
|
|
378
|
-
showCompaction: true, // default
|
|
386
|
+
showCompaction: true, // default — draw the marker
|
|
387
|
+
expandableCompaction: false, // default — but do not let it be opened
|
|
379
388
|
// Replace the built-in marker with your own node. Called once per
|
|
380
389
|
// checkpoint, and once more while one is in flight (checkpoint: null):
|
|
381
390
|
compactionRenderer: ({ checkpoint, activity, isActive }) =>
|
|
@@ -391,6 +400,10 @@ so without it the conversation just appears to have gone quiet.
|
|
|
391
400
|
/>
|
|
392
401
|
```
|
|
393
402
|
|
|
403
|
+
`showCompaction: false` hides the marker altogether — but a conversation that
|
|
404
|
+
was compacted reads oddly without it, since the assistant will not recall
|
|
405
|
+
messages that are still on screen. Prefer the closed marker to no marker.
|
|
406
|
+
|
|
394
407
|
Both are also available from the hook: `useDevicChat().compactions` (the
|
|
395
408
|
checkpoints, oldest first) and `useDevicChat().compaction` (the one being
|
|
396
409
|
written right now, or `null`).
|
|
@@ -96,6 +96,7 @@ const DEFAULT_OPTIONS = {
|
|
|
96
96
|
showRecalledMemories: true,
|
|
97
97
|
recalledMemoriesRenderer: undefined,
|
|
98
98
|
showCompaction: true,
|
|
99
|
+
expandableCompaction: false,
|
|
99
100
|
compactionRenderer: undefined,
|
|
100
101
|
showCoreMemoryButton: false,
|
|
101
102
|
coreMemoryLabels: undefined,
|
|
@@ -726,7 +727,7 @@ function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, e
|
|
|
726
727
|
}), [mergedOptions.zIndex, mergedOptions.position]);
|
|
727
728
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isInline && (jsxRuntime.jsx("div", { className: "devic-drawer-overlay", "data-open": isOpen, style: overlayStyle, onClick: handleClose })), jsxRuntime.jsxs("div", { ref: drawerRef, className: `devic-chat-drawer ${className || ''}`, "data-position": mergedOptions.position, "data-open": isOpen, "data-mode": mode, style: drawerStyle, children: [mergedOptions.resizable && (jsxRuntime.jsx("div", { className: "devic-resize-handle", "data-position": mergedOptions.position, onMouseDown: handleResizeStart })), jsxRuntime.jsxs("div", { className: "devic-drawer-header", children: [avatarUrl && (jsxRuntime.jsx("img", { className: "devic-drawer-avatar", src: avatarUrl, alt: "", "aria-hidden": "true" })), jsxRuntime.jsx("h2", { className: "devic-drawer-title", children: mergedOptions.title }), jsxRuntime.jsx(ConversationSelector.ConversationSelector, { assistantId: assistantId, currentChatUid: chat.chatUid, onSelect: handleConversationSelect, onNewChat: handleNewChat, apiKey: apiKey, baseUrl: baseUrl, tenantId: tenantId, subtenantId: subtenantId, conversationPreview: mergedOptions.conversationPreview }), jsxRuntime.jsxs("div", { className: "devic-drawer-header-actions", children: [mergedOptions.showIntegrationsButton !== false && (jsxRuntime.jsx(IntegrationsLauncher.IntegrationsLauncher, { state: integrationsState, mcp: mcpState, onClick: () => setIntegrationsOpen(true), label: mergedOptions.integrationsLabel, maxLogos: mergedOptions.maxIntegrationLogos, dark: theme.isDarkTheme(modalTheme), placeholders: pendingIntegrations, loading: integrationsDeciding })), mergedOptions.showCoreMemoryButton && (jsxRuntime.jsx("button", { className: "devic-new-chat-btn", onClick: () => setCoreMemoryOpen(true), type: "button", "aria-label": coreMemoryTitle, title: coreMemoryTitle, children: jsxRuntime.jsx(BrainIcon, {}) })), jsxRuntime.jsx("button", { className: "devic-new-chat-btn", onClick: handleNewChat, type: "button", "aria-label": "New chat", title: "New chat", children: jsxRuntime.jsx(PlusIcon, {}) }), !isInline && (jsxRuntime.jsx("button", { className: "devic-drawer-close", onClick: handleClose, type: "button", "aria-label": "Close chat", children: jsxRuntime.jsx(CloseIcon, {}) }))] })] }), chat.error && (jsxRuntime.jsx("div", { className: "devic-error", children: chat.error.message })), jsxRuntime.jsx(ChatMessages.ChatMessages, { messages: chat.messages, allMessages: chat.messages, isLoading: chat.isLoading, welcomeMessage: mergedOptions.welcomeMessage, suggestedMessages: mergedOptions.suggestedMessages, onSuggestedClick: handleSuggestedClick, showToolTimeline: mergedOptions.showToolTimeline, toolRenderers: mergedOptions.toolRenderers, toolIcons: mergedOptions.toolIcons, loadingIndicator: mergedOptions.loadingIndicator, showFeedback: mergedOptions.showFeedback, feedbackMap: feedbackMap, onFeedback: handleFeedback, handedOffSubThreadId: chat.handedOffSubThreadId || undefined, onHandoffCompleted: chat.onHandoffCompleted, handoffWidgetRenderer: mergedOptions.handoffWidgetRenderer, toolGroups: mergedOptions.toolGroups, userMessageRenderer: mergedOptions.userMessageRenderer, assistantMessageRenderer: mergedOptions.assistantMessageRenderer, apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl, pollingInterval: pollingInterval, pendingInlineWidgets: inlineWidgets, onSubmitWidget: chat.submitWidgetResponse, onCancelWidget: chat.cancelWidgetCall, recalledMemories: mergedOptions.showRecalledMemories
|
|
728
729
|
? chat.recalledMemories
|
|
729
|
-
: undefined, recalledMemoriesRenderer: mergedOptions.recalledMemoriesRenderer, compactions: mergedOptions.showCompaction ? chat.compactions : undefined, compaction: mergedOptions.showCompaction ? chat.compaction : undefined, compactionRenderer: mergedOptions.compactionRenderer }), mergedOptions.customPromptBox ? (jsxRuntime.jsxs("div", { className: "devic-input-area", children: [limitBannerNode, usageBarNode, integrationsHintNode, queueNoticeNode, mergedOptions.customPromptBox({
|
|
730
|
+
: undefined, recalledMemoriesRenderer: mergedOptions.recalledMemoriesRenderer, compactions: mergedOptions.showCompaction ? chat.compactions : undefined, compaction: mergedOptions.showCompaction ? chat.compaction : undefined, compactionRenderer: mergedOptions.compactionRenderer, expandableCompaction: mergedOptions.expandableCompaction }), mergedOptions.customPromptBox ? (jsxRuntime.jsxs("div", { className: "devic-input-area", children: [limitBannerNode, usageBarNode, integrationsHintNode, queueNoticeNode, mergedOptions.customPromptBox({
|
|
730
731
|
sendMessage: handleSend,
|
|
731
732
|
transcribeAudio,
|
|
732
733
|
stop: chat.stopChat,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatDrawer.js","sources":["../../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { useAssistantInfo } from '../../api/assistantInfo';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport { ConversationSelector } from './ConversationSelector';\nimport { ChatDrawerErrorBoundary } from './ErrorBoundary';\nimport { UsageBar } from './UsageBar';\nimport { LimitBanner } from './LimitBanner';\nimport { QueueNotice } from './QueueNotice';\nimport { CoreMemoryModal, DEFAULT_CORE_MEMORY_LABELS } from '../CoreMemoryModal';\nimport {\n IntegrationsHint,\n IntegrationsLauncher,\n IntegrationsModal,\n IntegrationsToggle,\n useIntegrations,\n useTenantMcp,\n integrationChoiceKey,\n readIntegrationChoice,\n writeIntegrationChoice,\n pruneIntegrationChoice,\n} from '../IntegrationsModal';\nimport { isDarkTheme } from '../theme';\nimport type { DevicTheme } from '../theme';\nimport type { ChatDrawerProps, ChatDrawerOptions, ChatDrawerHandle } from './ChatDrawer.types';\nimport type { QueueDisposition } from '../../api/types';\nimport './styles.css';\nimport { avatarUri } from '../../utils/avatar';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: '100%',\n defaultOpen: false,\n color: '#1890ff',\n welcomeMessage: '',\n suggestedMessages: [],\n enableFileUploads: false,\n allowedFileTypes: { images: true, documents: true },\n maxFileSize: 10 * 1024 * 1024,\n enableLongTextPaste: false,\n longTextPasteThreshold: 2000,\n enableSpeechToText: false,\n speechLanguage: undefined as any,\n speechAutoStop: true,\n speechAutoStopCountdownMs: 1000,\n speechAutoStopSilenceMs: 1000,\n speechAutoStopSilenceRatio: 0.1,\n speechAutoStopSilenceLevel: 0.02,\n speechAutoStopSpeechLevel: 0.12,\n speechHandoff: false,\n speechHandoffSendDelayMs: 1000,\n speechHandoffHoldMs: 3000,\n inputPlaceholder: 'Type a message...',\n title: 'Chat',\n showAvatar: false,\n avatarUrl: undefined as any,\n showToolTimeline: true,\n zIndex: 1000,\n borderRadius: 0,\n resizable: false,\n minWidth: 300,\n maxWidth: 800,\n style: {},\n fontFamily: undefined as any,\n backgroundColor: undefined as any,\n textColor: undefined as any,\n secondaryBackgroundColor: undefined as any,\n borderColor: undefined as any,\n userBubbleColor: undefined as any,\n userBubbleTextColor: undefined as any,\n assistantBubbleColor: undefined as any,\n assistantBubbleTextColor: undefined as any,\n sendButtonColor: undefined as any,\n loadingIndicator: undefined as any,\n sendButtonContent: undefined as any,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n showFeedback: true,\n handoffWidgetRenderer: undefined as any,\n toolGroups: undefined as any,\n stopButtonContent: undefined as any,\n debug: false,\n persistConversation: false,\n customPromptBox: undefined as any,\n userMessageRenderer: undefined as any,\n assistantMessageRenderer: undefined as any,\n conversationPreview: 'date',\n showUsageBar: false,\n usageBarMetric: undefined as any,\n usageBarDisplay: undefined as any,\n customUsageBar: undefined as any,\n hideLimitBanner: false,\n limitBannerRenderer: undefined as any,\n hideQueueNotice: false,\n queueNoticeRenderer: undefined as any,\n // Unset on purpose: the assistant's own setting decides.\n messageQueue: undefined as any,\n showRecalledMemories: true,\n recalledMemoriesRenderer: undefined as any,\n showCompaction: true,\n compactionRenderer: undefined as any,\n showCoreMemoryButton: false,\n coreMemoryLabels: undefined as any,\n showIntegrationsButton: true,\n integrationsLabel: 'Connected apps',\n maxIntegrationLogos: 6,\n showIntegrationsHint: true,\n // Left unset so the strip can say \"Connect your apps\" or \"Explore connected\n // apps\" depending on what the end user has actually done.\n integrationsHintLabel: undefined as any,\n showIntegrationsToggle: true,\n integrationsToggleLabel: 'Apps in this chat',\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\n * ref={drawerRef}\n * assistantId=\"my-assistant\"\n * options={{\n * position: 'right',\n * width: 400,\n * welcomeMessage: 'Hello! How can I help you?',\n * suggestedMessages: ['Help me with...', 'Tell me about...'],\n * }}\n * modelInterfaceTools={[\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ]}\n * onMessageReceived={(msg) => console.log('Received:', msg)}\n * />\n * ```\n */\nexport const ChatDrawer = forwardRef<ChatDrawerHandle, ChatDrawerProps>(\n function ChatDrawer(props, ref) {\n return (\n <ChatDrawerErrorBoundary>\n <ChatDrawerInner {...props} forwardedRef={ref} />\n </ChatDrawerErrorBoundary>\n );\n }\n);\n\ninterface ChatDrawerInnerProps extends ChatDrawerProps {\n forwardedRef?: React.Ref<ChatDrawerHandle>;\n}\n\nfunction ChatDrawerInner({\n assistantId,\n chatUid: initialChatUid,\n options = {},\n enabledTools,\n modelInterfaceTools,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n tags,\n apiKey,\n baseUrl,\n pollingInterval,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onFileUpload,\n onOpen,\n onClose,\n isOpen: controlledIsOpen,\n className,\n mode = 'drawer',\n onConversationChange,\n forwardedRef,\n}: ChatDrawerInnerProps): JSX.Element {\n // Merge options with defaults\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n // localStorage key for persisting selected conversation\n const storageKey = mergedOptions.persistConversation\n ? `devic-ui-chatUid-${assistantId}`\n : null;\n\n // Resolve initial chatUid: prop takes priority, then localStorage\n const resolvedInitialChatUid = useMemo(() => {\n if (initialChatUid) return initialChatUid;\n if (storageKey) {\n try { return localStorage.getItem(storageKey) || undefined; } catch { return undefined; }\n }\n return undefined;\n }, [initialChatUid, storageKey]);\n\n // Drawer open state (can be controlled or uncontrolled; inline mode is always open)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isInline = mode === 'inline';\n const isOpen = isInline ? true : (controlledIsOpen ?? internalIsOpen);\n\n // Wrap onChatCreated to persist chatUid in localStorage\n const handleChatCreated = useCallback(\n (chatUid: string) => {\n if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n onChatCreated?.(chatUid);\n },\n [storageKey, onChatCreated]\n );\n\n /**\n * What the end user switched off: connected apps by slug, and their own MCP\n * servers by the `toggleId` the API hands out.\n *\n * Remembered in this browser (see `integrationChoice`) rather than only for\n * the life of the drawer — a reload used to forget it, which for someone who\n * keeps an app switched off on purpose reads as the switch not working. The\n * server still keeps nothing beyond the turn it was sent for; what is stored\n * is a preference of whoever is at this keyboard.\n *\n * The badge on the plug is what keeps that honest: a remembered choice is\n * visible at a glance rather than being an unexplained silence from an app.\n */\n const [disabledIntegrations, setDisabledIntegrations] = useState<string[]>([]);\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: resolvedInitialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n tags,\n enabledTools,\n disabledIntegrations,\n modelInterfaceTools,\n pollingInterval,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated: handleChatCreated,\n onFileUpload,\n messageQueue: mergedOptions.messageQueue,\n debug: mergedOptions.debug,\n });\n\n // Fetch assistant avatar when showAvatar is enabled\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n // The session source, when the page authenticates with one. Every client\n // built below gets it, or a page without an API key would have nothing to\n // authenticate with.\n const resolvedTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const [coreMemoryOpen, setCoreMemoryOpen] = useState(false);\n const [integrationsOpen, setIntegrationsOpen] = useState(false);\n\n const infoClient = useMemo(\n () =>\n resolvedApiKey || resolvedTenantSession\n ? new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n })\n : null,\n [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]\n );\n\n // Asked for only when something on screen depends on it, and then at most\n // once per assistant however many times this drawer is mounted — a host that\n // remounts it to start a fresh conversation used to pay for the answer again\n // every time.\n const assistantInfo = useAssistantInfo({\n assistantId,\n client: infoClient,\n baseUrl: resolvedBaseUrl,\n credential: resolvedApiKey || 'session',\n enabled:\n (!!mergedOptions.showAvatar && !mergedOptions.avatarUrl) ||\n (mergedOptions.showIntegrationsButton !== false && isOpen),\n });\n // The host's own image wins: an assistant carries one image for everybody, so\n // this is the only place a per-account face can come from. Failing that, an\n // assistant with no uploaded image still gets a face, generated from its\n // identifier — the same one the console shows for it. Drawn from `assistantId`\n // rather than from the fetched assistant so the header is not empty while the\n // lookup is in flight; the two agree, since that is what was asked for.\n const avatarUrl = mergedOptions.showAvatar\n ? (mergedOptions.avatarUrl ??\n assistantInfo.assistant?.imgUrl ??\n avatarUri(\n assistantInfo.assistant?.identifier || assistantId,\n assistantInfo.assistant?.avatarStyle\n ))\n : null;\n\n /**\n * Whether to ask which apps this assistant offers.\n *\n * The listing is worth a request only when there is something to list, and\n * most assistants offer nothing — for those, the call existed purely to be\n * refused, once per page load. The assistant now says so itself, so a plain\n * `false` settles it without asking.\n *\n * Anything else asks, exactly as before: a field that is absent means the API\n * is older than it, not that the answer is no, and a failed lookup means we\n * could not find out. Hiding the button on either would lose the feature for\n * a deployment that has it, which is far worse than one spare request.\n *\n * Where there are apps to show, this puts the two requests in sequence rather\n * than at once, so the listing lands later than it used to. The header holds\n * its place in the meantime — see `pendingIntegrations`.\n */\n const mayOfferIntegrations =\n assistantInfo.settled &&\n assistantInfo.assistant?.tenantIntegrations?.enabled !== false;\n\n // The apps this assistant offers its tenants. Loaded once, here, because the\n // header control cannot decide whether to exist without it — and lent to the\n // modal so opening it does not ask for the same listing again. Nothing is\n // fetched until the drawer is opened for the first time.\n const integrationsState = useIntegrations({\n assistantId,\n tenantId,\n subtenantId,\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n enabled:\n mergedOptions.showIntegrationsButton !== false &&\n isOpen &&\n mayOfferIntegrations,\n });\n\n /**\n * Whether this assistant offers MCP servers of the tenant's own.\n *\n * Read exactly like `mayOfferIntegrations`: absence means \"cannot tell\", so\n * the listing is asked for anyway. A deployment older than the field keeps\n * the behaviour it had — one refusal per drawer open — rather than losing the\n * feature.\n */\n const mayOfferMcp =\n assistantInfo.settled &&\n assistantInfo.assistant?.tenantMcpServers?.enabled !== false;\n\n /**\n * The tenant's own MCP servers, loaded here rather than inside the modal.\n *\n * The composer's switch needs them too, and it is not inside the modal — so\n * the listing has to live above both. The modal takes it as a prop and stops\n * asking for its own.\n */\n const mcpState = useTenantMcp({\n assistantId,\n tenantId,\n subtenantId,\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n enabled:\n mergedOptions.showIntegrationsButton !== false && isOpen && mayOfferMcp,\n });\n\n /**\n * Whether the answer to \"is there anything to show here\" is still on its way.\n *\n * Two requests decide it — what the assistant offers, and then what this\n * tenant has connected — and until both have answered the control cannot\n * know whether to exist. Without this the header simply had a gap and then a\n * button, which reads as the page changing its mind.\n */\n const integrationsDeciding =\n mergedOptions.showIntegrationsButton !== false &&\n isOpen &&\n (!assistantInfo.settled ||\n (mayOfferIntegrations && !integrationsState.settled) ||\n (mayOfferMcp && !mcpState.settled));\n\n /**\n * Placeholder chips to hold while the listing is in flight.\n *\n * Only when the assistant has said outright that it offers apps, and how\n * many: on a maybe there would be nothing to hold the place of half the time,\n * and a control that appears and then vanishes is worse than one that arrives\n * late. So this stays at zero for an API that does not say, which is also the\n * behaviour every version until now had.\n */\n const pendingIntegrations =\n assistantInfo.assistant?.tenantIntegrations?.enabled === true &&\n !integrationsState.settled\n ? (assistantInfo.assistant.tenantIntegrations.count ?? 0)\n : 0;\n\n // Tenant/subtenant resolution mirrors useDevicChat (prop overrides provider).\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedSubtenantId = subtenantId || context?.subtenantId;\n\n // ── Remembering which apps and servers are switched off ────────────────\n\n const choiceKey = integrationChoiceKey(\n assistantId,\n resolvedTenantId,\n resolvedSubtenantId\n );\n\n // Loaded per key, so switching tenant loads that tenant's choice rather than\n // carrying the previous one over.\n const loadedChoiceRef = useRef<string | null>(null);\n useEffect(() => {\n if (loadedChoiceRef.current === choiceKey) return;\n loadedChoiceRef.current = choiceKey;\n setDisabledIntegrations(readIntegrationChoice(choiceKey));\n }, [choiceKey]);\n\n useEffect(() => {\n // Only once this key's stored value has been read, or the empty initial\n // state would erase it before it was ever loaded.\n if (loadedChoiceRef.current !== choiceKey) return;\n writeIntegrationChoice(choiceKey, disabledIntegrations);\n }, [choiceKey, disabledIntegrations]);\n\n /**\n * Forgets what is no longer on offer, once the listings can say so.\n *\n * Every clause of this is load-bearing. `mayOffer*` is false BEFORE the\n * assistant has answered as well as when the answer is no, so without the\n * `assistantInfo.settled` guard the prune runs on the first render against\n * two empty listings and erases the very thing that was just loaded — which\n * is exactly the reload-forgets-it bug this was meant to fix. A definite\n * \"this assistant offers none\" is an answer; an unsettled listing is not.\n *\n * With the drawer never opened, neither listing is ever fetched, so nothing\n * is pruned and the stored choice survives untouched.\n */\n const appsKnown =\n assistantInfo.settled && (!mayOfferIntegrations || integrationsState.settled);\n const mcpKnown = assistantInfo.settled && (!mayOfferMcp || mcpState.settled);\n useEffect(() => {\n if (!appsKnown || !mcpKnown) return;\n const live = [\n ...integrationsState.integrations\n .filter((i) => i.connected)\n .map((i) => i.app),\n ...mcpState.servers\n .filter((s) => s.connection?.status === 'active' && s.connection.toggleId)\n .map((s) => s.connection!.toggleId as string),\n ];\n setDisabledIntegrations((prev) => pruneIntegrationChoice(prev, live));\n }, [appsKnown, mcpKnown, integrationsState.integrations, mcpState.servers]);\n\n // Usage bar (above the input) — only when enabled and a tenant is known.\n // Refetches after each turn via the message count as refresh key.\n const usageBarNode =\n (mergedOptions.showUsageBar ||\n typeof mergedOptions.customUsageBar === 'function') &&\n resolvedTenantId ? (\n <UsageBar\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n tenantId={resolvedTenantId}\n subtenantId={resolvedSubtenantId}\n mode={mergedOptions.showUsageBar === 'onDemand' ? 'onDemand' : 'always'}\n metric={mergedOptions.usageBarMetric}\n display={mergedOptions.usageBarDisplay}\n customUsageBar={mergedOptions.customUsageBar}\n color={mergedOptions.color}\n refreshKey={chat.messages.length}\n debug={mergedOptions.debug}\n />\n ) : null;\n\n // Default usage-limit banner (above the input) — opt-out via hideLimitBanner,\n // override via limitBannerRenderer.\n const limitBannerNode =\n chat.limitExceeded && !mergedOptions.hideLimitBanner\n ? mergedOptions.limitBannerRenderer\n ? mergedOptions.limitBannerRenderer(chat.limitExceeded)\n : <LimitBanner limit={chat.limitExceeded} />\n : null;\n\n // Speech-to-text transcription, exposed to custom prompt boxes so a developer\n // can transcribe audio (binary or URL) and attach the resulting transcriptId.\n const transcribeAudio = useCallback(\n (\n audio: Blob | string,\n transcribeOptions?: {\n language?: string;\n messageUid?: string;\n chatUid?: string;\n tenantId?: string;\n },\n ) => {\n if (!resolvedApiKey && !resolvedTenantSession) {\n return Promise.reject(\n new Error('No credentials configured. Cannot transcribe audio.'),\n );\n }\n const client = new DevicApiClient({ apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl, getTenantSession: resolvedTenantSession, onSessionExpired });\n return client.transcribeAudio(audio, {\n language: transcribeOptions?.language ?? mergedOptions.speechLanguage,\n messageUid: transcribeOptions?.messageUid,\n chatUid: transcribeOptions?.chatUid,\n tenantId: transcribeOptions?.tenantId ?? tenantId,\n });\n },\n [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl, mergedOptions.speechLanguage, tenantId],\n );\n\n // Handle open/close\n const handleOpen = useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleToggle = useCallback(() => {\n setInternalIsOpen((prev) => !prev);\n }, []);\n\n // Expose handle for programmatic control\n useImperativeHandle(forwardedRef, () => ({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n setChatUid: (chatUid: string) => {\n chat.loadChat(chatUid);\n },\n sendMessage: (message: string) => {\n chat.sendMessage(message);\n },\n }), [handleOpen, handleClose, handleToggle, chat]);\n\n // Register this drawer in the DevicProvider so AIElementWrapper can open it\n useEffect(() => {\n if (!context?.registerDrawer) return;\n const unregister = context.registerDrawer({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n sendMessage: (message: string) => chat.sendMessage(message),\n });\n return unregister;\n }, [context, handleOpen, handleClose, handleToggle, chat]);\n\n // Partition pending widget calls by render mode\n const { inlineWidgets, inputWidget } = useMemo(() => {\n const inline: typeof chat.pendingWidgetCalls = [];\n let input: typeof chat.pendingWidgetCalls[number] | null = null;\n for (const wc of chat.pendingWidgetCalls) {\n if (wc.widget.render === 'input' && !input) {\n input = wc;\n } else {\n inline.push(wc);\n }\n }\n return { inlineWidgets: inline, inputWidget: input };\n }, [chat.pendingWidgetCalls]);\n\n // Active references from DevicProvider (created by AIElementWrapper)\n const references = context?.references ?? [];\n const removeReference = useCallback(\n (id: string) => {\n context?.removeReference(id);\n },\n [context]\n );\n const clearReferences = useCallback(() => {\n context?.clearReferences();\n }, [context]);\n\n // Handle send message — prefix references and clear them after sending\n /**\n * What the last accepted message was told about when it gets picked up. Only\n * the wording of the notice depends on it.\n */\n const [queueDisposition, setQueueDisposition] = useState<\n QueueDisposition | undefined\n >();\n /**\n * What became of a message that did not simply join the queue: it was turned\n * down, or a stop threw it away. Said out loud, because in both cases the\n * user's text has just moved back into the box on its own.\n */\n const [queueAlert, setQueueAlert] = useState<string | null>(null);\n\n const handleSend = useCallback(\n async (\n message: string,\n files?: File[],\n meta?: { transcriptId?: string; tags?: string[] }\n ) => {\n let finalMessage = message;\n if (references.length > 0) {\n const labels = references.map((r) => `\"${r.label}\"`).join(', ');\n finalMessage = `Elemento referenciado: ${labels}\\n\\n${message}`;\n }\n setQueueAlert(null);\n const result = await chat.sendMessage(finalMessage, {\n files,\n transcriptId: meta?.transcriptId,\n tags: meta?.tags,\n });\n\n if ('rejected' in result) {\n // The references belong to the message that was not sent, so they stay.\n if (result.reason !== 'error') {\n // An ordinary error already reaches the host through `onError`; these\n // two do not, and the only sign of them would otherwise be the text\n // reappearing in the box with no explanation.\n setQueueAlert(\n result.reason === 'queue_full'\n ? `${result.message} Your message is back in the box.`\n : 'The assistant is not taking messages while it works. Your message is back in the box.'\n );\n }\n return result;\n }\n\n setQueueDisposition('queued' in result && result.queued ? result.willProcess : undefined);\n if (references.length > 0) clearReferences();\n return result;\n },\n [chat, references, clearReferences]\n );\n\n /**\n * Whether a message may be written while the assistant is working.\n *\n * Being busy is not the only reason the box closes, and the other two are not\n * about waiting: an inline widget is the assistant waiting on *this* user, and\n * a usage limit is a refusal the queue cannot soften.\n */\n const canQueue =\n chat.queueEnabled && inlineWidgets.length === 0 && !chat.limitExceeded;\n\n const handleStopChat = useCallback(async () => {\n const result = await chat.stopChat();\n setQueueDisposition(undefined);\n setQueueAlert(\n result.discarded\n ? `${result.discarded === 1 ? 'A queued message was' : `${result.discarded} queued messages were`} not sent — the text is back in the box.`\n : null\n );\n return result;\n }, [chat]);\n\n /**\n * Shown while there is something to explain: the user is writing into a run\n * that has not finished, or messages are already waiting. With nothing typed\n * and nothing queued there is nothing to say.\n */\n const queueNoticeNode =\n !mergedOptions.hideQueueNotice &&\n // `queuedCount` on its own matters: an assistant with an input delay queues\n // what is written into an *idle* conversation whether or not it takes\n // messages while busy, so there can be something waiting with the queue\n // switched off.\n (queueAlert || chat.queuedCount > 0 || (canQueue && chat.isLoading))\n ? mergedOptions.queueNoticeRenderer\n ? mergedOptions.queueNoticeRenderer({\n queuedCount: chat.queuedCount,\n willProcess: queueDisposition,\n alert: queueAlert ?? undefined,\n })\n : (\n <QueueNotice\n queuedCount={chat.queuedCount}\n willProcess={queueDisposition}\n alert={queueAlert ?? undefined}\n />\n )\n : null;\n\n // Handle conversation selection\n const handleConversationSelect = useCallback(\n (chatUid: string) => {\n chat.loadChat(chatUid);\n onConversationChange?.(chatUid);\n if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n },\n [chat, onConversationChange, storageKey]\n );\n\n const handleNewChat = useCallback(() => {\n chat.clearChat();\n if (storageKey) {\n try { localStorage.removeItem(storageKey); } catch {}\n }\n }, [chat, storageKey]);\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Feedback state\n const [feedbackMap, setFeedbackMap] = useState<Map<string, 'positive' | 'negative'>>(new Map());\n const feedbackClientRef = useRef<DevicApiClient | null>(null);\n\n // Initialize feedback client\n useEffect(() => {\n if ((resolvedApiKey || resolvedTenantSession) && !feedbackClientRef.current) {\n feedbackClientRef.current = new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n });\n }\n }, [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]);\n\n // Load existing feedback when chat changes\n useEffect(() => {\n if (!chat.chatUid || !feedbackClientRef.current || !mergedOptions.showFeedback) return;\n\n feedbackClientRef.current.getChatFeedback(assistantId, chat.chatUid)\n .then((entries) => {\n const newMap = new Map<string, 'positive' | 'negative'>();\n for (const entry of entries) {\n if (entry.feedback !== undefined) {\n newMap.set(entry.requestId, entry.feedback ? 'positive' : 'negative');\n }\n }\n setFeedbackMap(newMap);\n })\n .catch(() => {\n // Silently ignore feedback loading errors\n });\n }, [chat.chatUid, assistantId, mergedOptions.showFeedback]);\n\n // Handle feedback submission\n const handleFeedback = useCallback(\n async (messageId: string, positive: boolean, comment?: string) => {\n if (!chat.chatUid || !feedbackClientRef.current) return;\n\n try {\n await feedbackClientRef.current.submitChatFeedback(assistantId, chat.chatUid, {\n messageId,\n feedback: positive,\n feedbackComment: comment,\n });\n\n setFeedbackMap((prev) => {\n const newMap = new Map(prev);\n newMap.set(messageId, positive ? 'positive' : 'negative');\n return newMap;\n });\n } catch (err) {\n console.error('Failed to submit feedback:', err);\n throw err;\n }\n },\n [chat.chatUid, assistantId]\n );\n\n // Apply CSS variables for theming on the drawer element itself\n // (must target the component root so they override the defaults defined on .devic-chat-drawer)\n const drawerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = drawerRef.current;\n if (!el) return;\n const vars: [string, string | undefined][] = [\n ['--devic-primary', mergedOptions.color !== DEFAULT_OPTIONS.color ? mergedOptions.color : undefined],\n ['--devic-font-family', mergedOptions.fontFamily],\n ['--devic-bg', mergedOptions.backgroundColor],\n ['--devic-text', mergedOptions.textColor],\n ['--devic-bg-secondary', mergedOptions.secondaryBackgroundColor],\n ['--devic-border', mergedOptions.borderColor],\n ['--devic-user-bubble', mergedOptions.userBubbleColor],\n ['--devic-user-bubble-text', mergedOptions.userBubbleTextColor],\n ['--devic-assistant-bubble', mergedOptions.assistantBubbleColor],\n ['--devic-assistant-bubble-text', mergedOptions.assistantBubbleTextColor],\n ['--devic-send-btn', mergedOptions.sendButtonColor],\n ];\n for (const [name, value] of vars) {\n if (value) {\n el.style.setProperty(name, value);\n } else {\n el.style.removeProperty(name);\n }\n }\n }, [mergedOptions.color, mergedOptions.fontFamily, mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.secondaryBackgroundColor, mergedOptions.borderColor, mergedOptions.userBubbleColor, mergedOptions.userBubbleTextColor, mergedOptions.assistantBubbleColor, mergedOptions.assistantBubbleTextColor, mergedOptions.sendButtonColor]);\n\n // The same values, handed to the dialogs this drawer opens. They render\n // through a portal into document.body, so the variables set above — which\n // live on the drawer element — never reach them.\n // The brain button says what the modal it opens is called.\n const coreMemoryTitle =\n mergedOptions.coreMemoryLabels?.title ?? DEFAULT_CORE_MEMORY_LABELS.title;\n\n const modalTheme: DevicTheme = useMemo(\n () => ({\n color:\n mergedOptions.color !== DEFAULT_OPTIONS.color\n ? mergedOptions.color\n : undefined,\n fontFamily: mergedOptions.fontFamily,\n backgroundColor: mergedOptions.backgroundColor,\n textColor: mergedOptions.textColor,\n secondaryBackgroundColor: mergedOptions.secondaryBackgroundColor,\n borderColor: mergedOptions.borderColor,\n }),\n [\n mergedOptions.color,\n mergedOptions.fontFamily,\n mergedOptions.backgroundColor,\n mergedOptions.textColor,\n mergedOptions.secondaryBackgroundColor,\n mergedOptions.borderColor,\n ]\n );\n\n // The strip above the composer. Dismissed per end user, because the whole\n // point of remembering a dismissal is that the same person is not told twice.\n const integrationsHintNode =\n mergedOptions.showIntegrationsButton !== false &&\n mergedOptions.showIntegrationsHint !== false ? (\n <IntegrationsHint\n state={integrationsState}\n onOpen={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsHintLabel}\n maxLogos={mergedOptions.maxIntegrationLogos}\n storageKey={`${assistantId}:${resolvedTenantId ?? ''}:${resolvedSubtenantId ?? ''}`}\n dark={isDarkTheme(modalTheme)}\n />\n ) : null;\n\n // The per-message switch in the composer row. Shown only where there is\n // something to switch — the control returns null with nothing connected —\n // and hidden outright by `showIntegrationsToggle: false`.\n const integrationsToggleNode =\n mergedOptions.showIntegrationsButton !== false &&\n mergedOptions.showIntegrationsToggle !== false ? (\n <IntegrationsToggle\n state={integrationsState}\n mcp={mcpState}\n disabled={disabledIntegrations}\n onChange={setDisabledIntegrations}\n onManage={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsToggleLabel}\n dark={isDarkTheme(modalTheme)}\n busy={chat.isLoading}\n loading={integrationsDeciding}\n />\n ) : null;\n\n // Resizable drawer\n const [resizedWidth, setResizedWidth] = useState<number | null>(null);\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const startX = e.clientX;\n const startWidth = drawerRef.current?.offsetWidth ?? 0;\n const isLeft = mergedOptions.position === 'left';\n\n const onMove = (ev: MouseEvent) => {\n const delta = ev.clientX - startX;\n const newWidth = startWidth + (isLeft ? delta : -delta);\n const clamped = Math.min(\n mergedOptions.maxWidth,\n Math.max(mergedOptions.minWidth, newWidth)\n );\n setResizedWidth(clamped);\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n },\n [mergedOptions.position, mergedOptions.minWidth, mergedOptions.maxWidth]\n );\n\n // Build style object\n const baseWidth = resizedWidth\n ? `${resizedWidth}px`\n : typeof mergedOptions.width === 'number'\n ? `${mergedOptions.width}px`\n : mergedOptions.width;\n\n const drawerStyle = useMemo(\n () => ({\n width: baseWidth,\n zIndex: mergedOptions.zIndex,\n borderRadius: typeof mergedOptions.borderRadius === 'number'\n ? `${mergedOptions.borderRadius}px`\n : mergedOptions.borderRadius,\n ...mergedOptions.style,\n }),\n [baseWidth, mergedOptions.zIndex, mergedOptions.borderRadius, mergedOptions.style]\n );\n\n const overlayStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n }),\n [mergedOptions.zIndex]\n );\n\n const triggerStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n [mergedOptions.position]: 20,\n bottom: 20,\n }),\n [mergedOptions.zIndex, mergedOptions.position]\n );\n\n return (\n <>\n {/* Overlay (drawer mode only) */}\n {!isInline && (\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n )}\n\n {/* Drawer */}\n <div\n ref={drawerRef}\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n data-mode={mode}\n style={drawerStyle}\n >\n {/* Resize handle */}\n {mergedOptions.resizable && (\n <div\n className=\"devic-resize-handle\"\n data-position={mergedOptions.position}\n onMouseDown={handleResizeStart}\n />\n )}\n\n {/* Header */}\n <div className=\"devic-drawer-header\">\n {avatarUrl && (\n <img\n className=\"devic-drawer-avatar\"\n src={avatarUrl}\n alt=\"\"\n aria-hidden=\"true\"\n />\n )}\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <ConversationSelector\n assistantId={assistantId}\n currentChatUid={chat.chatUid}\n onSelect={handleConversationSelect}\n onNewChat={handleNewChat}\n apiKey={apiKey}\n baseUrl={baseUrl}\n tenantId={tenantId}\n subtenantId={subtenantId}\n conversationPreview={mergedOptions.conversationPreview}\n />\n <div className=\"devic-drawer-header-actions\">\n {mergedOptions.showIntegrationsButton !== false && (\n <IntegrationsLauncher\n state={integrationsState}\n mcp={mcpState}\n onClick={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsLabel}\n maxLogos={mergedOptions.maxIntegrationLogos}\n dark={isDarkTheme(modalTheme)}\n placeholders={pendingIntegrations}\n loading={integrationsDeciding}\n />\n )}\n {mergedOptions.showCoreMemoryButton && (\n <button\n className=\"devic-new-chat-btn\"\n onClick={() => setCoreMemoryOpen(true)}\n type=\"button\"\n aria-label={coreMemoryTitle}\n title={coreMemoryTitle}\n >\n <BrainIcon />\n </button>\n )}\n <button\n className=\"devic-new-chat-btn\"\n onClick={handleNewChat}\n type=\"button\"\n aria-label=\"New chat\"\n title=\"New chat\"\n >\n <PlusIcon />\n </button>\n {!isInline && (\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {chat.error && (\n <div className=\"devic-error\">\n {chat.error.message}\n </div>\n )}\n\n {/* Messages */}\n <ChatMessages\n messages={chat.messages}\n allMessages={chat.messages}\n isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n toolRenderers={mergedOptions.toolRenderers}\n toolIcons={mergedOptions.toolIcons}\n loadingIndicator={mergedOptions.loadingIndicator}\n showFeedback={mergedOptions.showFeedback}\n feedbackMap={feedbackMap}\n onFeedback={handleFeedback}\n handedOffSubThreadId={chat.handedOffSubThreadId || undefined}\n onHandoffCompleted={chat.onHandoffCompleted}\n handoffWidgetRenderer={mergedOptions.handoffWidgetRenderer}\n toolGroups={mergedOptions.toolGroups}\n userMessageRenderer={mergedOptions.userMessageRenderer}\n assistantMessageRenderer={mergedOptions.assistantMessageRenderer}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n pollingInterval={pollingInterval}\n pendingInlineWidgets={inlineWidgets}\n onSubmitWidget={chat.submitWidgetResponse}\n onCancelWidget={chat.cancelWidgetCall}\n recalledMemories={\n mergedOptions.showRecalledMemories\n ? chat.recalledMemories\n : undefined\n }\n recalledMemoriesRenderer={mergedOptions.recalledMemoriesRenderer}\n compactions={\n mergedOptions.showCompaction ? chat.compactions : undefined\n }\n compaction={\n mergedOptions.showCompaction ? chat.compaction : undefined\n }\n compactionRenderer={mergedOptions.compactionRenderer}\n />\n\n {/* Input */}\n {mergedOptions.customPromptBox ? (\n <div className=\"devic-input-area\">\n {limitBannerNode}\n {usageBarNode}\n {integrationsHintNode}\n {queueNoticeNode}\n {mergedOptions.customPromptBox({\n sendMessage: handleSend,\n transcribeAudio,\n stop: chat.stopChat,\n isLoading: chat.isLoading,\n queueEnabled: canQueue,\n queuedCount: chat.queuedCount,\n newConversation: chat.clearChat,\n references,\n removeReference,\n clearReferences,\n limitExceeded: chat.limitExceeded,\n })}\n </div>\n ) : (\n <ChatInput\n onSend={handleSend}\n disabled={\n // `handedOff` is one of the states the queue covers — the\n // conversation is waiting on a subagent, which in an embedded\n // widget can take minutes — so with queueing on it no longer\n // closes the box. A pending widget and a usage limit still do:\n // one is the assistant waiting on this user, the other a refusal.\n (chat.isLoading && !canQueue) ||\n (chat.handedOff && !canQueue) ||\n inlineWidgets.length > 0 ||\n !!chat.limitExceeded\n }\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n enableLongTextPaste={mergedOptions.enableLongTextPaste}\n longTextPasteThreshold={mergedOptions.longTextPasteThreshold}\n enableSpeechToText={mergedOptions.enableSpeechToText}\n speechLanguage={mergedOptions.speechLanguage}\n speechTenantId={tenantId}\n speechAutoStop={mergedOptions.speechAutoStop}\n speechAutoStopCountdownMs={mergedOptions.speechAutoStopCountdownMs}\n speechAutoStopSilenceMs={mergedOptions.speechAutoStopSilenceMs}\n speechAutoStopSilenceRatio={mergedOptions.speechAutoStopSilenceRatio}\n speechAutoStopSilenceLevel={mergedOptions.speechAutoStopSilenceLevel}\n speechAutoStopSpeechLevel={mergedOptions.speechAutoStopSpeechLevel}\n speechHandoff={mergedOptions.speechHandoff}\n speechHandoffSendDelayMs={mergedOptions.speechHandoffSendDelayMs}\n speechHandoffHoldMs={mergedOptions.speechHandoffHoldMs}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n sendButtonContent={mergedOptions.sendButtonContent}\n disabledMessage={\n chat.handedOff\n ? 'Waiting for subagent to complete'\n : inlineWidgets.length > 0\n ? 'Waiting for tool response'\n : undefined\n }\n isProcessing={chat.isLoading && !chat.handedOff}\n onStop={handleStopChat}\n allowQueueing={canQueue}\n queueNotice={queueNoticeNode}\n stopButtonContent={mergedOptions.stopButtonContent}\n pendingInputWidget={inputWidget}\n onSubmitWidget={chat.submitWidgetResponse}\n onCancelWidget={chat.cancelWidgetCall}\n references={references}\n onRemoveReference={removeReference}\n usageBar={usageBarNode}\n limitBanner={limitBannerNode}\n integrationsHint={integrationsHintNode}\n integrationsToggle={integrationsToggleNode}\n />\n )}\n </div>\n\n {/* Trigger button (drawer mode only, when closed) */}\n {!isInline && !isOpen && (\n <button\n className=\"devic-trigger\"\n onClick={handleOpen}\n style={triggerStyle}\n type=\"button\"\n aria-label=\"Open chat\"\n >\n <ChatIcon />\n </button>\n )}\n\n {/* Core memory modal (opened from the header brain button) */}\n {mergedOptions.showCoreMemoryButton && (\n <CoreMemoryModal\n isOpen={coreMemoryOpen}\n onClose={() => setCoreMemoryOpen(false)}\n assistantId={assistantId}\n tenantId={tenantId}\n subtenantId={subtenantId}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n labels={mergedOptions.coreMemoryLabels}\n theme={modalTheme}\n />\n )}\n\n {/* Connected apps modal (opened from the header app stack) */}\n {mergedOptions.showIntegrationsButton !== false && (\n <IntegrationsModal\n isOpen={integrationsOpen}\n onClose={() => setIntegrationsOpen(false)}\n assistantId={assistantId}\n tenantId={tenantId}\n subtenantId={subtenantId}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n title={mergedOptions.integrationsLabel}\n theme={modalTheme}\n state={integrationsState}\n mcpState={mcpState}\n />\n )}\n </>\n );\n}\n\n/**\n * Brain icon for the core memory button\n */\nfunction BrainIcon(): JSX.Element {\n return (\n <svg\n width=\"17\"\n height=\"17\"\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=\"M9.5 2a2.5 2.5 0 0 0-2.45 2A3.5 3.5 0 0 0 4.6 8.6 3.5 3.5 0 0 0 3 11.5c0 1.1.5 2.08 1.29 2.73A3.5 3.5 0 0 0 7 20a3 3 0 0 0 5-2.24V4.5A2.5 2.5 0 0 0 9.5 2Z\" />\n <path d=\"M14.5 2a2.5 2.5 0 0 1 2.45 2 3.5 3.5 0 0 1 2.45 4.6A3.5 3.5 0 0 1 21 11.5a3.49 3.49 0 0 1-1.29 2.73A3.5 3.5 0 0 1 17 20a3 3 0 0 1-5-2.24V4.5A2.5 2.5 0 0 1 14.5 2Z\" />\n </svg>\n );\n}\n\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Plus icon for new chat button\n */\nfunction PlusIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n\n/**\n * Chat icon for trigger button\n */\nfunction ChatIcon(): JSX.Element {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z\" />\n </svg>\n );\n}\n"],"names":["forwardRef","_jsx","ChatDrawerErrorBoundary","useMemo","useState","useCallback","useDevicChat","useOptionalDevicContext","DevicApiClient","assistantInfo","useAssistantInfo","avatarUri","useIntegrations","useTenantMcp","integrationChoiceKey","useRef","useEffect","readIntegrationChoice","writeIntegrationChoice","pruneIntegrationChoice","UsageBar","LimitBanner","client","useImperativeHandle","QueueNotice","DEFAULT_CORE_MEMORY_LABELS","IntegrationsHint","isDarkTheme","IntegrationsToggle","_jsxs","_Fragment","ConversationSelector","IntegrationsLauncher","ChatMessages","ChatInput","CoreMemoryModal","IntegrationsModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatDrawer.js","sources":["../../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { useAssistantInfo } from '../../api/assistantInfo';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport { ConversationSelector } from './ConversationSelector';\nimport { ChatDrawerErrorBoundary } from './ErrorBoundary';\nimport { UsageBar } from './UsageBar';\nimport { LimitBanner } from './LimitBanner';\nimport { QueueNotice } from './QueueNotice';\nimport { CoreMemoryModal, DEFAULT_CORE_MEMORY_LABELS } from '../CoreMemoryModal';\nimport {\n IntegrationsHint,\n IntegrationsLauncher,\n IntegrationsModal,\n IntegrationsToggle,\n useIntegrations,\n useTenantMcp,\n integrationChoiceKey,\n readIntegrationChoice,\n writeIntegrationChoice,\n pruneIntegrationChoice,\n} from '../IntegrationsModal';\nimport { isDarkTheme } from '../theme';\nimport type { DevicTheme } from '../theme';\nimport type { ChatDrawerProps, ChatDrawerOptions, ChatDrawerHandle } from './ChatDrawer.types';\nimport type { QueueDisposition } from '../../api/types';\nimport './styles.css';\nimport { avatarUri } from '../../utils/avatar';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: '100%',\n defaultOpen: false,\n color: '#1890ff',\n welcomeMessage: '',\n suggestedMessages: [],\n enableFileUploads: false,\n allowedFileTypes: { images: true, documents: true },\n maxFileSize: 10 * 1024 * 1024,\n enableLongTextPaste: false,\n longTextPasteThreshold: 2000,\n enableSpeechToText: false,\n speechLanguage: undefined as any,\n speechAutoStop: true,\n speechAutoStopCountdownMs: 1000,\n speechAutoStopSilenceMs: 1000,\n speechAutoStopSilenceRatio: 0.1,\n speechAutoStopSilenceLevel: 0.02,\n speechAutoStopSpeechLevel: 0.12,\n speechHandoff: false,\n speechHandoffSendDelayMs: 1000,\n speechHandoffHoldMs: 3000,\n inputPlaceholder: 'Type a message...',\n title: 'Chat',\n showAvatar: false,\n avatarUrl: undefined as any,\n showToolTimeline: true,\n zIndex: 1000,\n borderRadius: 0,\n resizable: false,\n minWidth: 300,\n maxWidth: 800,\n style: {},\n fontFamily: undefined as any,\n backgroundColor: undefined as any,\n textColor: undefined as any,\n secondaryBackgroundColor: undefined as any,\n borderColor: undefined as any,\n userBubbleColor: undefined as any,\n userBubbleTextColor: undefined as any,\n assistantBubbleColor: undefined as any,\n assistantBubbleTextColor: undefined as any,\n sendButtonColor: undefined as any,\n loadingIndicator: undefined as any,\n sendButtonContent: undefined as any,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n showFeedback: true,\n handoffWidgetRenderer: undefined as any,\n toolGroups: undefined as any,\n stopButtonContent: undefined as any,\n debug: false,\n persistConversation: false,\n customPromptBox: undefined as any,\n userMessageRenderer: undefined as any,\n assistantMessageRenderer: undefined as any,\n conversationPreview: 'date',\n showUsageBar: false,\n usageBarMetric: undefined as any,\n usageBarDisplay: undefined as any,\n customUsageBar: undefined as any,\n hideLimitBanner: false,\n limitBannerRenderer: undefined as any,\n hideQueueNotice: false,\n queueNoticeRenderer: undefined as any,\n // Unset on purpose: the assistant's own setting decides.\n messageQueue: undefined as any,\n showRecalledMemories: true,\n recalledMemoriesRenderer: undefined as any,\n showCompaction: true,\n expandableCompaction: false,\n compactionRenderer: undefined as any,\n showCoreMemoryButton: false,\n coreMemoryLabels: undefined as any,\n showIntegrationsButton: true,\n integrationsLabel: 'Connected apps',\n maxIntegrationLogos: 6,\n showIntegrationsHint: true,\n // Left unset so the strip can say \"Connect your apps\" or \"Explore connected\n // apps\" depending on what the end user has actually done.\n integrationsHintLabel: undefined as any,\n showIntegrationsToggle: true,\n integrationsToggleLabel: 'Apps in this chat',\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\n * ref={drawerRef}\n * assistantId=\"my-assistant\"\n * options={{\n * position: 'right',\n * width: 400,\n * welcomeMessage: 'Hello! How can I help you?',\n * suggestedMessages: ['Help me with...', 'Tell me about...'],\n * }}\n * modelInterfaceTools={[\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ]}\n * onMessageReceived={(msg) => console.log('Received:', msg)}\n * />\n * ```\n */\nexport const ChatDrawer = forwardRef<ChatDrawerHandle, ChatDrawerProps>(\n function ChatDrawer(props, ref) {\n return (\n <ChatDrawerErrorBoundary>\n <ChatDrawerInner {...props} forwardedRef={ref} />\n </ChatDrawerErrorBoundary>\n );\n }\n);\n\ninterface ChatDrawerInnerProps extends ChatDrawerProps {\n forwardedRef?: React.Ref<ChatDrawerHandle>;\n}\n\nfunction ChatDrawerInner({\n assistantId,\n chatUid: initialChatUid,\n options = {},\n enabledTools,\n modelInterfaceTools,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n tags,\n apiKey,\n baseUrl,\n pollingInterval,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onFileUpload,\n onOpen,\n onClose,\n isOpen: controlledIsOpen,\n className,\n mode = 'drawer',\n onConversationChange,\n forwardedRef,\n}: ChatDrawerInnerProps): JSX.Element {\n // Merge options with defaults\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n // localStorage key for persisting selected conversation\n const storageKey = mergedOptions.persistConversation\n ? `devic-ui-chatUid-${assistantId}`\n : null;\n\n // Resolve initial chatUid: prop takes priority, then localStorage\n const resolvedInitialChatUid = useMemo(() => {\n if (initialChatUid) return initialChatUid;\n if (storageKey) {\n try { return localStorage.getItem(storageKey) || undefined; } catch { return undefined; }\n }\n return undefined;\n }, [initialChatUid, storageKey]);\n\n // Drawer open state (can be controlled or uncontrolled; inline mode is always open)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isInline = mode === 'inline';\n const isOpen = isInline ? true : (controlledIsOpen ?? internalIsOpen);\n\n // Wrap onChatCreated to persist chatUid in localStorage\n const handleChatCreated = useCallback(\n (chatUid: string) => {\n if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n onChatCreated?.(chatUid);\n },\n [storageKey, onChatCreated]\n );\n\n /**\n * What the end user switched off: connected apps by slug, and their own MCP\n * servers by the `toggleId` the API hands out.\n *\n * Remembered in this browser (see `integrationChoice`) rather than only for\n * the life of the drawer — a reload used to forget it, which for someone who\n * keeps an app switched off on purpose reads as the switch not working. The\n * server still keeps nothing beyond the turn it was sent for; what is stored\n * is a preference of whoever is at this keyboard.\n *\n * The badge on the plug is what keeps that honest: a remembered choice is\n * visible at a glance rather than being an unexplained silence from an app.\n */\n const [disabledIntegrations, setDisabledIntegrations] = useState<string[]>([]);\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: resolvedInitialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n subtenantId,\n subtenantMetadata,\n tags,\n enabledTools,\n disabledIntegrations,\n modelInterfaceTools,\n pollingInterval,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated: handleChatCreated,\n onFileUpload,\n messageQueue: mergedOptions.messageQueue,\n debug: mergedOptions.debug,\n });\n\n // Fetch assistant avatar when showAvatar is enabled\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n // The session source, when the page authenticates with one. Every client\n // built below gets it, or a page without an API key would have nothing to\n // authenticate with.\n const resolvedTenantSession = context?.getTenantSession;\n const onSessionExpired = context?.onSessionExpired;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const [coreMemoryOpen, setCoreMemoryOpen] = useState(false);\n const [integrationsOpen, setIntegrationsOpen] = useState(false);\n\n const infoClient = useMemo(\n () =>\n resolvedApiKey || resolvedTenantSession\n ? new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n })\n : null,\n [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]\n );\n\n // Asked for only when something on screen depends on it, and then at most\n // once per assistant however many times this drawer is mounted — a host that\n // remounts it to start a fresh conversation used to pay for the answer again\n // every time.\n const assistantInfo = useAssistantInfo({\n assistantId,\n client: infoClient,\n baseUrl: resolvedBaseUrl,\n credential: resolvedApiKey || 'session',\n enabled:\n (!!mergedOptions.showAvatar && !mergedOptions.avatarUrl) ||\n (mergedOptions.showIntegrationsButton !== false && isOpen),\n });\n // The host's own image wins: an assistant carries one image for everybody, so\n // this is the only place a per-account face can come from. Failing that, an\n // assistant with no uploaded image still gets a face, generated from its\n // identifier — the same one the console shows for it. Drawn from `assistantId`\n // rather than from the fetched assistant so the header is not empty while the\n // lookup is in flight; the two agree, since that is what was asked for.\n const avatarUrl = mergedOptions.showAvatar\n ? (mergedOptions.avatarUrl ??\n assistantInfo.assistant?.imgUrl ??\n avatarUri(\n assistantInfo.assistant?.identifier || assistantId,\n assistantInfo.assistant?.avatarStyle\n ))\n : null;\n\n /**\n * Whether to ask which apps this assistant offers.\n *\n * The listing is worth a request only when there is something to list, and\n * most assistants offer nothing — for those, the call existed purely to be\n * refused, once per page load. The assistant now says so itself, so a plain\n * `false` settles it without asking.\n *\n * Anything else asks, exactly as before: a field that is absent means the API\n * is older than it, not that the answer is no, and a failed lookup means we\n * could not find out. Hiding the button on either would lose the feature for\n * a deployment that has it, which is far worse than one spare request.\n *\n * Where there are apps to show, this puts the two requests in sequence rather\n * than at once, so the listing lands later than it used to. The header holds\n * its place in the meantime — see `pendingIntegrations`.\n */\n const mayOfferIntegrations =\n assistantInfo.settled &&\n assistantInfo.assistant?.tenantIntegrations?.enabled !== false;\n\n // The apps this assistant offers its tenants. Loaded once, here, because the\n // header control cannot decide whether to exist without it — and lent to the\n // modal so opening it does not ask for the same listing again. Nothing is\n // fetched until the drawer is opened for the first time.\n const integrationsState = useIntegrations({\n assistantId,\n tenantId,\n subtenantId,\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n enabled:\n mergedOptions.showIntegrationsButton !== false &&\n isOpen &&\n mayOfferIntegrations,\n });\n\n /**\n * Whether this assistant offers MCP servers of the tenant's own.\n *\n * Read exactly like `mayOfferIntegrations`: absence means \"cannot tell\", so\n * the listing is asked for anyway. A deployment older than the field keeps\n * the behaviour it had — one refusal per drawer open — rather than losing the\n * feature.\n */\n const mayOfferMcp =\n assistantInfo.settled &&\n assistantInfo.assistant?.tenantMcpServers?.enabled !== false;\n\n /**\n * The tenant's own MCP servers, loaded here rather than inside the modal.\n *\n * The composer's switch needs them too, and it is not inside the modal — so\n * the listing has to live above both. The modal takes it as a prop and stops\n * asking for its own.\n */\n const mcpState = useTenantMcp({\n assistantId,\n tenantId,\n subtenantId,\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n enabled:\n mergedOptions.showIntegrationsButton !== false && isOpen && mayOfferMcp,\n });\n\n /**\n * Whether the answer to \"is there anything to show here\" is still on its way.\n *\n * Two requests decide it — what the assistant offers, and then what this\n * tenant has connected — and until both have answered the control cannot\n * know whether to exist. Without this the header simply had a gap and then a\n * button, which reads as the page changing its mind.\n */\n const integrationsDeciding =\n mergedOptions.showIntegrationsButton !== false &&\n isOpen &&\n (!assistantInfo.settled ||\n (mayOfferIntegrations && !integrationsState.settled) ||\n (mayOfferMcp && !mcpState.settled));\n\n /**\n * Placeholder chips to hold while the listing is in flight.\n *\n * Only when the assistant has said outright that it offers apps, and how\n * many: on a maybe there would be nothing to hold the place of half the time,\n * and a control that appears and then vanishes is worse than one that arrives\n * late. So this stays at zero for an API that does not say, which is also the\n * behaviour every version until now had.\n */\n const pendingIntegrations =\n assistantInfo.assistant?.tenantIntegrations?.enabled === true &&\n !integrationsState.settled\n ? (assistantInfo.assistant.tenantIntegrations.count ?? 0)\n : 0;\n\n // Tenant/subtenant resolution mirrors useDevicChat (prop overrides provider).\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedSubtenantId = subtenantId || context?.subtenantId;\n\n // ── Remembering which apps and servers are switched off ────────────────\n\n const choiceKey = integrationChoiceKey(\n assistantId,\n resolvedTenantId,\n resolvedSubtenantId\n );\n\n // Loaded per key, so switching tenant loads that tenant's choice rather than\n // carrying the previous one over.\n const loadedChoiceRef = useRef<string | null>(null);\n useEffect(() => {\n if (loadedChoiceRef.current === choiceKey) return;\n loadedChoiceRef.current = choiceKey;\n setDisabledIntegrations(readIntegrationChoice(choiceKey));\n }, [choiceKey]);\n\n useEffect(() => {\n // Only once this key's stored value has been read, or the empty initial\n // state would erase it before it was ever loaded.\n if (loadedChoiceRef.current !== choiceKey) return;\n writeIntegrationChoice(choiceKey, disabledIntegrations);\n }, [choiceKey, disabledIntegrations]);\n\n /**\n * Forgets what is no longer on offer, once the listings can say so.\n *\n * Every clause of this is load-bearing. `mayOffer*` is false BEFORE the\n * assistant has answered as well as when the answer is no, so without the\n * `assistantInfo.settled` guard the prune runs on the first render against\n * two empty listings and erases the very thing that was just loaded — which\n * is exactly the reload-forgets-it bug this was meant to fix. A definite\n * \"this assistant offers none\" is an answer; an unsettled listing is not.\n *\n * With the drawer never opened, neither listing is ever fetched, so nothing\n * is pruned and the stored choice survives untouched.\n */\n const appsKnown =\n assistantInfo.settled && (!mayOfferIntegrations || integrationsState.settled);\n const mcpKnown = assistantInfo.settled && (!mayOfferMcp || mcpState.settled);\n useEffect(() => {\n if (!appsKnown || !mcpKnown) return;\n const live = [\n ...integrationsState.integrations\n .filter((i) => i.connected)\n .map((i) => i.app),\n ...mcpState.servers\n .filter((s) => s.connection?.status === 'active' && s.connection.toggleId)\n .map((s) => s.connection!.toggleId as string),\n ];\n setDisabledIntegrations((prev) => pruneIntegrationChoice(prev, live));\n }, [appsKnown, mcpKnown, integrationsState.integrations, mcpState.servers]);\n\n // Usage bar (above the input) — only when enabled and a tenant is known.\n // Refetches after each turn via the message count as refresh key.\n const usageBarNode =\n (mergedOptions.showUsageBar ||\n typeof mergedOptions.customUsageBar === 'function') &&\n resolvedTenantId ? (\n <UsageBar\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n tenantId={resolvedTenantId}\n subtenantId={resolvedSubtenantId}\n mode={mergedOptions.showUsageBar === 'onDemand' ? 'onDemand' : 'always'}\n metric={mergedOptions.usageBarMetric}\n display={mergedOptions.usageBarDisplay}\n customUsageBar={mergedOptions.customUsageBar}\n color={mergedOptions.color}\n refreshKey={chat.messages.length}\n debug={mergedOptions.debug}\n />\n ) : null;\n\n // Default usage-limit banner (above the input) — opt-out via hideLimitBanner,\n // override via limitBannerRenderer.\n const limitBannerNode =\n chat.limitExceeded && !mergedOptions.hideLimitBanner\n ? mergedOptions.limitBannerRenderer\n ? mergedOptions.limitBannerRenderer(chat.limitExceeded)\n : <LimitBanner limit={chat.limitExceeded} />\n : null;\n\n // Speech-to-text transcription, exposed to custom prompt boxes so a developer\n // can transcribe audio (binary or URL) and attach the resulting transcriptId.\n const transcribeAudio = useCallback(\n (\n audio: Blob | string,\n transcribeOptions?: {\n language?: string;\n messageUid?: string;\n chatUid?: string;\n tenantId?: string;\n },\n ) => {\n if (!resolvedApiKey && !resolvedTenantSession) {\n return Promise.reject(\n new Error('No credentials configured. Cannot transcribe audio.'),\n );\n }\n const client = new DevicApiClient({ apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl, getTenantSession: resolvedTenantSession, onSessionExpired });\n return client.transcribeAudio(audio, {\n language: transcribeOptions?.language ?? mergedOptions.speechLanguage,\n messageUid: transcribeOptions?.messageUid,\n chatUid: transcribeOptions?.chatUid,\n tenantId: transcribeOptions?.tenantId ?? tenantId,\n });\n },\n [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl, mergedOptions.speechLanguage, tenantId],\n );\n\n // Handle open/close\n const handleOpen = useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleToggle = useCallback(() => {\n setInternalIsOpen((prev) => !prev);\n }, []);\n\n // Expose handle for programmatic control\n useImperativeHandle(forwardedRef, () => ({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n setChatUid: (chatUid: string) => {\n chat.loadChat(chatUid);\n },\n sendMessage: (message: string) => {\n chat.sendMessage(message);\n },\n }), [handleOpen, handleClose, handleToggle, chat]);\n\n // Register this drawer in the DevicProvider so AIElementWrapper can open it\n useEffect(() => {\n if (!context?.registerDrawer) return;\n const unregister = context.registerDrawer({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n sendMessage: (message: string) => chat.sendMessage(message),\n });\n return unregister;\n }, [context, handleOpen, handleClose, handleToggle, chat]);\n\n // Partition pending widget calls by render mode\n const { inlineWidgets, inputWidget } = useMemo(() => {\n const inline: typeof chat.pendingWidgetCalls = [];\n let input: typeof chat.pendingWidgetCalls[number] | null = null;\n for (const wc of chat.pendingWidgetCalls) {\n if (wc.widget.render === 'input' && !input) {\n input = wc;\n } else {\n inline.push(wc);\n }\n }\n return { inlineWidgets: inline, inputWidget: input };\n }, [chat.pendingWidgetCalls]);\n\n // Active references from DevicProvider (created by AIElementWrapper)\n const references = context?.references ?? [];\n const removeReference = useCallback(\n (id: string) => {\n context?.removeReference(id);\n },\n [context]\n );\n const clearReferences = useCallback(() => {\n context?.clearReferences();\n }, [context]);\n\n // Handle send message — prefix references and clear them after sending\n /**\n * What the last accepted message was told about when it gets picked up. Only\n * the wording of the notice depends on it.\n */\n const [queueDisposition, setQueueDisposition] = useState<\n QueueDisposition | undefined\n >();\n /**\n * What became of a message that did not simply join the queue: it was turned\n * down, or a stop threw it away. Said out loud, because in both cases the\n * user's text has just moved back into the box on its own.\n */\n const [queueAlert, setQueueAlert] = useState<string | null>(null);\n\n const handleSend = useCallback(\n async (\n message: string,\n files?: File[],\n meta?: { transcriptId?: string; tags?: string[] }\n ) => {\n let finalMessage = message;\n if (references.length > 0) {\n const labels = references.map((r) => `\"${r.label}\"`).join(', ');\n finalMessage = `Elemento referenciado: ${labels}\\n\\n${message}`;\n }\n setQueueAlert(null);\n const result = await chat.sendMessage(finalMessage, {\n files,\n transcriptId: meta?.transcriptId,\n tags: meta?.tags,\n });\n\n if ('rejected' in result) {\n // The references belong to the message that was not sent, so they stay.\n if (result.reason !== 'error') {\n // An ordinary error already reaches the host through `onError`; these\n // two do not, and the only sign of them would otherwise be the text\n // reappearing in the box with no explanation.\n setQueueAlert(\n result.reason === 'queue_full'\n ? `${result.message} Your message is back in the box.`\n : 'The assistant is not taking messages while it works. Your message is back in the box.'\n );\n }\n return result;\n }\n\n setQueueDisposition('queued' in result && result.queued ? result.willProcess : undefined);\n if (references.length > 0) clearReferences();\n return result;\n },\n [chat, references, clearReferences]\n );\n\n /**\n * Whether a message may be written while the assistant is working.\n *\n * Being busy is not the only reason the box closes, and the other two are not\n * about waiting: an inline widget is the assistant waiting on *this* user, and\n * a usage limit is a refusal the queue cannot soften.\n */\n const canQueue =\n chat.queueEnabled && inlineWidgets.length === 0 && !chat.limitExceeded;\n\n const handleStopChat = useCallback(async () => {\n const result = await chat.stopChat();\n setQueueDisposition(undefined);\n setQueueAlert(\n result.discarded\n ? `${result.discarded === 1 ? 'A queued message was' : `${result.discarded} queued messages were`} not sent — the text is back in the box.`\n : null\n );\n return result;\n }, [chat]);\n\n /**\n * Shown while there is something to explain: the user is writing into a run\n * that has not finished, or messages are already waiting. With nothing typed\n * and nothing queued there is nothing to say.\n */\n const queueNoticeNode =\n !mergedOptions.hideQueueNotice &&\n // `queuedCount` on its own matters: an assistant with an input delay queues\n // what is written into an *idle* conversation whether or not it takes\n // messages while busy, so there can be something waiting with the queue\n // switched off.\n (queueAlert || chat.queuedCount > 0 || (canQueue && chat.isLoading))\n ? mergedOptions.queueNoticeRenderer\n ? mergedOptions.queueNoticeRenderer({\n queuedCount: chat.queuedCount,\n willProcess: queueDisposition,\n alert: queueAlert ?? undefined,\n })\n : (\n <QueueNotice\n queuedCount={chat.queuedCount}\n willProcess={queueDisposition}\n alert={queueAlert ?? undefined}\n />\n )\n : null;\n\n // Handle conversation selection\n const handleConversationSelect = useCallback(\n (chatUid: string) => {\n chat.loadChat(chatUid);\n onConversationChange?.(chatUid);\n if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n },\n [chat, onConversationChange, storageKey]\n );\n\n const handleNewChat = useCallback(() => {\n chat.clearChat();\n if (storageKey) {\n try { localStorage.removeItem(storageKey); } catch {}\n }\n }, [chat, storageKey]);\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Feedback state\n const [feedbackMap, setFeedbackMap] = useState<Map<string, 'positive' | 'negative'>>(new Map());\n const feedbackClientRef = useRef<DevicApiClient | null>(null);\n\n // Initialize feedback client\n useEffect(() => {\n if ((resolvedApiKey || resolvedTenantSession) && !feedbackClientRef.current) {\n feedbackClientRef.current = new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n getTenantSession: resolvedTenantSession,\n onSessionExpired,\n });\n }\n }, [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]);\n\n // Load existing feedback when chat changes\n useEffect(() => {\n if (!chat.chatUid || !feedbackClientRef.current || !mergedOptions.showFeedback) return;\n\n feedbackClientRef.current.getChatFeedback(assistantId, chat.chatUid)\n .then((entries) => {\n const newMap = new Map<string, 'positive' | 'negative'>();\n for (const entry of entries) {\n if (entry.feedback !== undefined) {\n newMap.set(entry.requestId, entry.feedback ? 'positive' : 'negative');\n }\n }\n setFeedbackMap(newMap);\n })\n .catch(() => {\n // Silently ignore feedback loading errors\n });\n }, [chat.chatUid, assistantId, mergedOptions.showFeedback]);\n\n // Handle feedback submission\n const handleFeedback = useCallback(\n async (messageId: string, positive: boolean, comment?: string) => {\n if (!chat.chatUid || !feedbackClientRef.current) return;\n\n try {\n await feedbackClientRef.current.submitChatFeedback(assistantId, chat.chatUid, {\n messageId,\n feedback: positive,\n feedbackComment: comment,\n });\n\n setFeedbackMap((prev) => {\n const newMap = new Map(prev);\n newMap.set(messageId, positive ? 'positive' : 'negative');\n return newMap;\n });\n } catch (err) {\n console.error('Failed to submit feedback:', err);\n throw err;\n }\n },\n [chat.chatUid, assistantId]\n );\n\n // Apply CSS variables for theming on the drawer element itself\n // (must target the component root so they override the defaults defined on .devic-chat-drawer)\n const drawerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = drawerRef.current;\n if (!el) return;\n const vars: [string, string | undefined][] = [\n ['--devic-primary', mergedOptions.color !== DEFAULT_OPTIONS.color ? mergedOptions.color : undefined],\n ['--devic-font-family', mergedOptions.fontFamily],\n ['--devic-bg', mergedOptions.backgroundColor],\n ['--devic-text', mergedOptions.textColor],\n ['--devic-bg-secondary', mergedOptions.secondaryBackgroundColor],\n ['--devic-border', mergedOptions.borderColor],\n ['--devic-user-bubble', mergedOptions.userBubbleColor],\n ['--devic-user-bubble-text', mergedOptions.userBubbleTextColor],\n ['--devic-assistant-bubble', mergedOptions.assistantBubbleColor],\n ['--devic-assistant-bubble-text', mergedOptions.assistantBubbleTextColor],\n ['--devic-send-btn', mergedOptions.sendButtonColor],\n ];\n for (const [name, value] of vars) {\n if (value) {\n el.style.setProperty(name, value);\n } else {\n el.style.removeProperty(name);\n }\n }\n }, [mergedOptions.color, mergedOptions.fontFamily, mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.secondaryBackgroundColor, mergedOptions.borderColor, mergedOptions.userBubbleColor, mergedOptions.userBubbleTextColor, mergedOptions.assistantBubbleColor, mergedOptions.assistantBubbleTextColor, mergedOptions.sendButtonColor]);\n\n // The same values, handed to the dialogs this drawer opens. They render\n // through a portal into document.body, so the variables set above — which\n // live on the drawer element — never reach them.\n // The brain button says what the modal it opens is called.\n const coreMemoryTitle =\n mergedOptions.coreMemoryLabels?.title ?? DEFAULT_CORE_MEMORY_LABELS.title;\n\n const modalTheme: DevicTheme = useMemo(\n () => ({\n color:\n mergedOptions.color !== DEFAULT_OPTIONS.color\n ? mergedOptions.color\n : undefined,\n fontFamily: mergedOptions.fontFamily,\n backgroundColor: mergedOptions.backgroundColor,\n textColor: mergedOptions.textColor,\n secondaryBackgroundColor: mergedOptions.secondaryBackgroundColor,\n borderColor: mergedOptions.borderColor,\n }),\n [\n mergedOptions.color,\n mergedOptions.fontFamily,\n mergedOptions.backgroundColor,\n mergedOptions.textColor,\n mergedOptions.secondaryBackgroundColor,\n mergedOptions.borderColor,\n ]\n );\n\n // The strip above the composer. Dismissed per end user, because the whole\n // point of remembering a dismissal is that the same person is not told twice.\n const integrationsHintNode =\n mergedOptions.showIntegrationsButton !== false &&\n mergedOptions.showIntegrationsHint !== false ? (\n <IntegrationsHint\n state={integrationsState}\n onOpen={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsHintLabel}\n maxLogos={mergedOptions.maxIntegrationLogos}\n storageKey={`${assistantId}:${resolvedTenantId ?? ''}:${resolvedSubtenantId ?? ''}`}\n dark={isDarkTheme(modalTheme)}\n />\n ) : null;\n\n // The per-message switch in the composer row. Shown only where there is\n // something to switch — the control returns null with nothing connected —\n // and hidden outright by `showIntegrationsToggle: false`.\n const integrationsToggleNode =\n mergedOptions.showIntegrationsButton !== false &&\n mergedOptions.showIntegrationsToggle !== false ? (\n <IntegrationsToggle\n state={integrationsState}\n mcp={mcpState}\n disabled={disabledIntegrations}\n onChange={setDisabledIntegrations}\n onManage={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsToggleLabel}\n dark={isDarkTheme(modalTheme)}\n busy={chat.isLoading}\n loading={integrationsDeciding}\n />\n ) : null;\n\n // Resizable drawer\n const [resizedWidth, setResizedWidth] = useState<number | null>(null);\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const startX = e.clientX;\n const startWidth = drawerRef.current?.offsetWidth ?? 0;\n const isLeft = mergedOptions.position === 'left';\n\n const onMove = (ev: MouseEvent) => {\n const delta = ev.clientX - startX;\n const newWidth = startWidth + (isLeft ? delta : -delta);\n const clamped = Math.min(\n mergedOptions.maxWidth,\n Math.max(mergedOptions.minWidth, newWidth)\n );\n setResizedWidth(clamped);\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n },\n [mergedOptions.position, mergedOptions.minWidth, mergedOptions.maxWidth]\n );\n\n // Build style object\n const baseWidth = resizedWidth\n ? `${resizedWidth}px`\n : typeof mergedOptions.width === 'number'\n ? `${mergedOptions.width}px`\n : mergedOptions.width;\n\n const drawerStyle = useMemo(\n () => ({\n width: baseWidth,\n zIndex: mergedOptions.zIndex,\n borderRadius: typeof mergedOptions.borderRadius === 'number'\n ? `${mergedOptions.borderRadius}px`\n : mergedOptions.borderRadius,\n ...mergedOptions.style,\n }),\n [baseWidth, mergedOptions.zIndex, mergedOptions.borderRadius, mergedOptions.style]\n );\n\n const overlayStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n }),\n [mergedOptions.zIndex]\n );\n\n const triggerStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n [mergedOptions.position]: 20,\n bottom: 20,\n }),\n [mergedOptions.zIndex, mergedOptions.position]\n );\n\n return (\n <>\n {/* Overlay (drawer mode only) */}\n {!isInline && (\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n )}\n\n {/* Drawer */}\n <div\n ref={drawerRef}\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n data-mode={mode}\n style={drawerStyle}\n >\n {/* Resize handle */}\n {mergedOptions.resizable && (\n <div\n className=\"devic-resize-handle\"\n data-position={mergedOptions.position}\n onMouseDown={handleResizeStart}\n />\n )}\n\n {/* Header */}\n <div className=\"devic-drawer-header\">\n {avatarUrl && (\n <img\n className=\"devic-drawer-avatar\"\n src={avatarUrl}\n alt=\"\"\n aria-hidden=\"true\"\n />\n )}\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <ConversationSelector\n assistantId={assistantId}\n currentChatUid={chat.chatUid}\n onSelect={handleConversationSelect}\n onNewChat={handleNewChat}\n apiKey={apiKey}\n baseUrl={baseUrl}\n tenantId={tenantId}\n subtenantId={subtenantId}\n conversationPreview={mergedOptions.conversationPreview}\n />\n <div className=\"devic-drawer-header-actions\">\n {mergedOptions.showIntegrationsButton !== false && (\n <IntegrationsLauncher\n state={integrationsState}\n mcp={mcpState}\n onClick={() => setIntegrationsOpen(true)}\n label={mergedOptions.integrationsLabel}\n maxLogos={mergedOptions.maxIntegrationLogos}\n dark={isDarkTheme(modalTheme)}\n placeholders={pendingIntegrations}\n loading={integrationsDeciding}\n />\n )}\n {mergedOptions.showCoreMemoryButton && (\n <button\n className=\"devic-new-chat-btn\"\n onClick={() => setCoreMemoryOpen(true)}\n type=\"button\"\n aria-label={coreMemoryTitle}\n title={coreMemoryTitle}\n >\n <BrainIcon />\n </button>\n )}\n <button\n className=\"devic-new-chat-btn\"\n onClick={handleNewChat}\n type=\"button\"\n aria-label=\"New chat\"\n title=\"New chat\"\n >\n <PlusIcon />\n </button>\n {!isInline && (\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {chat.error && (\n <div className=\"devic-error\">\n {chat.error.message}\n </div>\n )}\n\n {/* Messages */}\n <ChatMessages\n messages={chat.messages}\n allMessages={chat.messages}\n isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n toolRenderers={mergedOptions.toolRenderers}\n toolIcons={mergedOptions.toolIcons}\n loadingIndicator={mergedOptions.loadingIndicator}\n showFeedback={mergedOptions.showFeedback}\n feedbackMap={feedbackMap}\n onFeedback={handleFeedback}\n handedOffSubThreadId={chat.handedOffSubThreadId || undefined}\n onHandoffCompleted={chat.onHandoffCompleted}\n handoffWidgetRenderer={mergedOptions.handoffWidgetRenderer}\n toolGroups={mergedOptions.toolGroups}\n userMessageRenderer={mergedOptions.userMessageRenderer}\n assistantMessageRenderer={mergedOptions.assistantMessageRenderer}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n pollingInterval={pollingInterval}\n pendingInlineWidgets={inlineWidgets}\n onSubmitWidget={chat.submitWidgetResponse}\n onCancelWidget={chat.cancelWidgetCall}\n recalledMemories={\n mergedOptions.showRecalledMemories\n ? chat.recalledMemories\n : undefined\n }\n recalledMemoriesRenderer={mergedOptions.recalledMemoriesRenderer}\n compactions={\n mergedOptions.showCompaction ? chat.compactions : undefined\n }\n compaction={\n mergedOptions.showCompaction ? chat.compaction : undefined\n }\n compactionRenderer={mergedOptions.compactionRenderer}\n expandableCompaction={mergedOptions.expandableCompaction}\n />\n\n {/* Input */}\n {mergedOptions.customPromptBox ? (\n <div className=\"devic-input-area\">\n {limitBannerNode}\n {usageBarNode}\n {integrationsHintNode}\n {queueNoticeNode}\n {mergedOptions.customPromptBox({\n sendMessage: handleSend,\n transcribeAudio,\n stop: chat.stopChat,\n isLoading: chat.isLoading,\n queueEnabled: canQueue,\n queuedCount: chat.queuedCount,\n newConversation: chat.clearChat,\n references,\n removeReference,\n clearReferences,\n limitExceeded: chat.limitExceeded,\n })}\n </div>\n ) : (\n <ChatInput\n onSend={handleSend}\n disabled={\n // `handedOff` is one of the states the queue covers — the\n // conversation is waiting on a subagent, which in an embedded\n // widget can take minutes — so with queueing on it no longer\n // closes the box. A pending widget and a usage limit still do:\n // one is the assistant waiting on this user, the other a refusal.\n (chat.isLoading && !canQueue) ||\n (chat.handedOff && !canQueue) ||\n inlineWidgets.length > 0 ||\n !!chat.limitExceeded\n }\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n enableLongTextPaste={mergedOptions.enableLongTextPaste}\n longTextPasteThreshold={mergedOptions.longTextPasteThreshold}\n enableSpeechToText={mergedOptions.enableSpeechToText}\n speechLanguage={mergedOptions.speechLanguage}\n speechTenantId={tenantId}\n speechAutoStop={mergedOptions.speechAutoStop}\n speechAutoStopCountdownMs={mergedOptions.speechAutoStopCountdownMs}\n speechAutoStopSilenceMs={mergedOptions.speechAutoStopSilenceMs}\n speechAutoStopSilenceRatio={mergedOptions.speechAutoStopSilenceRatio}\n speechAutoStopSilenceLevel={mergedOptions.speechAutoStopSilenceLevel}\n speechAutoStopSpeechLevel={mergedOptions.speechAutoStopSpeechLevel}\n speechHandoff={mergedOptions.speechHandoff}\n speechHandoffSendDelayMs={mergedOptions.speechHandoffSendDelayMs}\n speechHandoffHoldMs={mergedOptions.speechHandoffHoldMs}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n sendButtonContent={mergedOptions.sendButtonContent}\n disabledMessage={\n chat.handedOff\n ? 'Waiting for subagent to complete'\n : inlineWidgets.length > 0\n ? 'Waiting for tool response'\n : undefined\n }\n isProcessing={chat.isLoading && !chat.handedOff}\n onStop={handleStopChat}\n allowQueueing={canQueue}\n queueNotice={queueNoticeNode}\n stopButtonContent={mergedOptions.stopButtonContent}\n pendingInputWidget={inputWidget}\n onSubmitWidget={chat.submitWidgetResponse}\n onCancelWidget={chat.cancelWidgetCall}\n references={references}\n onRemoveReference={removeReference}\n usageBar={usageBarNode}\n limitBanner={limitBannerNode}\n integrationsHint={integrationsHintNode}\n integrationsToggle={integrationsToggleNode}\n />\n )}\n </div>\n\n {/* Trigger button (drawer mode only, when closed) */}\n {!isInline && !isOpen && (\n <button\n className=\"devic-trigger\"\n onClick={handleOpen}\n style={triggerStyle}\n type=\"button\"\n aria-label=\"Open chat\"\n >\n <ChatIcon />\n </button>\n )}\n\n {/* Core memory modal (opened from the header brain button) */}\n {mergedOptions.showCoreMemoryButton && (\n <CoreMemoryModal\n isOpen={coreMemoryOpen}\n onClose={() => setCoreMemoryOpen(false)}\n assistantId={assistantId}\n tenantId={tenantId}\n subtenantId={subtenantId}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n labels={mergedOptions.coreMemoryLabels}\n theme={modalTheme}\n />\n )}\n\n {/* Connected apps modal (opened from the header app stack) */}\n {mergedOptions.showIntegrationsButton !== false && (\n <IntegrationsModal\n isOpen={integrationsOpen}\n onClose={() => setIntegrationsOpen(false)}\n assistantId={assistantId}\n tenantId={tenantId}\n subtenantId={subtenantId}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n title={mergedOptions.integrationsLabel}\n theme={modalTheme}\n state={integrationsState}\n mcpState={mcpState}\n />\n )}\n </>\n );\n}\n\n/**\n * Brain icon for the core memory button\n */\nfunction BrainIcon(): JSX.Element {\n return (\n <svg\n width=\"17\"\n height=\"17\"\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=\"M9.5 2a2.5 2.5 0 0 0-2.45 2A3.5 3.5 0 0 0 4.6 8.6 3.5 3.5 0 0 0 3 11.5c0 1.1.5 2.08 1.29 2.73A3.5 3.5 0 0 0 7 20a3 3 0 0 0 5-2.24V4.5A2.5 2.5 0 0 0 9.5 2Z\" />\n <path d=\"M14.5 2a2.5 2.5 0 0 1 2.45 2 3.5 3.5 0 0 1 2.45 4.6A3.5 3.5 0 0 1 21 11.5a3.49 3.49 0 0 1-1.29 2.73A3.5 3.5 0 0 1 17 20a3 3 0 0 1-5-2.24V4.5A2.5 2.5 0 0 1 14.5 2Z\" />\n </svg>\n );\n}\n\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Plus icon for new chat button\n */\nfunction PlusIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n\n/**\n * Chat icon for trigger button\n */\nfunction ChatIcon(): JSX.Element {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z\" />\n </svg>\n );\n}\n"],"names":["forwardRef","_jsx","ChatDrawerErrorBoundary","useMemo","useState","useCallback","useDevicChat","useOptionalDevicContext","DevicApiClient","assistantInfo","useAssistantInfo","avatarUri","useIntegrations","useTenantMcp","integrationChoiceKey","useRef","useEffect","readIntegrationChoice","writeIntegrationChoice","pruneIntegrationChoice","UsageBar","LimitBanner","client","useImperativeHandle","QueueNotice","DEFAULT_CORE_MEMORY_LABELS","IntegrationsHint","isDarkTheme","IntegrationsToggle","_jsxs","_Fragment","ConversationSelector","IntegrationsLauncher","ChatMessages","ChatInput","CoreMemoryModal","IntegrationsModal"],"mappings":"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"}
|
|
@@ -317,7 +317,7 @@ function extractSubThreadId(toolCallId, allMessages, handedOffSubThreadId) {
|
|
|
317
317
|
// Fall back to active handoff subthread ID
|
|
318
318
|
return handedOffSubThreadId || null;
|
|
319
319
|
}
|
|
320
|
-
function ChatMessages({ messages, allMessages, isLoading, welcomeMessage, suggestedMessages, onSuggestedClick, toolRenderers, toolIcons, loadingIndicator, showFeedback = true, feedbackMap, onFeedback, handedOffSubThreadId, onHandoffCompleted, handoffWidgetRenderer, toolGroups, userMessageRenderer, assistantMessageRenderer, apiKey, baseUrl, pollingInterval, pendingInlineWidgets, onSubmitWidget, onCancelWidget, recalledMemories, recalledMemoriesRenderer, compactions, compaction, compactionRenderer, }) {
|
|
320
|
+
function ChatMessages({ messages, allMessages, isLoading, welcomeMessage, suggestedMessages, onSuggestedClick, toolRenderers, toolIcons, loadingIndicator, showFeedback = true, feedbackMap, onFeedback, handedOffSubThreadId, onHandoffCompleted, handoffWidgetRenderer, toolGroups, userMessageRenderer, assistantMessageRenderer, apiKey, baseUrl, pollingInterval, pendingInlineWidgets, onSubmitWidget, onCancelWidget, recalledMemories, recalledMemoriesRenderer, compactions, compaction, compactionRenderer, expandableCompaction, }) {
|
|
321
321
|
const containerRef = React.useRef(null);
|
|
322
322
|
const prevLengthRef = React.useRef(messages.length);
|
|
323
323
|
// Anchor each recall record to the message that brought it in: the
|
|
@@ -385,7 +385,7 @@ function ChatMessages({ messages, allMessages, isLoading, welcomeMessage, sugges
|
|
|
385
385
|
};
|
|
386
386
|
}, [compactions, messages]);
|
|
387
387
|
const compactionsFor = (uids) => uids.flatMap((uid) => compactionsByAnchor.get(uid) ?? []);
|
|
388
|
-
const renderCompactions = (checkpoints) => checkpoints.map((checkpoint) => (jsxRuntime.jsx(CompactionWidget.CompactionWidget, { checkpoint: checkpoint, isActive: checkpoint.uid === activeCompactionUid, renderer: compactionRenderer }, checkpoint.uid)));
|
|
388
|
+
const renderCompactions = (checkpoints) => checkpoints.map((checkpoint) => (jsxRuntime.jsx(CompactionWidget.CompactionWidget, { checkpoint: checkpoint, isActive: checkpoint.uid === activeCompactionUid, renderer: compactionRenderer, expandable: expandableCompaction }, checkpoint.uid)));
|
|
389
389
|
// Auto-scroll to bottom when new messages arrive
|
|
390
390
|
React.useEffect(() => {
|
|
391
391
|
if (containerRef.current) {
|