@copilotz/chat-adapter 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +48 -56
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -197,6 +197,7 @@ interface UseCopilotzOptions {
|
|
|
197
197
|
}
|
|
198
198
|
declare function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, urlSync }: UseCopilotzOptions): {
|
|
199
199
|
messages: ChatMessage[];
|
|
200
|
+
isMessagesLoading: boolean;
|
|
200
201
|
threads: ChatThread[];
|
|
201
202
|
currentThreadId: string | null;
|
|
202
203
|
isStreaming: boolean;
|
package/dist/index.js
CHANGED
|
@@ -343,14 +343,13 @@ async function runCopilotzStream(options) {
|
|
|
343
343
|
if (parts.length === 1 && parts[0].type === "text") return parts[0].text;
|
|
344
344
|
return parts;
|
|
345
345
|
})();
|
|
346
|
-
const agentIdentifier = selectedAgent || "assistant";
|
|
347
346
|
const payload = {
|
|
348
347
|
content: contentParts,
|
|
349
348
|
sender: {
|
|
350
349
|
type: normalizedToolCalls.length > 0 ? "agent" : "user",
|
|
351
350
|
externalId: user.externalId,
|
|
352
|
-
id: normalizedToolCalls.length > 0 ?
|
|
353
|
-
name: normalizedToolCalls.length > 0 ?
|
|
351
|
+
id: normalizedToolCalls.length > 0 ? "assistant" : void 0,
|
|
352
|
+
name: normalizedToolCalls.length > 0 ? "assistant" : user.name ?? null,
|
|
354
353
|
metadata: Object.keys(senderMetadata).length > 0 ? senderMetadata : null
|
|
355
354
|
},
|
|
356
355
|
metadata: messageMetadata ?? null,
|
|
@@ -579,37 +578,37 @@ async function getAssetDataUrl(refOrId) {
|
|
|
579
578
|
return { dataUrl: data.dataUrl, mime: data.mime, assetId: data.assetId };
|
|
580
579
|
}
|
|
581
580
|
async function resolveAssetsInMessages(messages) {
|
|
582
|
-
const
|
|
583
|
-
|
|
581
|
+
const inFlightByRef = /* @__PURE__ */ new Map();
|
|
582
|
+
const resolveAssetRef = (assetRef) => {
|
|
583
|
+
if (!inFlightByRef.has(assetRef)) {
|
|
584
|
+
inFlightByRef.set(assetRef, getAssetDataUrl(assetRef));
|
|
585
|
+
}
|
|
586
|
+
return inFlightByRef.get(assetRef);
|
|
587
|
+
};
|
|
588
|
+
return Promise.all(messages.map(async (msg) => {
|
|
584
589
|
const meta = msg.metadata ?? void 0;
|
|
585
590
|
const attachments = Array.isArray(meta?.attachments) ? meta.attachments : void 0;
|
|
586
591
|
if (!attachments || attachments.length === 0) {
|
|
587
|
-
|
|
588
|
-
continue;
|
|
592
|
+
return msg;
|
|
589
593
|
}
|
|
590
|
-
const newAttachments =
|
|
591
|
-
for (const att of attachments) {
|
|
594
|
+
const newAttachments = await Promise.all(attachments.map(async (att) => {
|
|
592
595
|
const assetRef = typeof att?.assetRef === "string" ? att.assetRef : void 0;
|
|
593
|
-
if (assetRef)
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
} else {
|
|
606
|
-
newAttachments.push(att);
|
|
596
|
+
if (!assetRef) return att;
|
|
597
|
+
try {
|
|
598
|
+
const { dataUrl, mime } = await resolveAssetRef(assetRef);
|
|
599
|
+
const kind = typeof att.kind === "string" ? att.kind : "image";
|
|
600
|
+
return {
|
|
601
|
+
kind,
|
|
602
|
+
dataUrl,
|
|
603
|
+
mimeType: typeof att.mimeType === "string" ? att.mimeType : mime ?? void 0
|
|
604
|
+
};
|
|
605
|
+
} catch {
|
|
606
|
+
return att;
|
|
607
607
|
}
|
|
608
|
-
}
|
|
608
|
+
}));
|
|
609
609
|
const newMeta = { ...meta ?? {}, attachments: newAttachments };
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
return resolved;
|
|
610
|
+
return { ...msg, metadata: newMeta };
|
|
611
|
+
}));
|
|
613
612
|
}
|
|
614
613
|
|
|
615
614
|
// src/useUrlState.ts
|
|
@@ -787,6 +786,7 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
787
786
|
const [currentThreadId, setCurrentThreadId] = useState2(null);
|
|
788
787
|
const [currentThreadExternalId, setCurrentThreadExternalId] = useState2(null);
|
|
789
788
|
const [messages, setMessages] = useState2([]);
|
|
789
|
+
const [isMessagesLoading, setIsMessagesLoading] = useState2(false);
|
|
790
790
|
const [isStreaming, setIsStreaming] = useState2(false);
|
|
791
791
|
const [userContextSeed, setUserContextSeed] = useState2(initialContext || {});
|
|
792
792
|
const preferredAgentRef = useRef2(preferredAgentName ?? null);
|
|
@@ -932,8 +932,9 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
932
932
|
}
|
|
933
933
|
}, [updateThreadsState]);
|
|
934
934
|
const loadThreadMessages = useCallback2(async (threadId) => {
|
|
935
|
-
const requestId =
|
|
935
|
+
const requestId = messagesRequestRef.current + 1;
|
|
936
936
|
messagesRequestRef.current = requestId;
|
|
937
|
+
setIsMessagesLoading(true);
|
|
937
938
|
try {
|
|
938
939
|
const rawMessages = await fetchThreadMessages(threadId);
|
|
939
940
|
const resolvedMessages = await resolveAssetsInMessages(rawMessages);
|
|
@@ -960,15 +961,22 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
960
961
|
} catch (error) {
|
|
961
962
|
if (isAbortError(error)) return;
|
|
962
963
|
console.error(`Error loading messages for thread ${threadId}`, error);
|
|
964
|
+
} finally {
|
|
965
|
+
if (messagesRequestRef.current === requestId) {
|
|
966
|
+
setIsMessagesLoading(false);
|
|
967
|
+
}
|
|
963
968
|
}
|
|
964
969
|
}, [processToolOutput]);
|
|
965
970
|
const handleSelectThread = useCallback2(async (threadId) => {
|
|
966
971
|
setCurrentThreadId(threadId);
|
|
972
|
+
setMessages([]);
|
|
967
973
|
const extMap = threadExternalIdMapRef.current;
|
|
968
974
|
setCurrentThreadExternalId(extMap[threadId] ?? null);
|
|
969
975
|
await loadThreadMessages(threadId);
|
|
970
976
|
}, [loadThreadMessages]);
|
|
971
977
|
const handleCreateThread = useCallback2((title) => {
|
|
978
|
+
messagesRequestRef.current += 1;
|
|
979
|
+
setIsMessagesLoading(false);
|
|
972
980
|
const id = generateId();
|
|
973
981
|
const now = nowTs();
|
|
974
982
|
const newThread = {
|
|
@@ -1104,28 +1112,6 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1104
1112
|
params.onBeforeStart?.(currentAssistantId);
|
|
1105
1113
|
let hasStreamProgress = false;
|
|
1106
1114
|
let pendingStartNewAssistantBubble = false;
|
|
1107
|
-
const ensureStreamingPlaceholder = () => {
|
|
1108
|
-
setMessages((prev) => {
|
|
1109
|
-
const last = prev[prev.length - 1];
|
|
1110
|
-
if (last && last.role === "assistant" && last.isStreaming) {
|
|
1111
|
-
currentAssistantId = last.id;
|
|
1112
|
-
return prev;
|
|
1113
|
-
}
|
|
1114
|
-
const newId = generateId();
|
|
1115
|
-
currentAssistantId = newId;
|
|
1116
|
-
return [
|
|
1117
|
-
...prev,
|
|
1118
|
-
{
|
|
1119
|
-
id: newId,
|
|
1120
|
-
role: "assistant",
|
|
1121
|
-
content: "",
|
|
1122
|
-
timestamp: nowTs(),
|
|
1123
|
-
isStreaming: true,
|
|
1124
|
-
isComplete: false
|
|
1125
|
-
}
|
|
1126
|
-
];
|
|
1127
|
-
});
|
|
1128
|
-
};
|
|
1129
1115
|
const updateStreamingMessage = (partial, isComplete) => {
|
|
1130
1116
|
if (partial && partial.length > 0) {
|
|
1131
1117
|
hasStreamProgress = true;
|
|
@@ -1274,7 +1260,6 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1274
1260
|
abortControllerRef.current?.abort();
|
|
1275
1261
|
abortControllerRef.current = abortController;
|
|
1276
1262
|
setIsStreaming(true);
|
|
1277
|
-
ensureStreamingPlaceholder();
|
|
1278
1263
|
try {
|
|
1279
1264
|
const normalizedUserMetadata = params.userMetadata ? JSON.parse(JSON.stringify(params.userMetadata)) : void 0;
|
|
1280
1265
|
const contextSeed = userContextSeedRef.current;
|
|
@@ -1369,8 +1354,6 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1369
1354
|
(prev) => (() => {
|
|
1370
1355
|
const appendToolCall = (msg) => ({
|
|
1371
1356
|
...msg,
|
|
1372
|
-
isStreaming: true,
|
|
1373
|
-
isComplete: false,
|
|
1374
1357
|
toolCalls: [
|
|
1375
1358
|
...Array.isArray(msg.toolCalls) ? msg.toolCalls : [],
|
|
1376
1359
|
{
|
|
@@ -1386,7 +1369,11 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1386
1369
|
for (let i = prev.length - 1; i >= 0; i--) {
|
|
1387
1370
|
if (prev[i].role === "assistant") {
|
|
1388
1371
|
const next = [...prev];
|
|
1389
|
-
next[i] = appendToolCall(
|
|
1372
|
+
next[i] = appendToolCall({
|
|
1373
|
+
...next[i],
|
|
1374
|
+
isStreaming: false,
|
|
1375
|
+
isComplete: true
|
|
1376
|
+
});
|
|
1390
1377
|
return next;
|
|
1391
1378
|
}
|
|
1392
1379
|
}
|
|
@@ -1397,8 +1384,8 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1397
1384
|
role: "assistant",
|
|
1398
1385
|
content: "",
|
|
1399
1386
|
timestamp: nowTs(),
|
|
1400
|
-
isStreaming:
|
|
1401
|
-
isComplete:
|
|
1387
|
+
isStreaming: false,
|
|
1388
|
+
isComplete: true
|
|
1402
1389
|
})
|
|
1403
1390
|
];
|
|
1404
1391
|
})()
|
|
@@ -1552,6 +1539,7 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1552
1539
|
}
|
|
1553
1540
|
}, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName]);
|
|
1554
1541
|
const reset = useCallback2(() => {
|
|
1542
|
+
messagesRequestRef.current += 1;
|
|
1555
1543
|
setThreads([]);
|
|
1556
1544
|
setThreadMetadataMap({});
|
|
1557
1545
|
setThreadExternalIdMap({});
|
|
@@ -1559,6 +1547,7 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1559
1547
|
setCurrentThreadExternalId(null);
|
|
1560
1548
|
setMessages([]);
|
|
1561
1549
|
setUserContextSeed({});
|
|
1550
|
+
setIsMessagesLoading(false);
|
|
1562
1551
|
setIsStreaming(false);
|
|
1563
1552
|
abortControllerRef.current?.abort();
|
|
1564
1553
|
}, []);
|
|
@@ -1598,6 +1587,7 @@ function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onT
|
|
|
1598
1587
|
}, [currentThreadId, threadMetadataMap]);
|
|
1599
1588
|
return {
|
|
1600
1589
|
messages,
|
|
1590
|
+
isMessagesLoading,
|
|
1601
1591
|
threads,
|
|
1602
1592
|
currentThreadId,
|
|
1603
1593
|
isStreaming,
|
|
@@ -1652,6 +1642,7 @@ var CopilotzChat = ({
|
|
|
1652
1642
|
const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;
|
|
1653
1643
|
const {
|
|
1654
1644
|
messages,
|
|
1645
|
+
isMessagesLoading,
|
|
1655
1646
|
threads,
|
|
1656
1647
|
currentThreadId,
|
|
1657
1648
|
isStreaming,
|
|
@@ -1762,6 +1753,7 @@ var CopilotzChat = ({
|
|
|
1762
1753
|
ChatUI,
|
|
1763
1754
|
{
|
|
1764
1755
|
messages,
|
|
1756
|
+
isMessagesLoading,
|
|
1765
1757
|
threads,
|
|
1766
1758
|
currentThreadId,
|
|
1767
1759
|
config: mergedConfig,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/CopilotzChat.tsx","../../node_modules/shared/src/utils.ts","../../node_modules/lucide-react/src/defaultAttributes.ts","../../node_modules/lucide-react/src/Icon.ts","../../node_modules/lucide-react/src/createLucideIcon.ts","../../node_modules/lucide-react/src/icons/user.ts","../src/useCopilotzChat.ts","../src/copilotzService.ts","../src/assetsService.ts","../src/useUrlState.ts"],"sourcesContent":["import React, { useMemo, useEffect, useState } from 'react';\nimport { ChatUI, ChatUserContextProvider } from '@copilotz/chat-ui';\nimport type { AgentOption, ChatConfig, ChatCallbacks, ChatUserContext, MemoryItem } from '@copilotz/chat-ui';\nimport { User } from 'lucide-react';\nimport { useCopilotz } from './useCopilotzChat';\nimport type { UrlSyncConfig } from './useUrlState';\n\nexport interface CopilotzChatProps {\n userId: string;\n userName?: string;\n userAvatar?: string;\n userEmail?: string;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n config?: ChatConfig;\n callbacks?: Partial<ChatCallbacks>;\n /**\n * Custom component to render in the right sidebar panel (e.g. Profile info).\n * Can be:\n * - A React node (static)\n * - A function receiving context: `(context) => ReactNode`\n * - A render function receiving panel props: `(props: { onClose, isMobile }) => ReactNode`\n * Toggle visibility via the header button.\n */\n customComponent?: \n | React.ReactNode \n | ((context: ChatUserContext) => React.ReactNode)\n | ((props: { onClose: () => void; isMobile: boolean }) => React.ReactNode);\n onToolOutput?: (output: Record<string, unknown>) => void;\n /** Called when user clicks logout in the user menu */\n onLogout?: () => void;\n /** Called when user clicks \"View Profile\" in the user menu */\n onViewProfile?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n /** Empty-state suggestions */\n suggestions?: string[];\n /** Agent selector data (built-in ChatUI) */\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n className?: string;\n /**\n * URL state synchronization configuration.\n * When enabled, syncs thread ID, agent, and prompt to/from URL parameters.\n * \n * Features:\n * - `?thread=abc123` - Opens specific thread\n * - `?agent=support-bot` - Pre-selects agent\n * - `?prompt=Hello` - Pre-fills or auto-sends message\n * \n * @example\n * ```tsx\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{ enabled: true }}\n * />\n * \n * // With custom param names\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{\n * enabled: true,\n * params: { thread: 't', agent: 'a', prompt: 'q' },\n * promptBehavior: 'auto-send'\n * }}\n * />\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport const CopilotzChat: React.FC<CopilotzChatProps> = ({\n userId,\n userName,\n userAvatar,\n userEmail,\n initialContext,\n bootstrap,\n config: userConfig,\n callbacks: userCallbacks,\n customComponent,\n onToolOutput,\n onLogout,\n onViewProfile,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n suggestions,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n className,\n urlSync,\n}) => {\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n\n const {\n messages,\n threads,\n currentThreadId,\n isStreaming,\n userContextSeed,\n sendMessage,\n createThread,\n selectThread,\n renameThread,\n archiveThread,\n deleteThread,\n stopGeneration,\n initialPrompt,\n clearInitialPrompt,\n urlAgentId,\n setUrlAgentId,\n } = useCopilotz({ \n userId, \n initialContext, \n bootstrap, \n defaultThreadName: userConfig?.labels?.defaultThreadName,\n onToolOutput,\n preferredAgentName: selectedAgent?.name ?? null,\n urlSync,\n });\n\n // Track if we've handled the initial prompt\n const [promptHandled, setPromptHandled] = useState(false);\n\n // Handle URL agent ID - call onSelectAgent if URL has agent and it differs from current\n useEffect(() => {\n if (urlAgentId && onSelectAgent && urlAgentId !== selectedAgentId) {\n // Check if the agent exists in options\n const agentExists = agentOptions.some((a) => a.id === urlAgentId);\n if (agentExists) {\n onSelectAgent(urlAgentId);\n }\n }\n }, [urlAgentId, selectedAgentId, onSelectAgent, agentOptions]);\n\n // Sync selected agent to URL when it changes (after initial load)\n useEffect(() => {\n if (selectedAgentId && urlSync?.enabled) {\n setUrlAgentId(selectedAgentId);\n }\n }, [selectedAgentId, urlSync?.enabled, setUrlAgentId]);\n\n // Handle auto-send behavior for initial prompt\n useEffect(() => {\n if (initialPrompt && !promptHandled && urlSync?.promptBehavior === 'auto-send') {\n // Wait for initial load to complete\n const timer = setTimeout(() => {\n void sendMessage(initialPrompt);\n clearInitialPrompt();\n setPromptHandled(true);\n }, 500);\n return () => clearTimeout(timer);\n }\n }, [initialPrompt, promptHandled, urlSync?.promptBehavior, sendMessage, clearInitialPrompt]);\n\n // For prefill behavior, we'll pass initialInput to ChatUI\n\n const chatCallbacks: ChatCallbacks = useMemo(() => ({\n onSendMessage: (content, attachments) => {\n void sendMessage(content, attachments);\n userCallbacks?.onSendMessage?.(content, attachments);\n },\n onStopGeneration: () => {\n stopGeneration();\n userCallbacks?.onStopGeneration?.();\n },\n onCreateThread: (title) => {\n createThread(title);\n userCallbacks?.onCreateThread?.(title);\n },\n onSelectThread: (threadId) => {\n void selectThread(threadId);\n userCallbacks?.onSelectThread?.(threadId);\n },\n onRenameThread: (threadId, newTitle) => {\n void renameThread(threadId, newTitle);\n userCallbacks?.onRenameThread?.(threadId, newTitle);\n },\n onArchiveThread: (threadId) => {\n void archiveThread(threadId);\n userCallbacks?.onArchiveThread?.(threadId);\n },\n onDeleteThread: (threadId) => {\n void deleteThread(threadId);\n userCallbacks?.onDeleteThread?.(threadId);\n },\n onCopyMessage: async (messageId, content) => {\n try {\n await navigator.clipboard.writeText(content);\n userCallbacks?.onCopyMessage?.(messageId, content);\n } catch (error) {\n console.error('Failed to copy message', error);\n }\n },\n // User menu callbacks\n onLogout,\n onViewProfile,\n ...userCallbacks,\n }), [sendMessage, stopGeneration, createThread, selectThread, renameThread, archiveThread, deleteThread, userCallbacks, onLogout, onViewProfile]);\n\n // Merge user config with dynamic values\n // customComponent is passed through - it will be resolved in ChatUI\n // which can provide onClose and isMobile props\n const mergedConfig: ChatConfig = useMemo(() => {\n const base = userConfig || {};\n if (!customComponent) {\n return base;\n }\n return {\n ...base,\n customComponent: {\n ...base.customComponent,\n component: customComponent,\n icon: base.customComponent?.icon || <User className=\"h-6 w-6\" />,\n },\n };\n }, [userConfig, customComponent]);\n\n const effectiveUserName = userName || userId;\n // Don't try to extract avatar from profile automatically unless it's in context\n const effectiveUserAvatar = userAvatar;\n\n return (\n <ChatUserContextProvider initial={userContextSeed}>\n <ChatUI\n messages={messages}\n threads={threads}\n currentThreadId={currentThreadId}\n config={mergedConfig}\n callbacks={chatCallbacks}\n isGenerating={isStreaming}\n suggestions={suggestions}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n user={{\n id: userId,\n name: effectiveUserName,\n email: userEmail,\n avatar: effectiveUserAvatar,\n }}\n assistant={{\n name: userConfig?.branding?.title,\n avatar: userConfig?.branding?.avatar,\n description: userConfig?.branding?.subtitle,\n }}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n className={className}\n // Pass initial prompt for prefill behavior (not auto-send)\n initialInput={\n initialPrompt && !promptHandled && urlSync?.promptBehavior !== 'auto-send'\n ? initialPrompt\n : undefined\n }\n onInitialInputConsumed={() => {\n clearInitialPrompt();\n setPromptHandled(true);\n }}\n />\n </ChatUserContextProvider>\n );\n};\n","import { CamelToPascal } from './utility-types';\n\n/**\n * Converts string to kebab case\n *\n * @param {string} string\n * @returns {string} A kebabized string\n */\nexport const toKebabCase = (string: string) =>\n string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts string to camel case\n *\n * @param {string} string\n * @returns {string} A camelized string\n */\nexport const toCamelCase = <T extends string>(string: T) =>\n string.replace(/^([A-Z])|[\\s-_]+(\\w)/g, (match, p1, p2) =>\n p2 ? p2.toUpperCase() : p1.toLowerCase(),\n );\n\n/**\n * Converts string to pascal case\n *\n * @param {string} string\n * @returns {string} A pascalized string\n */\nexport const toPascalCase = <T extends string>(string: T): CamelToPascal<T> => {\n const camelCase = toCamelCase(string);\n\n return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal<T>;\n};\n\n/**\n * Merges classes into a single string\n *\n * @param {array} classes\n * @returns {string} A string of classes\n */\nexport const mergeClasses = <ClassType = string | undefined | null>(...classes: ClassType[]) =>\n classes\n .filter((className, index, array) => {\n return (\n Boolean(className) &&\n (className as string).trim() !== '' &&\n array.indexOf(className) === index\n );\n })\n .join(' ')\n .trim();\n\n/**\n * Is empty string\n *\n * @param {unknown} value\n * @returns {boolean} Whether the value is an empty string\n */\nexport const isEmptyString = (value: unknown): boolean => value === '';\n\n/**\n * Check if a component has an accessibility prop\n *\n * @param {object} props\n * @returns {boolean} Whether the component has an accessibility prop\n */\nexport const hasA11yProp = (props: Record<string, any>) => {\n for (const prop in props) {\n if (prop.startsWith('aria-') || prop === 'role' || prop === 'title') {\n return true;\n }\n }\n};\n","export default {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n","import { createElement, forwardRef } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport { IconNode, LucideProps } from './types';\nimport { mergeClasses, hasA11yProp } from '@lucide/shared';\n\ninterface IconComponentProps extends LucideProps {\n iconNode: IconNode;\n}\n\n/**\n * Lucide icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst Icon = forwardRef<SVGSVGElement, IconComponentProps>(\n (\n {\n color = 'currentColor',\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = '',\n children,\n iconNode,\n ...rest\n },\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,\n className: mergeClasses('lucide', className),\n ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }),\n ...rest,\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n);\n\nexport default Icon;\n","import { createElement, forwardRef } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';\nimport { IconNode, LucideProps } from './types';\nimport Icon from './Icon';\n\n/**\n * Create a Lucide icon component\n * @param {string} iconName\n * @param {array} iconNode\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst createLucideIcon = (iconName: string, iconNode: IconNode) => {\n const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>\n createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className,\n ),\n ...props,\n }),\n );\n\n Component.displayName = toPascalCase(iconName);\n\n return Component;\n};\n\nexport default createLucideIcon;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2', key: '975kel' }],\n ['circle', { cx: '12', cy: '7', r: '4', key: '17ys0d' }],\n];\n\n/**\n * @component @name User\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/user\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst User = createLucideIcon('user', __iconNode);\n\nexport default User;\n","// deno-lint-ignore-file no-explicit-any\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { runCopilotzStream, fetchThreads, fetchThreadMessages, updateThread as updateThreadApi, deleteThread as deleteThreadApi } from './copilotzService';\nimport { resolveAssetsInMessages } from './assetsService';\nimport type { ChatMessage as ChatViewMessage, ChatThread, MediaAttachment, ChatUserContext } from '@copilotz/chat-ui';\nimport { useUrlState, type UrlSyncConfig } from './useUrlState';\n\nconst nowTs = () => Date.now();\nconst generateId = () =>\n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`) as string;\nconst isAbortError = (error: unknown) => (\n error instanceof DOMException && error.name === 'AbortError'\n) || (typeof error === 'object' && error !== null && 'name' in error && (error as { name?: string }).name === 'AbortError');\n\ntype ServerThread = Awaited<ReturnType<typeof fetchThreads>>[number];\ntype ServerMessage = Awaited<ReturnType<typeof fetchThreadMessages>>[number];\n\nconst convertServerMessage = (msg: ServerMessage): ChatViewMessage => {\n const timestamp = msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs();\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachmentsMeta = Array.isArray(metadata?.attachments)\n ? (metadata!.attachments as Array<Record<string, unknown>>)\n : [];\n\n const attachments: MediaAttachment[] = attachmentsMeta.flatMap((att) => {\n const kind = typeof att.kind === 'string' ? att.kind : undefined;\n const dataUrl = typeof att.dataUrl === 'string' ? att.dataUrl : undefined;\n const mimeType = typeof att.mimeType === 'string' ? att.mimeType : undefined;\n if (!dataUrl) return [];\n\n if (kind === 'image') {\n return [{ kind: 'image', dataUrl, mimeType: mimeType ?? 'image/jpeg' }] as MediaAttachment[];\n }\n if (kind === 'audio') {\n return [{\n kind: 'audio',\n dataUrl,\n mimeType: mimeType ?? 'audio/webm',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n }] as MediaAttachment[];\n }\n if (kind === 'video') {\n return [{\n kind: 'video',\n dataUrl,\n mimeType: mimeType ?? 'video/mp4',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n poster: typeof att.poster === 'string' ? att.poster : undefined,\n }] as MediaAttachment[];\n }\n return [] as MediaAttachment[];\n });\n\n const role = msg.senderType === 'agent'\n ? 'assistant'\n : msg.senderType === 'user'\n ? 'user'\n : 'assistant';\n\n const mappedToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls)\n ? ((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls || []).map((tc) => ({\n id: typeof tc?.id === 'string' ? tc.id : generateId(),\n name: typeof tc?.name === 'string' ? tc.name : 'tool',\n arguments: (tc?.args as Record<string, unknown>) || {},\n status: 'completed' as const,\n }))\n : undefined;\n\n const hasToolCalls = Array.isArray(mappedToolCalls) && mappedToolCalls.length > 0;\n const isToolSender = msg.senderType === 'tool';\n const content =\n isToolSender\n ? '' // Do not render textual content for tool messages; attachments only\n : ((msg.content ?? '') || (hasToolCalls ? '' : ''));\n\n return {\n id: msg.id,\n role,\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isStreaming: false,\n isComplete: true,\n metadata,\n toolCalls: hasToolCalls ? mappedToolCalls : undefined,\n };\n};\n\nexport interface UseCopilotzOptions {\n userId: string | null;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n defaultThreadName?: string;\n onToolOutput?: (output: Record<string, unknown>) => void;\n preferredAgentName?: string | null;\n /**\n * URL state synchronization configuration.\n * When enabled, thread ID and agent are synced to/from URL parameters.\n * \n * @example\n * ```tsx\n * const chat = useCopilotz({\n * userId: 'user123',\n * urlSync: {\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * }\n * });\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, urlSync }: UseCopilotzOptions) {\n // URL state management\n const {\n state: urlState,\n setThreadId: setUrlThreadId,\n setAgentId: setUrlAgentId,\n clearPrompt: clearUrlPrompt,\n isEnabled: isUrlSyncEnabled,\n } = useUrlState(urlSync);\n\n const [threads, setThreads] = useState<ChatThread[]>([]);\n const [threadMetadataMap, setThreadMetadataMap] = useState<Record<string, Record<string, unknown> | undefined>>({});\n const [threadExternalIdMap, setThreadExternalIdMap] = useState<Record<string, string | null>>({});\n\n const [currentThreadId, setCurrentThreadId] = useState<string | null>(null);\n const [currentThreadExternalId, setCurrentThreadExternalId] = useState<string | null>(null);\n\n const [messages, setMessages] = useState<ChatViewMessage[]>([]);\n const [isStreaming, setIsStreaming] = useState(false);\n\n const [userContextSeed, setUserContextSeed] = useState<Partial<ChatUserContext>>(initialContext || {});\n const preferredAgentRef = useRef<string | null>(preferredAgentName ?? null);\n\n // Refs to hold latest state for callbacks to avoid dependency cycles\n // Using direct assignment pattern instead of useEffect for better performance\n const threadsRef = useRef(threads);\n const threadMetadataMapRef = useRef(threadMetadataMap);\n const threadExternalIdMapRef = useRef(threadExternalIdMap);\n const currentThreadIdRef = useRef(currentThreadId);\n const currentThreadExternalIdRef = useRef(currentThreadExternalId);\n const userContextSeedRef = useRef(userContextSeed);\n\n // Sync refs on every render (more efficient than multiple useEffects)\n threadsRef.current = threads;\n threadMetadataMapRef.current = threadMetadataMap;\n threadExternalIdMapRef.current = threadExternalIdMap;\n currentThreadIdRef.current = currentThreadId;\n currentThreadExternalIdRef.current = currentThreadExternalId;\n userContextSeedRef.current = userContextSeed;\n preferredAgentRef.current = preferredAgentName ?? null;\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const messagesRequestRef = useRef<number>(0);\n // Guard to prevent double initialization in StrictMode\n const initializationRef = useRef<{ userId: string | null; started: boolean }>({ userId: null, started: false });\n\n useEffect(() => {\n if (initialContext) {\n setUserContextSeed((prev) => ({ ...prev, ...initialContext }));\n }\n }, [initialContext]);\n\n const processToolOutput = useCallback((output: Record<string, unknown>) => {\n if (!output) return;\n\n const contextPatch: Partial<ChatUserContext> = {};\n\n // Generic merge of userContext from output if present\n if (output.userContext && typeof output.userContext === 'object') {\n Object.assign(contextPatch, output.userContext as Partial<ChatUserContext>);\n }\n\n if (Object.keys(contextPatch).length > 0) {\n setUserContextSeed((prev) => ({ ...prev, ...contextPatch }));\n }\n\n onToolOutput?.(output);\n }, [onToolOutput]);\n\n const handleStreamMessageEvent = useCallback((event: any) => {\n const payload = event?.payload;\n if (!payload) return;\n\n if (payload.senderType === 'tool') {\n const metadata = (payload.metadata ?? event.metadata ?? {}) as Record<string, unknown>;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n\n // Attach tool call details to the current assistant bubble (expandable)\n const toolName = (metadata?.toolName as string) || (metadata?.tool as string) || 'tool';\n let argsObj: Record<string, unknown> = {};\n try {\n const argStr = (metadata?.arguments as string) ?? '{}';\n argsObj = typeof argStr === 'string' ? JSON.parse(argStr) : (argStr as Record<string, unknown>);\n } catch (_) { /* ignore parse */ }\n const resultObj = metadata?.output as unknown;\n const callId = (payload.toolCallId as string) || generateId();\n\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant') {\n const existing = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n next[i] = {\n ...m,\n toolCalls: [\n ...existing,\n {\n id: callId,\n name: toolName,\n arguments: argsObj as Record<string, any>,\n result: resultObj,\n status: 'completed' as const,\n endTime: Date.now(),\n },\n ],\n };\n break;\n }\n }\n return next;\n });\n return;\n }\n\n if (payload.senderType === 'agent' && typeof payload.content === 'string') {\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant' && m.isStreaming) {\n next[i] = { ...m, content: payload.content, isStreaming: false, isComplete: true };\n break;\n }\n }\n return next;\n });\n }\n }, [processToolOutput]);\n\n const updateThreadsState = useCallback((rawThreads: ServerThread[], preferredExternalId?: string | null) => {\n const metadataMap: Record<string, Record<string, unknown> | undefined> = {};\n const externalMap: Record<string, string | null> = {};\n\n const normalized = rawThreads.map((thread) => {\n metadataMap[thread.id] = thread.metadata ?? undefined;\n externalMap[thread.id] = thread.externalId ?? null;\n const updatedAt = thread.updatedAt ? new Date(thread.updatedAt).getTime() : nowTs();\n const createdAt = thread.createdAt ? new Date(thread.createdAt).getTime() : updatedAt;\n return {\n id: thread.id,\n title: thread.name || 'Chat',\n createdAt,\n updatedAt,\n messageCount: typeof thread.metadata?.messageCount === 'number'\n ? thread.metadata!.messageCount as number\n : 0,\n isArchived: thread.status === 'archived',\n metadata: thread.metadata ?? undefined,\n } as ChatThread;\n });\n\n setThreadMetadataMap(metadataMap);\n setThreadExternalIdMap(externalMap);\n setThreads(normalized);\n\n // Use refs to avoid dependency cycle\n const curExtId = currentThreadExternalIdRef.current;\n const curId = currentThreadIdRef.current;\n\n let nextThreadId: string | null = null;\n\n if (preferredExternalId) {\n const preferred = rawThreads.find((thread) => (thread.externalId ?? thread.id) === preferredExternalId);\n if (preferred) nextThreadId = preferred.id;\n }\n\n if (!nextThreadId && curExtId) {\n const match = rawThreads.find((thread) => (thread.externalId ?? thread.id) === curExtId);\n if (match) nextThreadId = match.id;\n }\n\n if (!nextThreadId && curId && rawThreads.some((thread) => thread.id === curId)) {\n nextThreadId = curId;\n }\n\n if (!nextThreadId && normalized.length > 0) {\n nextThreadId = normalized[0].id;\n }\n\n setCurrentThreadId(nextThreadId ?? null);\n setCurrentThreadExternalId(nextThreadId ? externalMap[nextThreadId] ?? null : null);\n\n return nextThreadId;\n }, []); // No dependencies needed now as we use refs for reading current state\n\n const fetchAndSetThreadsState = useCallback(async (uid: string, preferredExternalId?: string | null) => {\n try {\n const rawThreads = await fetchThreads(uid);\n return updateThreadsState(rawThreads, preferredExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error loading threads', error);\n return null;\n }\n }, [updateThreadsState]);\n\n const loadThreadMessages = useCallback(async (threadId: string) => {\n const requestId = Date.now();\n messagesRequestRef.current = requestId;\n try {\n const rawMessages = await fetchThreadMessages(threadId);\n const resolvedMessages = await resolveAssetsInMessages(rawMessages as unknown as any[]);\n if (messagesRequestRef.current !== requestId) return;\n\n resolvedMessages.forEach((msg: any) => {\n if (msg.senderType === 'tool') {\n const metadata = msg.metadata as Record<string, unknown> | undefined;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n }\n });\n\n const viewMessages = resolvedMessages\n .filter((msg) => {\n const text = (typeof msg.content === 'string' ? msg.content : '').trim();\n const hasText = text.length > 0;\n const hasToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<unknown> }).toolCalls)\n && ((msg as unknown as { toolCalls?: Array<unknown> }).toolCalls as Array<unknown>).length > 0;\n const meta = (msg.metadata ?? {}) as Record<string, unknown>;\n const hasAttachments = Array.isArray(meta.attachments) && (meta.attachments as unknown[]).length > 0;\n // Keep tool messages only if they carry attachments (e.g., generated media)\n if (msg.senderType === 'tool') {\n return hasAttachments;\n }\n // For agent/user/system, keep if there is text, tool calls, or attachments\n return hasText || hasToolCalls || hasAttachments;\n })\n .map(convertServerMessage);\n\n setMessages(viewMessages);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error(`Error loading messages for thread ${threadId}`, error);\n }\n }, [processToolOutput]);\n\n const handleSelectThread = useCallback(async (threadId: string) => {\n setCurrentThreadId(threadId);\n // Use ref for external map to avoid re-creation\n const extMap = threadExternalIdMapRef.current;\n setCurrentThreadExternalId(extMap[threadId] ?? null);\n await loadThreadMessages(threadId);\n }, [loadThreadMessages]);\n\n const handleCreateThread = useCallback((title?: string) => {\n const id = generateId();\n const now = nowTs();\n const newThread: ChatThread = {\n id,\n title: title?.trim() || 'New Chat',\n createdAt: now,\n updatedAt: now,\n messageCount: 0,\n metadata: { pendingTitle: title?.trim() || undefined },\n };\n\n setThreads((prev) => [newThread, ...prev]);\n setThreadMetadataMap((prev) => ({ ...prev, [id]: { pendingTitle: title?.trim() || undefined } }));\n setThreadExternalIdMap((prev) => ({ ...prev, [id]: id }));\n setCurrentThreadId(id);\n setCurrentThreadExternalId(id);\n setMessages([]);\n }, []);\n\n const handleRenameThread = useCallback(async (threadId: string, newTitle: string) => {\n const trimmedTitle = newTitle.trim();\n if (!trimmedTitle) return;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title: trimmedTitle, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread (not yet persisted)\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (isPlaceholder) {\n // Store title in metadata for when thread is created\n setThreadMetadataMap((prev) => ({\n ...prev,\n [threadId]: { ...prev[threadId], pendingTitle: trimmedTitle },\n }));\n } else {\n // Persist to backend\n try {\n await updateThreadApi(threadId, { name: trimmedTitle });\n } catch (error) {\n console.error('Failed to rename thread:', error);\n // Revert on error - refetch threads\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleArchiveThread = useCallback(async (threadId: string) => {\n // Find current archive status\n const thread = threadsRef.current.find((t) => t.id === threadId);\n if (!thread) return;\n\n const newArchivedStatus = !thread.isArchived;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, isArchived: newArchivedStatus, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (!isPlaceholder) {\n try {\n await updateThreadApi(threadId, { status: newArchivedStatus ? 'archived' : 'active' });\n } catch (error) {\n console.error('Failed to archive thread:', error);\n // Revert on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleDeleteThread = useCallback(async (threadId: string) => {\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n // Remove from local state immediately\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n setThreadMetadataMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n setThreadExternalIdMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n\n // If deleting current thread, switch to another\n if (currentThreadIdRef.current === threadId) {\n const remaining = threadsRef.current.filter((t) => t.id !== threadId);\n if (remaining.length > 0) {\n setCurrentThreadId(remaining[0].id);\n setCurrentThreadExternalId(extMap[remaining[0].id] ?? null);\n await loadThreadMessages(remaining[0].id);\n } else {\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n }\n }\n\n if (!isPlaceholder) {\n try {\n await deleteThreadApi(threadId);\n } catch (error) {\n console.error('Failed to delete thread:', error);\n // Refetch to restore state on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages]);\n\n const handleStop = useCallback(() => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages((prev) => {\n // Check if any message needs updating before creating new array\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming ? { ...msg, isStreaming: false, isComplete: true } : msg));\n });\n }, []);\n\n const handleStreamAssetEvent = useCallback((payload: any, assistantMessageId: string) => {\n // Handle ASSET_CREATED event from copilotz\n if (!payload?.dataUrl) return;\n\n const mimeType = payload.mime || 'image/png';\n const dataUrl = payload.dataUrl;\n\n // Determine attachment kind based on mime type\n let kind: 'image' | 'audio' | 'video' = 'image';\n if (mimeType.startsWith('audio/')) {\n kind = 'audio';\n } else if (mimeType.startsWith('video/')) {\n kind = 'video';\n }\n\n const mediaAttachment: MediaAttachment = {\n kind,\n dataUrl,\n mimeType,\n };\n\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId\n ? {\n ...msg,\n attachments: [...(msg.attachments || []), mediaAttachment],\n isStreaming: false,\n isComplete: true\n }\n : msg)));\n }, []);\n\n const sendCopilotzMessage = useCallback(async (\n params: {\n threadId?: string | null;\n threadExternalId?: string | null;\n content: string;\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n userId: string;\n userName?: string;\n userMetadata?: Record<string, unknown>;\n agentName?: string | null;\n onBeforeStart?: (assistantMessageId: string) => void;\n },\n ) => {\n // Track current assistant streaming bubble id so we can split bubbles between events\n let currentAssistantId = generateId();\n params.onBeforeStart?.(currentAssistantId);\n\n let hasStreamProgress = false;\n let pendingStartNewAssistantBubble = false;\n\n // Ensure there is a streaming assistant bubble (for tool-first streams)\n const ensureStreamingPlaceholder = () => {\n setMessages((prev) => {\n const last = prev[prev.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n return prev;\n }\n const newId = generateId();\n currentAssistantId = newId;\n return [\n ...prev,\n {\n id: newId,\n role: 'assistant' as const,\n content: '',\n timestamp: nowTs(),\n isStreaming: true,\n isComplete: false,\n },\n ];\n });\n };\n\n // Combined function to ensure bubble exists AND update content in a single setMessages call\n const updateStreamingMessage = (partial: string, isComplete: boolean) => {\n if (partial && partial.length > 0) {\n hasStreamProgress = true;\n }\n \n setMessages((prev) => {\n // First, check if we need to create a new streaming bubble\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx >= 0 && prev[idx].role === 'assistant') {\n // Found our current bubble - just update it\n const msg = prev[idx];\n if (msg.content === partial && msg.isStreaming === !isComplete && msg.isComplete === isComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[idx] = { ...msg, content: partial, isStreaming: !isComplete, isComplete };\n return updated;\n }\n \n // Check if last message is a streaming assistant we can reuse\n const last = prev[prev.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n pendingStartNewAssistantBubble = false;\n if (last.content === partial && last.isStreaming === !isComplete && last.isComplete === isComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[prev.length - 1] = { ...last, content: partial, isStreaming: !isComplete, isComplete };\n return updated;\n }\n \n // Need to create a new bubble\n if (pendingStartNewAssistantBubble || !prev.length || (prev[prev.length - 1].role !== 'assistant' || !prev[prev.length - 1].isStreaming)) {\n const newId = generateId();\n currentAssistantId = newId;\n pendingStartNewAssistantBubble = false;\n return [\n ...prev,\n {\n id: newId,\n role: 'assistant' as const,\n content: partial,\n timestamp: nowTs(),\n isStreaming: !isComplete,\n isComplete,\n },\n ];\n }\n \n return prev;\n });\n };\n\n const finalizeCurrentAssistantBubble = () => {\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx < 0) return prev;\n const msg = prev[idx];\n // Skip update if already finalized\n if (!msg.isStreaming && msg.isComplete) return prev;\n const updated = [...prev];\n updated[idx] = { ...msg, isStreaming: false, isComplete: true };\n return updated;\n });\n };\n\n // Using Refs for accessing current state inside callback\n const curThreadId = currentThreadIdRef.current;\n\n // Build a ServerMessage-like object from various streaming event payloads\n const toServerMessageFromEvent = async (event: any): Promise<ServerMessage | null> => {\n if (!event) return null;\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // TOOL_CALL bubble\n if (type === 'TOOL_CALL') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n const call = (payload?.call ?? (metadata as any)?.call) as Record<string, unknown> | undefined;\n const func = (call?.function ?? (payload as any)?.function) as Record<string, unknown> | undefined;\n\n // Extract tool name from various possible locations\n const toolName =\n (func?.name as string) ||\n (payload?.name as string) ||\n (call?.name as string) ||\n (metadata.toolName as string) ||\n (metadata.tool as string) ||\n 'tool';\n\n // Robust args extraction across shapes, including the call.function.arguments pattern\n let argsObj: Record<string, unknown> = {};\n const possibleArgs = [\n func?.arguments, // Try call.function.arguments first (most specific for this event structure)\n payload?.args,\n call?.arguments,\n (metadata as any)?.args,\n (metadata as any)?.arguments,\n ];\n for (const candidate of possibleArgs) {\n if (candidate === undefined || candidate === null) continue;\n try {\n if (typeof candidate === 'string') {\n argsObj = JSON.parse(candidate);\n break;\n }\n if (typeof candidate === 'object') {\n argsObj = candidate as Record<string, unknown>;\n break;\n }\n } catch { /* ignore */ }\n }\n\n const output =\n (metadata as any)?.output !== undefined ? (metadata as any).output\n : payload?.output !== undefined ? payload.output\n : undefined;\n\n // Extract call ID from various locations\n const callId =\n (call?.id as string) ||\n (func?.id as string) ||\n (payload?.id as string) ||\n generateId();\n\n const statusVal =\n (payload?.status as string) ||\n ((event as any)?.status as string) ||\n 'pending';\n\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n toolCalls: [{\n id: callId,\n name: toolName,\n args: argsObj as Record<string, unknown>,\n output,\n status: statusVal,\n }] as Array<Record<string, unknown>>,\n } as unknown as ServerMessage;\n }\n\n // MESSAGE bubble (agent text only - ignore system/tool messages and empty content)\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n // Only process agent messages, skip system/tool/user messages\n if (senderType !== 'agent') {\n return null;\n }\n const content = typeof payload?.content === 'string' ? payload.content : '';\n // Skip messages with empty content (especially NEW_MESSAGE events that only have toolCalls)\n if (!content.trim()) {\n return null;\n }\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'agent',\n content,\n metadata: (payload?.metadata ?? {}) as Record<string, unknown>,\n } as unknown as ServerMessage;\n }\n\n // ASSET_CREATED bubble (tool-generated media)\n if (type === 'ASSET_CREATED') {\n // Only render assets created by tools (ignore user uploads)\n const by = (payload?.by as string) || '';\n if (by && by !== 'tool') return null;\n\n const mime = (payload?.mime as string) || 'image/png';\n const ref = (payload?.ref as string) || (payload?.assetRef as string) || '';\n if (!ref) return null;\n const kind = mime.startsWith('audio/') ? 'audio' : (mime.startsWith('video/') ? 'video' : 'image');\n const msgLike = {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n metadata: {\n attachments: [{ kind, assetRef: ref, mimeType: mime }],\n },\n } as unknown as ServerMessage;\n // Resolve assetRef → dataUrl via service\n const [resolved] = await resolveAssetsInMessages([msgLike] as any);\n return resolved as unknown as ServerMessage;\n }\n\n return null;\n };\n\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n setIsStreaming(true);\n ensureStreamingPlaceholder();\n\n try {\n const normalizedUserMetadata = params.userMetadata\n ? JSON.parse(JSON.stringify(params.userMetadata)) as Record<string, unknown>\n : undefined;\n\n const contextSeed = userContextSeedRef.current;\n const contextMetadata = contextSeed\n ? JSON.parse(JSON.stringify(contextSeed)) as Record<string, unknown>\n : undefined;\n const requestContent = params.content && params.content.length > 0 ? params.content : '';\n\n const metadataKey = params.threadId ?? params.threadExternalId ?? undefined;\n // Read from ref to avoid dependency on threadMetadataMap\n const currentThreadMetadataMap = threadMetadataMapRef.current;\n const messageMetadata = metadataKey ? currentThreadMetadataMap[metadataKey]?.userContext as Record<string, unknown> | undefined : undefined;\n const threadMetadata = metadataKey ? currentThreadMetadataMap[metadataKey] : undefined;\n\n const mergedMetadata = {\n ...(messageMetadata ?? {}),\n ...(params.metadata ?? {}),\n } as Record<string, unknown>;\n\n const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n await runCopilotzStream({\n threadId: params.threadId ?? undefined,\n threadExternalId: params.threadExternalId ?? undefined,\n content: requestContent,\n user: {\n externalId: params.userId,\n name: params.userName ?? params.userId,\n metadata: {\n ...(contextMetadata ? contextMetadata : {}),\n ...(normalizedUserMetadata ?? {}),\n },\n },\n attachments: params.attachments,\n metadata: finalMetadata,\n threadMetadata: params.threadMetadata ?? threadMetadata,\n toolCalls: params.toolCalls,\n selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,\n onToken: (token, isComplete) => updateStreamingMessage(token, isComplete),\n onMessageEvent: async (event: any) => {\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // Handle MESSAGE/NEW_MESSAGE events for tool responses\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n \n // Handle tool responses: update the matching tool call status\n if (senderType === 'tool') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n \n // Extract tool call information from metadata.toolCalls array\n const toolCallsArray = metadata?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCallData = toolCallsArray && toolCallsArray.length > 0 ? toolCallsArray[0] : undefined;\n \n if (!toolCallData) {\n return; // No tool call data found\n }\n \n // Notify onToolOutput callback with the full metadata (includes toolCalls array)\n // This allows consumers to react to tool completions in real-time\n processToolOutput(metadata);\n \n // Extract tool call ID and name\n const toolCallId = toolCallData.id as string | undefined;\n const toolCallName = toolCallData.name as string | undefined;\n \n // Extract the tool result/output\n const toolResult = toolCallData.output || payload?.content;\n \n // Check if the tool execution failed\n const toolStatus = (toolCallData.status as string) || 'completed';\n const isFailed = toolStatus === 'failed' || toolCallData?.error;\n \n // Update the tool call status in the assistant message\n setMessages((prev) => {\n const updated = [...prev];\n // Find the assistant message with the matching tool call\n for (let i = updated.length - 1; i >= 0; i--) {\n if (updated[i].role === 'assistant' && updated[i].toolCalls) {\n const toolCalls = updated[i].toolCalls;\n if (toolCalls) {\n // Try to find by ID first, then by name for pending/running tools\n let toolCallIndex = toolCallId \n ? toolCalls.findIndex(tc => tc.id === toolCallId)\n : -1;\n \n // If not found by ID, try to find a pending/running tool with the same name\n if (toolCallIndex === -1 && toolCallName) {\n toolCallIndex = toolCalls.findIndex(\n tc => tc.name === toolCallName && \n (tc.status === 'pending' || tc.status === 'running')\n );\n }\n \n if (toolCallIndex !== -1) {\n const updatedToolCalls = [...toolCalls];\n updatedToolCalls[toolCallIndex] = {\n ...updatedToolCalls[toolCallIndex],\n status: isFailed ? 'failed' : 'completed',\n result: toolResult,\n endTime: Date.now(),\n };\n updated[i] = {\n ...updated[i],\n toolCalls: updatedToolCalls,\n };\n break;\n }\n }\n }\n }\n return updated;\n });\n return; // Don't create a separate bubble for tool responses\n }\n \n // Ignore other MESSAGE snapshots; TOKEN stream already rendered content\n return;\n }\n\n // TOOL_CALL events: render inside current assistant bubble\n if (type === 'TOOL_CALL') {\n const sm = await toServerMessageFromEvent(event);\n const toolCalls = sm?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCall = toolCalls && toolCalls[0];\n if (!toolCall) return;\n\n setMessages((prev) =>\n (() => {\n const appendToolCall = (msg: ChatViewMessage) => ({\n ...msg,\n isStreaming: true,\n isComplete: false,\n toolCalls: [\n ...(Array.isArray(msg.toolCalls) ? msg.toolCalls : []),\n {\n id: (toolCall.id as string) ?? generateId(),\n name: (toolCall.name as string) ?? 'tool',\n arguments:\n (toolCall.args as Record<string, unknown>) ??\n (toolCall.arguments as Record<string, unknown>) ??\n {},\n result: toolCall.output,\n status:\n (toolCall.status as 'pending' | 'running' | 'completed' | 'failed') ??\n 'running',\n startTime: Date.now(),\n },\n ],\n });\n\n // Try to attach to the most recent assistant message\n for (let i = prev.length - 1; i >= 0; i--) {\n if (prev[i].role === 'assistant') {\n const next = [...prev];\n next[i] = appendToolCall(next[i]);\n return next;\n }\n }\n\n // No assistant message yet – create one to host the tool call\n return [\n ...prev,\n appendToolCall({\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: nowTs(),\n isStreaming: true,\n isComplete: false,\n }),\n ];\n })(),\n );\n hasStreamProgress = true;\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Other event types (ASSET_CREATED, etc.) should render as their own bubbles\n const sm = await toServerMessageFromEvent(event);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n finalizeCurrentAssistantBubble();\n setMessages((prev) => [...prev, viewMsg]);\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Fallback for unknown events\n handleStreamMessageEvent(event);\n },\n onAssetEvent: async (payload: any) => {\n // Treat as ASSET_CREATED event in unified handler\n await (async () => {\n if (!hasStreamProgress) return;\n finalizeCurrentAssistantBubble();\n const evt = { type: 'ASSET_CREATED', payload };\n const sm = await toServerMessageFromEvent(evt);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n setMessages((prev) => [...prev, viewMsg]);\n }\n // Defer creating a new assistant bubble until next TOKEN arrives\n pendingStartNewAssistantBubble = true;\n })();\n },\n signal: abortController.signal,\n });\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n }\n\n return currentAssistantId;\n }, [handleStreamMessageEvent, handleStreamAssetEvent]);\n\n const handleSendMessage = useCallback(async (content: string, attachments: MediaAttachment[] = []) => {\n if (!content.trim() && attachments.length === 0) return;\n if (!userId) return;\n\n const timestamp = nowTs();\n const curThreadId = currentThreadIdRef.current;\n const curThreadExtId = currentThreadExternalIdRef.current;\n\n const existingThreadId = curThreadId ?? undefined;\n // Use Ref to check without adding dependency\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholderThread = existingThreadId\n ? extMap[existingThreadId] === existingThreadId\n : false;\n\n const threadIdForSend = isPlaceholderThread ? undefined : existingThreadId;\n\n let effectiveThreadExternalId = curThreadExtId ?? (isPlaceholderThread ? existingThreadId : undefined);\n\n if (!threadIdForSend) {\n if (!effectiveThreadExternalId) {\n effectiveThreadExternalId = generateId();\n }\n setCurrentThreadExternalId(effectiveThreadExternalId);\n } else if (curThreadExtId !== (effectiveThreadExternalId ?? null)) {\n setCurrentThreadExternalId(effectiveThreadExternalId ?? null);\n }\n\n const conversationKey = threadIdForSend ?? effectiveThreadExternalId!;\n\n // Get pending title for new threads if any\n const currentMetadata = threadMetadataMapRef.current[conversationKey];\n const pendingTitle = currentMetadata?.pendingTitle as string | undefined;\n\n const userMessage: ChatViewMessage = {\n id: generateId(),\n role: 'user',\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isComplete: true,\n };\n\n // Create an assistant message placeholder with streaming state for typewriter effect\n const assistantPlaceholder: ChatViewMessage = {\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: timestamp + 1,\n isStreaming: true,\n isComplete: false,\n };\n\n // Add user message and assistant placeholder for typewriter loading effect\n setMessages((prev) => [...prev, userMessage, assistantPlaceholder]);\n\n // Use ref for threads check\n if (!threadsRef.current.some(t => t.id === conversationKey)) {\n const newThread: ChatThread = {\n id: conversationKey,\n title: content.slice(0, 40) || 'Nova conversa',\n createdAt: timestamp,\n updatedAt: timestamp,\n messageCount: 0,\n };\n setThreads(prev => [newThread, ...prev]);\n setThreadMetadataMap(prev => ({ ...prev, [conversationKey]: {} }));\n setThreadExternalIdMap(prev => ({ ...prev, [conversationKey]: effectiveThreadExternalId ?? null }));\n }\n\n try {\n await sendCopilotzMessage({\n threadId: threadIdForSend,\n threadExternalId: effectiveThreadExternalId,\n content,\n attachments,\n userId,\n // userName can be anything, but let's try to find it in context or just fallback\n userName: (userContextSeedRef.current?.profile as any)?.full_name ?? userId,\n agentName: preferredAgentRef.current,\n // Include pending title for new threads\n threadMetadata: pendingTitle ? { name: pendingTitle } : undefined,\n });\n\n // Wait to ensure the assistant message is persisted before refreshing\n await new Promise((r) => setTimeout(r, 1000));\n // Refresh threads list to update metadata (message count, timestamps, etc.)\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(userId, effectiveThreadExternalId ?? existingThreadId ?? null);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error sending Copilotz message', error);\n setMessages((prev) => prev.map((msg) => (msg.isStreaming\n ? {\n ...msg,\n isStreaming: false,\n isComplete: true,\n content: 'Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.',\n }\n : msg)));\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage]);\n\n const bootstrapConversation = useCallback(async (uid: string) => {\n if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;\n\n const bootstrapThreadExternalId = generateId();\n setCurrentThreadId(bootstrapThreadExternalId);\n setCurrentThreadExternalId(bootstrapThreadExternalId);\n setThreadExternalIdMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: bootstrapThreadExternalId }));\n setThreadMetadataMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: {} }));\n // Clear messages; let streaming create bubbles as needed\n setMessages([]);\n\n try {\n await sendCopilotzMessage({\n threadExternalId: bootstrapThreadExternalId,\n content: bootstrap.initialMessage || '',\n toolCalls: bootstrap.initialToolCalls,\n userId: uid,\n agentName: preferredAgentRef.current,\n threadMetadata: {\n name: defaultThreadName || 'Main Thread',\n },\n });\n\n // Give the backend time to persist tool outputs/messages before refresh\n await new Promise((r) => setTimeout(r, 1000));\n\n // Refresh threads list to update metadata\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(uid, bootstrapThreadExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error bootstrapping conversation', error);\n setMessages([\n {\n id: generateId(),\n role: 'assistant',\n content: 'Não foi possível iniciar a conversa. Tente novamente mais tarde.',\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n },\n ]);\n }\n }, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName]);\n\n const reset = useCallback(() => {\n setThreads([]);\n setThreadMetadataMap({});\n setThreadExternalIdMap({});\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n setUserContextSeed({});\n setIsStreaming(false);\n abortControllerRef.current?.abort();\n }, []);\n\n // Initialize when userId changes\n useEffect(() => {\n if (userId) {\n // Guard against double initialization in StrictMode\n if (initializationRef.current.userId === userId && initializationRef.current.started) {\n return;\n }\n initializationRef.current = { userId, started: true };\n\n const init = async () => {\n // Use URL thread ID as preferred if available\n const urlPreferredThread = isUrlSyncEnabled ? urlState.threadId : undefined;\n const preferredThreadId = await fetchAndSetThreadsState(userId, urlPreferredThread);\n if (preferredThreadId) {\n await loadThreadMessages(preferredThreadId);\n } else if (bootstrap) {\n await bootstrapConversation(userId);\n }\n };\n init();\n } else {\n initializationRef.current = { userId: null, started: false };\n reset();\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);\n\n // Sync currentThreadExternalId to URL when it changes\n useEffect(() => {\n if (!isUrlSyncEnabled) return;\n // Only sync after initial load is complete\n if (!initializationRef.current.started) return;\n \n setUrlThreadId(currentThreadExternalId);\n }, [currentThreadExternalId, isUrlSyncEnabled, setUrlThreadId]);\n\n // Sync metadata map effects\n useEffect(() => {\n if (!currentThreadId) return;\n const metadata = threadMetadataMap[currentThreadId];\n if (!metadata) return;\n\n if (metadata.userContext && typeof metadata.userContext === 'object') {\n setUserContextSeed((prev) => ({ ...prev, ...(metadata.userContext as Partial<ChatUserContext>) }));\n }\n }, [currentThreadId, threadMetadataMap]);\n\n return {\n messages,\n threads,\n currentThreadId,\n isStreaming,\n userContextSeed,\n sendMessage: handleSendMessage,\n createThread: handleCreateThread,\n selectThread: handleSelectThread,\n renameThread: handleRenameThread,\n archiveThread: handleArchiveThread,\n deleteThread: handleDeleteThread,\n stopGeneration: handleStop,\n fetchAndSetThreadsState,\n loadThreadMessages,\n reset,\n // URL state\n /** Initial prompt from URL (if urlSync enabled) - use for pre-filling input */\n initialPrompt: isUrlSyncEnabled ? urlState.prompt : null,\n /** Clear the initial prompt from URL (call after consuming it) */\n clearInitialPrompt: clearUrlPrompt,\n /** URL agent ID (if urlSync enabled) - use for agent pre-selection */\n urlAgentId: isUrlSyncEnabled ? urlState.agentId : null,\n /** Update agent ID in URL */\n setUrlAgentId,\n };\n}\n","import type { MediaAttachment } from '@copilotz/chat-ui';\n\nconst rawBaseValue = import.meta.env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst runtimeProcess: typeof process | undefined = typeof process !== 'undefined' ? process : undefined;\n\nconst API_KEY = (() => {\n const env = (import.meta as { env?: Record<string, string | undefined> }).env ?? {};\n const candidates = [\n env.VITE_API_KEY,\n env.VITE_COPILOTZ_API_KEY,\n runtimeProcess?.env?.COPILOTZ_API_KEY,\n runtimeProcess?.env?.API_KEY,\n ];\n return candidates.find((value) => typeof value === 'string' && value.length > 0);\n})();\n\nconst withAuthHeaders = (headers: Record<string, string> = {}): Record<string, string> => {\n if (API_KEY) {\n return { ...headers, Authorization: `Bearer ${API_KEY}` };\n }\n return headers;\n};\n\ntype RestThread = {\n id: string;\n name?: string | null;\n externalId?: string | null;\n description?: string | null;\n participants?: string[] | null;\n status?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype RestMessage = {\n id: string;\n threadId: string;\n senderId?: string | null;\n senderType: string;\n senderUserId?: string | null;\n content?: string | null;\n metadata?: Record<string, unknown> | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype MessageSenderType = 'agent' | 'user' | 'tool' | 'system';\n\ntype MessageContent =\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image'; url?: string; dataBase64?: string; mimeType?: string; alt?: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n | { type: 'file'; url?: string; dataBase64?: string; mimeType?: string; name?: string }\n | { type: 'json'; value: unknown }\n >;\n\ntype MessageToolCall = {\n id?: string | null;\n name: string;\n args: Record<string, unknown>;\n};\n\ntype MessageThread = {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n externalId?: string | null;\n participants?: string[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessageSender = {\n id?: string | null;\n externalId?: string | null;\n type: MessageSenderType;\n name?: string | null;\n identifierType?: 'id' | 'name' | 'email' | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessagePayload = {\n content: MessageContent;\n sender: MessageSender;\n thread?: MessageThread | null;\n toolCalls?: MessageToolCall[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype StreamCallbacks = {\n onToken?: (token: string, isComplete: boolean, raw?: any) => void;\n onMessageEvent?: (payload: any) => void;\n onAssetEvent?: (payload: any) => void;\n signal?: AbortSignal;\n};\n\ntype RunOptions = {\n threadId?: string;\n threadExternalId?: string;\n content: string;\n user: {\n externalId: string;\n name?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n };\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown>; id?: string }>;\n selectedAgent?: string | null;\n} & StreamCallbacks;\n\nexport type CopilotzStreamResult = {\n text: string;\n messages: any[];\n media: Record<string, string> | null;\n};\n\nconst SSE_LINE_BREAK = '\\n\\n';\n\nconst appendChunk = (buffer: string, chunk: string): string => {\n if (!buffer) return chunk;\n if (!chunk) return buffer;\n if (chunk.startsWith(buffer)) return chunk;\n if (buffer.startsWith(chunk)) return buffer;\n const maxOverlap = Math.min(buffer.length, chunk.length);\n for (let i = maxOverlap; i > 0; i--) {\n if (buffer.endsWith(chunk.slice(0, i))) {\n return buffer + chunk.slice(i);\n }\n }\n return buffer + chunk;\n};\n\nconst toAttachmentPayload = (attachments?: MediaAttachment[]) => {\n if (!attachments || attachments.length === 0) return undefined;\n return attachments.map(att => {\n const base = {\n kind: att.kind,\n dataUrl: att.dataUrl,\n mimeType: att.mimeType,\n fileName: att.fileName,\n };\n if (att.kind === 'audio' || att.kind === 'video') {\n return {\n ...base,\n durationMs: att.durationMs,\n ...(att.kind === 'video' && 'poster' in att ? { poster: att.poster } : {}),\n };\n }\n return base;\n });\n};\n\n// --- Audio helpers: convert browser-recorded WebM/Opus to WAV (16-bit PCM) ---\nconst base64FromUint8 = (bytes: Uint8Array): string => {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n binary += String.fromCharCode.apply(null, Array.from(chunk));\n }\n // btoa is available in browsers\n return btoa(binary);\n};\n\nconst parseDataUrl = (dataUrl: string): { mime: string; base64: string } | null => {\n const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) return null;\n return { mime: match[1], base64: match[2] };\n};\n\nconst dataUrlToArrayBuffer = (dataUrl: string): ArrayBuffer => {\n const parsed = parseDataUrl(dataUrl);\n if (!parsed) return new ArrayBuffer(0);\n const binaryString = atob(parsed.base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n};\n\nconst encodeWav16BitPCM = (audioBuffer: AudioBuffer): Uint8Array => {\n const numChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const numFrames = audioBuffer.length;\n const bytesPerSample = 2; // 16-bit\n const dataSize = numFrames * numChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buffer);\n\n // RIFF header\n const writeString = (offset: number, str: string) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n };\n\n let offset = 0;\n writeString(offset, \"RIFF\"); offset += 4;\n view.setUint32(offset, 36 + dataSize, true); offset += 4;\n writeString(offset, \"WAVE\"); offset += 4;\n\n // fmt subchunk\n writeString(offset, \"fmt \"); offset += 4;\n view.setUint32(offset, 16, true); offset += 4; // Subchunk1Size (16 for PCM)\n view.setUint16(offset, 1, true); offset += 2; // AudioFormat (1 = PCM)\n view.setUint16(offset, numChannels, true); offset += 2; // NumChannels\n view.setUint32(offset, sampleRate, true); offset += 4; // SampleRate\n view.setUint32(offset, sampleRate * numChannels * bytesPerSample, true); offset += 4; // ByteRate\n view.setUint16(offset, numChannels * bytesPerSample, true); offset += 2; // BlockAlign\n view.setUint16(offset, 16, true); offset += 2; // BitsPerSample\n\n // data subchunk\n writeString(offset, \"data\"); offset += 4;\n view.setUint32(offset, dataSize, true); offset += 4;\n\n // Interleave channels and write PCM samples\n const channelData: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData.push(audioBuffer.getChannelData(ch));\n }\n\n let idx = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n let sample = channelData[ch][i];\n // Clamp\n sample = Math.max(-1, Math.min(1, sample));\n // Convert to 16-bit PCM\n const s = sample < 0 ? sample * 0x8000 : sample * 0x7FFF;\n view.setInt16(offset + idx, s, true);\n idx += 2;\n }\n }\n\n return new Uint8Array(buffer);\n};\n\nconst convertAudioDataUrlToWavBase64 = async (dataUrl: string): Promise<string | null> => {\n try {\n const ab = dataUrlToArrayBuffer(dataUrl);\n const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n const audioBuffer = await ctx.decodeAudioData(ab.slice(0)); // ensure detached buffer\n // Optionally downsample here if desired; we'll keep source sampleRate.\n const wavBytes = encodeWav16BitPCM(audioBuffer);\n return base64FromUint8(wavBytes);\n } catch (_err) {\n return null;\n }\n};\n\nexport async function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult> {\n const {\n threadId,\n threadExternalId,\n content,\n user,\n attachments,\n metadata,\n threadMetadata,\n toolCalls,\n selectedAgent,\n onToken,\n onMessageEvent,\n onAssetEvent,\n signal,\n } = options;\n\n const controller = new AbortController();\n if (signal) {\n signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });\n }\n\n // Separate audio attachments from other attachments\n const audioAttachments = attachments?.filter(att => att.kind === 'audio') ?? [];\n const nonAudioAttachments = attachments?.filter(att => att.kind !== 'audio') ?? [];\n \n const attachmentPayload = toAttachmentPayload(nonAudioAttachments);\n\n const normalizedToolCalls =\n toolCalls?.map<MessageToolCall>((call) => ({\n id: call.id ?? crypto.randomUUID(),\n name: call.name,\n args: call.args ?? {},\n })) ?? [];\n\n const metadataToolCalls =\n normalizedToolCalls.length > 0\n ? normalizedToolCalls.map((tc) => ({\n id: tc.id ?? undefined,\n name: tc.name,\n args: JSON.stringify(tc.args ?? {}),\n }))\n : undefined;\n\n const baseMetadata = {\n ...(metadata ?? {}),\n ...(attachmentPayload ? { attachments: attachmentPayload } : {}),\n ...(metadataToolCalls ? { toolCalls: metadataToolCalls } : {}),\n userExternalId: user.externalId,\n } as Record<string, unknown>;\n\n const messageMetadata = Object.keys(baseMetadata).length > 0 ? baseMetadata : undefined;\n\n const senderMetadata = {\n ...(user.metadata ?? {}),\n ...(user.email ? { email: user.email } : {}),\n } as Record<string, unknown>;\n\n const mergedThreadMetadata = {\n ...(threadMetadata ?? {}),\n } as Record<string, unknown>;\n\n if (mergedThreadMetadata.userExternalId === undefined) {\n mergedThreadMetadata.userExternalId = user.externalId;\n }\n\n // Extract name from threadMetadata if present\n const threadName = (mergedThreadMetadata.name as string) ?? null;\n // Remove name from metadata since it's a top-level field\n const { name: _threadName, ...restThreadMetadata } = mergedThreadMetadata;\n\n const threadPayload: MessageThread | undefined = (threadId || threadExternalId || threadName || Object.keys(restThreadMetadata).length > 0)\n ? {\n id: threadId ?? null,\n externalId: threadExternalId ?? null,\n name: threadName,\n participants: [selectedAgent || 'assistant'],\n metadata: Object.keys(restThreadMetadata).length > 0 ? restThreadMetadata : null,\n }\n : undefined;\n\n // Prepare audio parts (convert to WAV when needed)\n const preparedAudioParts: Array<{ type: 'audio'; dataBase64?: string; url?: string; mimeType?: string; transcript?: string }> = [];\n for (const audioAtt of audioAttachments) {\n if (!audioAtt.dataUrl) continue;\n const parsed = parseDataUrl(audioAtt.dataUrl);\n if (parsed && (parsed.mime.includes('wav') || parsed.mime.includes('mp3') || parsed.mime.includes('mpeg'))) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: parsed.base64,\n mimeType: parsed.mime.includes('wav') ? 'audio/wav' : 'audio/mp3',\n });\n continue;\n }\n // Convert other formats (e.g., audio/webm) to WAV\n const wavBase64 = await convertAudioDataUrlToWavBase64(audioAtt.dataUrl);\n if (wavBase64) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: wavBase64,\n mimeType: 'audio/wav',\n });\n } else {\n // Fallback: send as URL (may fail at provider side, but do not block)\n preparedAudioParts.push({\n type: 'audio',\n url: audioAtt.dataUrl,\n mimeType: audioAtt.mimeType || 'audio/webm',\n });\n }\n }\n\n // Build content array: include text and prepared audio parts\n const contentParts: MessageContent = (() => {\n const parts: Array<\n | { type: 'text'; text: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n > = [];\n const text = (typeof content === 'string' && content.trim().length > 0) ? content : '';\n parts.push({ type: 'text', text });\n for (const p of preparedAudioParts) parts.push(p);\n if (parts.length === 1 && parts[0].type === 'text') return parts[0].text;\n return parts;\n })();\n\n // Use selectedAgent for sender when sending tool calls, fallback to 'assistant' for backward compatibility\n const agentIdentifier = selectedAgent || 'assistant';\n\n const payload: MessagePayload = {\n content: contentParts,\n sender: {\n type: normalizedToolCalls.length > 0 ? 'agent' : 'user',\n externalId: user.externalId,\n id: normalizedToolCalls.length > 0 ? agentIdentifier : undefined,\n name: normalizedToolCalls.length > 0 ? agentIdentifier : (user.name ?? null),\n metadata: Object.keys(senderMetadata).length > 0 ? senderMetadata : null,\n },\n metadata: messageMetadata ?? null,\n thread: threadPayload ?? null,\n toolCalls: normalizedToolCalls.length > 0 ? normalizedToolCalls : null,\n };\n\n const response = await fetch(apiUrl('/v1/providers/web'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(errorText || 'Failed to run Copilotz agent');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let aggregatedText = '';\n const collectedMessages: any[] = [];\n let collectedMedia: Record<string, string> | null = null;\n\n const processEvent = (eventChunk: string) => {\n if (!eventChunk.trim()) return;\n const lines = eventChunk.split('\\n');\n let eventType = 'message';\n let dataRaw = '';\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n dataRaw += line.slice(5).trim();\n }\n }\n\n if (!dataRaw) return;\n\n let payload: any;\n try {\n payload = JSON.parse(dataRaw);\n } catch (error) {\n console.warn('copilotzService: failed to parse SSE payload', error, dataRaw);\n return;\n }\n\n switch (eventType) {\n case 'TOKEN': {\n const chunk =\n typeof payload?.payload?.token === 'string'\n ? payload.payload.token\n : (typeof payload?.token === 'string' ? payload.token : '');\n if (chunk) {\n aggregatedText = appendChunk(aggregatedText, chunk);\n }\n const isComplete = Boolean(\n (payload && payload.payload && payload.payload.isComplete) ?? payload?.isComplete\n );\n if (chunk || isComplete) {\n onToken?.(aggregatedText, isComplete, payload);\n }\n break;\n }\n case 'MESSAGE': {\n collectedMessages.push(payload);\n // Pass the payload with its internal type (e.g., NEW_MESSAGE, MESSAGE, etc.)\n // The hook will use payload.type to determine the actual event type\n onMessageEvent?.(payload);\n const senderType =\n payload?.payload?.senderType ??\n payload?.payload?.sender?.type;\n\n if (senderType === 'agent' && typeof payload?.payload?.content === 'string') {\n aggregatedText = payload.payload.content;\n }\n break;\n }\n case 'TOOL_CALL': {\n // Pass TOOL_CALL events directly to the message event handler\n // The payload already has the full event structure with type: \"TOOL_CALL\"\n onMessageEvent?.(payload);\n break;\n }\n case 'ASSET_CREATED': {\n const assetPayload = (payload && typeof payload === 'object' && 'payload' in payload)\n ? (payload as { payload?: any }).payload\n : payload;\n // Convert ASSET_CREATED to media format for backward compatibility\n if (assetPayload?.dataUrl) {\n collectedMedia = {\n [assetPayload.assetId || '0']: assetPayload.dataUrl\n };\n }\n // Call the asset event handler\n onAssetEvent?.(assetPayload);\n break;\n }\n case 'ERROR':\n throw new Error(payload?.error || 'Copilotz stream error');\n default:\n // For other event types, wrap in a structure with type and payload\n onMessageEvent?.({ type: eventType, payload });\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n if (buffer.includes('\\r')) {\n buffer = buffer.replace(/\\r/g, '');\n }\n\n let eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n while (eventBoundary >= 0) {\n const chunk = buffer.slice(0, eventBoundary);\n buffer = buffer.slice(eventBoundary + SSE_LINE_BREAK.length);\n processEvent(chunk);\n eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n }\n }\n\n if (buffer.length > 0) {\n processEvent(buffer);\n }\n\n return {\n text: aggregatedText,\n messages: collectedMessages,\n media: collectedMedia,\n };\n}\n\nexport async function fetchThreads(userId: string) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ \"metadata.userExternalId\": userId } ));\n params.set('sort', '-updatedAt');\n\n const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load threads (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestThread[];\n}\n\nexport async function fetchThreadMessages(threadId: string) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n params.set('sort', 'createdAt:asc');\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load thread messages (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestMessage[];\n}\n\nexport async function updateThread(threadId: string, updates: Partial<RestThread>) {\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'PUT',\n headers: withAuthHeaders({ 'Content-Type': 'application/json', Accept: 'application/json' }),\n body: JSON.stringify(updates),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to update thread (${res.status})`);\n }\n\n const data = await res.json();\n return data?.body ?? data;\n}\n\nexport async function deleteMessagesByThreadId(threadId: string) {\n // First fetch all messages for the thread (no field selection to avoid issues)\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n // If we can't fetch messages, we can't delete them - but this might be ok if there are none\n console.warn('Could not fetch messages for deletion:', res.status);\n return;\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data) || data.length === 0) {\n return; // No messages to delete\n }\n\n // Delete each message sequentially to avoid overwhelming the server\n for (const msg of data) {\n if (msg?.id) {\n try {\n await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n } catch {\n // Ignore individual message delete errors\n }\n }\n }\n}\n\nexport async function deleteThread(threadId: string) {\n // First delete all messages in the thread to avoid foreign key constraint\n await deleteMessagesByThreadId(threadId);\n\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to delete thread (${res.status})`);\n }\n\n return true;\n}\n\nexport const copilotzService = {\n runCopilotzStream,\n fetchThreads,\n fetchThreadMessages,\n updateThread,\n deleteThread,\n};\n","// Minimal API client for Copilotz assets\n\ntype FetchAssetResult = {\n assetId: string;\n ref: string;\n dataUrl?: string;\n base64?: string;\n mime?: string;\n error?: string;\n};\n\nconst rawBaseValue = (import.meta as { env?: Record<string, string | undefined> }).env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst extractAssetId = (refOrId: string) =>\n refOrId.startsWith('asset://') ? refOrId.slice('asset://'.length) : refOrId;\n\nexport async function getAssetDataUrl(refOrId: string): Promise<{ dataUrl: string; mime?: string; assetId: string }> {\n const id = extractAssetId(refOrId);\n const res = await fetch(apiUrl(`/v1/assets/${encodeURIComponent(id)}?format=dataUrl`), {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => res.statusText);\n throw new Error(text || `Failed to fetch asset ${refOrId}`);\n }\n const data = (await res.json()) as FetchAssetResult;\n if (!data?.dataUrl) {\n throw new Error(data?.error || `Asset ${refOrId} has no dataUrl`);\n }\n return { dataUrl: data.dataUrl, mime: data.mime, assetId: data.assetId };\n}\n\n// Resolve assets in messages by replacing metadata.attachments[].assetRef with dataUrl\ntype WithMetadata = {\n metadata?: Record<string, unknown> | null;\n};\n\nexport async function resolveAssetsInMessages<T extends WithMetadata>(messages: T[]): Promise<T[]> {\n const resolved: T[] = [];\n for (const msg of messages) {\n const meta = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachments = Array.isArray(meta?.attachments)\n ? (meta!.attachments as Array<Record<string, unknown>>)\n : undefined;\n\n if (!attachments || attachments.length === 0) {\n resolved.push(msg);\n continue;\n }\n\n const newAttachments: Array<Record<string, unknown>> = [];\n for (const att of attachments) {\n const assetRef = typeof att?.assetRef === 'string' ? (att.assetRef as string) : undefined;\n if (assetRef) {\n try {\n const { dataUrl, mime } = await getAssetDataUrl(assetRef);\n const kind = typeof att.kind === 'string' ? (att.kind as string) : 'image';\n newAttachments.push({\n kind,\n dataUrl,\n mimeType: typeof att.mimeType === 'string' ? att.mimeType : (mime ?? undefined),\n });\n } catch {\n // If fetching fails, keep original so UI can ignore gracefully\n newAttachments.push(att);\n }\n } else {\n newAttachments.push(att);\n }\n }\n\n const newMeta = { ...(meta ?? {}), attachments: newAttachments } as Record<string, unknown>;\n resolved.push({ ...msg, metadata: newMeta });\n }\n return resolved;\n}\n\n\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Configuration for URL parameter names\n */\nexport interface UrlParamsConfig {\n /** URL param name for thread ID (default: 'thread') */\n thread?: string;\n /** URL param name for agent ID (default: 'agent') */\n agent?: string;\n /** URL param name for initial prompt (default: 'prompt') */\n prompt?: string;\n}\n\n/**\n * URL sync behavior configuration\n */\nexport interface UrlSyncConfig {\n /** Enable/disable URL sync (default: true) */\n enabled?: boolean;\n /** \n * How to update the URL when state changes:\n * - 'push': Creates browser history entries (back button works)\n * - 'replace': Updates URL without history entries (default)\n * - 'read-only': Only reads from URL, never writes\n */\n mode?: 'push' | 'replace' | 'read-only';\n /** Custom parameter names */\n params?: UrlParamsConfig;\n /**\n * Behavior for the prompt parameter:\n * - 'prefill': Pre-fills the input field (default)\n * - 'auto-send': Automatically sends the message on load\n */\n promptBehavior?: 'prefill' | 'auto-send';\n /**\n * Whether to clear the prompt param from URL after reading\n * Prevents re-sending on refresh (default: true)\n */\n clearPromptAfterRead?: boolean;\n}\n\n/**\n * State values parsed from URL\n */\nexport interface UrlState {\n threadId: string | null;\n agentId: string | null;\n prompt: string | null;\n}\n\n/**\n * Return type of useUrlState hook\n */\nexport interface UseUrlStateReturn {\n /** Current state parsed from URL */\n state: UrlState;\n /** Update thread ID in URL */\n setThreadId: (threadId: string | null) => void;\n /** Update agent ID in URL */\n setAgentId: (agentId: string | null) => void;\n /** Clear prompt from URL (call after consuming it) */\n clearPrompt: () => void;\n /** Whether URL sync is enabled */\n isEnabled: boolean;\n}\n\nconst DEFAULT_PARAMS: Required<UrlParamsConfig> = {\n thread: 'thread',\n agent: 'agent',\n prompt: 'prompt',\n};\n\n/**\n * Check if we're in a browser environment\n */\nconst isBrowser = typeof globalThis !== 'undefined' && typeof globalThis.location !== 'undefined';\n\n/**\n * Get current URL search params (SSR-safe)\n */\nconst getSearchParams = (): URLSearchParams => {\n if (!isBrowser) return new URLSearchParams();\n return new URLSearchParams(globalThis.location.search);\n};\n\n/**\n * Update URL with new search params\n */\nconst updateUrl = (params: URLSearchParams, mode: 'push' | 'replace') => {\n if (!isBrowser) return;\n \n const url = new URL(globalThis.location.href);\n url.search = params.toString();\n \n if (mode === 'push') {\n globalThis.history.pushState({}, '', url.toString());\n } else {\n globalThis.history.replaceState({}, '', url.toString());\n }\n};\n\n/**\n * Hook to manage chat state persistence via URL parameters.\n * \n * Supports:\n * - Thread ID: Navigate to specific conversation\n * - Agent ID: Pre-select an agent\n * - Prompt: Pre-fill or auto-send a message\n * \n * @example\n * ```tsx\n * const { state, setThreadId, setAgentId } = useUrlState({\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * });\n * \n * // Read initial values\n * console.log(state.threadId, state.agentId, state.prompt);\n * \n * // Update URL when thread changes\n * setThreadId('abc123');\n * ```\n */\nexport function useUrlState(config: UrlSyncConfig = {}): UseUrlStateReturn {\n const {\n enabled = true,\n mode = 'replace',\n params: userParams = {},\n clearPromptAfterRead = true,\n } = config;\n\n const params = { ...DEFAULT_PARAMS, ...userParams };\n const isReadOnly = mode === 'read-only';\n const updateMode = mode === 'read-only' ? 'replace' : mode;\n\n // Track if initial read has been done\n const initialReadDone = useRef(false);\n const promptCleared = useRef(false);\n\n // Parse initial state from URL\n const parseUrlState = useCallback((): UrlState => {\n if (!enabled || !isBrowser) {\n return { threadId: null, agentId: null, prompt: null };\n }\n\n const searchParams = getSearchParams();\n \n return {\n threadId: searchParams.get(params.thread) || null,\n agentId: searchParams.get(params.agent) || null,\n prompt: promptCleared.current ? null : (searchParams.get(params.prompt) || null),\n };\n }, [enabled, params.thread, params.agent, params.prompt]);\n\n const [state, setState] = useState<UrlState>(parseUrlState);\n\n // Read URL state on mount and handle popstate (back/forward navigation)\n useEffect(() => {\n if (!enabled || !isBrowser) return;\n\n // Initial read\n if (!initialReadDone.current) {\n const initialState = parseUrlState();\n setState(initialState);\n initialReadDone.current = true;\n\n // Clear prompt from URL after reading if configured\n if (clearPromptAfterRead && initialState.prompt && !isReadOnly) {\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n }\n }\n\n // Listen for popstate (browser back/forward)\n const handlePopState = () => {\n setState(parseUrlState());\n };\n\n globalThis.addEventListener('popstate', handlePopState);\n return () => globalThis.removeEventListener('popstate', handlePopState);\n }, [enabled, parseUrlState, clearPromptAfterRead, params.prompt, isReadOnly]);\n\n // Update thread ID in URL\n const setThreadId = useCallback((threadId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (threadId) {\n searchParams.set(params.thread, threadId);\n } else {\n searchParams.delete(params.thread);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, threadId }));\n }, [enabled, isReadOnly, params.thread, updateMode]);\n\n // Update agent ID in URL\n const setAgentId = useCallback((agentId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (agentId) {\n searchParams.set(params.agent, agentId);\n } else {\n searchParams.delete(params.agent);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, agentId }));\n }, [enabled, isReadOnly, params.agent, updateMode]);\n\n // Clear prompt from URL\n const clearPrompt = useCallback(() => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n setState(prev => ({ ...prev, prompt: null }));\n }, [enabled, isReadOnly, params.prompt]);\n\n return {\n state,\n setThreadId,\n setAgentId,\n clearPrompt,\n isEnabled: enabled,\n };\n}\n"],"mappings":"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","names":["useEffect","useState","forwardRef","createElement","useState","useCallback","useRef","useEffect","offset","payload","rawBaseValue","rawBase","normalizedBase","API_BASE","apiUrl","useState","useRef","useEffect","useCallback","sm","deleteThread","useState","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/CopilotzChat.tsx","../../node_modules/shared/src/utils.ts","../../node_modules/lucide-react/src/defaultAttributes.ts","../../node_modules/lucide-react/src/Icon.ts","../../node_modules/lucide-react/src/createLucideIcon.ts","../../node_modules/lucide-react/src/icons/user.ts","../src/useCopilotzChat.ts","../src/copilotzService.ts","../src/assetsService.ts","../src/useUrlState.ts"],"sourcesContent":["import React, { useMemo, useEffect, useState } from 'react';\nimport { ChatUI, ChatUserContextProvider } from '@copilotz/chat-ui';\nimport type { AgentOption, ChatConfig, ChatCallbacks, ChatUserContext, MemoryItem } from '@copilotz/chat-ui';\nimport { User } from 'lucide-react';\nimport { useCopilotz } from './useCopilotzChat';\nimport type { UrlSyncConfig } from './useUrlState';\n\nexport interface CopilotzChatProps {\n userId: string;\n userName?: string;\n userAvatar?: string;\n userEmail?: string;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n config?: ChatConfig;\n callbacks?: Partial<ChatCallbacks>;\n /**\n * Custom component to render in the right sidebar panel (e.g. Profile info).\n * Can be:\n * - A React node (static)\n * - A function receiving context: `(context) => ReactNode`\n * - A render function receiving panel props: `(props: { onClose, isMobile }) => ReactNode`\n * Toggle visibility via the header button.\n */\n customComponent?: \n | React.ReactNode \n | ((context: ChatUserContext) => React.ReactNode)\n | ((props: { onClose: () => void; isMobile: boolean }) => React.ReactNode);\n onToolOutput?: (output: Record<string, unknown>) => void;\n /** Called when user clicks logout in the user menu */\n onLogout?: () => void;\n /** Called when user clicks \"View Profile\" in the user menu */\n onViewProfile?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n /** Empty-state suggestions */\n suggestions?: string[];\n /** Agent selector data (built-in ChatUI) */\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n className?: string;\n /**\n * URL state synchronization configuration.\n * When enabled, syncs thread ID, agent, and prompt to/from URL parameters.\n * \n * Features:\n * - `?thread=abc123` - Opens specific thread\n * - `?agent=support-bot` - Pre-selects agent\n * - `?prompt=Hello` - Pre-fills or auto-sends message\n * \n * @example\n * ```tsx\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{ enabled: true }}\n * />\n * \n * // With custom param names\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{\n * enabled: true,\n * params: { thread: 't', agent: 'a', prompt: 'q' },\n * promptBehavior: 'auto-send'\n * }}\n * />\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport const CopilotzChat: React.FC<CopilotzChatProps> = ({\n userId,\n userName,\n userAvatar,\n userEmail,\n initialContext,\n bootstrap,\n config: userConfig,\n callbacks: userCallbacks,\n customComponent,\n onToolOutput,\n onLogout,\n onViewProfile,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n suggestions,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n className,\n urlSync,\n}) => {\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n\n const {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n userContextSeed,\n sendMessage,\n createThread,\n selectThread,\n renameThread,\n archiveThread,\n deleteThread,\n stopGeneration,\n initialPrompt,\n clearInitialPrompt,\n urlAgentId,\n setUrlAgentId,\n } = useCopilotz({ \n userId, \n initialContext, \n bootstrap, \n defaultThreadName: userConfig?.labels?.defaultThreadName,\n onToolOutput,\n preferredAgentName: selectedAgent?.name ?? null,\n urlSync,\n });\n\n // Track if we've handled the initial prompt\n const [promptHandled, setPromptHandled] = useState(false);\n\n // Handle URL agent ID - call onSelectAgent if URL has agent and it differs from current\n useEffect(() => {\n if (urlAgentId && onSelectAgent && urlAgentId !== selectedAgentId) {\n // Check if the agent exists in options\n const agentExists = agentOptions.some((a) => a.id === urlAgentId);\n if (agentExists) {\n onSelectAgent(urlAgentId);\n }\n }\n }, [urlAgentId, selectedAgentId, onSelectAgent, agentOptions]);\n\n // Sync selected agent to URL when it changes (after initial load)\n useEffect(() => {\n if (selectedAgentId && urlSync?.enabled) {\n setUrlAgentId(selectedAgentId);\n }\n }, [selectedAgentId, urlSync?.enabled, setUrlAgentId]);\n\n // Handle auto-send behavior for initial prompt\n useEffect(() => {\n if (initialPrompt && !promptHandled && urlSync?.promptBehavior === 'auto-send') {\n // Wait for initial load to complete\n const timer = setTimeout(() => {\n void sendMessage(initialPrompt);\n clearInitialPrompt();\n setPromptHandled(true);\n }, 500);\n return () => clearTimeout(timer);\n }\n }, [initialPrompt, promptHandled, urlSync?.promptBehavior, sendMessage, clearInitialPrompt]);\n\n // For prefill behavior, we'll pass initialInput to ChatUI\n\n const chatCallbacks: ChatCallbacks = useMemo(() => ({\n onSendMessage: (content, attachments) => {\n void sendMessage(content, attachments);\n userCallbacks?.onSendMessage?.(content, attachments);\n },\n onStopGeneration: () => {\n stopGeneration();\n userCallbacks?.onStopGeneration?.();\n },\n onCreateThread: (title) => {\n createThread(title);\n userCallbacks?.onCreateThread?.(title);\n },\n onSelectThread: (threadId) => {\n void selectThread(threadId);\n userCallbacks?.onSelectThread?.(threadId);\n },\n onRenameThread: (threadId, newTitle) => {\n void renameThread(threadId, newTitle);\n userCallbacks?.onRenameThread?.(threadId, newTitle);\n },\n onArchiveThread: (threadId) => {\n void archiveThread(threadId);\n userCallbacks?.onArchiveThread?.(threadId);\n },\n onDeleteThread: (threadId) => {\n void deleteThread(threadId);\n userCallbacks?.onDeleteThread?.(threadId);\n },\n onCopyMessage: async (messageId, content) => {\n try {\n await navigator.clipboard.writeText(content);\n userCallbacks?.onCopyMessage?.(messageId, content);\n } catch (error) {\n console.error('Failed to copy message', error);\n }\n },\n // User menu callbacks\n onLogout,\n onViewProfile,\n ...userCallbacks,\n }), [sendMessage, stopGeneration, createThread, selectThread, renameThread, archiveThread, deleteThread, userCallbacks, onLogout, onViewProfile]);\n\n // Merge user config with dynamic values\n // customComponent is passed through - it will be resolved in ChatUI\n // which can provide onClose and isMobile props\n const mergedConfig: ChatConfig = useMemo(() => {\n const base = userConfig || {};\n if (!customComponent) {\n return base;\n }\n return {\n ...base,\n customComponent: {\n ...base.customComponent,\n component: customComponent,\n icon: base.customComponent?.icon || <User className=\"h-6 w-6\" />,\n },\n };\n }, [userConfig, customComponent]);\n\n const effectiveUserName = userName || userId;\n // Don't try to extract avatar from profile automatically unless it's in context\n const effectiveUserAvatar = userAvatar;\n\n return (\n <ChatUserContextProvider initial={userContextSeed}>\n <ChatUI\n messages={messages}\n isMessagesLoading={isMessagesLoading}\n threads={threads}\n currentThreadId={currentThreadId}\n config={mergedConfig}\n callbacks={chatCallbacks}\n isGenerating={isStreaming}\n suggestions={suggestions}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n user={{\n id: userId,\n name: effectiveUserName,\n email: userEmail,\n avatar: effectiveUserAvatar,\n }}\n assistant={{\n name: userConfig?.branding?.title,\n avatar: userConfig?.branding?.avatar,\n description: userConfig?.branding?.subtitle,\n }}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n className={className}\n // Pass initial prompt for prefill behavior (not auto-send)\n initialInput={\n initialPrompt && !promptHandled && urlSync?.promptBehavior !== 'auto-send'\n ? initialPrompt\n : undefined\n }\n onInitialInputConsumed={() => {\n clearInitialPrompt();\n setPromptHandled(true);\n }}\n />\n </ChatUserContextProvider>\n );\n};\n","import { CamelToPascal } from './utility-types';\n\n/**\n * Converts string to kebab case\n *\n * @param {string} string\n * @returns {string} A kebabized string\n */\nexport const toKebabCase = (string: string) =>\n string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts string to camel case\n *\n * @param {string} string\n * @returns {string} A camelized string\n */\nexport const toCamelCase = <T extends string>(string: T) =>\n string.replace(/^([A-Z])|[\\s-_]+(\\w)/g, (match, p1, p2) =>\n p2 ? p2.toUpperCase() : p1.toLowerCase(),\n );\n\n/**\n * Converts string to pascal case\n *\n * @param {string} string\n * @returns {string} A pascalized string\n */\nexport const toPascalCase = <T extends string>(string: T): CamelToPascal<T> => {\n const camelCase = toCamelCase(string);\n\n return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal<T>;\n};\n\n/**\n * Merges classes into a single string\n *\n * @param {array} classes\n * @returns {string} A string of classes\n */\nexport const mergeClasses = <ClassType = string | undefined | null>(...classes: ClassType[]) =>\n classes\n .filter((className, index, array) => {\n return (\n Boolean(className) &&\n (className as string).trim() !== '' &&\n array.indexOf(className) === index\n );\n })\n .join(' ')\n .trim();\n\n/**\n * Is empty string\n *\n * @param {unknown} value\n * @returns {boolean} Whether the value is an empty string\n */\nexport const isEmptyString = (value: unknown): boolean => value === '';\n\n/**\n * Check if a component has an accessibility prop\n *\n * @param {object} props\n * @returns {boolean} Whether the component has an accessibility prop\n */\nexport const hasA11yProp = (props: Record<string, any>) => {\n for (const prop in props) {\n if (prop.startsWith('aria-') || prop === 'role' || prop === 'title') {\n return true;\n }\n }\n};\n","export default {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n","import { createElement, forwardRef } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport { IconNode, LucideProps } from './types';\nimport { mergeClasses, hasA11yProp } from '@lucide/shared';\n\ninterface IconComponentProps extends LucideProps {\n iconNode: IconNode;\n}\n\n/**\n * Lucide icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst Icon = forwardRef<SVGSVGElement, IconComponentProps>(\n (\n {\n color = 'currentColor',\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = '',\n children,\n iconNode,\n ...rest\n },\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,\n className: mergeClasses('lucide', className),\n ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }),\n ...rest,\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n);\n\nexport default Icon;\n","import { createElement, forwardRef } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';\nimport { IconNode, LucideProps } from './types';\nimport Icon from './Icon';\n\n/**\n * Create a Lucide icon component\n * @param {string} iconName\n * @param {array} iconNode\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst createLucideIcon = (iconName: string, iconNode: IconNode) => {\n const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>\n createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className,\n ),\n ...props,\n }),\n );\n\n Component.displayName = toPascalCase(iconName);\n\n return Component;\n};\n\nexport default createLucideIcon;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2', key: '975kel' }],\n ['circle', { cx: '12', cy: '7', r: '4', key: '17ys0d' }],\n];\n\n/**\n * @component @name User\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/user\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst User = createLucideIcon('user', __iconNode);\n\nexport default User;\n","// deno-lint-ignore-file no-explicit-any\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { runCopilotzStream, fetchThreads, fetchThreadMessages, updateThread as updateThreadApi, deleteThread as deleteThreadApi } from './copilotzService';\nimport { resolveAssetsInMessages } from './assetsService';\nimport type { ChatMessage as ChatViewMessage, ChatThread, MediaAttachment, ChatUserContext } from '@copilotz/chat-ui';\nimport { useUrlState, type UrlSyncConfig } from './useUrlState';\n\nconst nowTs = () => Date.now();\nconst generateId = () =>\n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`) as string;\nconst isAbortError = (error: unknown) => (\n error instanceof DOMException && error.name === 'AbortError'\n) || (typeof error === 'object' && error !== null && 'name' in error && (error as { name?: string }).name === 'AbortError');\n\ntype ServerThread = Awaited<ReturnType<typeof fetchThreads>>[number];\ntype ServerMessage = Awaited<ReturnType<typeof fetchThreadMessages>>[number];\n\nconst convertServerMessage = (msg: ServerMessage): ChatViewMessage => {\n const timestamp = msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs();\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachmentsMeta = Array.isArray(metadata?.attachments)\n ? (metadata!.attachments as Array<Record<string, unknown>>)\n : [];\n\n const attachments: MediaAttachment[] = attachmentsMeta.flatMap((att) => {\n const kind = typeof att.kind === 'string' ? att.kind : undefined;\n const dataUrl = typeof att.dataUrl === 'string' ? att.dataUrl : undefined;\n const mimeType = typeof att.mimeType === 'string' ? att.mimeType : undefined;\n if (!dataUrl) return [];\n\n if (kind === 'image') {\n return [{ kind: 'image', dataUrl, mimeType: mimeType ?? 'image/jpeg' }] as MediaAttachment[];\n }\n if (kind === 'audio') {\n return [{\n kind: 'audio',\n dataUrl,\n mimeType: mimeType ?? 'audio/webm',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n }] as MediaAttachment[];\n }\n if (kind === 'video') {\n return [{\n kind: 'video',\n dataUrl,\n mimeType: mimeType ?? 'video/mp4',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n poster: typeof att.poster === 'string' ? att.poster : undefined,\n }] as MediaAttachment[];\n }\n return [] as MediaAttachment[];\n });\n\n const role = msg.senderType === 'agent'\n ? 'assistant'\n : msg.senderType === 'user'\n ? 'user'\n : 'assistant';\n\n const mappedToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls)\n ? ((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls || []).map((tc) => ({\n id: typeof tc?.id === 'string' ? tc.id : generateId(),\n name: typeof tc?.name === 'string' ? tc.name : 'tool',\n arguments: (tc?.args as Record<string, unknown>) || {},\n status: 'completed' as const,\n }))\n : undefined;\n\n const hasToolCalls = Array.isArray(mappedToolCalls) && mappedToolCalls.length > 0;\n const isToolSender = msg.senderType === 'tool';\n const content =\n isToolSender\n ? '' // Do not render textual content for tool messages; attachments only\n : ((msg.content ?? '') || (hasToolCalls ? '' : ''));\n\n return {\n id: msg.id,\n role,\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isStreaming: false,\n isComplete: true,\n metadata,\n toolCalls: hasToolCalls ? mappedToolCalls : undefined,\n };\n};\n\nexport interface UseCopilotzOptions {\n userId: string | null;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n defaultThreadName?: string;\n onToolOutput?: (output: Record<string, unknown>) => void;\n preferredAgentName?: string | null;\n /**\n * URL state synchronization configuration.\n * When enabled, thread ID and agent are synced to/from URL parameters.\n * \n * @example\n * ```tsx\n * const chat = useCopilotz({\n * userId: 'user123',\n * urlSync: {\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * }\n * });\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, urlSync }: UseCopilotzOptions) {\n // URL state management\n const {\n state: urlState,\n setThreadId: setUrlThreadId,\n setAgentId: setUrlAgentId,\n clearPrompt: clearUrlPrompt,\n isEnabled: isUrlSyncEnabled,\n } = useUrlState(urlSync);\n\n const [threads, setThreads] = useState<ChatThread[]>([]);\n const [threadMetadataMap, setThreadMetadataMap] = useState<Record<string, Record<string, unknown> | undefined>>({});\n const [threadExternalIdMap, setThreadExternalIdMap] = useState<Record<string, string | null>>({});\n\n const [currentThreadId, setCurrentThreadId] = useState<string | null>(null);\n const [currentThreadExternalId, setCurrentThreadExternalId] = useState<string | null>(null);\n\n const [messages, setMessages] = useState<ChatViewMessage[]>([]);\n const [isMessagesLoading, setIsMessagesLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n\n const [userContextSeed, setUserContextSeed] = useState<Partial<ChatUserContext>>(initialContext || {});\n const preferredAgentRef = useRef<string | null>(preferredAgentName ?? null);\n\n // Refs to hold latest state for callbacks to avoid dependency cycles\n // Using direct assignment pattern instead of useEffect for better performance\n const threadsRef = useRef(threads);\n const threadMetadataMapRef = useRef(threadMetadataMap);\n const threadExternalIdMapRef = useRef(threadExternalIdMap);\n const currentThreadIdRef = useRef(currentThreadId);\n const currentThreadExternalIdRef = useRef(currentThreadExternalId);\n const userContextSeedRef = useRef(userContextSeed);\n\n // Sync refs on every render (more efficient than multiple useEffects)\n threadsRef.current = threads;\n threadMetadataMapRef.current = threadMetadataMap;\n threadExternalIdMapRef.current = threadExternalIdMap;\n currentThreadIdRef.current = currentThreadId;\n currentThreadExternalIdRef.current = currentThreadExternalId;\n userContextSeedRef.current = userContextSeed;\n preferredAgentRef.current = preferredAgentName ?? null;\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const messagesRequestRef = useRef<number>(0);\n // Guard to prevent double initialization in StrictMode\n const initializationRef = useRef<{ userId: string | null; started: boolean }>({ userId: null, started: false });\n\n useEffect(() => {\n if (initialContext) {\n setUserContextSeed((prev) => ({ ...prev, ...initialContext }));\n }\n }, [initialContext]);\n\n const processToolOutput = useCallback((output: Record<string, unknown>) => {\n if (!output) return;\n\n const contextPatch: Partial<ChatUserContext> = {};\n\n // Generic merge of userContext from output if present\n if (output.userContext && typeof output.userContext === 'object') {\n Object.assign(contextPatch, output.userContext as Partial<ChatUserContext>);\n }\n\n if (Object.keys(contextPatch).length > 0) {\n setUserContextSeed((prev) => ({ ...prev, ...contextPatch }));\n }\n\n onToolOutput?.(output);\n }, [onToolOutput]);\n\n const handleStreamMessageEvent = useCallback((event: any) => {\n const payload = event?.payload;\n if (!payload) return;\n\n if (payload.senderType === 'tool') {\n const metadata = (payload.metadata ?? event.metadata ?? {}) as Record<string, unknown>;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n\n // Attach tool call details to the current assistant bubble (expandable)\n const toolName = (metadata?.toolName as string) || (metadata?.tool as string) || 'tool';\n let argsObj: Record<string, unknown> = {};\n try {\n const argStr = (metadata?.arguments as string) ?? '{}';\n argsObj = typeof argStr === 'string' ? JSON.parse(argStr) : (argStr as Record<string, unknown>);\n } catch (_) { /* ignore parse */ }\n const resultObj = metadata?.output as unknown;\n const callId = (payload.toolCallId as string) || generateId();\n\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant') {\n const existing = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n next[i] = {\n ...m,\n toolCalls: [\n ...existing,\n {\n id: callId,\n name: toolName,\n arguments: argsObj as Record<string, any>,\n result: resultObj,\n status: 'completed' as const,\n endTime: Date.now(),\n },\n ],\n };\n break;\n }\n }\n return next;\n });\n return;\n }\n\n if (payload.senderType === 'agent' && typeof payload.content === 'string') {\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant' && m.isStreaming) {\n next[i] = { ...m, content: payload.content, isStreaming: false, isComplete: true };\n break;\n }\n }\n return next;\n });\n }\n }, [processToolOutput]);\n\n const updateThreadsState = useCallback((rawThreads: ServerThread[], preferredExternalId?: string | null) => {\n const metadataMap: Record<string, Record<string, unknown> | undefined> = {};\n const externalMap: Record<string, string | null> = {};\n\n const normalized = rawThreads.map((thread) => {\n metadataMap[thread.id] = thread.metadata ?? undefined;\n externalMap[thread.id] = thread.externalId ?? null;\n const updatedAt = thread.updatedAt ? new Date(thread.updatedAt).getTime() : nowTs();\n const createdAt = thread.createdAt ? new Date(thread.createdAt).getTime() : updatedAt;\n return {\n id: thread.id,\n title: thread.name || 'Chat',\n createdAt,\n updatedAt,\n messageCount: typeof thread.metadata?.messageCount === 'number'\n ? thread.metadata!.messageCount as number\n : 0,\n isArchived: thread.status === 'archived',\n metadata: thread.metadata ?? undefined,\n } as ChatThread;\n });\n\n setThreadMetadataMap(metadataMap);\n setThreadExternalIdMap(externalMap);\n setThreads(normalized);\n\n // Use refs to avoid dependency cycle\n const curExtId = currentThreadExternalIdRef.current;\n const curId = currentThreadIdRef.current;\n\n let nextThreadId: string | null = null;\n\n if (preferredExternalId) {\n const preferred = rawThreads.find((thread) => (thread.externalId ?? thread.id) === preferredExternalId);\n if (preferred) nextThreadId = preferred.id;\n }\n\n if (!nextThreadId && curExtId) {\n const match = rawThreads.find((thread) => (thread.externalId ?? thread.id) === curExtId);\n if (match) nextThreadId = match.id;\n }\n\n if (!nextThreadId && curId && rawThreads.some((thread) => thread.id === curId)) {\n nextThreadId = curId;\n }\n\n if (!nextThreadId && normalized.length > 0) {\n nextThreadId = normalized[0].id;\n }\n\n setCurrentThreadId(nextThreadId ?? null);\n setCurrentThreadExternalId(nextThreadId ? externalMap[nextThreadId] ?? null : null);\n\n return nextThreadId;\n }, []); // No dependencies needed now as we use refs for reading current state\n\n const fetchAndSetThreadsState = useCallback(async (uid: string, preferredExternalId?: string | null) => {\n try {\n const rawThreads = await fetchThreads(uid);\n return updateThreadsState(rawThreads, preferredExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error loading threads', error);\n return null;\n }\n }, [updateThreadsState]);\n\n const loadThreadMessages = useCallback(async (threadId: string) => {\n const requestId = messagesRequestRef.current + 1;\n messagesRequestRef.current = requestId;\n setIsMessagesLoading(true);\n try {\n const rawMessages = await fetchThreadMessages(threadId);\n const resolvedMessages = await resolveAssetsInMessages(rawMessages as unknown as any[]);\n if (messagesRequestRef.current !== requestId) return;\n\n resolvedMessages.forEach((msg: any) => {\n if (msg.senderType === 'tool') {\n const metadata = msg.metadata as Record<string, unknown> | undefined;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n }\n });\n\n const viewMessages = resolvedMessages\n .filter((msg) => {\n const text = (typeof msg.content === 'string' ? msg.content : '').trim();\n const hasText = text.length > 0;\n const hasToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<unknown> }).toolCalls)\n && ((msg as unknown as { toolCalls?: Array<unknown> }).toolCalls as Array<unknown>).length > 0;\n const meta = (msg.metadata ?? {}) as Record<string, unknown>;\n const hasAttachments = Array.isArray(meta.attachments) && (meta.attachments as unknown[]).length > 0;\n // Keep tool messages only if they carry attachments (e.g., generated media)\n if (msg.senderType === 'tool') {\n return hasAttachments;\n }\n // For agent/user/system, keep if there is text, tool calls, or attachments\n return hasText || hasToolCalls || hasAttachments;\n })\n .map(convertServerMessage);\n\n setMessages(viewMessages);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error(`Error loading messages for thread ${threadId}`, error);\n } finally {\n if (messagesRequestRef.current === requestId) {\n setIsMessagesLoading(false);\n }\n }\n }, [processToolOutput]);\n\n const handleSelectThread = useCallback(async (threadId: string) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n // Use ref for external map to avoid re-creation\n const extMap = threadExternalIdMapRef.current;\n setCurrentThreadExternalId(extMap[threadId] ?? null);\n await loadThreadMessages(threadId);\n }, [loadThreadMessages]);\n\n const handleCreateThread = useCallback((title?: string) => {\n messagesRequestRef.current += 1;\n setIsMessagesLoading(false);\n const id = generateId();\n const now = nowTs();\n const newThread: ChatThread = {\n id,\n title: title?.trim() || 'New Chat',\n createdAt: now,\n updatedAt: now,\n messageCount: 0,\n metadata: { pendingTitle: title?.trim() || undefined },\n };\n\n setThreads((prev) => [newThread, ...prev]);\n setThreadMetadataMap((prev) => ({ ...prev, [id]: { pendingTitle: title?.trim() || undefined } }));\n setThreadExternalIdMap((prev) => ({ ...prev, [id]: id }));\n setCurrentThreadId(id);\n setCurrentThreadExternalId(id);\n setMessages([]);\n }, []);\n\n const handleRenameThread = useCallback(async (threadId: string, newTitle: string) => {\n const trimmedTitle = newTitle.trim();\n if (!trimmedTitle) return;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title: trimmedTitle, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread (not yet persisted)\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (isPlaceholder) {\n // Store title in metadata for when thread is created\n setThreadMetadataMap((prev) => ({\n ...prev,\n [threadId]: { ...prev[threadId], pendingTitle: trimmedTitle },\n }));\n } else {\n // Persist to backend\n try {\n await updateThreadApi(threadId, { name: trimmedTitle });\n } catch (error) {\n console.error('Failed to rename thread:', error);\n // Revert on error - refetch threads\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleArchiveThread = useCallback(async (threadId: string) => {\n // Find current archive status\n const thread = threadsRef.current.find((t) => t.id === threadId);\n if (!thread) return;\n\n const newArchivedStatus = !thread.isArchived;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, isArchived: newArchivedStatus, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (!isPlaceholder) {\n try {\n await updateThreadApi(threadId, { status: newArchivedStatus ? 'archived' : 'active' });\n } catch (error) {\n console.error('Failed to archive thread:', error);\n // Revert on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleDeleteThread = useCallback(async (threadId: string) => {\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n // Remove from local state immediately\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n setThreadMetadataMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n setThreadExternalIdMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n\n // If deleting current thread, switch to another\n if (currentThreadIdRef.current === threadId) {\n const remaining = threadsRef.current.filter((t) => t.id !== threadId);\n if (remaining.length > 0) {\n setCurrentThreadId(remaining[0].id);\n setCurrentThreadExternalId(extMap[remaining[0].id] ?? null);\n await loadThreadMessages(remaining[0].id);\n } else {\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n }\n }\n\n if (!isPlaceholder) {\n try {\n await deleteThreadApi(threadId);\n } catch (error) {\n console.error('Failed to delete thread:', error);\n // Refetch to restore state on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages]);\n\n const handleStop = useCallback(() => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages((prev) => {\n // Check if any message needs updating before creating new array\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming ? { ...msg, isStreaming: false, isComplete: true } : msg));\n });\n }, []);\n\n const handleStreamAssetEvent = useCallback((payload: any, assistantMessageId: string) => {\n // Handle ASSET_CREATED event from copilotz\n if (!payload?.dataUrl) return;\n\n const mimeType = payload.mime || 'image/png';\n const dataUrl = payload.dataUrl;\n\n // Determine attachment kind based on mime type\n let kind: 'image' | 'audio' | 'video' = 'image';\n if (mimeType.startsWith('audio/')) {\n kind = 'audio';\n } else if (mimeType.startsWith('video/')) {\n kind = 'video';\n }\n\n const mediaAttachment: MediaAttachment = {\n kind,\n dataUrl,\n mimeType,\n };\n\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId\n ? {\n ...msg,\n attachments: [...(msg.attachments || []), mediaAttachment],\n isStreaming: false,\n isComplete: true\n }\n : msg)));\n }, []);\n\n const sendCopilotzMessage = useCallback(async (\n params: {\n threadId?: string | null;\n threadExternalId?: string | null;\n content: string;\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n userId: string;\n userName?: string;\n userMetadata?: Record<string, unknown>;\n agentName?: string | null;\n onBeforeStart?: (assistantMessageId: string) => void;\n },\n ) => {\n // Track current assistant streaming bubble id so we can split bubbles between events\n let currentAssistantId = generateId();\n params.onBeforeStart?.(currentAssistantId);\n\n let hasStreamProgress = false;\n let pendingStartNewAssistantBubble = false;\n\n // Combined function to ensure bubble exists AND update content in a single setMessages call\n const updateStreamingMessage = (partial: string, isComplete: boolean) => {\n if (partial && partial.length > 0) {\n hasStreamProgress = true;\n }\n \n setMessages((prev) => {\n // First, check if we need to create a new streaming bubble\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx >= 0 && prev[idx].role === 'assistant') {\n // Found our current bubble - just update it\n const msg = prev[idx];\n if (msg.content === partial && msg.isStreaming === !isComplete && msg.isComplete === isComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[idx] = { ...msg, content: partial, isStreaming: !isComplete, isComplete };\n return updated;\n }\n \n // Check if last message is a streaming assistant we can reuse\n const last = prev[prev.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n pendingStartNewAssistantBubble = false;\n if (last.content === partial && last.isStreaming === !isComplete && last.isComplete === isComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[prev.length - 1] = { ...last, content: partial, isStreaming: !isComplete, isComplete };\n return updated;\n }\n \n // Need to create a new bubble\n if (pendingStartNewAssistantBubble || !prev.length || (prev[prev.length - 1].role !== 'assistant' || !prev[prev.length - 1].isStreaming)) {\n const newId = generateId();\n currentAssistantId = newId;\n pendingStartNewAssistantBubble = false;\n return [\n ...prev,\n {\n id: newId,\n role: 'assistant' as const,\n content: partial,\n timestamp: nowTs(),\n isStreaming: !isComplete,\n isComplete,\n },\n ];\n }\n \n return prev;\n });\n };\n\n const finalizeCurrentAssistantBubble = () => {\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx < 0) return prev;\n const msg = prev[idx];\n // Skip update if already finalized\n if (!msg.isStreaming && msg.isComplete) return prev;\n const updated = [...prev];\n updated[idx] = { ...msg, isStreaming: false, isComplete: true };\n return updated;\n });\n };\n\n // Using Refs for accessing current state inside callback\n const curThreadId = currentThreadIdRef.current;\n\n // Build a ServerMessage-like object from various streaming event payloads\n const toServerMessageFromEvent = async (event: any): Promise<ServerMessage | null> => {\n if (!event) return null;\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // TOOL_CALL bubble\n if (type === 'TOOL_CALL') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n const call = (payload?.call ?? (metadata as any)?.call) as Record<string, unknown> | undefined;\n const func = (call?.function ?? (payload as any)?.function) as Record<string, unknown> | undefined;\n\n // Extract tool name from various possible locations\n const toolName =\n (func?.name as string) ||\n (payload?.name as string) ||\n (call?.name as string) ||\n (metadata.toolName as string) ||\n (metadata.tool as string) ||\n 'tool';\n\n // Robust args extraction across shapes, including the call.function.arguments pattern\n let argsObj: Record<string, unknown> = {};\n const possibleArgs = [\n func?.arguments, // Try call.function.arguments first (most specific for this event structure)\n payload?.args,\n call?.arguments,\n (metadata as any)?.args,\n (metadata as any)?.arguments,\n ];\n for (const candidate of possibleArgs) {\n if (candidate === undefined || candidate === null) continue;\n try {\n if (typeof candidate === 'string') {\n argsObj = JSON.parse(candidate);\n break;\n }\n if (typeof candidate === 'object') {\n argsObj = candidate as Record<string, unknown>;\n break;\n }\n } catch { /* ignore */ }\n }\n\n const output =\n (metadata as any)?.output !== undefined ? (metadata as any).output\n : payload?.output !== undefined ? payload.output\n : undefined;\n\n // Extract call ID from various locations\n const callId =\n (call?.id as string) ||\n (func?.id as string) ||\n (payload?.id as string) ||\n generateId();\n\n const statusVal =\n (payload?.status as string) ||\n ((event as any)?.status as string) ||\n 'pending';\n\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n toolCalls: [{\n id: callId,\n name: toolName,\n args: argsObj as Record<string, unknown>,\n output,\n status: statusVal,\n }] as Array<Record<string, unknown>>,\n } as unknown as ServerMessage;\n }\n\n // MESSAGE bubble (agent text only - ignore system/tool messages and empty content)\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n // Only process agent messages, skip system/tool/user messages\n if (senderType !== 'agent') {\n return null;\n }\n const content = typeof payload?.content === 'string' ? payload.content : '';\n // Skip messages with empty content (especially NEW_MESSAGE events that only have toolCalls)\n if (!content.trim()) {\n return null;\n }\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'agent',\n content,\n metadata: (payload?.metadata ?? {}) as Record<string, unknown>,\n } as unknown as ServerMessage;\n }\n\n // ASSET_CREATED bubble (tool-generated media)\n if (type === 'ASSET_CREATED') {\n // Only render assets created by tools (ignore user uploads)\n const by = (payload?.by as string) || '';\n if (by && by !== 'tool') return null;\n\n const mime = (payload?.mime as string) || 'image/png';\n const ref = (payload?.ref as string) || (payload?.assetRef as string) || '';\n if (!ref) return null;\n const kind = mime.startsWith('audio/') ? 'audio' : (mime.startsWith('video/') ? 'video' : 'image');\n const msgLike = {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n metadata: {\n attachments: [{ kind, assetRef: ref, mimeType: mime }],\n },\n } as unknown as ServerMessage;\n // Resolve assetRef → dataUrl via service\n const [resolved] = await resolveAssetsInMessages([msgLike] as any);\n return resolved as unknown as ServerMessage;\n }\n\n return null;\n };\n\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n setIsStreaming(true);\n\n try {\n const normalizedUserMetadata = params.userMetadata\n ? JSON.parse(JSON.stringify(params.userMetadata)) as Record<string, unknown>\n : undefined;\n\n const contextSeed = userContextSeedRef.current;\n const contextMetadata = contextSeed\n ? JSON.parse(JSON.stringify(contextSeed)) as Record<string, unknown>\n : undefined;\n const requestContent = params.content && params.content.length > 0 ? params.content : '';\n\n const metadataKey = params.threadId ?? params.threadExternalId ?? undefined;\n // Read from ref to avoid dependency on threadMetadataMap\n const currentThreadMetadataMap = threadMetadataMapRef.current;\n const messageMetadata = metadataKey ? currentThreadMetadataMap[metadataKey]?.userContext as Record<string, unknown> | undefined : undefined;\n const threadMetadata = metadataKey ? currentThreadMetadataMap[metadataKey] : undefined;\n\n const mergedMetadata = {\n ...(messageMetadata ?? {}),\n ...(params.metadata ?? {}),\n } as Record<string, unknown>;\n\n const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n await runCopilotzStream({\n threadId: params.threadId ?? undefined,\n threadExternalId: params.threadExternalId ?? undefined,\n content: requestContent,\n user: {\n externalId: params.userId,\n name: params.userName ?? params.userId,\n metadata: {\n ...(contextMetadata ? contextMetadata : {}),\n ...(normalizedUserMetadata ?? {}),\n },\n },\n attachments: params.attachments,\n metadata: finalMetadata,\n threadMetadata: params.threadMetadata ?? threadMetadata,\n toolCalls: params.toolCalls,\n selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,\n onToken: (token, isComplete) => updateStreamingMessage(token, isComplete),\n onMessageEvent: async (event: any) => {\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // Handle MESSAGE/NEW_MESSAGE events for tool responses\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n \n // Handle tool responses: update the matching tool call status\n if (senderType === 'tool') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n \n // Extract tool call information from metadata.toolCalls array\n const toolCallsArray = metadata?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCallData = toolCallsArray && toolCallsArray.length > 0 ? toolCallsArray[0] : undefined;\n \n if (!toolCallData) {\n return; // No tool call data found\n }\n \n // Notify onToolOutput callback with the full metadata (includes toolCalls array)\n // This allows consumers to react to tool completions in real-time\n processToolOutput(metadata);\n \n // Extract tool call ID and name\n const toolCallId = toolCallData.id as string | undefined;\n const toolCallName = toolCallData.name as string | undefined;\n \n // Extract the tool result/output\n const toolResult = toolCallData.output || payload?.content;\n \n // Check if the tool execution failed\n const toolStatus = (toolCallData.status as string) || 'completed';\n const isFailed = toolStatus === 'failed' || toolCallData?.error;\n \n // Update the tool call status in the assistant message\n setMessages((prev) => {\n const updated = [...prev];\n // Find the assistant message with the matching tool call\n for (let i = updated.length - 1; i >= 0; i--) {\n if (updated[i].role === 'assistant' && updated[i].toolCalls) {\n const toolCalls = updated[i].toolCalls;\n if (toolCalls) {\n // Try to find by ID first, then by name for pending/running tools\n let toolCallIndex = toolCallId \n ? toolCalls.findIndex(tc => tc.id === toolCallId)\n : -1;\n \n // If not found by ID, try to find a pending/running tool with the same name\n if (toolCallIndex === -1 && toolCallName) {\n toolCallIndex = toolCalls.findIndex(\n tc => tc.name === toolCallName && \n (tc.status === 'pending' || tc.status === 'running')\n );\n }\n \n if (toolCallIndex !== -1) {\n const updatedToolCalls = [...toolCalls];\n updatedToolCalls[toolCallIndex] = {\n ...updatedToolCalls[toolCallIndex],\n status: isFailed ? 'failed' : 'completed',\n result: toolResult,\n endTime: Date.now(),\n };\n updated[i] = {\n ...updated[i],\n toolCalls: updatedToolCalls,\n };\n break;\n }\n }\n }\n }\n return updated;\n });\n return; // Don't create a separate bubble for tool responses\n }\n \n // Ignore other MESSAGE snapshots; TOKEN stream already rendered content\n return;\n }\n\n // TOOL_CALL events: render inside current assistant bubble\n if (type === 'TOOL_CALL') {\n const sm = await toServerMessageFromEvent(event);\n const toolCalls = sm?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCall = toolCalls && toolCalls[0];\n if (!toolCall) return;\n\n setMessages((prev) =>\n (() => {\n const appendToolCall = (msg: ChatViewMessage) => ({\n ...msg,\n toolCalls: [\n ...(Array.isArray(msg.toolCalls) ? msg.toolCalls : []),\n {\n id: (toolCall.id as string) ?? generateId(),\n name: (toolCall.name as string) ?? 'tool',\n arguments:\n (toolCall.args as Record<string, unknown>) ??\n (toolCall.arguments as Record<string, unknown>) ??\n {},\n result: toolCall.output,\n status:\n (toolCall.status as 'pending' | 'running' | 'completed' | 'failed') ??\n 'running',\n startTime: Date.now(),\n },\n ],\n });\n\n // Try to attach to the most recent assistant message\n for (let i = prev.length - 1; i >= 0; i--) {\n if (prev[i].role === 'assistant') {\n const next = [...prev];\n next[i] = appendToolCall({\n ...next[i],\n isStreaming: false,\n isComplete: true,\n });\n return next;\n }\n }\n\n // No assistant message yet – create one to host the tool call\n return [\n ...prev,\n appendToolCall({\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n }),\n ];\n })(),\n );\n hasStreamProgress = true;\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Other event types (ASSET_CREATED, etc.) should render as their own bubbles\n const sm = await toServerMessageFromEvent(event);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n finalizeCurrentAssistantBubble();\n setMessages((prev) => [...prev, viewMsg]);\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Fallback for unknown events\n handleStreamMessageEvent(event);\n },\n onAssetEvent: async (payload: any) => {\n // Treat as ASSET_CREATED event in unified handler\n await (async () => {\n if (!hasStreamProgress) return;\n finalizeCurrentAssistantBubble();\n const evt = { type: 'ASSET_CREATED', payload };\n const sm = await toServerMessageFromEvent(evt);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n setMessages((prev) => [...prev, viewMsg]);\n }\n // Defer creating a new assistant bubble until next TOKEN arrives\n pendingStartNewAssistantBubble = true;\n })();\n },\n signal: abortController.signal,\n });\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n }\n\n return currentAssistantId;\n }, [handleStreamMessageEvent, handleStreamAssetEvent]);\n\n const handleSendMessage = useCallback(async (content: string, attachments: MediaAttachment[] = []) => {\n if (!content.trim() && attachments.length === 0) return;\n if (!userId) return;\n\n const timestamp = nowTs();\n const curThreadId = currentThreadIdRef.current;\n const curThreadExtId = currentThreadExternalIdRef.current;\n\n const existingThreadId = curThreadId ?? undefined;\n // Use Ref to check without adding dependency\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholderThread = existingThreadId\n ? extMap[existingThreadId] === existingThreadId\n : false;\n\n const threadIdForSend = isPlaceholderThread ? undefined : existingThreadId;\n\n let effectiveThreadExternalId = curThreadExtId ?? (isPlaceholderThread ? existingThreadId : undefined);\n\n if (!threadIdForSend) {\n if (!effectiveThreadExternalId) {\n effectiveThreadExternalId = generateId();\n }\n setCurrentThreadExternalId(effectiveThreadExternalId);\n } else if (curThreadExtId !== (effectiveThreadExternalId ?? null)) {\n setCurrentThreadExternalId(effectiveThreadExternalId ?? null);\n }\n\n const conversationKey = threadIdForSend ?? effectiveThreadExternalId!;\n\n // Get pending title for new threads if any\n const currentMetadata = threadMetadataMapRef.current[conversationKey];\n const pendingTitle = currentMetadata?.pendingTitle as string | undefined;\n\n const userMessage: ChatViewMessage = {\n id: generateId(),\n role: 'user',\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isComplete: true,\n };\n\n // Create an assistant message placeholder with streaming state for typewriter effect\n const assistantPlaceholder: ChatViewMessage = {\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: timestamp + 1,\n isStreaming: true,\n isComplete: false,\n };\n\n // Add user message and assistant placeholder for typewriter loading effect\n setMessages((prev) => [...prev, userMessage, assistantPlaceholder]);\n\n // Use ref for threads check\n if (!threadsRef.current.some(t => t.id === conversationKey)) {\n const newThread: ChatThread = {\n id: conversationKey,\n title: content.slice(0, 40) || 'Nova conversa',\n createdAt: timestamp,\n updatedAt: timestamp,\n messageCount: 0,\n };\n setThreads(prev => [newThread, ...prev]);\n setThreadMetadataMap(prev => ({ ...prev, [conversationKey]: {} }));\n setThreadExternalIdMap(prev => ({ ...prev, [conversationKey]: effectiveThreadExternalId ?? null }));\n }\n\n try {\n await sendCopilotzMessage({\n threadId: threadIdForSend,\n threadExternalId: effectiveThreadExternalId,\n content,\n attachments,\n userId,\n // userName can be anything, but let's try to find it in context or just fallback\n userName: (userContextSeedRef.current?.profile as any)?.full_name ?? userId,\n agentName: preferredAgentRef.current,\n // Include pending title for new threads\n threadMetadata: pendingTitle ? { name: pendingTitle } : undefined,\n });\n\n // Wait to ensure the assistant message is persisted before refreshing\n await new Promise((r) => setTimeout(r, 1000));\n // Refresh threads list to update metadata (message count, timestamps, etc.)\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(userId, effectiveThreadExternalId ?? existingThreadId ?? null);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error sending Copilotz message', error);\n setMessages((prev) => prev.map((msg) => (msg.isStreaming\n ? {\n ...msg,\n isStreaming: false,\n isComplete: true,\n content: 'Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.',\n }\n : msg)));\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage]);\n\n const bootstrapConversation = useCallback(async (uid: string) => {\n if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;\n\n const bootstrapThreadExternalId = generateId();\n setCurrentThreadId(bootstrapThreadExternalId);\n setCurrentThreadExternalId(bootstrapThreadExternalId);\n setThreadExternalIdMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: bootstrapThreadExternalId }));\n setThreadMetadataMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: {} }));\n // Clear messages; let streaming create bubbles as needed\n setMessages([]);\n\n try {\n await sendCopilotzMessage({\n threadExternalId: bootstrapThreadExternalId,\n content: bootstrap.initialMessage || '',\n toolCalls: bootstrap.initialToolCalls,\n userId: uid,\n agentName: preferredAgentRef.current,\n threadMetadata: {\n name: defaultThreadName || 'Main Thread',\n },\n });\n\n // Give the backend time to persist tool outputs/messages before refresh\n await new Promise((r) => setTimeout(r, 1000));\n\n // Refresh threads list to update metadata\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(uid, bootstrapThreadExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error bootstrapping conversation', error);\n setMessages([\n {\n id: generateId(),\n role: 'assistant',\n content: 'Não foi possível iniciar a conversa. Tente novamente mais tarde.',\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n },\n ]);\n }\n }, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName]);\n\n const reset = useCallback(() => {\n messagesRequestRef.current += 1;\n setThreads([]);\n setThreadMetadataMap({});\n setThreadExternalIdMap({});\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n setUserContextSeed({});\n setIsMessagesLoading(false);\n setIsStreaming(false);\n abortControllerRef.current?.abort();\n }, []);\n\n // Initialize when userId changes\n useEffect(() => {\n if (userId) {\n // Guard against double initialization in StrictMode\n if (initializationRef.current.userId === userId && initializationRef.current.started) {\n return;\n }\n initializationRef.current = { userId, started: true };\n\n const init = async () => {\n // Use URL thread ID as preferred if available\n const urlPreferredThread = isUrlSyncEnabled ? urlState.threadId : undefined;\n const preferredThreadId = await fetchAndSetThreadsState(userId, urlPreferredThread);\n if (preferredThreadId) {\n await loadThreadMessages(preferredThreadId);\n } else if (bootstrap) {\n await bootstrapConversation(userId);\n }\n };\n init();\n } else {\n initializationRef.current = { userId: null, started: false };\n reset();\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);\n\n // Sync currentThreadExternalId to URL when it changes\n useEffect(() => {\n if (!isUrlSyncEnabled) return;\n // Only sync after initial load is complete\n if (!initializationRef.current.started) return;\n \n setUrlThreadId(currentThreadExternalId);\n }, [currentThreadExternalId, isUrlSyncEnabled, setUrlThreadId]);\n\n // Sync metadata map effects\n useEffect(() => {\n if (!currentThreadId) return;\n const metadata = threadMetadataMap[currentThreadId];\n if (!metadata) return;\n\n if (metadata.userContext && typeof metadata.userContext === 'object') {\n setUserContextSeed((prev) => ({ ...prev, ...(metadata.userContext as Partial<ChatUserContext>) }));\n }\n }, [currentThreadId, threadMetadataMap]);\n\n return {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n userContextSeed,\n sendMessage: handleSendMessage,\n createThread: handleCreateThread,\n selectThread: handleSelectThread,\n renameThread: handleRenameThread,\n archiveThread: handleArchiveThread,\n deleteThread: handleDeleteThread,\n stopGeneration: handleStop,\n fetchAndSetThreadsState,\n loadThreadMessages,\n reset,\n // URL state\n /** Initial prompt from URL (if urlSync enabled) - use for pre-filling input */\n initialPrompt: isUrlSyncEnabled ? urlState.prompt : null,\n /** Clear the initial prompt from URL (call after consuming it) */\n clearInitialPrompt: clearUrlPrompt,\n /** URL agent ID (if urlSync enabled) - use for agent pre-selection */\n urlAgentId: isUrlSyncEnabled ? urlState.agentId : null,\n /** Update agent ID in URL */\n setUrlAgentId,\n };\n}\n","import type { MediaAttachment } from '@copilotz/chat-ui';\n\nconst rawBaseValue = import.meta.env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst runtimeProcess: typeof process | undefined = typeof process !== 'undefined' ? process : undefined;\n\nconst API_KEY = (() => {\n const env = (import.meta as { env?: Record<string, string | undefined> }).env ?? {};\n const candidates = [\n env.VITE_API_KEY,\n env.VITE_COPILOTZ_API_KEY,\n runtimeProcess?.env?.COPILOTZ_API_KEY,\n runtimeProcess?.env?.API_KEY,\n ];\n return candidates.find((value) => typeof value === 'string' && value.length > 0);\n})();\n\nconst withAuthHeaders = (headers: Record<string, string> = {}): Record<string, string> => {\n if (API_KEY) {\n return { ...headers, Authorization: `Bearer ${API_KEY}` };\n }\n return headers;\n};\n\ntype RestThread = {\n id: string;\n name?: string | null;\n externalId?: string | null;\n description?: string | null;\n participants?: string[] | null;\n status?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype RestMessage = {\n id: string;\n threadId: string;\n senderId?: string | null;\n senderType: string;\n senderUserId?: string | null;\n content?: string | null;\n metadata?: Record<string, unknown> | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype MessageSenderType = 'agent' | 'user' | 'tool' | 'system';\n\ntype MessageContent =\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image'; url?: string; dataBase64?: string; mimeType?: string; alt?: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n | { type: 'file'; url?: string; dataBase64?: string; mimeType?: string; name?: string }\n | { type: 'json'; value: unknown }\n >;\n\ntype MessageToolCall = {\n id?: string | null;\n name: string;\n args: Record<string, unknown>;\n};\n\ntype MessageThread = {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n externalId?: string | null;\n participants?: string[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessageSender = {\n id?: string | null;\n externalId?: string | null;\n type: MessageSenderType;\n name?: string | null;\n identifierType?: 'id' | 'name' | 'email' | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessagePayload = {\n content: MessageContent;\n sender: MessageSender;\n thread?: MessageThread | null;\n toolCalls?: MessageToolCall[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype StreamCallbacks = {\n onToken?: (token: string, isComplete: boolean, raw?: any) => void;\n onMessageEvent?: (payload: any) => void;\n onAssetEvent?: (payload: any) => void;\n signal?: AbortSignal;\n};\n\ntype RunOptions = {\n threadId?: string;\n threadExternalId?: string;\n content: string;\n user: {\n externalId: string;\n name?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n };\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown>; id?: string }>;\n selectedAgent?: string | null;\n} & StreamCallbacks;\n\nexport type CopilotzStreamResult = {\n text: string;\n messages: any[];\n media: Record<string, string> | null;\n};\n\nconst SSE_LINE_BREAK = '\\n\\n';\n\nconst appendChunk = (buffer: string, chunk: string): string => {\n if (!buffer) return chunk;\n if (!chunk) return buffer;\n if (chunk.startsWith(buffer)) return chunk;\n if (buffer.startsWith(chunk)) return buffer;\n const maxOverlap = Math.min(buffer.length, chunk.length);\n for (let i = maxOverlap; i > 0; i--) {\n if (buffer.endsWith(chunk.slice(0, i))) {\n return buffer + chunk.slice(i);\n }\n }\n return buffer + chunk;\n};\n\nconst toAttachmentPayload = (attachments?: MediaAttachment[]) => {\n if (!attachments || attachments.length === 0) return undefined;\n return attachments.map(att => {\n const base = {\n kind: att.kind,\n dataUrl: att.dataUrl,\n mimeType: att.mimeType,\n fileName: att.fileName,\n };\n if (att.kind === 'audio' || att.kind === 'video') {\n return {\n ...base,\n durationMs: att.durationMs,\n ...(att.kind === 'video' && 'poster' in att ? { poster: att.poster } : {}),\n };\n }\n return base;\n });\n};\n\n// --- Audio helpers: convert browser-recorded WebM/Opus to WAV (16-bit PCM) ---\nconst base64FromUint8 = (bytes: Uint8Array): string => {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n binary += String.fromCharCode.apply(null, Array.from(chunk));\n }\n // btoa is available in browsers\n return btoa(binary);\n};\n\nconst parseDataUrl = (dataUrl: string): { mime: string; base64: string } | null => {\n const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) return null;\n return { mime: match[1], base64: match[2] };\n};\n\nconst dataUrlToArrayBuffer = (dataUrl: string): ArrayBuffer => {\n const parsed = parseDataUrl(dataUrl);\n if (!parsed) return new ArrayBuffer(0);\n const binaryString = atob(parsed.base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n};\n\nconst encodeWav16BitPCM = (audioBuffer: AudioBuffer): Uint8Array => {\n const numChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const numFrames = audioBuffer.length;\n const bytesPerSample = 2; // 16-bit\n const dataSize = numFrames * numChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buffer);\n\n // RIFF header\n const writeString = (offset: number, str: string) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n };\n\n let offset = 0;\n writeString(offset, \"RIFF\"); offset += 4;\n view.setUint32(offset, 36 + dataSize, true); offset += 4;\n writeString(offset, \"WAVE\"); offset += 4;\n\n // fmt subchunk\n writeString(offset, \"fmt \"); offset += 4;\n view.setUint32(offset, 16, true); offset += 4; // Subchunk1Size (16 for PCM)\n view.setUint16(offset, 1, true); offset += 2; // AudioFormat (1 = PCM)\n view.setUint16(offset, numChannels, true); offset += 2; // NumChannels\n view.setUint32(offset, sampleRate, true); offset += 4; // SampleRate\n view.setUint32(offset, sampleRate * numChannels * bytesPerSample, true); offset += 4; // ByteRate\n view.setUint16(offset, numChannels * bytesPerSample, true); offset += 2; // BlockAlign\n view.setUint16(offset, 16, true); offset += 2; // BitsPerSample\n\n // data subchunk\n writeString(offset, \"data\"); offset += 4;\n view.setUint32(offset, dataSize, true); offset += 4;\n\n // Interleave channels and write PCM samples\n const channelData: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData.push(audioBuffer.getChannelData(ch));\n }\n\n let idx = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n let sample = channelData[ch][i];\n // Clamp\n sample = Math.max(-1, Math.min(1, sample));\n // Convert to 16-bit PCM\n const s = sample < 0 ? sample * 0x8000 : sample * 0x7FFF;\n view.setInt16(offset + idx, s, true);\n idx += 2;\n }\n }\n\n return new Uint8Array(buffer);\n};\n\nconst convertAudioDataUrlToWavBase64 = async (dataUrl: string): Promise<string | null> => {\n try {\n const ab = dataUrlToArrayBuffer(dataUrl);\n const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n const audioBuffer = await ctx.decodeAudioData(ab.slice(0)); // ensure detached buffer\n // Optionally downsample here if desired; we'll keep source sampleRate.\n const wavBytes = encodeWav16BitPCM(audioBuffer);\n return base64FromUint8(wavBytes);\n } catch (_err) {\n return null;\n }\n};\n\nexport async function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult> {\n const {\n threadId,\n threadExternalId,\n content,\n user,\n attachments,\n metadata,\n threadMetadata,\n toolCalls,\n selectedAgent,\n onToken,\n onMessageEvent,\n onAssetEvent,\n signal,\n } = options;\n\n const controller = new AbortController();\n if (signal) {\n signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });\n }\n\n // Separate audio attachments from other attachments\n const audioAttachments = attachments?.filter(att => att.kind === 'audio') ?? [];\n const nonAudioAttachments = attachments?.filter(att => att.kind !== 'audio') ?? [];\n \n const attachmentPayload = toAttachmentPayload(nonAudioAttachments);\n\n const normalizedToolCalls =\n toolCalls?.map<MessageToolCall>((call) => ({\n id: call.id ?? crypto.randomUUID(),\n name: call.name,\n args: call.args ?? {},\n })) ?? [];\n\n const metadataToolCalls =\n normalizedToolCalls.length > 0\n ? normalizedToolCalls.map((tc) => ({\n id: tc.id ?? undefined,\n name: tc.name,\n args: JSON.stringify(tc.args ?? {}),\n }))\n : undefined;\n\n const baseMetadata = {\n ...(metadata ?? {}),\n ...(attachmentPayload ? { attachments: attachmentPayload } : {}),\n ...(metadataToolCalls ? { toolCalls: metadataToolCalls } : {}),\n userExternalId: user.externalId,\n } as Record<string, unknown>;\n\n const messageMetadata = Object.keys(baseMetadata).length > 0 ? baseMetadata : undefined;\n\n const senderMetadata = {\n ...(user.metadata ?? {}),\n ...(user.email ? { email: user.email } : {}),\n } as Record<string, unknown>;\n\n const mergedThreadMetadata = {\n ...(threadMetadata ?? {}),\n } as Record<string, unknown>;\n\n if (mergedThreadMetadata.userExternalId === undefined) {\n mergedThreadMetadata.userExternalId = user.externalId;\n }\n\n // Extract name from threadMetadata if present\n const threadName = (mergedThreadMetadata.name as string) ?? null;\n // Remove name from metadata since it's a top-level field\n const { name: _threadName, ...restThreadMetadata } = mergedThreadMetadata;\n\n const threadPayload: MessageThread | undefined = (threadId || threadExternalId || threadName || Object.keys(restThreadMetadata).length > 0)\n ? {\n id: threadId ?? null,\n externalId: threadExternalId ?? null,\n name: threadName,\n participants: [selectedAgent || 'assistant'],\n metadata: Object.keys(restThreadMetadata).length > 0 ? restThreadMetadata : null,\n }\n : undefined;\n\n // Prepare audio parts (convert to WAV when needed)\n const preparedAudioParts: Array<{ type: 'audio'; dataBase64?: string; url?: string; mimeType?: string; transcript?: string }> = [];\n for (const audioAtt of audioAttachments) {\n if (!audioAtt.dataUrl) continue;\n const parsed = parseDataUrl(audioAtt.dataUrl);\n if (parsed && (parsed.mime.includes('wav') || parsed.mime.includes('mp3') || parsed.mime.includes('mpeg'))) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: parsed.base64,\n mimeType: parsed.mime.includes('wav') ? 'audio/wav' : 'audio/mp3',\n });\n continue;\n }\n // Convert other formats (e.g., audio/webm) to WAV\n const wavBase64 = await convertAudioDataUrlToWavBase64(audioAtt.dataUrl);\n if (wavBase64) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: wavBase64,\n mimeType: 'audio/wav',\n });\n } else {\n // Fallback: send as URL (may fail at provider side, but do not block)\n preparedAudioParts.push({\n type: 'audio',\n url: audioAtt.dataUrl,\n mimeType: audioAtt.mimeType || 'audio/webm',\n });\n }\n }\n\n // Build content array: include text and prepared audio parts\n const contentParts: MessageContent = (() => {\n const parts: Array<\n | { type: 'text'; text: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n > = [];\n const text = (typeof content === 'string' && content.trim().length > 0) ? content : '';\n parts.push({ type: 'text', text });\n for (const p of preparedAudioParts) parts.push(p);\n if (parts.length === 1 && parts[0].type === 'text') return parts[0].text;\n return parts;\n })();\n\n const payload: MessagePayload = {\n content: contentParts,\n sender: {\n type: normalizedToolCalls.length > 0 ? 'agent' : 'user',\n externalId: user.externalId,\n id: normalizedToolCalls.length > 0 ? 'assistant' : undefined,\n name: normalizedToolCalls.length > 0 ? 'assistant' : (user.name ?? null),\n metadata: Object.keys(senderMetadata).length > 0 ? senderMetadata : null,\n },\n metadata: messageMetadata ?? null,\n thread: threadPayload ?? null,\n toolCalls: normalizedToolCalls.length > 0 ? normalizedToolCalls : null,\n };\n\n const response = await fetch(apiUrl('/v1/providers/web'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(errorText || 'Failed to run Copilotz agent');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let aggregatedText = '';\n const collectedMessages: any[] = [];\n let collectedMedia: Record<string, string> | null = null;\n\n const processEvent = (eventChunk: string) => {\n if (!eventChunk.trim()) return;\n const lines = eventChunk.split('\\n');\n let eventType = 'message';\n let dataRaw = '';\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n dataRaw += line.slice(5).trim();\n }\n }\n\n if (!dataRaw) return;\n\n let payload: any;\n try {\n payload = JSON.parse(dataRaw);\n } catch (error) {\n console.warn('copilotzService: failed to parse SSE payload', error, dataRaw);\n return;\n }\n\n switch (eventType) {\n case 'TOKEN': {\n const chunk =\n typeof payload?.payload?.token === 'string'\n ? payload.payload.token\n : (typeof payload?.token === 'string' ? payload.token : '');\n if (chunk) {\n aggregatedText = appendChunk(aggregatedText, chunk);\n }\n const isComplete = Boolean(\n (payload && payload.payload && payload.payload.isComplete) ?? payload?.isComplete\n );\n if (chunk || isComplete) {\n onToken?.(aggregatedText, isComplete, payload);\n }\n break;\n }\n case 'MESSAGE': {\n collectedMessages.push(payload);\n // Pass the payload with its internal type (e.g., NEW_MESSAGE, MESSAGE, etc.)\n // The hook will use payload.type to determine the actual event type\n onMessageEvent?.(payload);\n const senderType =\n payload?.payload?.senderType ??\n payload?.payload?.sender?.type;\n\n if (senderType === 'agent' && typeof payload?.payload?.content === 'string') {\n aggregatedText = payload.payload.content;\n }\n break;\n }\n case 'TOOL_CALL': {\n // Pass TOOL_CALL events directly to the message event handler\n // The payload already has the full event structure with type: \"TOOL_CALL\"\n onMessageEvent?.(payload);\n break;\n }\n case 'ASSET_CREATED': {\n const assetPayload = (payload && typeof payload === 'object' && 'payload' in payload)\n ? (payload as { payload?: any }).payload\n : payload;\n // Convert ASSET_CREATED to media format for backward compatibility\n if (assetPayload?.dataUrl) {\n collectedMedia = {\n [assetPayload.assetId || '0']: assetPayload.dataUrl\n };\n }\n // Call the asset event handler\n onAssetEvent?.(assetPayload);\n break;\n }\n case 'ERROR':\n throw new Error(payload?.error || 'Copilotz stream error');\n default:\n // For other event types, wrap in a structure with type and payload\n onMessageEvent?.({ type: eventType, payload });\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n if (buffer.includes('\\r')) {\n buffer = buffer.replace(/\\r/g, '');\n }\n\n let eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n while (eventBoundary >= 0) {\n const chunk = buffer.slice(0, eventBoundary);\n buffer = buffer.slice(eventBoundary + SSE_LINE_BREAK.length);\n processEvent(chunk);\n eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n }\n }\n\n if (buffer.length > 0) {\n processEvent(buffer);\n }\n\n return {\n text: aggregatedText,\n messages: collectedMessages,\n media: collectedMedia,\n };\n}\n\nexport async function fetchThreads(userId: string) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ \"metadata.userExternalId\": userId } ));\n params.set('sort', '-updatedAt');\n\n const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load threads (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestThread[];\n}\n\nexport async function fetchThreadMessages(threadId: string) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n params.set('sort', 'createdAt:asc');\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load thread messages (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestMessage[];\n}\n\nexport async function updateThread(threadId: string, updates: Partial<RestThread>) {\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'PUT',\n headers: withAuthHeaders({ 'Content-Type': 'application/json', Accept: 'application/json' }),\n body: JSON.stringify(updates),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to update thread (${res.status})`);\n }\n\n const data = await res.json();\n return data?.body ?? data;\n}\n\nexport async function deleteMessagesByThreadId(threadId: string) {\n // First fetch all messages for the thread (no field selection to avoid issues)\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n // If we can't fetch messages, we can't delete them - but this might be ok if there are none\n console.warn('Could not fetch messages for deletion:', res.status);\n return;\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data) || data.length === 0) {\n return; // No messages to delete\n }\n\n // Delete each message sequentially to avoid overwhelming the server\n for (const msg of data) {\n if (msg?.id) {\n try {\n await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n } catch {\n // Ignore individual message delete errors\n }\n }\n }\n}\n\nexport async function deleteThread(threadId: string) {\n // First delete all messages in the thread to avoid foreign key constraint\n await deleteMessagesByThreadId(threadId);\n\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to delete thread (${res.status})`);\n }\n\n return true;\n}\n\nexport const copilotzService = {\n runCopilotzStream,\n fetchThreads,\n fetchThreadMessages,\n updateThread,\n deleteThread,\n};\n","// Minimal API client for Copilotz assets\n\ntype FetchAssetResult = {\n assetId: string;\n ref: string;\n dataUrl?: string;\n base64?: string;\n mime?: string;\n error?: string;\n};\n\nconst rawBaseValue = (import.meta as { env?: Record<string, string | undefined> }).env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst extractAssetId = (refOrId: string) =>\n refOrId.startsWith('asset://') ? refOrId.slice('asset://'.length) : refOrId;\n\nexport async function getAssetDataUrl(refOrId: string): Promise<{ dataUrl: string; mime?: string; assetId: string }> {\n const id = extractAssetId(refOrId);\n const res = await fetch(apiUrl(`/v1/assets/${encodeURIComponent(id)}?format=dataUrl`), {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => res.statusText);\n throw new Error(text || `Failed to fetch asset ${refOrId}`);\n }\n const data = (await res.json()) as FetchAssetResult;\n if (!data?.dataUrl) {\n throw new Error(data?.error || `Asset ${refOrId} has no dataUrl`);\n }\n return { dataUrl: data.dataUrl, mime: data.mime, assetId: data.assetId };\n}\n\n// Resolve assets in messages by replacing metadata.attachments[].assetRef with dataUrl\ntype WithMetadata = {\n metadata?: Record<string, unknown> | null;\n};\n\nexport async function resolveAssetsInMessages<T extends WithMetadata>(messages: T[]): Promise<T[]> {\n // Deduplicate in-flight fetches so the same assetRef is resolved only once.\n const inFlightByRef = new Map<string, Promise<{ dataUrl: string; mime?: string; assetId: string }>>();\n\n const resolveAssetRef = (assetRef: string) => {\n if (!inFlightByRef.has(assetRef)) {\n inFlightByRef.set(assetRef, getAssetDataUrl(assetRef));\n }\n return inFlightByRef.get(assetRef)!;\n };\n\n return Promise.all(messages.map(async (msg) => {\n const meta = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachments = Array.isArray(meta?.attachments)\n ? (meta!.attachments as Array<Record<string, unknown>>)\n : undefined;\n\n if (!attachments || attachments.length === 0) {\n return msg;\n }\n\n const newAttachments = await Promise.all(attachments.map(async (att) => {\n const assetRef = typeof att?.assetRef === 'string' ? (att.assetRef as string) : undefined;\n if (!assetRef) return att;\n\n try {\n const { dataUrl, mime } = await resolveAssetRef(assetRef);\n const kind = typeof att.kind === 'string' ? (att.kind as string) : 'image';\n return {\n kind,\n dataUrl,\n mimeType: typeof att.mimeType === 'string' ? att.mimeType : (mime ?? undefined),\n } as Record<string, unknown>;\n } catch {\n // If fetching fails, keep original so UI can ignore gracefully\n return att;\n }\n }));\n\n const newMeta = { ...(meta ?? {}), attachments: newAttachments } as Record<string, unknown>;\n return { ...msg, metadata: newMeta };\n }));\n}\n\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Configuration for URL parameter names\n */\nexport interface UrlParamsConfig {\n /** URL param name for thread ID (default: 'thread') */\n thread?: string;\n /** URL param name for agent ID (default: 'agent') */\n agent?: string;\n /** URL param name for initial prompt (default: 'prompt') */\n prompt?: string;\n}\n\n/**\n * URL sync behavior configuration\n */\nexport interface UrlSyncConfig {\n /** Enable/disable URL sync (default: true) */\n enabled?: boolean;\n /** \n * How to update the URL when state changes:\n * - 'push': Creates browser history entries (back button works)\n * - 'replace': Updates URL without history entries (default)\n * - 'read-only': Only reads from URL, never writes\n */\n mode?: 'push' | 'replace' | 'read-only';\n /** Custom parameter names */\n params?: UrlParamsConfig;\n /**\n * Behavior for the prompt parameter:\n * - 'prefill': Pre-fills the input field (default)\n * - 'auto-send': Automatically sends the message on load\n */\n promptBehavior?: 'prefill' | 'auto-send';\n /**\n * Whether to clear the prompt param from URL after reading\n * Prevents re-sending on refresh (default: true)\n */\n clearPromptAfterRead?: boolean;\n}\n\n/**\n * State values parsed from URL\n */\nexport interface UrlState {\n threadId: string | null;\n agentId: string | null;\n prompt: string | null;\n}\n\n/**\n * Return type of useUrlState hook\n */\nexport interface UseUrlStateReturn {\n /** Current state parsed from URL */\n state: UrlState;\n /** Update thread ID in URL */\n setThreadId: (threadId: string | null) => void;\n /** Update agent ID in URL */\n setAgentId: (agentId: string | null) => void;\n /** Clear prompt from URL (call after consuming it) */\n clearPrompt: () => void;\n /** Whether URL sync is enabled */\n isEnabled: boolean;\n}\n\nconst DEFAULT_PARAMS: Required<UrlParamsConfig> = {\n thread: 'thread',\n agent: 'agent',\n prompt: 'prompt',\n};\n\n/**\n * Check if we're in a browser environment\n */\nconst isBrowser = typeof globalThis !== 'undefined' && typeof globalThis.location !== 'undefined';\n\n/**\n * Get current URL search params (SSR-safe)\n */\nconst getSearchParams = (): URLSearchParams => {\n if (!isBrowser) return new URLSearchParams();\n return new URLSearchParams(globalThis.location.search);\n};\n\n/**\n * Update URL with new search params\n */\nconst updateUrl = (params: URLSearchParams, mode: 'push' | 'replace') => {\n if (!isBrowser) return;\n \n const url = new URL(globalThis.location.href);\n url.search = params.toString();\n \n if (mode === 'push') {\n globalThis.history.pushState({}, '', url.toString());\n } else {\n globalThis.history.replaceState({}, '', url.toString());\n }\n};\n\n/**\n * Hook to manage chat state persistence via URL parameters.\n * \n * Supports:\n * - Thread ID: Navigate to specific conversation\n * - Agent ID: Pre-select an agent\n * - Prompt: Pre-fill or auto-send a message\n * \n * @example\n * ```tsx\n * const { state, setThreadId, setAgentId } = useUrlState({\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * });\n * \n * // Read initial values\n * console.log(state.threadId, state.agentId, state.prompt);\n * \n * // Update URL when thread changes\n * setThreadId('abc123');\n * ```\n */\nexport function useUrlState(config: UrlSyncConfig = {}): UseUrlStateReturn {\n const {\n enabled = true,\n mode = 'replace',\n params: userParams = {},\n clearPromptAfterRead = true,\n } = config;\n\n const params = { ...DEFAULT_PARAMS, ...userParams };\n const isReadOnly = mode === 'read-only';\n const updateMode = mode === 'read-only' ? 'replace' : mode;\n\n // Track if initial read has been done\n const initialReadDone = useRef(false);\n const promptCleared = useRef(false);\n\n // Parse initial state from URL\n const parseUrlState = useCallback((): UrlState => {\n if (!enabled || !isBrowser) {\n return { threadId: null, agentId: null, prompt: null };\n }\n\n const searchParams = getSearchParams();\n \n return {\n threadId: searchParams.get(params.thread) || null,\n agentId: searchParams.get(params.agent) || null,\n prompt: promptCleared.current ? null : (searchParams.get(params.prompt) || null),\n };\n }, [enabled, params.thread, params.agent, params.prompt]);\n\n const [state, setState] = useState<UrlState>(parseUrlState);\n\n // Read URL state on mount and handle popstate (back/forward navigation)\n useEffect(() => {\n if (!enabled || !isBrowser) return;\n\n // Initial read\n if (!initialReadDone.current) {\n const initialState = parseUrlState();\n setState(initialState);\n initialReadDone.current = true;\n\n // Clear prompt from URL after reading if configured\n if (clearPromptAfterRead && initialState.prompt && !isReadOnly) {\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n }\n }\n\n // Listen for popstate (browser back/forward)\n const handlePopState = () => {\n setState(parseUrlState());\n };\n\n globalThis.addEventListener('popstate', handlePopState);\n return () => globalThis.removeEventListener('popstate', handlePopState);\n }, [enabled, parseUrlState, clearPromptAfterRead, params.prompt, isReadOnly]);\n\n // Update thread ID in URL\n const setThreadId = useCallback((threadId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (threadId) {\n searchParams.set(params.thread, threadId);\n } else {\n searchParams.delete(params.thread);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, threadId }));\n }, [enabled, isReadOnly, params.thread, updateMode]);\n\n // Update agent ID in URL\n const setAgentId = useCallback((agentId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (agentId) {\n searchParams.set(params.agent, agentId);\n } else {\n searchParams.delete(params.agent);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, agentId }));\n }, [enabled, isReadOnly, params.agent, updateMode]);\n\n // Clear prompt from URL\n const clearPrompt = useCallback(() => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n setState(prev => ({ ...prev, prompt: null }));\n }, [enabled, isReadOnly, params.prompt]);\n\n return {\n state,\n setThreadId,\n setAgentId,\n clearPrompt,\n isEnabled: enabled,\n };\n}\n"],"mappings":"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","names":["useEffect","useState","forwardRef","createElement","useState","useCallback","useRef","useEffect","offset","payload","rawBaseValue","rawBase","normalizedBase","API_BASE","apiUrl","useState","useRef","useEffect","useCallback","sm","deleteThread","useState","useEffect"]}
|