@copilotkit/react-core 1.55.3-canary.1776260990 → 1.55.3-canary.1776979102

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 (59) hide show
  1. package/dist/{copilotkit-Dcf7Lkjb.d.mts → copilotkit-3mXoM0Hd.d.mts} +9 -36
  2. package/dist/copilotkit-3mXoM0Hd.d.mts.map +1 -0
  3. package/dist/{copilotkit-9_JxoZgF.d.cts → copilotkit-BDDjvB-p.d.cts} +9 -36
  4. package/dist/copilotkit-BDDjvB-p.d.cts.map +1 -0
  5. package/dist/{copilotkit-9l47K1Ot.cjs → copilotkit-BkcqmpWt.cjs} +163 -282
  6. package/dist/copilotkit-BkcqmpWt.cjs.map +1 -0
  7. package/dist/{copilotkit-a2pL_KeT.mjs → copilotkit-C7n8Umv9.mjs} +165 -278
  8. package/dist/copilotkit-C7n8Umv9.mjs.map +1 -0
  9. package/dist/index.cjs +4 -9
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.mts +1 -1
  13. package/dist/index.mjs +4 -9
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/index.umd.js +144 -233
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/v2/index.cjs +1 -2
  18. package/dist/v2/index.d.cts +2 -2
  19. package/dist/v2/index.d.mts +2 -2
  20. package/dist/v2/index.mjs +2 -2
  21. package/dist/v2/index.umd.js +166 -282
  22. package/dist/v2/index.umd.js.map +1 -1
  23. package/package.json +6 -6
  24. package/src/components/copilot-provider/copilot-messages.tsx +24 -39
  25. package/src/components/copilot-provider/copilotkit-props.tsx +5 -9
  26. package/src/components/copilot-provider/copilotkit.tsx +1 -4
  27. package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +16 -27
  28. package/src/hooks/use-copilot-chat_internal.ts +4 -15
  29. package/src/v2/__tests__/utils/test-helpers.tsx +7 -40
  30. package/src/v2/components/chat/CopilotChat.tsx +1 -1
  31. package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +15 -18
  32. package/src/v2/components/chat/CopilotChatMessageView.tsx +2 -7
  33. package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +4 -17
  34. package/src/v2/components/chat/CopilotChatUserMessage.tsx +10 -13
  35. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +5 -131
  36. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +0 -60
  37. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +1 -1
  38. package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +2 -5
  39. package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +2 -5
  40. package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +1 -55
  41. package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +0 -8
  42. package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +10 -10
  43. package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +2 -13
  44. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +4 -23
  45. package/src/v2/hooks/index.ts +0 -1
  46. package/src/v2/hooks/use-agent.tsx +10 -157
  47. package/src/v2/hooks/use-interrupt.tsx +1 -10
  48. package/src/v2/hooks/use-render-activity-message.tsx +3 -9
  49. package/src/v2/hooks/use-render-custom-messages.tsx +1 -6
  50. package/src/v2/providers/CopilotKitProvider.tsx +2 -6
  51. package/dist/copilotkit-9_JxoZgF.d.cts.map +0 -1
  52. package/dist/copilotkit-9l47K1Ot.cjs.map +0 -1
  53. package/dist/copilotkit-Dcf7Lkjb.d.mts.map +0 -1
  54. package/dist/copilotkit-a2pL_KeT.mjs.map +0 -1
  55. package/src/components/copilot-provider/__tests__/error-visibility-prod.test.tsx +0 -70
  56. package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.tsx +0 -241
  57. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +0 -327
  58. package/src/v2/hooks/__tests__/use-capabilities.test.tsx +0 -76
  59. package/src/v2/hooks/use-capabilities.tsx +0 -25
@@ -3108,7 +3108,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3108
3108
  }, [value, warningMessage]);
3109
3109
  return value;
3110
3110
  }
3111
- const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor }) => {
3111
+ const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor }) => {
3112
3112
  var _openGenerativeUI$des;
3113
3113
  const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
3114
3114
  const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
@@ -3170,7 +3170,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3170
3170
  ...selfManagedAgents
3171
3171
  }), [agents, selfManagedAgents]);
3172
3172
  const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
3173
- const headers = typeof headersProp === "function" ? headersProp() : headersProp;
3174
3173
  const mergedHeaders = (0, react.useMemo)(() => {
3175
3174
  if (!resolvedPublicKey) return headers;
3176
3175
  if (headers[HEADER_NAME]) return headers;
@@ -3532,204 +3531,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3532
3531
  ]);
3533
3532
  }
3534
3533
 
3535
- //#endregion
3536
- //#region src/v2/hooks/use-agent.tsx
3537
- let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
3538
- UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
3539
- UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
3540
- UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
3541
- return UseAgentUpdate;
3542
- }({});
3543
- const ALL_UPDATES = [
3544
- UseAgentUpdate.OnMessagesChanged,
3545
- UseAgentUpdate.OnStateChanged,
3546
- UseAgentUpdate.OnRunStatusChanged
3547
- ];
3548
- /**
3549
- * Clone a registry agent for per-thread isolation.
3550
- * Copies agent configuration (transport, headers, etc.) but resets conversation
3551
- * state (messages, threadId, state) so each thread starts fresh.
3552
- */
3553
- function cloneForThread(source, threadId, headers) {
3554
- const clone = source.clone();
3555
- if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
3556
- clone.threadId = threadId;
3557
- clone.setMessages([]);
3558
- clone.setState({});
3559
- if (clone instanceof _ag_ui_client.HttpAgent) clone.headers = { ...headers };
3560
- return clone;
3561
- }
3562
- /**
3563
- * Module-level WeakMap: registryAgent → (threadId → clone).
3564
- * Shared across all useAgent() calls so that every component using the same
3565
- * (agentId, threadId) pair receives the same agent instance. Using WeakMap
3566
- * ensures the clone map is garbage-collected when the registry agent is
3567
- * replaced (e.g. after reconnect or hot-reload).
3568
- */
3569
- const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
3570
- /**
3571
- * Look up an existing per-thread clone without creating one.
3572
- * Returns undefined when no clone has been created yet for this pair.
3573
- */
3574
- function getThreadClone(registryAgent, threadId) {
3575
- var _globalThreadCloneMap;
3576
- if (!registryAgent || !threadId) return void 0;
3577
- return (_globalThreadCloneMap = globalThreadCloneMap.get(registryAgent)) === null || _globalThreadCloneMap === void 0 ? void 0 : _globalThreadCloneMap.get(threadId);
3578
- }
3579
- function getOrCreateThreadClone(existing, threadId, headers) {
3580
- let byThread = globalThreadCloneMap.get(existing);
3581
- if (!byThread) {
3582
- byThread = /* @__PURE__ */ new Map();
3583
- globalThreadCloneMap.set(existing, byThread);
3584
- }
3585
- const cached = byThread.get(threadId);
3586
- if (cached) return cached;
3587
- const clone = cloneForThread(existing, threadId, headers);
3588
- byThread.set(threadId, clone);
3589
- return clone;
3590
- }
3591
- function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
3592
- var _agentId, _threadId;
3593
- (_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
3594
- const { copilotkit } = useCopilotKit();
3595
- const providerThrottleMs = copilotkit.defaultThrottleMs;
3596
- const chatConfig = useCopilotChatConfiguration();
3597
- (_threadId = threadId) !== null && _threadId !== void 0 || (threadId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.threadId);
3598
- const effectiveThrottleMs = (0, react.useMemo)(() => {
3599
- var _ref;
3600
- const resolved = (_ref = throttleMs !== null && throttleMs !== void 0 ? throttleMs : providerThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
3601
- if (!Number.isFinite(resolved) || resolved < 0) {
3602
- const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
3603
- console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
3604
- return 0;
3605
- }
3606
- return resolved;
3607
- }, [throttleMs, providerThrottleMs]);
3608
- const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
3609
- const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
3610
- const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
3611
- const agent = (0, react.useMemo)(() => {
3612
- var _copilotkit$agents;
3613
- const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
3614
- const existing = copilotkit.getAgent(agentId);
3615
- if (existing) {
3616
- provisionalAgentCache.current.delete(cacheKey);
3617
- provisionalAgentCache.current.delete(agentId);
3618
- if (!threadId) return existing;
3619
- return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
3620
- }
3621
- const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
3622
- const status = copilotkit.runtimeConnectionStatus;
3623
- if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
3624
- const cached = provisionalAgentCache.current.get(cacheKey);
3625
- if (cached) {
3626
- cached.headers = { ...copilotkit.headers };
3627
- return cached;
3628
- }
3629
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
3630
- runtimeUrl: copilotkit.runtimeUrl,
3631
- agentId,
3632
- transport: copilotkit.runtimeTransport,
3633
- runtimeMode: "pending"
3634
- });
3635
- provisional.headers = { ...copilotkit.headers };
3636
- if (threadId) provisional.threadId = threadId;
3637
- provisionalAgentCache.current.set(cacheKey, provisional);
3638
- return provisional;
3639
- }
3640
- if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
3641
- const cached = provisionalAgentCache.current.get(cacheKey);
3642
- if (cached) {
3643
- cached.headers = { ...copilotkit.headers };
3644
- return cached;
3645
- }
3646
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
3647
- runtimeUrl: copilotkit.runtimeUrl,
3648
- agentId,
3649
- transport: copilotkit.runtimeTransport,
3650
- runtimeMode: "pending"
3651
- });
3652
- provisional.headers = { ...copilotkit.headers };
3653
- if (threadId) provisional.threadId = threadId;
3654
- provisionalAgentCache.current.set(cacheKey, provisional);
3655
- return provisional;
3656
- }
3657
- const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
3658
- const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
3659
- throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
3660
- }, [
3661
- agentId,
3662
- threadId,
3663
- copilotkit.agents,
3664
- copilotkit.runtimeConnectionStatus,
3665
- copilotkit.runtimeUrl,
3666
- copilotkit.runtimeTransport,
3667
- JSON.stringify(copilotkit.headers)
3668
- ]);
3669
- (0, react.useEffect)(() => {
3670
- if (updateFlags.length === 0) return;
3671
- const handlers = {};
3672
- let timerId = null;
3673
- let active = true;
3674
- let batchScheduled = false;
3675
- const batchedForceUpdate = () => {
3676
- if (!active) return;
3677
- if (!batchScheduled) {
3678
- batchScheduled = true;
3679
- queueMicrotask(() => {
3680
- batchScheduled = false;
3681
- if (active) forceUpdate();
3682
- });
3683
- }
3684
- };
3685
- if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
3686
- const ms = effectiveThrottleMs;
3687
- if (ms > 0) {
3688
- let throttleActive = false;
3689
- let pending = false;
3690
- const throttledNotify = () => {
3691
- if (!active) return;
3692
- if (!throttleActive) {
3693
- throttleActive = true;
3694
- pending = false;
3695
- forceUpdate();
3696
- timerId = setTimeout(function trailingEdge() {
3697
- timerId = null;
3698
- if (active && pending) {
3699
- pending = false;
3700
- forceUpdate();
3701
- timerId = setTimeout(trailingEdge, ms);
3702
- } else throttleActive = false;
3703
- }, ms);
3704
- } else pending = true;
3705
- };
3706
- handlers.onMessagesChanged = throttledNotify;
3707
- } else handlers.onMessagesChanged = forceUpdate;
3708
- }
3709
- if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
3710
- if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
3711
- handlers.onRunInitialized = batchedForceUpdate;
3712
- handlers.onRunFinalized = batchedForceUpdate;
3713
- handlers.onRunFailed = batchedForceUpdate;
3714
- }
3715
- const subscription = agent.subscribe(handlers);
3716
- return () => {
3717
- active = false;
3718
- if (timerId !== null) clearTimeout(timerId);
3719
- subscription.unsubscribe();
3720
- };
3721
- }, [
3722
- agent,
3723
- forceUpdate,
3724
- effectiveThrottleMs,
3725
- updateFlags
3726
- ]);
3727
- (0, react.useEffect)(() => {
3728
- if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
3729
- }, [agent, JSON.stringify(copilotkit.headers)]);
3730
- return { agent };
3731
- }
3732
-
3733
3534
  //#endregion
3734
3535
  //#region src/v2/hooks/use-render-custom-messages.tsx
3735
3536
  function useRenderCustomMessages() {
@@ -3743,13 +3544,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3743
3544
  return aHasAgent ? -1 : 1;
3744
3545
  });
3745
3546
  return function(params) {
3746
- var _copilotkit$getRunIdF, _getThreadClone;
3547
+ var _copilotkit$getRunIdF;
3747
3548
  if (!customMessageRenderers.length) return null;
3748
3549
  const { message, position } = params;
3749
3550
  const resolvedRunId = (_copilotkit$getRunIdF = copilotkit.getRunIdForMessage(agentId, threadId, message.id)) !== null && _copilotkit$getRunIdF !== void 0 ? _copilotkit$getRunIdF : copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
3750
3551
  const runId = resolvedRunId !== null && resolvedRunId !== void 0 ? resolvedRunId : `missing-run-id:${message.id}`;
3751
- const registryAgent = copilotkit.getAgent(agentId);
3752
- const agent = (_getThreadClone = getThreadClone(registryAgent, threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
3552
+ const agent = copilotkit.getAgent(agentId);
3753
3553
  if (!agent) throw new Error("Agent not found");
3754
3554
  const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
3755
3555
  const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
@@ -3792,7 +3592,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3792
3592
  return (_ref = (_ref2 = (_matches$find = matches.find((candidate) => candidate.agentId === agentId)) !== null && _matches$find !== void 0 ? _matches$find : matches.find((candidate) => candidate.agentId === void 0)) !== null && _ref2 !== void 0 ? _ref2 : renderers.find((candidate) => candidate.activityType === "*")) !== null && _ref !== void 0 ? _ref : null;
3793
3593
  }, [agentId, renderers]);
3794
3594
  const renderActivityMessage = (0, react.useCallback)((message) => {
3795
- var _getThreadClone;
3796
3595
  const renderer = findRenderer(message.activityType);
3797
3596
  if (!renderer) return null;
3798
3597
  const parseResult = renderer.content.safeParse(message.content);
@@ -3801,8 +3600,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3801
3600
  return null;
3802
3601
  }
3803
3602
  const Component = renderer.render;
3804
- const registryAgent = copilotkit.getAgent(agentId);
3805
- const agent = (_getThreadClone = getThreadClone(registryAgent, config === null || config === void 0 ? void 0 : config.threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
3603
+ const agent = copilotkit.getAgent(agentId);
3806
3604
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
3807
3605
  activityType: message.activityType,
3808
3606
  content: parseResult.data,
@@ -3811,7 +3609,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3811
3609
  }, message.id);
3812
3610
  }, [
3813
3611
  agentId,
3814
- config === null || config === void 0 ? void 0 : config.threadId,
3815
3612
  copilotkit,
3816
3613
  findRenderer
3817
3614
  ]);
@@ -4253,21 +4050,130 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4253
4050
  }
4254
4051
 
4255
4052
  //#endregion
4256
- //#region src/v2/hooks/use-capabilities.tsx
4257
- /**
4258
- * Returns the capabilities declared by the given agent (or the default agent).
4259
- * Capabilities are populated from the runtime `/info` response at connection
4260
- * time. The hook reads them synchronously from the agent instance — there is
4261
- * no separate loading state, but the value will be `undefined` until the
4262
- * runtime handshake completes.
4263
- *
4264
- * @param agentId - Optional agent ID. If omitted, uses the default agent.
4265
- * @returns The agent's capabilities, or `undefined` if the agent doesn't
4266
- * declare capabilities.
4267
- */
4268
- function useCapabilities(agentId) {
4269
- const { agent } = useAgent({ agentId });
4270
- if (agent && "capabilities" in agent) return agent.capabilities;
4053
+ //#region src/v2/hooks/use-agent.tsx
4054
+ let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
4055
+ UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
4056
+ UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
4057
+ UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
4058
+ return UseAgentUpdate;
4059
+ }({});
4060
+ const ALL_UPDATES = [
4061
+ UseAgentUpdate.OnMessagesChanged,
4062
+ UseAgentUpdate.OnStateChanged,
4063
+ UseAgentUpdate.OnRunStatusChanged
4064
+ ];
4065
+ function useAgent({ agentId, updates, throttleMs } = {}) {
4066
+ var _agentId;
4067
+ (_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
4068
+ const { copilotkit } = useCopilotKit();
4069
+ const providerThrottleMs = copilotkit.defaultThrottleMs;
4070
+ const effectiveThrottleMs = (0, react.useMemo)(() => {
4071
+ var _ref;
4072
+ const resolved = (_ref = throttleMs !== null && throttleMs !== void 0 ? throttleMs : providerThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
4073
+ if (!Number.isFinite(resolved) || resolved < 0) {
4074
+ const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
4075
+ console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
4076
+ return 0;
4077
+ }
4078
+ return resolved;
4079
+ }, [throttleMs, providerThrottleMs]);
4080
+ const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
4081
+ const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
4082
+ const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
4083
+ const agent = (0, react.useMemo)(() => {
4084
+ var _copilotkit$agents;
4085
+ const existing = copilotkit.getAgent(agentId);
4086
+ if (existing) {
4087
+ provisionalAgentCache.current.delete(agentId);
4088
+ return existing;
4089
+ }
4090
+ const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
4091
+ const status = copilotkit.runtimeConnectionStatus;
4092
+ if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
4093
+ const cached = provisionalAgentCache.current.get(agentId);
4094
+ if (cached) {
4095
+ cached.headers = { ...copilotkit.headers };
4096
+ return cached;
4097
+ }
4098
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
4099
+ runtimeUrl: copilotkit.runtimeUrl,
4100
+ agentId,
4101
+ transport: copilotkit.runtimeTransport,
4102
+ runtimeMode: "pending"
4103
+ });
4104
+ provisional.headers = { ...copilotkit.headers };
4105
+ provisionalAgentCache.current.set(agentId, provisional);
4106
+ return provisional;
4107
+ }
4108
+ if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
4109
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
4110
+ runtimeUrl: copilotkit.runtimeUrl,
4111
+ agentId,
4112
+ transport: copilotkit.runtimeTransport,
4113
+ runtimeMode: "pending"
4114
+ });
4115
+ provisional.headers = { ...copilotkit.headers };
4116
+ return provisional;
4117
+ }
4118
+ const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
4119
+ const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
4120
+ throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
4121
+ }, [
4122
+ agentId,
4123
+ copilotkit.agents,
4124
+ copilotkit.runtimeConnectionStatus,
4125
+ copilotkit.runtimeUrl,
4126
+ copilotkit.runtimeTransport,
4127
+ JSON.stringify(copilotkit.headers)
4128
+ ]);
4129
+ (0, react.useEffect)(() => {
4130
+ if (updateFlags.length === 0) return;
4131
+ const handlers = {};
4132
+ let timerId = null;
4133
+ let active = true;
4134
+ if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
4135
+ const ms = effectiveThrottleMs;
4136
+ if (ms > 0) {
4137
+ let throttleActive = false;
4138
+ let pending = false;
4139
+ const throttledNotify = () => {
4140
+ if (!active) return;
4141
+ if (!throttleActive) {
4142
+ throttleActive = true;
4143
+ pending = false;
4144
+ forceUpdate();
4145
+ timerId = setTimeout(function trailingEdge() {
4146
+ timerId = null;
4147
+ if (active && pending) {
4148
+ pending = false;
4149
+ forceUpdate();
4150
+ timerId = setTimeout(trailingEdge, ms);
4151
+ } else throttleActive = false;
4152
+ }, ms);
4153
+ } else pending = true;
4154
+ };
4155
+ handlers.onMessagesChanged = throttledNotify;
4156
+ } else handlers.onMessagesChanged = forceUpdate;
4157
+ }
4158
+ if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
4159
+ if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
4160
+ handlers.onRunInitialized = forceUpdate;
4161
+ handlers.onRunFinalized = forceUpdate;
4162
+ handlers.onRunFailed = forceUpdate;
4163
+ }
4164
+ const subscription = agent.subscribe(handlers);
4165
+ return () => {
4166
+ active = false;
4167
+ if (timerId !== null) clearTimeout(timerId);
4168
+ subscription.unsubscribe();
4169
+ };
4170
+ }, [
4171
+ agent,
4172
+ forceUpdate,
4173
+ effectiveThrottleMs,
4174
+ updateFlags
4175
+ ]);
4176
+ return { agent };
4271
4177
  }
4272
4178
 
4273
4179
  //#endregion
@@ -4535,10 +4441,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4535
4441
  * ```
4536
4442
  */
4537
4443
  function useInterrupt(config) {
4538
- var _config$agent;
4539
4444
  const { copilotkit } = useCopilotKit();
4540
- const { agent: internalAgent } = useAgent({ agentId: config.agentId });
4541
- const agent = (_config$agent = config.agent) !== null && _config$agent !== void 0 ? _config$agent : internalAgent;
4445
+ const { agent } = useAgent({ agentId: config.agentId });
4542
4446
  const [pendingEvent, setPendingEvent] = (0, react.useState)(null);
4543
4447
  const pendingEventRef = (0, react.useRef)(pendingEvent);
4544
4448
  pendingEventRef.current = pendingEvent;
@@ -4949,8 +4853,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4949
4853
  useKatexStyles();
4950
4854
  const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
4951
4855
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
4952
- if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
4953
- return false;
4856
+ if (message.content) try {
4857
+ await navigator.clipboard.writeText(message.content);
4858
+ } catch (err) {
4859
+ console.error("Failed to copy message:", err);
4860
+ }
4954
4861
  } });
4955
4862
  const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp });
4956
4863
  const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown });
@@ -5050,17 +4957,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5050
4957
  if (timerRef.current !== null) clearTimeout(timerRef.current);
5051
4958
  };
5052
4959
  }, []);
5053
- const handleClick = async (event) => {
5054
- let success = false;
5055
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5056
- if (success) {
5057
- setCopied(true);
5058
- if (timerRef.current !== null) clearTimeout(timerRef.current);
5059
- timerRef.current = setTimeout(() => {
5060
- timerRef.current = null;
5061
- setCopied(false);
5062
- }, 2e3);
5063
- }
4960
+ const handleClick = (event) => {
4961
+ setCopied(true);
4962
+ if (timerRef.current !== null) clearTimeout(timerRef.current);
4963
+ timerRef.current = setTimeout(() => {
4964
+ timerRef.current = null;
4965
+ setCopied(false);
4966
+ }, 2e3);
4967
+ if (onClick) onClick(event);
5064
4968
  };
5065
4969
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
5066
4970
  "data-testid": "copilot-copy-button",
@@ -5222,8 +5126,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5222
5126
  const mediaParts = (0, react.useMemo)(() => getMediaParts(message.content), [message.content]);
5223
5127
  const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
5224
5128
  const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
5225
- if (flattenedContent) return await (0, _copilotkit_shared.copyToClipboard)(flattenedContent);
5226
- return false;
5129
+ if (flattenedContent) try {
5130
+ await navigator.clipboard.writeText(flattenedContent);
5131
+ } catch (err) {
5132
+ console.error("Failed to copy message:", err);
5133
+ }
5227
5134
  } });
5228
5135
  const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage === null || onEditMessage === void 0 ? void 0 : onEditMessage({ message }) });
5229
5136
  const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
@@ -5313,13 +5220,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5313
5220
  const config = useCopilotChatConfiguration();
5314
5221
  const labels = (_config$labels = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels !== void 0 ? _config$labels : CopilotChatDefaultLabels;
5315
5222
  const [copied, setCopied] = (0, react.useState)(false);
5316
- const handleClick = async (event) => {
5317
- let success = false;
5318
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5319
- if (success) {
5320
- setCopied(true);
5321
- setTimeout(() => setCopied(false), 2e3);
5322
- }
5223
+ const handleClick = (event) => {
5224
+ setCopied(true);
5225
+ setTimeout(() => setCopied(false), 2e3);
5226
+ if (onClick) onClick(event);
5323
5227
  };
5324
5228
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
5325
5229
  "data-testid": "copilot-user-copy-button",
@@ -5429,24 +5333,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5429
5333
  return () => clearInterval(timer);
5430
5334
  }, [isStreaming]);
5431
5335
  const [isOpen, setIsOpen] = (0, react.useState)(isStreaming);
5432
- const userToggledRef = (0, react.useRef)(false);
5433
5336
  (0, react.useEffect)(() => {
5434
- if (isStreaming) {
5435
- userToggledRef.current = false;
5436
- setIsOpen(true);
5437
- } else if (!userToggledRef.current) setIsOpen(false);
5337
+ if (isStreaming) setIsOpen(true);
5338
+ else setIsOpen(false);
5438
5339
  }, [isStreaming]);
5439
- const handleToggle = hasContent ? () => {
5440
- userToggledRef.current = true;
5441
- setIsOpen((prev) => !prev);
5442
- } : void 0;
5443
5340
  const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
5444
5341
  const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
5445
5342
  isOpen,
5446
5343
  label,
5447
5344
  hasContent,
5448
5345
  isStreaming,
5449
- onClick: handleToggle
5346
+ onClick: hasContent ? () => setIsOpen((prev) => !prev) : void 0
5450
5347
  });
5451
5348
  const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
5452
5349
  isStreaming,
@@ -5797,16 +5694,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5797
5694
  const config = useCopilotChatConfiguration();
5798
5695
  const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
5799
5696
  (0, react.useEffect)(() => {
5800
- var _getThreadClone;
5801
5697
  if (!(config === null || config === void 0 ? void 0 : config.agentId)) return;
5802
- const registryAgent = copilotkit.getAgent(config.agentId);
5803
- const agent = (_getThreadClone = getThreadClone(registryAgent, config.threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
5698
+ const agent = copilotkit.getAgent(config.agentId);
5804
5699
  if (!agent) return;
5805
5700
  const subscription = agent.subscribe({ onStateChanged: forceUpdate });
5806
5701
  return () => subscription.unsubscribe();
5807
5702
  }, [
5808
5703
  config === null || config === void 0 ? void 0 : config.agentId,
5809
- config === null || config === void 0 ? void 0 : config.threadId,
5810
5704
  copilotkit,
5811
5705
  forceUpdate
5812
5706
  ]);
@@ -6757,7 +6651,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6757
6651
  }, [threadId, existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId]);
6758
6652
  const { agent } = useAgent({
6759
6653
  agentId: resolvedAgentId,
6760
- threadId: resolvedThreadId,
6761
6654
  throttleMs
6762
6655
  });
6763
6656
  const { copilotkit } = useCopilotKit();
@@ -6808,6 +6701,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6808
6701
  console.error("CopilotChat: connectAgent failed", error);
6809
6702
  }
6810
6703
  };
6704
+ agent.threadId = resolvedThreadId;
6811
6705
  connect(agent);
6812
6706
  return () => {
6813
6707
  detached = true;
@@ -8178,20 +8072,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8178
8072
  /**
8179
8073
  * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
8180
8074
  */
8181
- /**
8182
- * Determine whether a GraphQL error should be suppressed based on its visibility
8183
- * and whether the dev console is active.
8184
- *
8185
- * Returns `null` when the error should be surfaced to the UI, or a log prefix
8186
- * string when the error should be suppressed (logged to console only).
8187
- *
8188
- * Exported for unit testing.
8189
- */
8190
- function getErrorSuppression(visibility, isDev) {
8191
- if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
8192
- if (!isDev && visibility === _copilotkit_shared.ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
8193
- return null;
8194
- }
8195
8075
  const MessagesTapContext = (0, react.createContext)(null);
8196
8076
  function useMessagesTap() {
8197
8077
  const tap = (0, react.useContext)(MessagesTapContext);
@@ -8276,9 +8156,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8276
8156
  const graphQLErrors = error.graphQLErrors;
8277
8157
  const routeError = (gqlError) => {
8278
8158
  const extensions = gqlError.extensions;
8279
- const suppression = getErrorSuppression(extensions === null || extensions === void 0 ? void 0 : extensions.visibility, shouldShowDevConsole(showDevConsole));
8280
- if (suppression) {
8281
- console.error(suppression, gqlError.message);
8159
+ const visibility = extensions === null || extensions === void 0 ? void 0 : extensions.visibility;
8160
+ if (!shouldShowDevConsole(showDevConsole)) {
8161
+ console.error("CopilotKit Error (hidden in production):", gqlError.message);
8162
+ return;
8163
+ }
8164
+ if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) {
8165
+ console.error("CopilotKit Silent Error:", gqlError.message);
8282
8166
  return;
8283
8167
  }
8284
8168
  const ckError = createStructuredError(gqlError);
@@ -8295,7 +8179,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8295
8179
  }
8296
8180
  };
8297
8181
  graphQLErrors.forEach(routeError);
8298
- } else {
8182
+ } else if (!shouldShowDevConsole(showDevConsole)) console.error("CopilotKit Error (hidden in production):", error);
8183
+ else {
8299
8184
  const fallbackError = new _copilotkit_shared.CopilotKitError({
8300
8185
  message: (error === null || error === void 0 ? void 0 : error.message) || String(error),
8301
8186
  code: _copilotkit_shared.CopilotKitErrorCode.UNKNOWN
@@ -9275,7 +9160,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
9275
9160
  publicApiKey,
9276
9161
  ...cloud ? { cloud } : {},
9277
9162
  chatApiEndpoint,
9278
- headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
9163
+ headers: props.headers || {},
9279
9164
  properties: props.properties || {},
9280
9165
  transcribeAudioUrl: props.transcribeAudioUrl,
9281
9166
  textToSpeechUrl: props.textToSpeechUrl,
@@ -9692,7 +9577,6 @@ exports.defineToolCallRenderer = defineToolCallRenderer;
9692
9577
  exports.useAgent = useAgent;
9693
9578
  exports.useAgentContext = useAgentContext;
9694
9579
  exports.useAttachments = useAttachments;
9695
- exports.useCapabilities = useCapabilities;
9696
9580
  exports.useComponent = useComponent;
9697
9581
  exports.useConfigureSuggestions = useConfigureSuggestions;
9698
9582
  exports.useCopilotChatConfiguration = useCopilotChatConfiguration;