@copilotz/chat-adapter 0.9.42 → 0.9.43
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 +2 -2
- package/dist/index.js +63 -28
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -57,8 +57,8 @@ type StreamCallbacks = {
|
|
|
57
57
|
onToken?: (token: string, isComplete: boolean, raw?: any, options?: {
|
|
58
58
|
isReasoning?: boolean;
|
|
59
59
|
}) => void;
|
|
60
|
-
onMessageEvent?: (payload: any) => void
|
|
61
|
-
onAssetEvent?: (payload: any) => void
|
|
60
|
+
onMessageEvent?: (payload: any) => void | Promise<void>;
|
|
61
|
+
onAssetEvent?: (payload: any) => void | Promise<void>;
|
|
62
62
|
signal?: AbortSignal;
|
|
63
63
|
};
|
|
64
64
|
type RunOptions = {
|
package/dist/index.js
CHANGED
|
@@ -436,7 +436,7 @@ async function runCopilotzStream(options) {
|
|
|
436
436
|
lastTokenWasReasoning = false;
|
|
437
437
|
hadNonReasoningContent = false;
|
|
438
438
|
};
|
|
439
|
-
const processEvent = (eventChunk) => {
|
|
439
|
+
const processEvent = async (eventChunk) => {
|
|
440
440
|
if (!eventChunk.trim()) return;
|
|
441
441
|
const lines = eventChunk.split("\n");
|
|
442
442
|
let eventType = "message";
|
|
@@ -496,13 +496,13 @@ async function runCopilotzStream(options) {
|
|
|
496
496
|
hadNonReasoningContent = true;
|
|
497
497
|
lastTokenWasReasoning = false;
|
|
498
498
|
collectedMessages.push(payload2);
|
|
499
|
-
onMessageEvent?.(payload2);
|
|
499
|
+
await onMessageEvent?.(payload2);
|
|
500
500
|
break;
|
|
501
501
|
}
|
|
502
502
|
case "TOOL_CALL": {
|
|
503
503
|
hadNonReasoningContent = true;
|
|
504
504
|
lastTokenWasReasoning = false;
|
|
505
|
-
onMessageEvent?.(payload2);
|
|
505
|
+
await onMessageEvent?.(payload2);
|
|
506
506
|
break;
|
|
507
507
|
}
|
|
508
508
|
case "TOOL_RESULT":
|
|
@@ -512,7 +512,7 @@ async function runCopilotzStream(options) {
|
|
|
512
512
|
lastCompletedText = resultAnswer;
|
|
513
513
|
}
|
|
514
514
|
resetTokenAggregation();
|
|
515
|
-
onMessageEvent?.(payload2);
|
|
515
|
+
await onMessageEvent?.(payload2);
|
|
516
516
|
break;
|
|
517
517
|
}
|
|
518
518
|
case "ASSET_CREATED": {
|
|
@@ -522,7 +522,7 @@ async function runCopilotzStream(options) {
|
|
|
522
522
|
[assetPayload.assetId || "0"]: assetPayload.dataUrl
|
|
523
523
|
};
|
|
524
524
|
}
|
|
525
|
-
onAssetEvent?.(assetPayload);
|
|
525
|
+
await onAssetEvent?.(assetPayload);
|
|
526
526
|
break;
|
|
527
527
|
}
|
|
528
528
|
case "ERROR":
|
|
@@ -530,9 +530,9 @@ async function runCopilotzStream(options) {
|
|
|
530
530
|
default: {
|
|
531
531
|
const hasEnvelope = payload2 && typeof payload2 === "object" && "type" in payload2;
|
|
532
532
|
if (hasEnvelope) {
|
|
533
|
-
onMessageEvent?.(payload2);
|
|
533
|
+
await onMessageEvent?.(payload2);
|
|
534
534
|
} else {
|
|
535
|
-
onMessageEvent?.({ type: eventType, payload: payload2 });
|
|
535
|
+
await onMessageEvent?.({ type: eventType, payload: payload2 });
|
|
536
536
|
}
|
|
537
537
|
break;
|
|
538
538
|
}
|
|
@@ -549,12 +549,12 @@ async function runCopilotzStream(options) {
|
|
|
549
549
|
while (eventBoundary >= 0) {
|
|
550
550
|
const chunk = buffer.slice(0, eventBoundary);
|
|
551
551
|
buffer = buffer.slice(eventBoundary + SSE_LINE_BREAK.length);
|
|
552
|
-
processEvent(chunk);
|
|
552
|
+
await processEvent(chunk);
|
|
553
553
|
eventBoundary = buffer.indexOf(SSE_LINE_BREAK);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
556
|
if (buffer.length > 0) {
|
|
557
|
-
processEvent(buffer);
|
|
557
|
+
await processEvent(buffer);
|
|
558
558
|
}
|
|
559
559
|
return {
|
|
560
560
|
text: lastCompletedText || aggregatedText,
|
|
@@ -925,27 +925,33 @@ var applyAssistantToolResult = (message, update) => {
|
|
|
925
925
|
const index = items.findIndex((item2) => item2.kind === "tool" && (update.id && item2.id === update.id || !update.id && item2.toolName === update.name));
|
|
926
926
|
if (index === -1) return message;
|
|
927
927
|
const item = items[index];
|
|
928
|
+
const { error, ...toolCallUpdate } = update;
|
|
928
929
|
const toolCall = item.details?.toolCall;
|
|
929
|
-
const nextToolCall = toolCall ? { ...toolCall, ...
|
|
930
|
-
id:
|
|
931
|
-
name:
|
|
930
|
+
const nextToolCall = toolCall ? { ...toolCall, ...toolCallUpdate } : {
|
|
931
|
+
id: toolCallUpdate.id ?? item.id,
|
|
932
|
+
name: toolCallUpdate.name,
|
|
932
933
|
arguments: {},
|
|
933
|
-
status:
|
|
934
|
-
...
|
|
935
|
-
...
|
|
934
|
+
status: toolCallUpdate.status,
|
|
935
|
+
...toolCallUpdate.result !== void 0 ? { result: toolCallUpdate.result } : {},
|
|
936
|
+
...toolCallUpdate.endTime !== void 0 ? { endTime: toolCallUpdate.endTime } : {}
|
|
936
937
|
};
|
|
937
938
|
const status = toolStatusToActivityStatus(update.status);
|
|
939
|
+
const details = {
|
|
940
|
+
...item.details ?? {},
|
|
941
|
+
toolCall: nextToolCall,
|
|
942
|
+
...update.result !== void 0 ? { result: update.result } : {},
|
|
943
|
+
...error !== void 0 ? { error } : {}
|
|
944
|
+
};
|
|
945
|
+
if (error === void 0 && update.status !== "failed") {
|
|
946
|
+
delete details.error;
|
|
947
|
+
}
|
|
938
948
|
const next = [...items];
|
|
939
949
|
next[index] = {
|
|
940
950
|
...item,
|
|
941
951
|
status,
|
|
942
952
|
toolName: update.name,
|
|
943
953
|
...status !== "active" ? { completedAt: update.endTime ?? Date.now() } : {},
|
|
944
|
-
details
|
|
945
|
-
...item.details ?? {},
|
|
946
|
-
toolCall: nextToolCall,
|
|
947
|
-
...update.result !== void 0 ? { result: update.result } : {}
|
|
948
|
-
}
|
|
954
|
+
details
|
|
949
955
|
};
|
|
950
956
|
return setItems(message, next);
|
|
951
957
|
};
|
|
@@ -1243,8 +1249,18 @@ var expectToolStatus = (status, path) => {
|
|
|
1243
1249
|
if (status === "pending") return "pending";
|
|
1244
1250
|
if (status === "running" || status === "processing") return "running";
|
|
1245
1251
|
if (status === "failed") return "failed";
|
|
1252
|
+
if (status === "cancelled") return "failed";
|
|
1246
1253
|
if (status === "completed") return "completed";
|
|
1247
|
-
return fail(`${path} must be pending, running, processing, completed, or
|
|
1254
|
+
return fail(`${path} must be pending, running, processing, completed, failed, or cancelled`);
|
|
1255
|
+
};
|
|
1256
|
+
var formatToolError = (error) => {
|
|
1257
|
+
if (error === void 0) return void 0;
|
|
1258
|
+
if (typeof error === "string") return error;
|
|
1259
|
+
try {
|
|
1260
|
+
return JSON.stringify(error);
|
|
1261
|
+
} catch {
|
|
1262
|
+
return String(error);
|
|
1263
|
+
}
|
|
1248
1264
|
};
|
|
1249
1265
|
var expectToolArguments = (value, path) => {
|
|
1250
1266
|
if (isRecord(value)) return value;
|
|
@@ -1271,7 +1287,7 @@ var matchesToolResultUpdate = (target, update) => {
|
|
|
1271
1287
|
var findMatchingToolItem = (toolItems, update) => toolItems.find((item) => matchesToolResultUpdate(
|
|
1272
1288
|
{ id: item.id, name: item.toolName },
|
|
1273
1289
|
update
|
|
1274
|
-
) && (item.status === "active" || item.details?.result === void 0));
|
|
1290
|
+
) && (item.status === "active" || item.details?.result === void 0 && item.details?.error === void 0));
|
|
1275
1291
|
var applyToolResultUpdateToMessages = (messages, update, assistantPatch) => {
|
|
1276
1292
|
const nextMessages = [...messages];
|
|
1277
1293
|
for (let i = nextMessages.length - 1; i >= 0; i--) {
|
|
@@ -1289,6 +1305,7 @@ var applyToolResultUpdateToMessages = (messages, update, assistantPatch) => {
|
|
|
1289
1305
|
name: update.name ?? toolItem.toolName ?? toolItem.id,
|
|
1290
1306
|
status: update.status,
|
|
1291
1307
|
...update.result !== void 0 ? { result: update.result } : {},
|
|
1308
|
+
...update.error !== void 0 ? { error: update.error } : {},
|
|
1292
1309
|
endTime: update.endTime
|
|
1293
1310
|
}),
|
|
1294
1311
|
...assistantPatch ?? {}
|
|
@@ -1314,12 +1331,13 @@ var extractLiveToolResultUpdate = (payload, now = () => Date.now()) => {
|
|
|
1314
1331
|
const payloadRecord = expectRecord(payload, "TOOL_RESULT payload");
|
|
1315
1332
|
const tool = expectRecord(payloadRecord.tool, "TOOL_RESULT payload.tool");
|
|
1316
1333
|
const result = payloadRecord.projectedOutput !== void 0 ? payloadRecord.projectedOutput : payloadRecord.output;
|
|
1317
|
-
|
|
1334
|
+
const error = formatToolError(payloadRecord.error);
|
|
1318
1335
|
return {
|
|
1319
1336
|
id: expectString(payloadRecord.toolCallId, "TOOL_RESULT payload.toolCallId"),
|
|
1320
1337
|
name: expectToolName(tool, "TOOL_RESULT payload.tool.id"),
|
|
1321
1338
|
status: expectToolStatus(payloadRecord.status, "TOOL_RESULT payload.status"),
|
|
1322
|
-
result,
|
|
1339
|
+
...result !== void 0 ? { result } : {},
|
|
1340
|
+
...error !== void 0 ? { error } : {},
|
|
1323
1341
|
endTime: now()
|
|
1324
1342
|
};
|
|
1325
1343
|
};
|
|
@@ -1342,6 +1360,7 @@ var extractToolCallsFromServerMessage = (msg) => {
|
|
|
1342
1360
|
const name = expectToolName(tool, "toolCall.tool.id");
|
|
1343
1361
|
const argsRaw = primary.args ?? secondary?.args;
|
|
1344
1362
|
const result = primary.output !== void 0 ? primary.output : secondary?.output !== void 0 ? secondary.output : primary.projectedOutput !== void 0 ? primary.projectedOutput : secondary?.projectedOutput;
|
|
1363
|
+
const error = formatToolError(primary.error !== void 0 ? primary.error : secondary?.error);
|
|
1345
1364
|
const rawStatus = primary.status ?? secondary?.status;
|
|
1346
1365
|
return {
|
|
1347
1366
|
id,
|
|
@@ -1349,6 +1368,7 @@ var extractToolCallsFromServerMessage = (msg) => {
|
|
|
1349
1368
|
name,
|
|
1350
1369
|
arguments: expectToolArguments(argsRaw, "toolCall.args"),
|
|
1351
1370
|
...result !== void 0 ? { result } : {},
|
|
1371
|
+
...error !== void 0 ? { error } : {},
|
|
1352
1372
|
status: rawStatus === void 0 ? "running" : expectToolStatus(rawStatus, "toolCall.status")
|
|
1353
1373
|
};
|
|
1354
1374
|
};
|
|
@@ -1374,13 +1394,13 @@ var extractToolResultUpdateFromMessage = (msg, now = () => Date.now()) => {
|
|
|
1374
1394
|
const toolCalls = extractToolCallsFromServerMessage(msg);
|
|
1375
1395
|
if (toolCalls.length === 0) fail("tool message requires metadata.toolCalls");
|
|
1376
1396
|
const firstToolCall = toolCalls[0];
|
|
1377
|
-
if (firstToolCall.result === void 0) fail("tool result message requires tool call output");
|
|
1378
1397
|
expectStringValue(msg.createdAt, "tool result message.createdAt");
|
|
1379
1398
|
return {
|
|
1380
1399
|
id: firstToolCall.id,
|
|
1381
1400
|
...firstToolCall.toolExecutionId ? { toolExecutionId: firstToolCall.toolExecutionId } : {},
|
|
1382
1401
|
name: firstToolCall.name,
|
|
1383
|
-
result: firstToolCall.result,
|
|
1402
|
+
...firstToolCall.result !== void 0 ? { result: firstToolCall.result } : {},
|
|
1403
|
+
...firstToolCall.error !== void 0 ? { error: firstToolCall.error } : {},
|
|
1384
1404
|
status: firstToolCall.status,
|
|
1385
1405
|
endTime: new Date(msg.createdAt).getTime()
|
|
1386
1406
|
};
|
|
@@ -1632,6 +1652,15 @@ var isTerminalEmptyLlmResultEvent = (event) => {
|
|
|
1632
1652
|
return true;
|
|
1633
1653
|
};
|
|
1634
1654
|
|
|
1655
|
+
// src/threadIdentity.ts
|
|
1656
|
+
var identityValues = ({ id, externalId }) => [id, externalId].filter((value) => typeof value === "string" && value.length > 0);
|
|
1657
|
+
var isSameThreadIdentity = (owner, current) => {
|
|
1658
|
+
const ownerValues = identityValues(owner);
|
|
1659
|
+
if (ownerValues.length === 0) return true;
|
|
1660
|
+
const currentValues = new Set(identityValues(current));
|
|
1661
|
+
return ownerValues.some((value) => currentValues.has(value));
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1635
1664
|
// src/useCopilotzChat.ts
|
|
1636
1665
|
var nowTs = () => Date.now();
|
|
1637
1666
|
var generateId = () => globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
@@ -2328,7 +2357,10 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2328
2357
|
let currentAssistantSender = params.assistantSender;
|
|
2329
2358
|
const streamOwnerThreadId = currentThreadIdRef.current;
|
|
2330
2359
|
const streamOwnerThreadExternalId = params.threadExternalId ?? currentThreadExternalIdRef.current;
|
|
2331
|
-
const streamStillOwnsVisibleThread = () =>
|
|
2360
|
+
const streamStillOwnsVisibleThread = () => isSameThreadIdentity(
|
|
2361
|
+
{ id: streamOwnerThreadId, externalId: streamOwnerThreadExternalId },
|
|
2362
|
+
{ id: currentThreadIdRef.current, externalId: currentThreadExternalIdRef.current }
|
|
2363
|
+
);
|
|
2332
2364
|
params.onBeforeStart?.(currentAssistantId);
|
|
2333
2365
|
let hasStreamProgress = false;
|
|
2334
2366
|
const updateStreamingMessage = (partial, opts) => {
|
|
@@ -2724,7 +2756,10 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2724
2756
|
}
|
|
2725
2757
|
const conversationKey = threadIdForSend ?? effectiveThreadExternalId;
|
|
2726
2758
|
const sendOwnerThreadExternalId = effectiveThreadExternalId ?? curThreadExtId;
|
|
2727
|
-
const stillShowingSendOwnerThread = () =>
|
|
2759
|
+
const stillShowingSendOwnerThread = () => isSameThreadIdentity(
|
|
2760
|
+
{ id: sendOwnerThreadId, externalId: sendOwnerThreadExternalId },
|
|
2761
|
+
{ id: currentThreadIdRef.current, externalId: currentThreadExternalIdRef.current }
|
|
2762
|
+
);
|
|
2728
2763
|
const currentMetadata = threadMetadataMapRef.current[conversationKey];
|
|
2729
2764
|
const pendingTitle = currentMetadata?.pendingTitle;
|
|
2730
2765
|
const userMessage = {
|