@copilotz/chat-adapter 0.9.29 → 0.9.31
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.js +36 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1732,6 +1732,9 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
1732
1732
|
const userContextSeedRef = useRef2(userContextSeed);
|
|
1733
1733
|
const messagePageInfoRef = useRef2(messagePageInfo);
|
|
1734
1734
|
const isLoadingOlderMessagesRef = useRef2(isLoadingOlderMessages);
|
|
1735
|
+
const isStreamingRef = useRef2(isStreaming);
|
|
1736
|
+
const threadActivityStatusRef = useRef2(threadActivityStatus);
|
|
1737
|
+
const isRecoveringStreamRef = useRef2(isRecoveringStream);
|
|
1735
1738
|
const senderOptionsRef = useRef2({
|
|
1736
1739
|
agents: agentOptions,
|
|
1737
1740
|
user: userId ? { id: userId, name: userName, avatarUrl: userAvatar } : null,
|
|
@@ -1749,6 +1752,9 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
1749
1752
|
userContextSeedRef.current = userContextSeed;
|
|
1750
1753
|
messagePageInfoRef.current = messagePageInfo;
|
|
1751
1754
|
isLoadingOlderMessagesRef.current = isLoadingOlderMessages;
|
|
1755
|
+
isStreamingRef.current = isStreaming;
|
|
1756
|
+
threadActivityStatusRef.current = threadActivityStatus;
|
|
1757
|
+
isRecoveringStreamRef.current = isRecoveringStream;
|
|
1752
1758
|
senderOptionsRef.current = {
|
|
1753
1759
|
agents: agentOptions,
|
|
1754
1760
|
user: userId ? { id: userId, name: userName, avatarUrl: userAvatar } : null,
|
|
@@ -2293,11 +2299,16 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2293
2299
|
async (params) => {
|
|
2294
2300
|
let currentAssistantId = params.assistantMessageId ?? generateId();
|
|
2295
2301
|
let currentAssistantSender = params.assistantSender;
|
|
2302
|
+
const streamOwnerThreadId = currentThreadIdRef.current;
|
|
2303
|
+
const streamOwnerThreadExternalId = params.threadExternalId ?? currentThreadExternalIdRef.current;
|
|
2304
|
+
const streamStillOwnsVisibleThread = () => streamOwnerThreadId ? currentThreadIdRef.current === streamOwnerThreadId : !streamOwnerThreadExternalId || currentThreadExternalIdRef.current === streamOwnerThreadExternalId || currentThreadIdRef.current === streamOwnerThreadExternalId;
|
|
2296
2305
|
params.onBeforeStart?.(currentAssistantId);
|
|
2297
2306
|
let hasStreamProgress = false;
|
|
2298
2307
|
const updateStreamingMessage = (partial, opts) => {
|
|
2308
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2299
2309
|
if (partial && partial.length > 0) {
|
|
2300
2310
|
hasStreamProgress = true;
|
|
2311
|
+
setIsRecoveringStream(false);
|
|
2301
2312
|
}
|
|
2302
2313
|
const isReasoning = opts?.isReasoning ?? false;
|
|
2303
2314
|
const nextSender = opts?.agent ? resolveAgentSender(opts.agent, senderOptionsRef.current) : currentAssistantSender;
|
|
@@ -2356,6 +2367,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2356
2367
|
});
|
|
2357
2368
|
};
|
|
2358
2369
|
const finalizeCurrentAssistantBubble = () => {
|
|
2370
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2359
2371
|
setMessages((prev) => {
|
|
2360
2372
|
const idx = prev.findIndex((m) => m.id === currentAssistantId);
|
|
2361
2373
|
if (idx < 0) return prev;
|
|
@@ -2368,6 +2380,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2368
2380
|
};
|
|
2369
2381
|
const curThreadId = currentThreadIdRef.current;
|
|
2370
2382
|
const applyLiveToolResultUpdate = (update) => {
|
|
2383
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2371
2384
|
let matched = false;
|
|
2372
2385
|
setMessages((prev) => {
|
|
2373
2386
|
const next = applyToolResultUpdateToMessages(prev, update, {
|
|
@@ -2382,6 +2395,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2382
2395
|
}
|
|
2383
2396
|
};
|
|
2384
2397
|
const finalizeActiveAssistantTurn = (finalAnswer) => {
|
|
2398
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2385
2399
|
setMessages((prev) => {
|
|
2386
2400
|
const currentIdx = prev.findIndex((message2) => message2.id === currentAssistantId && message2.role === "assistant");
|
|
2387
2401
|
const fallbackIdx = currentIdx >= 0 ? currentIdx : (() => {
|
|
@@ -2429,12 +2443,14 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2429
2443
|
return null;
|
|
2430
2444
|
};
|
|
2431
2445
|
const abortController = new AbortController();
|
|
2432
|
-
|
|
2446
|
+
if (!params.preserveActiveRun) {
|
|
2447
|
+
abortControllerRef.current?.abort();
|
|
2448
|
+
recoveryPollGenerationRef.current += 1;
|
|
2449
|
+
setIsRecoveringStream(false);
|
|
2450
|
+
}
|
|
2433
2451
|
abortControllerRef.current = abortController;
|
|
2434
2452
|
stopRequestedRef.current = false;
|
|
2435
|
-
recoveryPollGenerationRef.current += 1;
|
|
2436
2453
|
setThreadActivityStatus("running");
|
|
2437
|
-
setIsRecoveringStream(false);
|
|
2438
2454
|
setIsStreaming(true);
|
|
2439
2455
|
liveToolUpdatesRef.current = [];
|
|
2440
2456
|
let streamError = null;
|
|
@@ -2488,6 +2504,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2488
2504
|
agent: raw?.payload?.agent ?? raw?.agent ?? null
|
|
2489
2505
|
}),
|
|
2490
2506
|
onMessageEvent: async (event) => {
|
|
2507
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2491
2508
|
const intercepted = applyEventInterceptor(event);
|
|
2492
2509
|
if (intercepted?.handled) {
|
|
2493
2510
|
return;
|
|
@@ -2596,6 +2613,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2596
2613
|
handleStreamMessageEvent(event);
|
|
2597
2614
|
},
|
|
2598
2615
|
onAssetEvent: async (payload) => {
|
|
2616
|
+
if (!streamStillOwnsVisibleThread()) return;
|
|
2599
2617
|
const intercepted = applyEventInterceptor({
|
|
2600
2618
|
type: "ASSET_CREATED",
|
|
2601
2619
|
payload
|
|
@@ -2615,7 +2633,7 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2615
2633
|
}
|
|
2616
2634
|
const wasStopped = stopRequestedRef.current || abortController.signal.aborted || isAbortError(streamError);
|
|
2617
2635
|
let recoveryStarted = false;
|
|
2618
|
-
if (!wasStopped) {
|
|
2636
|
+
if (!wasStopped && streamStillOwnsVisibleThread()) {
|
|
2619
2637
|
try {
|
|
2620
2638
|
const activityThreadId = await resolveActivityThreadId();
|
|
2621
2639
|
if (activityThreadId) {
|
|
@@ -2635,7 +2653,12 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2635
2653
|
}
|
|
2636
2654
|
}
|
|
2637
2655
|
}
|
|
2638
|
-
abortControllerRef.current
|
|
2656
|
+
if (abortControllerRef.current === abortController) {
|
|
2657
|
+
abortControllerRef.current = null;
|
|
2658
|
+
}
|
|
2659
|
+
if (!streamStillOwnsVisibleThread()) {
|
|
2660
|
+
return currentAssistantId;
|
|
2661
|
+
}
|
|
2639
2662
|
if (recoveryStarted) {
|
|
2640
2663
|
return currentAssistantId;
|
|
2641
2664
|
}
|
|
@@ -2654,6 +2677,8 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2654
2677
|
const timestamp = nowTs();
|
|
2655
2678
|
const curThreadId = currentThreadIdRef.current;
|
|
2656
2679
|
const curThreadExtId = currentThreadExternalIdRef.current;
|
|
2680
|
+
const sendOwnerThreadId = curThreadId;
|
|
2681
|
+
const preserveActiveRun = threadActivityStatusRef.current === "running" || isRecoveringStreamRef.current || isStreamingRef.current;
|
|
2657
2682
|
const existingThreadId = curThreadId ?? void 0;
|
|
2658
2683
|
const extMap = threadExternalIdMapRef.current;
|
|
2659
2684
|
const isPlaceholderThread = existingThreadId ? extMap[existingThreadId] === existingThreadId : false;
|
|
@@ -2668,6 +2693,8 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2668
2693
|
setCurrentThreadExternalId(effectiveThreadExternalId ?? null);
|
|
2669
2694
|
}
|
|
2670
2695
|
const conversationKey = threadIdForSend ?? effectiveThreadExternalId;
|
|
2696
|
+
const sendOwnerThreadExternalId = effectiveThreadExternalId ?? curThreadExtId;
|
|
2697
|
+
const stillShowingSendOwnerThread = () => sendOwnerThreadId ? currentThreadIdRef.current === sendOwnerThreadId : !sendOwnerThreadExternalId || currentThreadExternalIdRef.current === sendOwnerThreadExternalId || currentThreadIdRef.current === sendOwnerThreadExternalId;
|
|
2671
2698
|
const currentMetadata = threadMetadataMapRef.current[conversationKey];
|
|
2672
2699
|
const pendingTitle = currentMetadata?.pendingTitle;
|
|
2673
2700
|
const userMessage = {
|
|
@@ -2727,11 +2754,14 @@ function useCopilotz({ userId, userName, userAvatar, assistantName, agentOptions
|
|
|
2727
2754
|
agentName: preferredAgentRef.current,
|
|
2728
2755
|
assistantMessageId: assistantPlaceholder.id,
|
|
2729
2756
|
assistantSender,
|
|
2757
|
+
preserveActiveRun,
|
|
2730
2758
|
// Include pending title for new threads
|
|
2731
2759
|
threadMetadata: pendingTitle ? { name: pendingTitle } : void 0
|
|
2732
2760
|
});
|
|
2733
2761
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
2734
|
-
|
|
2762
|
+
if (stillShowingSendOwnerThread()) {
|
|
2763
|
+
await fetchAndSetThreadsState(userId, effectiveThreadExternalId ?? existingThreadId ?? null);
|
|
2764
|
+
}
|
|
2735
2765
|
} catch (error) {
|
|
2736
2766
|
if (isAbortError(error)) return;
|
|
2737
2767
|
console.error("Error sending Copilotz message", error);
|