@copilotkit/react-core 1.56.5-canary.1777915231 → 1.56.5-canary.1777972218
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-BoiGcRsU.cjs → copilotkit-BGIsblrk.cjs} +218 -3
- package/dist/copilotkit-BGIsblrk.cjs.map +1 -0
- package/dist/{copilotkit-B6kDTnFY.mjs → copilotkit-BVK_b6St.mjs} +213 -4
- package/dist/copilotkit-BVK_b6St.mjs.map +1 -0
- package/dist/{copilotkit-DTyTNR6Y.d.cts → copilotkit-Bc7kZ72T.d.cts} +50 -2
- package/dist/copilotkit-Bc7kZ72T.d.cts.map +1 -0
- package/dist/{copilotkit-FJWQLKBE.d.mts → copilotkit-DV9LwRgi.d.mts} +50 -2
- package/dist/copilotkit-DV9LwRgi.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/v2/index.cjs +2 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/index.umd.js +219 -2
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/v2/components/chat/CopilotChatMessageView.tsx +122 -6
- package/src/v2/components/index.ts +1 -0
- package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +265 -0
- package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +362 -0
- package/src/v2/components/intelligence-indicator/index.ts +2 -0
- package/src/v2/styles/globals.css +112 -0
- package/dist/copilotkit-B6kDTnFY.mjs.map +0 -1
- package/dist/copilotkit-BoiGcRsU.cjs.map +0 -1
- package/dist/copilotkit-DTyTNR6Y.d.cts.map +0 -1
- package/dist/copilotkit-FJWQLKBE.d.mts.map +0 -1
|
@@ -5601,6 +5601,171 @@ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
|
5601
5601
|
*/
|
|
5602
5602
|
const ScrollElementContext = react.default.createContext(null);
|
|
5603
5603
|
|
|
5604
|
+
//#endregion
|
|
5605
|
+
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
|
|
5606
|
+
/**
|
|
5607
|
+
* Brief debounce on `agent.isRunning` falling edges. Multi-step agent
|
|
5608
|
+
* runs can emit transient `RUN_FINISHED → RUN_STARTED` cycles between
|
|
5609
|
+
* LLM steps inside one user turn; without a small grace window the pill
|
|
5610
|
+
* would flicker spinner → check → spinner. 500 ms is well below
|
|
5611
|
+
* human-perceptible flash latency yet long enough to absorb step blips.
|
|
5612
|
+
*/
|
|
5613
|
+
const RUN_IDLE_DEBOUNCE_MS = 500;
|
|
5614
|
+
/** Hold the checkmark briefly before fading out. */
|
|
5615
|
+
const CHECK_HOLD_MS = 800;
|
|
5616
|
+
/**
|
|
5617
|
+
* Duration of the fade-out animation. Must match
|
|
5618
|
+
* `cpk-intelligence-pill-fade-out` keyframes in `v2/styles/globals.css`.
|
|
5619
|
+
*/
|
|
5620
|
+
const FADE_OUT_ANIMATION_MS = 480;
|
|
5621
|
+
/**
|
|
5622
|
+
* Polling interval for `agent.isRunning`. Background: AG-UI's `runAgent`
|
|
5623
|
+
* snapshots `[...this.subscribers]` at invocation time and threads that
|
|
5624
|
+
* snapshot through the entire run pipeline (including the `finalize`
|
|
5625
|
+
* block that fires `onRunFinalized` and flips `isRunning` off). A
|
|
5626
|
+
* subscriber added AFTER `runAgent` starts — which is always the case
|
|
5627
|
+
* here, because the renderer mounts when the matching message first
|
|
5628
|
+
* appears INSIDE the run — is missing from that snapshot and never
|
|
5629
|
+
* receives the falling edge.
|
|
5630
|
+
*
|
|
5631
|
+
* Re-renders driven by parent state still keep the pill alive while
|
|
5632
|
+
* messages stream, but `agent.isRunning` only flips off via the
|
|
5633
|
+
* snapshotted set. A 200 ms poll reads the live property and forces a
|
|
5634
|
+
* re-render when it changes, closing the gap.
|
|
5635
|
+
*/
|
|
5636
|
+
const ISRUNNING_POLL_MS = 200;
|
|
5637
|
+
/**
|
|
5638
|
+
* Tool-name regex patterns that trigger the indicator. Currently
|
|
5639
|
+
* hardcoded to the Intelligence MCP server's canonical tool name. If
|
|
5640
|
+
* we add per-instance customization later (e.g. a `CopilotKitProvider`
|
|
5641
|
+
* prop or a runtime-info field), this constant becomes the fallback.
|
|
5642
|
+
*/
|
|
5643
|
+
const DEFAULT_TOOL_PATTERNS = [/^bash$/];
|
|
5644
|
+
/**
|
|
5645
|
+
* The "Using CopilotKit Intelligence" pill. Auto-mounted by
|
|
5646
|
+
* `CopilotChatMessageView` for every message slot when
|
|
5647
|
+
* `copilotkit.intelligence` is configured — callers do not register
|
|
5648
|
+
* this themselves. Self-gates so only the canonical message renders a
|
|
5649
|
+
* pill.
|
|
5650
|
+
*
|
|
5651
|
+
* Render gates (all must hold):
|
|
5652
|
+
* 1. `copilotkit.intelligence !== undefined` (Intelligence runtime
|
|
5653
|
+
* is configured; checked by the parent before mounting, and
|
|
5654
|
+
* again here as a defence)
|
|
5655
|
+
* 2. The message is the last message of its run
|
|
5656
|
+
* 3. The message's run is the latest run on the thread
|
|
5657
|
+
* 4. The message has at least one tool call whose name matches
|
|
5658
|
+
* {@link DEFAULT_TOOL_PATTERNS}
|
|
5659
|
+
* 5. The phase machine is not yet `hidden`
|
|
5660
|
+
*
|
|
5661
|
+
* Phase machine (per-instance, all timers local):
|
|
5662
|
+
* - `spinner` while `agent.isRunning`
|
|
5663
|
+
* - → `check` after `agent.isRunning` falls (debounced 500 ms to
|
|
5664
|
+
* absorb step-boundary `RUN_FINISHED → RUN_STARTED` blips inside
|
|
5665
|
+
* one user turn)
|
|
5666
|
+
* - → `fading` after a brief hold ({@link CHECK_HOLD_MS})
|
|
5667
|
+
* - → `hidden` after the fade animation
|
|
5668
|
+
* ({@link FADE_OUT_ANIMATION_MS})
|
|
5669
|
+
*
|
|
5670
|
+
* The "exactly one pill at a time" guarantee is structural — only one
|
|
5671
|
+
* message at any moment satisfies gates 2–4 — so no shared coordination
|
|
5672
|
+
* state is required.
|
|
5673
|
+
*/
|
|
5674
|
+
function IntelligenceIndicator(props) {
|
|
5675
|
+
const { message, agentId, label = "Using CopilotKit Intelligence" } = props;
|
|
5676
|
+
const { copilotkit } = useCopilotKit();
|
|
5677
|
+
const config = useCopilotChatConfiguration();
|
|
5678
|
+
const { agent } = useAgent({
|
|
5679
|
+
agentId,
|
|
5680
|
+
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
5681
|
+
});
|
|
5682
|
+
const [, forceRender] = (0, react.useReducer)((n) => n + 1, 0);
|
|
5683
|
+
const lastSeenIsRunningRef = (0, react.useRef)(agent.isRunning);
|
|
5684
|
+
(0, react.useEffect)(() => {
|
|
5685
|
+
const interval = setInterval(() => {
|
|
5686
|
+
const live = agent.isRunning;
|
|
5687
|
+
if (live !== lastSeenIsRunningRef.current) {
|
|
5688
|
+
lastSeenIsRunningRef.current = live;
|
|
5689
|
+
forceRender();
|
|
5690
|
+
}
|
|
5691
|
+
}, ISRUNNING_POLL_MS);
|
|
5692
|
+
return () => clearInterval(interval);
|
|
5693
|
+
}, [agent]);
|
|
5694
|
+
const [phase, setPhase] = (0, react.useState)(agent.isRunning ? "spinner" : "check");
|
|
5695
|
+
(0, react.useEffect)(() => {
|
|
5696
|
+
if (agent.isRunning) {
|
|
5697
|
+
setPhase("spinner");
|
|
5698
|
+
return;
|
|
5699
|
+
}
|
|
5700
|
+
const t = setTimeout(() => setPhase("check"), RUN_IDLE_DEBOUNCE_MS);
|
|
5701
|
+
return () => clearTimeout(t);
|
|
5702
|
+
}, [agent.isRunning]);
|
|
5703
|
+
(0, react.useEffect)(() => {
|
|
5704
|
+
if (phase !== "check") return void 0;
|
|
5705
|
+
const t = setTimeout(() => setPhase("fading"), CHECK_HOLD_MS);
|
|
5706
|
+
return () => clearTimeout(t);
|
|
5707
|
+
}, [phase]);
|
|
5708
|
+
(0, react.useEffect)(() => {
|
|
5709
|
+
if (phase !== "fading") return void 0;
|
|
5710
|
+
const t = setTimeout(() => setPhase("hidden"), FADE_OUT_ANIMATION_MS);
|
|
5711
|
+
return () => clearTimeout(t);
|
|
5712
|
+
}, [phase]);
|
|
5713
|
+
if (copilotkit.intelligence === void 0) return null;
|
|
5714
|
+
if (!config) return null;
|
|
5715
|
+
if (phase === "hidden") return null;
|
|
5716
|
+
if (message.role !== "assistant") return null;
|
|
5717
|
+
if (!(Array.isArray(message.toolCalls) ? message.toolCalls : []).some((tc) => {
|
|
5718
|
+
const name = tc?.function?.name;
|
|
5719
|
+
return typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
|
|
5720
|
+
})) return null;
|
|
5721
|
+
const messageRunId = copilotkit.getRunIdForMessage(agentId, config.threadId, message.id);
|
|
5722
|
+
if (!messageRunId) return null;
|
|
5723
|
+
let latestRunId;
|
|
5724
|
+
let lastMessageIdInThisRun;
|
|
5725
|
+
for (let i = agent.messages.length - 1; i >= 0; i -= 1) {
|
|
5726
|
+
const m = agent.messages[i];
|
|
5727
|
+
const r = copilotkit.getRunIdForMessage(agentId, config.threadId, m.id);
|
|
5728
|
+
if (latestRunId === void 0 && r) latestRunId = r;
|
|
5729
|
+
if (lastMessageIdInThisRun === void 0 && r === messageRunId) lastMessageIdInThisRun = m.id;
|
|
5730
|
+
if (latestRunId !== void 0 && lastMessageIdInThisRun !== void 0) break;
|
|
5731
|
+
}
|
|
5732
|
+
if (latestRunId !== messageRunId) return null;
|
|
5733
|
+
if (lastMessageIdInThisRun !== message.id) return null;
|
|
5734
|
+
const showSpinner = phase === "spinner";
|
|
5735
|
+
const isFading = phase === "fading";
|
|
5736
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5737
|
+
className: "cpk-intelligence-pill" + (isFading ? " cpk-intelligence-pill--fading" : ""),
|
|
5738
|
+
role: "status",
|
|
5739
|
+
"aria-live": "polite",
|
|
5740
|
+
"aria-hidden": isFading || void 0,
|
|
5741
|
+
"data-testid": `cpk-intelligence-pill-${message.id}`,
|
|
5742
|
+
title: label,
|
|
5743
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
5744
|
+
className: "cpk-intelligence-pill__icon",
|
|
5745
|
+
viewBox: "0 0 24 24",
|
|
5746
|
+
width: "14",
|
|
5747
|
+
height: "14",
|
|
5748
|
+
"aria-hidden": "true",
|
|
5749
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
5750
|
+
cx: "12",
|
|
5751
|
+
cy: "12",
|
|
5752
|
+
r: "9",
|
|
5753
|
+
fill: "none",
|
|
5754
|
+
strokeWidth: "2.5",
|
|
5755
|
+
strokeLinecap: "round",
|
|
5756
|
+
className: "cpk-intelligence-pill__ring" + (showSpinner ? "" : " cpk-intelligence-pill__ring--done")
|
|
5757
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
5758
|
+
d: "M8 12.5l3 3 5-6",
|
|
5759
|
+
fill: "none",
|
|
5760
|
+
strokeWidth: "2.5",
|
|
5761
|
+
strokeLinecap: "round",
|
|
5762
|
+
strokeLinejoin: "round",
|
|
5763
|
+
className: "cpk-intelligence-pill__check" + (showSpinner ? "" : " cpk-intelligence-pill__check--shown")
|
|
5764
|
+
})]
|
|
5765
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
5766
|
+
});
|
|
5767
|
+
}
|
|
5768
|
+
|
|
5604
5769
|
//#endregion
|
|
5605
5770
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
5606
5771
|
/**
|
|
@@ -5720,6 +5885,9 @@ const MemoizedCustomMessage = react.default.memo(function MemoizedCustomMessage(
|
|
|
5720
5885
|
if (prevProps.message.content !== nextProps.message.content) return false;
|
|
5721
5886
|
if (prevProps.message.role !== nextProps.message.role) return false;
|
|
5722
5887
|
if (JSON.stringify(prevProps.stateSnapshot) !== JSON.stringify(nextProps.stateSnapshot)) return false;
|
|
5888
|
+
if (prevProps.numberOfMessagesInRun !== nextProps.numberOfMessagesInRun) return false;
|
|
5889
|
+
if (prevProps.isInLatestRun !== nextProps.isInLatestRun) return false;
|
|
5890
|
+
if (nextProps.isInLatestRun && prevProps.isRunning !== nextProps.isRunning) return false;
|
|
5723
5891
|
return true;
|
|
5724
5892
|
});
|
|
5725
5893
|
/**
|
|
@@ -5775,6 +5943,34 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5775
5943
|
} });
|
|
5776
5944
|
return () => subscription.unsubscribe();
|
|
5777
5945
|
}, [copilotkit]);
|
|
5946
|
+
const runMetadata = (0, react.useMemo)(() => {
|
|
5947
|
+
if (!config) return null;
|
|
5948
|
+
const runIdByMessageId = /* @__PURE__ */ new Map();
|
|
5949
|
+
for (const msg of messages) {
|
|
5950
|
+
const r = copilotkit.getRunIdForMessage(config.agentId, config.threadId, msg.id);
|
|
5951
|
+
if (r) runIdByMessageId.set(msg.id, r);
|
|
5952
|
+
}
|
|
5953
|
+
const countByRunId = /* @__PURE__ */ new Map();
|
|
5954
|
+
for (const r of runIdByMessageId.values()) countByRunId.set(r, (countByRunId.get(r) ?? 0) + 1);
|
|
5955
|
+
let latestRunId;
|
|
5956
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
5957
|
+
const r = runIdByMessageId.get(messages[i].id);
|
|
5958
|
+
if (r) {
|
|
5959
|
+
latestRunId = r;
|
|
5960
|
+
break;
|
|
5961
|
+
}
|
|
5962
|
+
}
|
|
5963
|
+
return {
|
|
5964
|
+
runIdByMessageId,
|
|
5965
|
+
countByRunId,
|
|
5966
|
+
latestRunId
|
|
5967
|
+
};
|
|
5968
|
+
}, [
|
|
5969
|
+
messages,
|
|
5970
|
+
config?.agentId,
|
|
5971
|
+
config?.threadId,
|
|
5972
|
+
copilotkit
|
|
5973
|
+
]);
|
|
5778
5974
|
const getStateSnapshotForMessage = (messageId) => {
|
|
5779
5975
|
if (!config) return void 0;
|
|
5780
5976
|
const resolvedRunId = copilotkit.getRunIdForMessage(config.agentId, config.threadId, messageId) ?? copilotkit.getRunIdsForThread(config.agentId, config.threadId).slice(-1)[0];
|
|
@@ -5811,11 +6007,17 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5811
6007
|
const renderMessageBlock = (message) => {
|
|
5812
6008
|
const elements = [];
|
|
5813
6009
|
const stateSnapshot = getStateSnapshotForMessage(message.id);
|
|
6010
|
+
const messageRunId = runMetadata?.runIdByMessageId.get(message.id);
|
|
6011
|
+
const numberOfMessagesInRun = messageRunId ? runMetadata?.countByRunId.get(messageRunId) : void 0;
|
|
6012
|
+
const isInLatestRun = messageRunId === void 0 ? void 0 : messageRunId === runMetadata?.latestRunId;
|
|
5814
6013
|
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
|
|
5815
6014
|
message,
|
|
5816
6015
|
position: "before",
|
|
5817
6016
|
renderCustomMessage,
|
|
5818
|
-
stateSnapshot
|
|
6017
|
+
stateSnapshot,
|
|
6018
|
+
numberOfMessagesInRun,
|
|
6019
|
+
isInLatestRun,
|
|
6020
|
+
isRunning
|
|
5819
6021
|
}, `${message.id}-custom-before`));
|
|
5820
6022
|
if (message.role === "assistant") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedAssistantMessage, {
|
|
5821
6023
|
message,
|
|
@@ -5844,8 +6046,15 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5844
6046
|
message,
|
|
5845
6047
|
position: "after",
|
|
5846
6048
|
renderCustomMessage,
|
|
5847
|
-
stateSnapshot
|
|
6049
|
+
stateSnapshot,
|
|
6050
|
+
numberOfMessagesInRun,
|
|
6051
|
+
isInLatestRun,
|
|
6052
|
+
isRunning
|
|
5848
6053
|
}, `${message.id}-custom-after`));
|
|
6054
|
+
if (copilotkit.intelligence !== void 0 && message.role === "assistant") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IntelligenceIndicator, {
|
|
6055
|
+
message,
|
|
6056
|
+
agentId: config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID
|
|
6057
|
+
}, `${message.id}-intelligence`));
|
|
5849
6058
|
return elements.filter(Boolean);
|
|
5850
6059
|
};
|
|
5851
6060
|
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
@@ -9968,6 +10177,12 @@ Object.defineProperty(exports, 'DefaultOpenIcon', {
|
|
|
9968
10177
|
return DefaultOpenIcon;
|
|
9969
10178
|
}
|
|
9970
10179
|
});
|
|
10180
|
+
Object.defineProperty(exports, 'IntelligenceIndicator', {
|
|
10181
|
+
enumerable: true,
|
|
10182
|
+
get: function () {
|
|
10183
|
+
return IntelligenceIndicator;
|
|
10184
|
+
}
|
|
10185
|
+
});
|
|
9971
10186
|
Object.defineProperty(exports, 'MCPAppsActivityContentSchema', {
|
|
9972
10187
|
enumerable: true,
|
|
9973
10188
|
get: function () {
|
|
@@ -10196,4 +10411,4 @@ Object.defineProperty(exports, 'useToast', {
|
|
|
10196
10411
|
return useToast;
|
|
10197
10412
|
}
|
|
10198
10413
|
});
|
|
10199
|
-
//# sourceMappingURL=copilotkit-
|
|
10414
|
+
//# sourceMappingURL=copilotkit-BGIsblrk.cjs.map
|