@copilotz/chat-adapter 0.1.23 → 0.1.24

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 CHANGED
@@ -130,10 +130,9 @@ type RestMessage = {
130
130
  updatedAt?: string;
131
131
  };
132
132
  type StreamCallbacks = {
133
- /**
134
- * `text` = non-reasoning token stream; `reasoningText` = accumulated reasoning when the backend sets `payload.isReasoning`.
135
- */
136
- onToken?: (text: string, isComplete: boolean, raw?: any, reasoningText?: string) => void;
133
+ onToken?: (token: string, isComplete: boolean, raw?: any, options?: {
134
+ isReasoning?: boolean;
135
+ }) => void;
137
136
  onMessageEvent?: (payload: any) => void;
138
137
  onAssetEvent?: (payload: any) => void;
139
138
  signal?: AbortSignal;
package/dist/index.js CHANGED
@@ -431,9 +431,8 @@ async function runCopilotzStream(options) {
431
431
  switch (eventType) {
432
432
  case "TOKEN": {
433
433
  const inner = payload2?.payload ?? payload2;
434
- const chunk = typeof inner?.token === "string" ? inner.token : typeof payload2?.token === "string" ? payload2.token : "";
434
+ const chunk = typeof inner?.token === "string" ? inner.token : "";
435
435
  const isReasoning = Boolean(inner?.isReasoning);
436
- const isComplete = Boolean(inner?.isComplete ?? payload2?.isComplete);
437
436
  if (chunk) {
438
437
  if (isReasoning) {
439
438
  aggregatedReasoning = appendChunk(aggregatedReasoning, chunk);
@@ -441,8 +440,10 @@ async function runCopilotzStream(options) {
441
440
  aggregatedText = appendChunk(aggregatedText, chunk);
442
441
  }
443
442
  }
443
+ const isComplete = Boolean(inner?.isComplete);
444
444
  if (chunk || isComplete) {
445
- onToken?.(aggregatedText, isComplete, payload2, aggregatedReasoning);
445
+ const tokenText = isReasoning ? aggregatedReasoning : aggregatedText;
446
+ onToken?.(tokenText, isComplete, payload2, { isReasoning });
446
447
  }
447
448
  break;
448
449
  }
@@ -510,12 +511,11 @@ async function fetchThreads(userId, getRequestHeaders) {
510
511
  const errorText = await res.text().catch(() => res.statusText);
511
512
  throw new Error(errorText || `Failed to load threads (${res.status})`);
512
513
  }
513
- const json = await res.json();
514
- const list = json?.data ?? json?.body;
515
- if (!Array.isArray(list)) {
514
+ const { data } = await res.json();
515
+ if (!Array.isArray(data)) {
516
516
  return [];
517
517
  }
518
- return list;
518
+ return data;
519
519
  }
520
520
  async function fetchThreadMessages(threadId, getRequestHeaders) {
521
521
  const graphParams = new URLSearchParams();
@@ -555,12 +555,11 @@ async function fetchThreadMessages(threadId, getRequestHeaders) {
555
555
  const errorText = await res.text().catch(() => res.statusText);
556
556
  throw new Error(errorText || `Failed to load thread messages (${res.status})`);
557
557
  }
558
- const json = await res.json();
559
- const list = json?.data ?? json?.body;
560
- if (!Array.isArray(list)) {
558
+ const { data } = await res.json();
559
+ if (!Array.isArray(data)) {
561
560
  return [];
562
561
  }
563
- return list;
562
+ return data;
564
563
  }
565
564
  async function updateThread(threadId, updates, getRequestHeaders) {
566
565
  const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {
@@ -805,23 +804,6 @@ var generateId = () => globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${
805
804
  var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError" || typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
806
805
  var getEventPayload = (event) => event?.payload ?? event;
807
806
  var getEventSenderType = (payload) => payload?.senderType || payload?.sender?.type;
808
- var hasToolCallsInPayload = (payload) => {
809
- if (!payload || typeof payload !== "object") return false;
810
- const p = payload;
811
- if (Array.isArray(p.toolCalls) && p.toolCalls.length > 0) return true;
812
- const meta = p.metadata;
813
- if (!meta || typeof meta !== "object" || Array.isArray(meta)) return false;
814
- const m = meta.toolCalls;
815
- return Array.isArray(m) && m.length > 0;
816
- };
817
- var isAgentToolOnlyPlaceholderPayload = (payload) => {
818
- if (!payload || typeof payload !== "object") return false;
819
- const p = payload;
820
- if (getEventSenderType(p) !== "agent") return false;
821
- const content = typeof p.content === "string" ? p.content : "";
822
- if (content.trim().length > 0) return false;
823
- return hasToolCallsInPayload(p);
824
- };
825
807
  var hasVisibleAssistantOutput = (message) => {
826
808
  if (message.role !== "assistant") return false;
827
809
  if (typeof message.content === "string" && message.content.trim().length > 0) return true;
@@ -856,29 +838,16 @@ var extractToolCallsFromServerMessage = (msg) => {
856
838
  const metadataToolCalls = Array.isArray(metadata?.toolCalls) ? metadata.toolCalls : [];
857
839
  const usedMetadataIndexes = /* @__PURE__ */ new Set();
858
840
  const parsed = [];
859
- const candidateToolLabel = (c) => {
860
- if (typeof c.name === "string") return c.name;
861
- const t = c.tool && typeof c.tool === "object" && c.tool !== null && !Array.isArray(c.tool) ? c.tool : void 0;
862
- if (typeof t?.name === "string") return t.name;
863
- if (typeof t?.id === "string") return t.id;
864
- return void 0;
865
- };
866
841
  const findMatchingMetadataIndex = (toolCall) => {
867
842
  const id = typeof toolCall.id === "string" ? toolCall.id : void 0;
868
- const nested = toolCall.tool && typeof toolCall.tool === "object" && toolCall.tool !== null && !Array.isArray(toolCall.tool) ? toolCall.tool : void 0;
869
- const name = (typeof toolCall.name === "string" ? toolCall.name : void 0) || (typeof nested?.name === "string" ? nested.name : void 0) || (typeof nested?.id === "string" ? nested.id : void 0);
843
+ const name = typeof toolCall.name === "string" ? toolCall.name : void 0;
870
844
  const byId = id ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.id === id) : -1;
871
845
  if (byId >= 0) return byId;
872
- return name ? metadataToolCalls.findIndex((candidate, idx) => {
873
- if (usedMetadataIndexes.has(idx)) return false;
874
- const label = candidateToolLabel(candidate);
875
- return label === name;
876
- }) : -1;
846
+ return name ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.name === name) : -1;
877
847
  };
878
848
  const parseToolCall = (primary, secondary) => {
879
- const nestedTool = primary && typeof primary.tool === "object" && primary.tool !== null && !Array.isArray(primary.tool) ? primary.tool : void 0;
880
849
  const id = typeof primary.id === "string" ? primary.id : typeof secondary?.id === "string" ? secondary.id : void 0;
881
- const name = typeof primary.name === "string" ? primary.name : (typeof nestedTool?.name === "string" ? nestedTool.name : typeof nestedTool?.id === "string" ? nestedTool.id : void 0) ?? (typeof secondary?.name === "string" ? secondary.name : "tool");
850
+ const name = typeof primary.name === "string" ? primary.name : typeof secondary?.name === "string" ? secondary.name : "tool";
882
851
  const argsRaw = primary.args ?? primary.arguments ?? secondary?.args ?? secondary?.arguments;
883
852
  const result = primary.output !== void 0 ? primary.output : primary.result !== void 0 ? primary.result : secondary?.output !== void 0 ? secondary.output : secondary?.result;
884
853
  const status = normalizeToolStatus(primary.status ?? secondary?.status);
@@ -900,17 +869,7 @@ var extractToolCallsFromServerMessage = (msg) => {
900
869
  if (usedMetadataIndexes.has(index)) return;
901
870
  parsed.push(parseToolCall(toolCall));
902
871
  });
903
- const seenIds = /* @__PURE__ */ new Set();
904
- const deduped = [];
905
- for (const p of parsed) {
906
- const id = p.id;
907
- if (typeof id === "string" && id.length > 0) {
908
- if (seenIds.has(id)) continue;
909
- seenIds.add(id);
910
- }
911
- deduped.push(p);
912
- }
913
- return deduped;
872
+ return parsed;
914
873
  };
915
874
  var extractToolResultUpdateFromMessage = (msg) => {
916
875
  if (msg.senderType !== "tool") return null;
@@ -1148,11 +1107,6 @@ function useCopilotz({
1148
1107
  return;
1149
1108
  }
1150
1109
  if (senderType === "agent" && typeof payload.content === "string") {
1151
- const trimmedContent = payload.content.trim();
1152
- const hasToolCalls = hasToolCallsInPayload(payload);
1153
- if (!trimmedContent && hasToolCalls) {
1154
- return;
1155
- }
1156
1110
  setMessages((prev) => {
1157
1111
  const next = [...prev];
1158
1112
  for (let i = next.length - 1; i >= 0; i--) {
@@ -1162,6 +1116,7 @@ function useCopilotz({
1162
1116
  return next;
1163
1117
  }
1164
1118
  }
1119
+ const trimmedContent = payload.content.trim();
1165
1120
  if (!trimmedContent) {
1166
1121
  return prev;
1167
1122
  }
@@ -1218,11 +1173,9 @@ function useCopilotz({
1218
1173
  if (!nextThreadId && normalized.length > 0) {
1219
1174
  nextThreadId = normalized[0].id;
1220
1175
  }
1221
- if (nextThreadId) {
1222
- setCurrentThreadId(nextThreadId);
1223
- setCurrentThreadExternalId(externalMap[nextThreadId] ?? null);
1224
- }
1225
- return nextThreadId ?? curId ?? null;
1176
+ setCurrentThreadId(nextThreadId ?? null);
1177
+ setCurrentThreadExternalId(nextThreadId ? externalMap[nextThreadId] ?? null : null);
1178
+ return nextThreadId;
1226
1179
  }, []);
1227
1180
  const fetchAndSetThreadsState = useCallback2(async (uid, preferredExternalId) => {
1228
1181
  try {
@@ -1417,60 +1370,57 @@ function useCopilotz({
1417
1370
  params.onBeforeStart?.(currentAssistantId);
1418
1371
  let hasStreamProgress = false;
1419
1372
  let pendingStartNewAssistantBubble = false;
1420
- const updateStreamingMessage = (partial, _isComplete, _raw, reasoningPartial) => {
1373
+ const updateStreamingMessage = (partial, opts) => {
1421
1374
  if (partial && partial.length > 0) {
1422
1375
  hasStreamProgress = true;
1423
1376
  }
1424
- if (reasoningPartial !== void 0 && reasoningPartial.length > 0) {
1425
- hasStreamProgress = true;
1426
- }
1427
1377
  const nextStreaming = true;
1428
1378
  const nextComplete = false;
1379
+ const isReasoning = opts?.isReasoning ?? false;
1380
+ const applyUpdate = (msg) => {
1381
+ if (isReasoning) {
1382
+ return { ...msg, reasoning: partial, isReasoningStreaming: true, isStreaming: nextStreaming, isComplete: nextComplete };
1383
+ }
1384
+ const reasoningPatch = msg.reasoning ? { isReasoningStreaming: false } : {};
1385
+ return { ...msg, content: partial, ...reasoningPatch, isStreaming: nextStreaming, isComplete: nextComplete };
1386
+ };
1429
1387
  setMessages((prev) => {
1430
- const patch = (msg) => ({
1431
- ...msg,
1432
- content: partial,
1433
- ...reasoningPartial !== void 0 ? { reasoning: reasoningPartial } : {},
1434
- isStreaming: nextStreaming,
1435
- isComplete: nextComplete
1436
- });
1437
1388
  const idx = prev.findIndex((m) => m.id === currentAssistantId);
1438
1389
  if (idx >= 0 && prev[idx].role === "assistant" && prev[idx].isStreaming) {
1439
1390
  const msg = prev[idx];
1440
- if (msg.content === partial && (msg.reasoning ?? "") === (reasoningPartial ?? "") && msg.isStreaming === nextStreaming && msg.isComplete === nextComplete) {
1391
+ const next = applyUpdate(msg);
1392
+ if (msg.content === next.content && msg.reasoning === next.reasoning && msg.isReasoningStreaming === next.isReasoningStreaming && msg.isStreaming === next.isStreaming && msg.isComplete === next.isComplete) {
1441
1393
  return prev;
1442
1394
  }
1443
1395
  const updated = [...prev];
1444
- updated[idx] = patch(msg);
1396
+ updated[idx] = next;
1445
1397
  return updated;
1446
1398
  }
1447
1399
  const last = prev[prev.length - 1];
1448
1400
  if (last && last.role === "assistant" && last.isStreaming) {
1449
1401
  currentAssistantId = last.id;
1450
1402
  pendingStartNewAssistantBubble = false;
1451
- if (last.content === partial && (last.reasoning ?? "") === (reasoningPartial ?? "") && last.isStreaming === nextStreaming && last.isComplete === nextComplete) {
1403
+ const next = applyUpdate(last);
1404
+ if (last.content === next.content && last.reasoning === next.reasoning && last.isReasoningStreaming === next.isReasoningStreaming && last.isStreaming === next.isStreaming && last.isComplete === next.isComplete) {
1452
1405
  return prev;
1453
1406
  }
1454
1407
  const updated = [...prev];
1455
- updated[prev.length - 1] = patch(last);
1408
+ updated[prev.length - 1] = next;
1456
1409
  return updated;
1457
1410
  }
1458
1411
  if (pendingStartNewAssistantBubble || !prev.length || (prev[prev.length - 1].role !== "assistant" || !prev[prev.length - 1].isStreaming)) {
1459
1412
  const newId = generateId();
1460
1413
  currentAssistantId = newId;
1461
1414
  pendingStartNewAssistantBubble = false;
1462
- return [
1463
- ...prev,
1464
- {
1465
- id: newId,
1466
- role: "assistant",
1467
- content: partial,
1468
- ...reasoningPartial !== void 0 ? { reasoning: reasoningPartial } : {},
1469
- timestamp: nowTs(),
1470
- isStreaming: nextStreaming,
1471
- isComplete: nextComplete
1472
- }
1473
- ];
1415
+ const base = {
1416
+ id: newId,
1417
+ role: "assistant",
1418
+ content: "",
1419
+ timestamp: nowTs(),
1420
+ isStreaming: nextStreaming,
1421
+ isComplete: nextComplete
1422
+ };
1423
+ return [...prev, applyUpdate(base)];
1474
1424
  }
1475
1425
  return prev;
1476
1426
  });
@@ -1493,21 +1443,37 @@ function useCopilotz({
1493
1443
  const payload = event?.payload ?? event;
1494
1444
  if (type === "TOOL_CALL") {
1495
1445
  const metadata = payload?.metadata ?? {};
1496
- const tc = payload?.toolCall ?? payload?.call ?? metadata.call;
1497
- const nestedTool = tc && typeof tc.tool === "object" && tc.tool !== null && !Array.isArray(tc.tool) ? tc.tool : void 0;
1498
- const toolName = (typeof nestedTool?.name === "string" ? nestedTool.name : void 0) || (typeof nestedTool?.id === "string" ? nestedTool.id : void 0) || (typeof payload.name === "string" ? payload.name : void 0) || metadata.toolName || "tool";
1446
+ const tc = payload?.toolCall ?? void 0;
1447
+ const tcTool = tc?.tool ?? void 0;
1448
+ const call = payload?.call ?? metadata?.call;
1449
+ const func = call?.function ?? payload?.function;
1450
+ const toolName = tcTool?.name || func?.name || payload?.name || call?.name || metadata.toolName || metadata.tool || "tool";
1499
1451
  let argsObj = {};
1500
- const argsRaw = tc?.args ?? payload?.args ?? metadata.args;
1501
- if (typeof argsRaw === "string") {
1452
+ const possibleArgs = [
1453
+ tc?.args,
1454
+ func?.arguments,
1455
+ payload?.args,
1456
+ call?.arguments,
1457
+ metadata?.args,
1458
+ metadata?.arguments
1459
+ ];
1460
+ for (const candidate of possibleArgs) {
1461
+ if (candidate === void 0 || candidate === null) continue;
1502
1462
  try {
1503
- argsObj = JSON.parse(argsRaw);
1463
+ if (typeof candidate === "string") {
1464
+ argsObj = JSON.parse(candidate);
1465
+ break;
1466
+ }
1467
+ if (typeof candidate === "object") {
1468
+ argsObj = candidate;
1469
+ break;
1470
+ }
1504
1471
  } catch {
1505
1472
  }
1506
- } else if (argsRaw && typeof argsRaw === "object" && !Array.isArray(argsRaw)) {
1507
- argsObj = argsRaw;
1508
1473
  }
1509
- const callId = (typeof tc?.id === "string" ? tc.id : void 0) || (typeof payload.id === "string" ? payload.id : void 0) || generateId();
1510
- const statusVal = "running";
1474
+ const output = (tc?.output !== void 0 ? tc.output : void 0) ?? (metadata?.output !== void 0 ? metadata.output : void 0) ?? (payload?.output !== void 0 ? payload.output : void 0);
1475
+ const callId = tc?.id || call?.id || func?.id || payload?.id || generateId();
1476
+ const statusVal = tc?.status || payload?.status || event?.status || "pending";
1511
1477
  return {
1512
1478
  id: generateId(),
1513
1479
  threadId: curThreadId ?? "",
@@ -1517,6 +1483,7 @@ function useCopilotz({
1517
1483
  id: callId,
1518
1484
  name: toolName,
1519
1485
  args: argsObj,
1486
+ output,
1520
1487
  status: statusVal
1521
1488
  }]
1522
1489
  };
@@ -1595,9 +1562,7 @@ function useCopilotz({
1595
1562
  toolCalls: params.toolCalls,
1596
1563
  selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,
1597
1564
  getRequestHeaders,
1598
- onToken: (token, isComplete, raw, reasoning) => {
1599
- updateStreamingMessage(token, isComplete, raw, reasoning);
1600
- },
1565
+ onToken: (token, _isComplete, _raw, opts) => updateStreamingMessage(token, opts),
1601
1566
  onMessageEvent: async (event) => {
1602
1567
  const intercepted = applyEventInterceptor(event);
1603
1568
  if (intercepted?.handled) {
@@ -1607,9 +1572,6 @@ function useCopilotz({
1607
1572
  const payload = getEventPayload(event);
1608
1573
  if (type === "MESSAGE" || type === "NEW_MESSAGE") {
1609
1574
  const senderType = getEventSenderType(payload);
1610
- if (senderType === "agent" && hasStreamProgress) {
1611
- return;
1612
- }
1613
1575
  if (senderType === "tool") {
1614
1576
  const metadata = payload?.metadata ?? {};
1615
1577
  const toolCallsArray = metadata?.toolCalls;
@@ -1619,16 +1581,8 @@ function useCopilotz({
1619
1581
  }
1620
1582
  processToolOutput(metadata);
1621
1583
  const toolCallId = toolCallData.id;
1622
- const nestedTool = toolCallData.tool;
1623
- const toolCallName = toolCallData.name || (typeof nestedTool?.name === "string" ? nestedTool.name : void 0) || (typeof nestedTool?.id === "string" ? nestedTool.id : void 0);
1624
- const toolResultRaw = toolCallData.output || payload?.content;
1625
- const toolResult = typeof toolResultRaw === "string" ? (() => {
1626
- try {
1627
- return JSON.parse(toolResultRaw);
1628
- } catch {
1629
- return toolResultRaw;
1630
- }
1631
- })() : toolResultRaw;
1584
+ const toolCallName = toolCallData.name;
1585
+ const toolResult = toolCallData.output || payload?.content;
1632
1586
  const toolStatus = toolCallData.status || "completed";
1633
1587
  const isFailed = toolStatus === "failed" || toolCallData?.error;
1634
1588
  setMessages((prev) => {
@@ -1667,7 +1621,7 @@ function useCopilotz({
1667
1621
  return;
1668
1622
  }
1669
1623
  handleStreamMessageEvent(event);
1670
- if (senderType === "agent" && !isAgentToolOnlyPlaceholderPayload(payload)) {
1624
+ if (senderType === "agent") {
1671
1625
  currentAssistantId = generateId();
1672
1626
  pendingStartNewAssistantBubble = true;
1673
1627
  }
@@ -1680,27 +1634,20 @@ function useCopilotz({
1680
1634
  if (!toolCall) return;
1681
1635
  setMessages(
1682
1636
  (prev) => (() => {
1683
- const appendToolCall = (msg) => {
1684
- const existing = Array.isArray(msg.toolCalls) ? msg.toolCalls : [];
1685
- const id = toolCall.id ?? generateId();
1686
- if (existing.some((t) => t.id === id)) {
1687
- return msg;
1688
- }
1689
- return {
1690
- ...msg,
1691
- toolCalls: [
1692
- ...existing,
1693
- {
1694
- id,
1695
- name: toolCall.name ?? "tool",
1696
- arguments: toolCall.args ?? toolCall.arguments ?? {},
1697
- result: toolCall.output,
1698
- status: toolCall.status ?? "running",
1699
- startTime: Date.now()
1700
- }
1701
- ]
1702
- };
1703
- };
1637
+ const appendToolCall = (msg) => ({
1638
+ ...msg,
1639
+ toolCalls: [
1640
+ ...Array.isArray(msg.toolCalls) ? msg.toolCalls : [],
1641
+ {
1642
+ id: toolCall.id ?? generateId(),
1643
+ name: toolCall.name ?? "tool",
1644
+ arguments: toolCall.args ?? toolCall.arguments ?? {},
1645
+ result: toolCall.output,
1646
+ status: toolCall.status ?? "running",
1647
+ startTime: Date.now()
1648
+ }
1649
+ ]
1650
+ });
1704
1651
  const currentIdx = prev.findIndex((message) => message.id === currentAssistantId && message.role === "assistant" && message.isStreaming);
1705
1652
  if (currentIdx >= 0) {
1706
1653
  const next = [...prev];
@@ -1712,7 +1659,7 @@ function useCopilotz({
1712
1659
  return next;
1713
1660
  }
1714
1661
  const last = prev[prev.length - 1];
1715
- if (last?.role === "assistant" && last.isStreaming) {
1662
+ if (!pendingStartNewAssistantBubble && last?.role === "assistant" && last.isStreaming) {
1716
1663
  currentAssistantId = last.id;
1717
1664
  const next = [...prev];
1718
1665
  next[prev.length - 1] = appendToolCall({
@@ -1739,6 +1686,7 @@ function useCopilotz({
1739
1686
  })()
1740
1687
  );
1741
1688
  hasStreamProgress = true;
1689
+ pendingStartNewAssistantBubble = true;
1742
1690
  return;
1743
1691
  }
1744
1692
  const sm = await toServerMessageFromEvent(event);
@@ -1797,10 +1745,8 @@ function useCopilotz({
1797
1745
  effectiveThreadExternalId = generateId();
1798
1746
  }
1799
1747
  setCurrentThreadExternalId(effectiveThreadExternalId);
1800
- currentThreadExternalIdRef.current = effectiveThreadExternalId;
1801
1748
  } else if (curThreadExtId !== (effectiveThreadExternalId ?? null)) {
1802
1749
  setCurrentThreadExternalId(effectiveThreadExternalId ?? null);
1803
- currentThreadExternalIdRef.current = effectiveThreadExternalId ?? null;
1804
1750
  }
1805
1751
  const conversationKey = threadIdForSend ?? effectiveThreadExternalId;
1806
1752
  const currentMetadata = threadMetadataMapRef.current[conversationKey];
@@ -1834,13 +1780,6 @@ function useCopilotz({
1834
1780
  setThreads((prev) => [newThread, ...prev]);
1835
1781
  setThreadMetadataMap((prev) => ({ ...prev, [conversationKey]: {} }));
1836
1782
  setThreadExternalIdMap((prev) => ({ ...prev, [conversationKey]: effectiveThreadExternalId ?? null }));
1837
- setCurrentThreadId(conversationKey);
1838
- currentThreadIdRef.current = conversationKey;
1839
- threadsRef.current = [newThread, ...threadsRef.current];
1840
- threadExternalIdMapRef.current = {
1841
- ...threadExternalIdMapRef.current,
1842
- [conversationKey]: effectiveThreadExternalId ?? null
1843
- };
1844
1783
  }
1845
1784
  try {
1846
1785
  await sendCopilotzMessage({