@copilotkit/react-core 1.79.1 → 1.80.0

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 (42) hide show
  1. package/dist/{copilotkit-CD3uPUN3.mjs → copilotkit-BNLtgOyD.mjs} +1855 -221
  2. package/dist/copilotkit-BNLtgOyD.mjs.map +1 -0
  3. package/dist/{copilotkit-Yz8qXx00.d.mts → copilotkit-CWOSXhRO.d.mts} +277 -40
  4. package/dist/copilotkit-CWOSXhRO.d.mts.map +1 -0
  5. package/dist/{copilotkit-DEaA0Cat.cjs → copilotkit-DKICi3nC.cjs} +1843 -196
  6. package/dist/copilotkit-DKICi3nC.cjs.map +1 -0
  7. package/dist/{copilotkit-k7IYk2AN.d.cts → copilotkit-Dfw9HzO9.d.cts} +277 -40
  8. package/dist/copilotkit-Dfw9HzO9.d.cts.map +1 -0
  9. package/dist/index.cjs +15 -3
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts +1 -1
  14. package/dist/index.d.mts.map +1 -1
  15. package/dist/index.mjs +15 -3
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/index.umd.js +127 -16
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/v2/context.d.cts +7 -0
  20. package/dist/v2/context.d.cts.map +1 -1
  21. package/dist/v2/context.d.mts +7 -0
  22. package/dist/v2/context.d.mts.map +1 -1
  23. package/dist/v2/headless.cjs +106 -16
  24. package/dist/v2/headless.cjs.map +1 -1
  25. package/dist/v2/headless.d.cts +20 -2
  26. package/dist/v2/headless.d.cts.map +1 -1
  27. package/dist/v2/headless.d.mts +20 -2
  28. package/dist/v2/headless.d.mts.map +1 -1
  29. package/dist/v2/headless.mjs +106 -16
  30. package/dist/v2/headless.mjs.map +1 -1
  31. package/dist/v2/index.cjs +3 -1
  32. package/dist/v2/index.css +1 -1
  33. package/dist/v2/index.d.cts +2 -2
  34. package/dist/v2/index.d.mts +2 -2
  35. package/dist/v2/index.mjs +2 -2
  36. package/dist/v2/index.umd.js +1858 -222
  37. package/dist/v2/index.umd.js.map +1 -1
  38. package/package.json +11 -8
  39. package/dist/copilotkit-CD3uPUN3.mjs.map +0 -1
  40. package/dist/copilotkit-DEaA0Cat.cjs.map +0 -1
  41. package/dist/copilotkit-Yz8qXx00.d.mts.map +0 -1
  42. package/dist/copilotkit-k7IYk2AN.d.cts.map +0 -1
package/dist/index.umd.js CHANGED
@@ -178,7 +178,7 @@ react_markdown = __toESM(react_markdown);
178
178
  * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
179
179
  * class instances, and other exotic objects that happen to have typeof "object".
180
180
  */
181
- function isPlainObject(obj) {
181
+ function isPlainObject$1(obj) {
182
182
  return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
183
183
  }
184
184
  /**
@@ -197,7 +197,7 @@ react_markdown = __toESM(react_markdown);
197
197
  function useShallowStableRef(value) {
198
198
  const ref = (0, react.useRef)(value);
199
199
  if (ref.current === value) return ref.current;
200
- if (isPlainObject(ref.current) && isPlainObject(value)) {
200
+ if (isPlainObject$1(ref.current) && isPlainObject$1(value)) {
201
201
  if (shallowEqual(ref.current, value)) return ref.current;
202
202
  }
203
203
  ref.current = value;
@@ -213,6 +213,8 @@ react_markdown = __toESM(react_markdown);
213
213
  chatInputToolbarFinishTranscribeButtonLabel: "Finish",
214
214
  chatInputToolbarAddButtonLabel: "Add attachments",
215
215
  chatInputToolbarToolsButtonLabel: "Tools",
216
+ chatInputToolbarSendButtonLabel: "Send message",
217
+ chatInputToolbarStopButtonLabel: "Stop",
216
218
  assistantMessageToolbarCopyCodeLabel: "Copy",
217
219
  assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
218
220
  assistantMessageToolbarCopyMessageLabel: "Copy",
@@ -225,13 +227,18 @@ react_markdown = __toESM(react_markdown);
225
227
  assistantMessageToolbarInspectorHideDescription: "Until you reload this page",
226
228
  assistantMessageToolbarThumbsUpLabel: "Good response",
227
229
  assistantMessageToolbarThumbsDownLabel: "Bad response",
230
+ assistantMessageFeedbackCommentPlaceholder: "Add a comment (optional)",
231
+ assistantMessageFeedbackCommentSubmitLabel: "Send comment",
228
232
  assistantMessageToolbarReadAloudLabel: "Read aloud",
229
233
  assistantMessageToolbarRegenerateLabel: "Regenerate",
230
234
  userMessageToolbarCopyMessageLabel: "Copy",
231
235
  userMessageToolbarEditMessageLabel: "Edit",
236
+ userMessageToolbarPreviousBranchLabel: "Previous branch",
237
+ userMessageToolbarNextBranchLabel: "Next branch",
232
238
  chatDisclaimerText: "AI can make mistakes. Please verify important information.",
233
239
  chatToggleOpenLabel: "Open chat",
234
240
  chatToggleCloseLabel: "Close chat",
241
+ chatScrollToBottomLabel: "Scroll to bottom",
235
242
  modalHeaderTitle: "CopilotKit Chat",
236
243
  welcomeMessageText: "How can I help you today?"
237
244
  };
@@ -555,6 +562,14 @@ react_markdown = __toESM(react_markdown);
555
562
  }
556
563
  }
557
564
  /**
565
+ * The tool-call renderers registered on the provider, kept current.
566
+ * @internal
567
+ */
568
+ function useToolCallRenderers() {
569
+ const { copilotkit } = useCopilotKit();
570
+ return (0, react.useSyncExternalStore)((callback) => copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
571
+ }
572
+ /**
558
573
  * Hook that returns a function to render tool calls based on the render functions
559
574
  * defined in CopilotKitProvider.
560
575
  *
@@ -565,9 +580,7 @@ react_markdown = __toESM(react_markdown);
565
580
  const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
566
581
  const unrenderedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
567
582
  const warnedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
568
- const renderToolCalls = (0, react.useSyncExternalStore)((callback) => {
569
- return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
570
- }, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
583
+ const renderToolCalls = useToolCallRenderers();
571
584
  const renderToolCall = (0, react.useCallback)(({ toolCall, toolMessage }) => {
572
585
  const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
573
586
  const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
@@ -602,7 +615,7 @@ react_markdown = __toESM(react_markdown);
602
615
 
603
616
  //#endregion
604
617
  //#region package.json
605
- var version = "1.79.1";
618
+ var version = "1.80.0";
606
619
 
607
620
  //#endregion
608
621
  //#region src/v2/components/CopilotKitInspector.tsx
@@ -806,7 +819,7 @@ react_markdown = __toESM(react_markdown);
806
819
  * Fetches resource content on-demand via proxied MCP requests. The React shell
807
820
  * owns the iframe; `bindMcpApp` owns the protocol.
808
821
  */
809
- const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, message, agent }) {
822
+ const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, message, agent, allowSameOriginFallback }) {
810
823
  const { copilotkit } = useCopilotKit();
811
824
  const messageId = message?.id;
812
825
  const containerRef = (0, react.useRef)(null);
@@ -856,6 +869,7 @@ react_markdown = __toESM(react_markdown);
856
869
  getAgent: () => agentRef.current,
857
870
  host: copilotkit,
858
871
  messageId,
872
+ options: { allowSameOriginFallback },
859
873
  hooks: {
860
874
  onResource: (resource) => {
861
875
  if (!mounted) return;
@@ -897,6 +911,7 @@ react_markdown = __toESM(react_markdown);
897
911
  agent,
898
912
  copilotkit,
899
913
  messageId,
914
+ allowSameOriginFallback,
900
915
  content.resourceUri,
901
916
  content.serverHash,
902
917
  content.serverId
@@ -2111,7 +2126,8 @@ react_markdown = __toESM(react_markdown);
2111
2126
  name: def.name,
2112
2127
  args: argsSchema,
2113
2128
  render: def.render,
2114
- ...def.agentId ? { agentId: def.agentId } : {}
2129
+ ...def.agentId ? { agentId: def.agentId } : {},
2130
+ ...def.group ? { group: true } : {}
2115
2131
  };
2116
2132
  }
2117
2133
 
@@ -2231,6 +2247,11 @@ react_markdown = __toESM(react_markdown);
2231
2247
  - Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
2232
2248
  - Minimal transitions (150ms) for hover/focus states only. No decorative animations.
2233
2249
  - Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
2250
+ /** The MCP Apps renderer with `mcpApps.allowSameOriginFallback` applied. */
2251
+ const SameOriginMCPAppsActivityRenderer = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MCPAppsActivityRenderer, {
2252
+ ...props,
2253
+ allowSameOriginFallback: true
2254
+ });
2234
2255
  const DEFAULT_LEARNING = Object.freeze({});
2235
2256
  function toLearningConfig(learning) {
2236
2257
  if (learning === true) return DEFAULT_LEARNING;
@@ -2247,7 +2268,8 @@ react_markdown = __toESM(react_markdown);
2247
2268
  }, [value, warningMessage]);
2248
2269
  return value;
2249
2270
  }
2250
- const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, defaultThrottleMs, debug, learning }) => {
2271
+ /** Provide a shared core instance and synchronize runtime, tool, and UI configuration. */
2272
+ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, mcpApps, defaultThrottleMs, debug, learning }) => {
2251
2273
  const learningConfig = (0, react.useMemo)(() => toLearningConfig(learning), [learning]);
2252
2274
  const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
2253
2275
  const [inspectorVisible, setInspectorVisible] = (0, react.useState)(false);
@@ -2304,11 +2326,12 @@ react_markdown = __toESM(react_markdown);
2304
2326
  const core = copilotkitRef.current;
2305
2327
  return (0, _copilotkit_a2ui_renderer.filterCatalog)(rawCatalog, (name) => core ? core.isCatalogComponentEnabled(name) : true);
2306
2328
  }, [rawCatalog, catalogToggleVersion]);
2329
+ const mcpAppsAllowSameOrigin = mcpApps?.allowSameOriginFallback === true;
2307
2330
  const builtInActivityRenderers = (0, react.useMemo)(() => {
2308
2331
  const renderers = [{
2309
2332
  activityType: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityType,
2310
2333
  content: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityContentSchema,
2311
- render: MCPAppsActivityRenderer
2334
+ render: mcpAppsAllowSameOrigin ? SameOriginMCPAppsActivityRenderer : MCPAppsActivityRenderer
2312
2335
  }];
2313
2336
  if (openGenUIActive) renderers.push({
2314
2337
  activityType: OpenGenerativeUIActivityType,
@@ -2326,7 +2349,8 @@ react_markdown = __toESM(react_markdown);
2326
2349
  a2uiActive,
2327
2350
  openGenUIActive,
2328
2351
  a2ui,
2329
- filteredCatalog
2352
+ filteredCatalog,
2353
+ mcpAppsAllowSameOrigin
2330
2354
  ]);
2331
2355
  const allActivityRenderers = (0, react.useMemo)(() => {
2332
2356
  return [...renderActivityMessagesList, ...builtInActivityRenderers];
@@ -2434,6 +2458,7 @@ react_markdown = __toESM(react_markdown);
2434
2458
  description: _copilotkit_shared.GENERATE_SANDBOXED_UI_DESCRIPTION,
2435
2459
  parameters: GenerateSandboxedUiArgsSchema,
2436
2460
  handler: async () => "UI generated",
2461
+ reconnectBehavior: "resume-pending",
2437
2462
  followUp: true,
2438
2463
  render: OpenGenerativeUIToolRenderer
2439
2464
  }];
@@ -2798,11 +2823,85 @@ react_markdown = __toESM(react_markdown);
2798
2823
  }
2799
2824
 
2800
2825
  //#endregion
2801
- //#region src/v2/hooks/use-frontend-tool.tsx
2826
+ //#region src/v2/hooks/tool-registration.ts
2827
+ /**
2828
+ * Deps comparison shared by `useFrontendTool` (and through it
2829
+ * `useHumanInTheLoop` and `useComponent`) and `useRenderTool`. Not part of the
2830
+ * public API.
2831
+ */
2802
2832
  const EMPTY_DEPS = [];
2833
+ function isPlainObject(value) {
2834
+ const proto = Object.getPrototypeOf(value);
2835
+ return proto === Object.prototype || proto === null;
2836
+ }
2837
+ /**
2838
+ * Plain data (primitives, plain objects, arrays, dates) compares by value.
2839
+ * Functions always compare equal: these hooks used to compare
2840
+ * `JSON.stringify(deps)`, which turns every function into `null`, and a
2841
+ * function that counted as changed would re-register on every render when it
2842
+ * is written inline (and loop in a component that also reads
2843
+ * `useRenderToolCall`). Everything else (class instances, maps, sets) compares
2844
+ * by identity. A cycle inside plain data is safe: a pair already being
2845
+ * compared counts as equal for that branch.
2846
+ */
2847
+ function depEqual(a, b, seen) {
2848
+ if (Object.is(a, b)) return true;
2849
+ if (typeof a === "function" && typeof b === "function") return true;
2850
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
2851
+ if (a instanceof Date && b instanceof Date) return Object.is(a.getTime(), b.getTime());
2852
+ const aIsArray = Array.isArray(a);
2853
+ if (aIsArray !== Array.isArray(b)) return false;
2854
+ if (!aIsArray && !(isPlainObject(a) && isPlainObject(b))) return false;
2855
+ if (seen.get(a) === b) return true;
2856
+ seen.set(a, b);
2857
+ if (aIsArray) {
2858
+ const left = a;
2859
+ const right = b;
2860
+ if (left.length !== right.length) return false;
2861
+ for (let i = 0; i < left.length; i++) if (!depEqual(left[i], right[i], seen)) return false;
2862
+ return true;
2863
+ }
2864
+ const left = a;
2865
+ const right = b;
2866
+ const leftKeys = Object.keys(left);
2867
+ if (leftKeys.length !== Object.keys(right).length) return false;
2868
+ for (const key of leftKeys) {
2869
+ if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
2870
+ if (!depEqual(left[key], right[key], seen)) return false;
2871
+ }
2872
+ return true;
2873
+ }
2874
+ /** Whether two deps arrays are equal. A change in length is always a change. */
2875
+ function depsEqual(prev, next) {
2876
+ if (prev.length !== next.length) return false;
2877
+ const seen = /* @__PURE__ */ new Map();
2878
+ for (let i = 0; i < prev.length; i++) if (!depEqual(prev[i], next[i], seen)) return false;
2879
+ return true;
2880
+ }
2881
+ /**
2882
+ * Turns a caller's `deps` array into a number that changes exactly when the
2883
+ * deps change, by the rules of {@link depsEqual}. Put the number, not the
2884
+ * array, in the registration effect's dependency list: that keeps the list a
2885
+ * constant length and never serializes a value.
2886
+ */
2887
+ function useDepsVersion(deps) {
2888
+ const next = deps ?? EMPTY_DEPS;
2889
+ const ref = (0, react.useRef)({
2890
+ deps: next,
2891
+ version: 0
2892
+ });
2893
+ if (ref.current.deps !== next && !depsEqual(ref.current.deps, next)) ref.current = {
2894
+ deps: next,
2895
+ version: ref.current.version + 1
2896
+ };
2897
+ return ref.current.version;
2898
+ }
2899
+
2900
+ //#endregion
2901
+ //#region src/v2/hooks/use-frontend-tool.tsx
2803
2902
  function useFrontendTool$1(tool, deps) {
2804
2903
  const { copilotkit } = useCopilotKit();
2805
- const extraDeps = deps ?? EMPTY_DEPS;
2904
+ const depsVersion = useDepsVersion(deps);
2806
2905
  (0, react.useLayoutEffect)(() => {
2807
2906
  const name = tool.name;
2808
2907
  if (copilotkit.getTool({
@@ -2826,7 +2925,7 @@ react_markdown = __toESM(react_markdown);
2826
2925
  tool.name,
2827
2926
  tool.available,
2828
2927
  copilotkit,
2829
- JSON.stringify(extraDeps),
2928
+ depsVersion,
2830
2929
  JSON.stringify(tool.webmcp ?? null)
2831
2930
  ]);
2832
2931
  }
@@ -6693,6 +6792,14 @@ react_markdown = __toESM(react_markdown);
6693
6792
  *
6694
6793
  * This hooks enables you to dynamically generate UI elements and render them in the copilot chat. For more information, check out the [Generative UI](/guides/generative-ui) page.
6695
6794
  */
6795
+ function toRenderToolCallArgs(action) {
6796
+ const { render } = action;
6797
+ if (typeof render === "string") return {
6798
+ ...action,
6799
+ render: () => react.default.createElement(react.default.Fragment, null, render)
6800
+ };
6801
+ return action;
6802
+ }
6696
6803
  function getActionConfig(action) {
6697
6804
  if (action.name === "*") {
6698
6805
  const catchAll = action;
@@ -6728,14 +6835,18 @@ react_markdown = __toESM(react_markdown);
6728
6835
  };
6729
6836
  if (action.available === "frontend" || action.available === "disabled") return {
6730
6837
  type: "render",
6731
- action
6838
+ action: toRenderToolCallArgs(action)
6732
6839
  };
6733
6840
  }
6734
6841
  if ("handler" in action) return {
6735
6842
  type: "frontend",
6736
6843
  action
6737
6844
  };
6738
- throw new Error("Invalid action configuration");
6845
+ if ("render" in action && action.render) return {
6846
+ type: "render",
6847
+ action: toRenderToolCallArgs(action)
6848
+ };
6849
+ throw new Error(`useCopilotAction(${JSON.stringify(action.name)}): this action has no handler and no render function. Add a handler to run the action in the browser, or a render function to render a tool call that the agent runs.`);
6739
6850
  }
6740
6851
  /**
6741
6852
  * useCopilotAction is a legacy hook maintained for backwards compatibility.