@copilotkit/react-core 1.56.5-canary.1778052912 → 1.56.5-canary.1778068503
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/copilotkit-BNlJq5UO.d.mts.map +1 -1
- package/dist/copilotkit-DgC5oCFO.d.cts.map +1 -1
- package/dist/{copilotkit-mJjSHUFd.mjs → copilotkit-DhuXdtE1.mjs} +3 -43
- package/dist/copilotkit-DhuXdtE1.mjs.map +1 -0
- package/dist/{copilotkit-CkhjqPU3.cjs → copilotkit-XGd8L2jL.cjs} +3 -43
- package/dist/copilotkit-XGd8L2jL.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +2 -45
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/v2/components/chat/CopilotChatMessageView.tsx +15 -111
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +3 -3
- package/dist/copilotkit-CkhjqPU3.cjs.map +0 -1
- package/dist/copilotkit-mJjSHUFd.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/react-core",
|
|
3
|
-
"version": "1.56.5-canary.
|
|
3
|
+
"version": "1.56.5-canary.1778068503",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -73,11 +73,11 @@
|
|
|
73
73
|
"untruncate-json": "^0.0.1",
|
|
74
74
|
"use-stick-to-bottom": "^1.1.1",
|
|
75
75
|
"zod-to-json-schema": "^3.24.5",
|
|
76
|
-
"@copilotkit/a2ui-renderer": "1.56.5-canary.
|
|
77
|
-
"@copilotkit/
|
|
78
|
-
"@copilotkit/
|
|
79
|
-
"@copilotkit/
|
|
80
|
-
"@copilotkit/
|
|
76
|
+
"@copilotkit/a2ui-renderer": "1.56.5-canary.1778068503",
|
|
77
|
+
"@copilotkit/core": "1.56.5-canary.1778068503",
|
|
78
|
+
"@copilotkit/runtime-client-gql": "1.56.5-canary.1778068503",
|
|
79
|
+
"@copilotkit/shared": "1.56.5-canary.1778068503",
|
|
80
|
+
"@copilotkit/web-inspector": "1.56.5-canary.1778068503"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@tailwindcss/cli": "^4.1.11",
|
|
@@ -8,11 +8,12 @@ import React, {
|
|
|
8
8
|
} from "react";
|
|
9
9
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
10
10
|
import { ScrollElementContext } from "./scroll-element-context";
|
|
11
|
-
import { WithSlots
|
|
11
|
+
import type { WithSlots } from "../../lib/slots";
|
|
12
|
+
import { renderSlot, isReactComponentType } from "../../lib/slots";
|
|
12
13
|
import CopilotChatAssistantMessage from "./CopilotChatAssistantMessage";
|
|
13
14
|
import CopilotChatUserMessage from "./CopilotChatUserMessage";
|
|
14
15
|
import CopilotChatReasoningMessage from "./CopilotChatReasoningMessage";
|
|
15
|
-
import {
|
|
16
|
+
import type {
|
|
16
17
|
ActivityMessage,
|
|
17
18
|
AssistantMessage,
|
|
18
19
|
Message,
|
|
@@ -283,63 +284,25 @@ const MemoizedCustomMessage = React.memo(
|
|
|
283
284
|
message: Message;
|
|
284
285
|
position: "before" | "after";
|
|
285
286
|
}) => React.ReactElement | null;
|
|
286
|
-
stateSnapshot
|
|
287
|
-
numberOfMessagesInRun: number | undefined;
|
|
288
|
-
isInLatestRun: boolean | undefined;
|
|
289
|
-
isRunning: boolean;
|
|
287
|
+
stateSnapshot?: unknown;
|
|
290
288
|
}) {
|
|
291
289
|
return renderCustomMessage({ message, position });
|
|
292
290
|
},
|
|
293
291
|
(prevProps, nextProps) => {
|
|
294
|
-
//
|
|
295
|
-
// observe has changed. Each branch returns false to invalidate.
|
|
292
|
+
// Only re-render if the message or position changed
|
|
296
293
|
if (prevProps.message.id !== nextProps.message.id) return false;
|
|
297
294
|
if (prevProps.position !== nextProps.position) return false;
|
|
295
|
+
// Compare message content - for assistant messages this is a string, for others may differ
|
|
298
296
|
if (prevProps.message.content !== nextProps.message.content) return false;
|
|
299
297
|
if (prevProps.message.role !== nextProps.message.role) return false;
|
|
300
|
-
//
|
|
301
|
-
// JSON.stringify (state-manager already deep-copies on each call, so
|
|
302
|
-
// reference equality would never hit anyway).
|
|
298
|
+
// Compare state snapshot - custom renderers may depend on state
|
|
303
299
|
if (
|
|
304
300
|
JSON.stringify(prevProps.stateSnapshot) !==
|
|
305
301
|
JSON.stringify(nextProps.stateSnapshot)
|
|
306
302
|
)
|
|
307
303
|
return false;
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
// revoked except via clearAgentState/clearThreadState which wipe
|
|
311
|
-
// wholesale), so in practice this fires only on growth as new messages
|
|
312
|
-
// stream into the run. Slots in completed runs are unaffected — their
|
|
313
|
-
// count is stable once the run has finished.
|
|
314
|
-
if (prevProps.numberOfMessagesInRun !== nextProps.numberOfMessagesInRun)
|
|
315
|
-
return false;
|
|
316
|
-
// Re-render when this message's run stops being the latest run on the
|
|
317
|
-
// thread — e.g. a new run starts and previously-completed messages need
|
|
318
|
-
// to drop "is this the latest activity?" indicators. Only the slots
|
|
319
|
-
// belonging to the run that just lost its "latest" status are
|
|
320
|
-
// invalidated; the new run's slots and any older runs are unaffected.
|
|
321
|
-
if (prevProps.isInLatestRun !== nextProps.isInLatestRun) return false;
|
|
322
|
-
// Re-render when isRunning flips, but only for slots known to belong
|
|
323
|
-
// to the latest run (`isInLatestRun === true`). Slots whose run is
|
|
324
|
-
// older or whose run-id hasn't been recorded yet (undefined) are not
|
|
325
|
-
// invalidated on isRunning changes — this preserves the perf guarantee
|
|
326
|
-
// that completed messages skip re-renders during streaming.
|
|
327
|
-
//
|
|
328
|
-
// Renderers that gate solely on `agent.isRunning` and attach to a
|
|
329
|
-
// message added before any run started (e.g. a user message inserted
|
|
330
|
-
// before runAgent fires) won't observe the false→true transition for
|
|
331
|
-
// the first run. In practice this is rare; the canonical pattern is
|
|
332
|
-
// to gate on the slot's own runId membership (see
|
|
333
|
-
// intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx
|
|
334
|
-
// for the recommended renderer shape).
|
|
335
|
-
if (
|
|
336
|
-
nextProps.isInLatestRun &&
|
|
337
|
-
prevProps.isRunning !== nextProps.isRunning
|
|
338
|
-
)
|
|
339
|
-
return false;
|
|
340
|
-
// Note: renderCustomMessage's reference is intentionally not compared —
|
|
341
|
-
// it's a closure that changes frequently. The inputs above are the only
|
|
342
|
-
// observable signals.
|
|
304
|
+
// Note: We don't compare renderCustomMessage function reference because it changes
|
|
305
|
+
// frequently. The message and state comparison is sufficient to determine if a re-render is needed.
|
|
343
306
|
return true;
|
|
344
307
|
},
|
|
345
308
|
);
|
|
@@ -453,48 +416,6 @@ export function CopilotChatMessageView({
|
|
|
453
416
|
return () => subscription.unsubscribe();
|
|
454
417
|
}, [copilotkit]);
|
|
455
418
|
|
|
456
|
-
// Build per-run metadata once per render, not once per message. The two
|
|
457
|
-
// memo inputs MemoizedCustomMessage cares about (numberOfMessagesInRun and
|
|
458
|
-
// isInLatestRun) are both derived from the same scan of `messages` →
|
|
459
|
-
// `getRunIdForMessage`, so consolidating here turns an O(n²) per-render
|
|
460
|
-
// pass (one O(n) helper call per message) into a single O(n) pass.
|
|
461
|
-
//
|
|
462
|
-
// Re-fires whenever messages, the active agent/thread, or copilotkit
|
|
463
|
-
// changes. The internal messageToRun map can update without these props
|
|
464
|
-
// changing (a runId association lands one tick after the message is
|
|
465
|
-
// appended) — in that case the next external trigger refreshes. Note
|
|
466
|
-
// the `MemoizedCustomMessage` gate at the `isInLatestRun &&` check is
|
|
467
|
-
// strict-truthy — slots whose runId is still undefined during that
|
|
468
|
-
// pre-association window will not re-render on isRunning flips. The
|
|
469
|
-
// canonical pattern (see the IntelligenceIndicator e2e test) is to gate
|
|
470
|
-
// the renderer on the slot's own runId membership rather than `isRunning`
|
|
471
|
-
// alone, so the limitation doesn't bite typical use.
|
|
472
|
-
const runMetadata = useMemo(() => {
|
|
473
|
-
if (!config) return null;
|
|
474
|
-
const runIdByMessageId = new Map<string, string>();
|
|
475
|
-
for (const msg of messages) {
|
|
476
|
-
const r = copilotkit.getRunIdForMessage(
|
|
477
|
-
config.agentId,
|
|
478
|
-
config.threadId,
|
|
479
|
-
msg.id,
|
|
480
|
-
);
|
|
481
|
-
if (r) runIdByMessageId.set(msg.id, r);
|
|
482
|
-
}
|
|
483
|
-
const countByRunId = new Map<string, number>();
|
|
484
|
-
for (const r of runIdByMessageId.values()) {
|
|
485
|
-
countByRunId.set(r, (countByRunId.get(r) ?? 0) + 1);
|
|
486
|
-
}
|
|
487
|
-
let latestRunId: string | undefined;
|
|
488
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
489
|
-
const r = runIdByMessageId.get(messages[i]!.id);
|
|
490
|
-
if (r) {
|
|
491
|
-
latestRunId = r;
|
|
492
|
-
break;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
return { runIdByMessageId, countByRunId, latestRunId };
|
|
496
|
-
}, [messages, config?.agentId, config?.threadId, copilotkit]);
|
|
497
|
-
|
|
498
419
|
// Helper to get state snapshot for a message (used for memoization)
|
|
499
420
|
const getStateSnapshotForMessage = (messageId: string): unknown => {
|
|
500
421
|
if (!config) return undefined;
|
|
@@ -619,14 +540,6 @@ export function CopilotChatMessageView({
|
|
|
619
540
|
const renderMessageBlock = (message: Message): React.ReactElement[] => {
|
|
620
541
|
const elements: (React.ReactElement | null | undefined)[] = [];
|
|
621
542
|
const stateSnapshot = getStateSnapshotForMessage(message.id);
|
|
622
|
-
const messageRunId = runMetadata?.runIdByMessageId.get(message.id);
|
|
623
|
-
const numberOfMessagesInRun = messageRunId
|
|
624
|
-
? runMetadata?.countByRunId.get(messageRunId)
|
|
625
|
-
: undefined;
|
|
626
|
-
const isInLatestRun =
|
|
627
|
-
messageRunId === undefined
|
|
628
|
-
? undefined
|
|
629
|
-
: messageRunId === runMetadata?.latestRunId;
|
|
630
543
|
|
|
631
544
|
if (renderCustomMessage) {
|
|
632
545
|
elements.push(
|
|
@@ -636,9 +549,6 @@ export function CopilotChatMessageView({
|
|
|
636
549
|
position="before"
|
|
637
550
|
renderCustomMessage={renderCustomMessage}
|
|
638
551
|
stateSnapshot={stateSnapshot}
|
|
639
|
-
numberOfMessagesInRun={numberOfMessagesInRun}
|
|
640
|
-
isInLatestRun={isInLatestRun}
|
|
641
|
-
isRunning={isRunning}
|
|
642
552
|
/>,
|
|
643
553
|
);
|
|
644
554
|
}
|
|
@@ -692,24 +602,18 @@ export function CopilotChatMessageView({
|
|
|
692
602
|
position="after"
|
|
693
603
|
renderCustomMessage={renderCustomMessage}
|
|
694
604
|
stateSnapshot={stateSnapshot}
|
|
695
|
-
numberOfMessagesInRun={numberOfMessagesInRun}
|
|
696
|
-
isInLatestRun={isInLatestRun}
|
|
697
|
-
isRunning={isRunning}
|
|
698
605
|
/>,
|
|
699
606
|
);
|
|
700
607
|
}
|
|
701
608
|
|
|
702
609
|
// Auto-mount the IntelligenceIndicator on assistant message slots
|
|
703
610
|
// when the runtime is in intelligence mode. The component self-gates
|
|
704
|
-
// further (
|
|
705
|
-
// pill renders at a time —
|
|
706
|
-
// messages avoids
|
|
707
|
-
//
|
|
708
|
-
//
|
|
709
|
-
if (
|
|
710
|
-
copilotkit.intelligence !== undefined &&
|
|
711
|
-
message.role === "assistant"
|
|
712
|
-
) {
|
|
611
|
+
// further (latest matching-assistant slot, pending tool-call grace
|
|
612
|
+
// window) so only one pill renders at a time — mounting only for
|
|
613
|
+
// assistant messages avoids the per-slot `useAgent` subscription
|
|
614
|
+
// and four effects on user/reasoning/activity slots that would just
|
|
615
|
+
// return null at the role gate anyway.
|
|
616
|
+
if (copilotkit.intelligence !== undefined && message.role === "assistant") {
|
|
713
617
|
elements.push(
|
|
714
618
|
<IntelligenceIndicator
|
|
715
619
|
key={`${message.id}-intelligence`}
|
|
@@ -313,13 +313,13 @@ describe("CopilotChat activity message rendering", () => {
|
|
|
313
313
|
//
|
|
314
314
|
// The trap this catches is a refactor where the renderer pipeline keys
|
|
315
315
|
// on something other than `config.agentId` (e.g. for proxied
|
|
316
|
-
// registrations, accidentally keying on `proxy.
|
|
316
|
+
// registrations, accidentally keying on `proxy.runtimeAgentId`). The
|
|
317
317
|
// assertion shape — "two agents in the registry, the renderer must
|
|
318
318
|
// receive the one matching config.agentId" — is generic to that bug
|
|
319
319
|
// class. The proxy-routing-specific behavior (registering a
|
|
320
|
-
// ProxiedCopilotRuntimeAgent with `
|
|
320
|
+
// ProxiedCopilotRuntimeAgent with `runtimeAgentId !== agentId` and
|
|
321
321
|
// verifying `getAgent(agentId)` returns the proxy, not the agent at
|
|
322
|
-
//
|
|
322
|
+
// runtimeAgentId) is covered by `core-register-proxied-agent.test.ts`
|
|
323
323
|
// at the registry level.
|
|
324
324
|
const localAgent = new MockStepwiseAgent();
|
|
325
325
|
localAgent.agentId = "chat-1";
|