@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.
Files changed (30) hide show
  1. package/dist/{copilotkit-BoiGcRsU.cjs → copilotkit-BGIsblrk.cjs} +218 -3
  2. package/dist/copilotkit-BGIsblrk.cjs.map +1 -0
  3. package/dist/{copilotkit-B6kDTnFY.mjs → copilotkit-BVK_b6St.mjs} +213 -4
  4. package/dist/copilotkit-BVK_b6St.mjs.map +1 -0
  5. package/dist/{copilotkit-DTyTNR6Y.d.cts → copilotkit-Bc7kZ72T.d.cts} +50 -2
  6. package/dist/copilotkit-Bc7kZ72T.d.cts.map +1 -0
  7. package/dist/{copilotkit-FJWQLKBE.d.mts → copilotkit-DV9LwRgi.d.mts} +50 -2
  8. package/dist/copilotkit-DV9LwRgi.d.mts.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.mts +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/v2/index.cjs +2 -1
  14. package/dist/v2/index.css +1 -1
  15. package/dist/v2/index.d.cts +2 -2
  16. package/dist/v2/index.d.mts +2 -2
  17. package/dist/v2/index.mjs +2 -2
  18. package/dist/v2/index.umd.js +219 -2
  19. package/dist/v2/index.umd.js.map +1 -1
  20. package/package.json +6 -6
  21. package/src/v2/components/chat/CopilotChatMessageView.tsx +122 -6
  22. package/src/v2/components/index.ts +1 -0
  23. package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +265 -0
  24. package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +362 -0
  25. package/src/v2/components/intelligence-indicator/index.ts +2 -0
  26. package/src/v2/styles/globals.css +112 -0
  27. package/dist/copilotkit-B6kDTnFY.mjs.map +0 -1
  28. package/dist/copilotkit-BoiGcRsU.cjs.map +0 -1
  29. package/dist/copilotkit-DTyTNR6Y.d.cts.map +0 -1
  30. 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-BoiGcRsU.cjs.map
10414
+ //# sourceMappingURL=copilotkit-BGIsblrk.cjs.map