@copilotkit/react-core 1.55.3-canary.1776243725 → 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 (58) hide show
  1. package/dist/{copilotkit-opur-20s.d.mts → copilotkit-3mXoM0Hd.d.mts} +9 -29
  2. package/dist/copilotkit-3mXoM0Hd.d.mts.map +1 -0
  3. package/dist/{copilotkit-EfopO2gn.d.cts → copilotkit-BDDjvB-p.d.cts} +9 -29
  4. package/dist/copilotkit-BDDjvB-p.d.cts.map +1 -0
  5. package/dist/{copilotkit-BoOnQHlE.cjs → copilotkit-BkcqmpWt.cjs} +162 -280
  6. package/dist/copilotkit-BkcqmpWt.cjs.map +1 -0
  7. package/dist/{copilotkit-Bm4ox8G0.mjs → copilotkit-C7n8Umv9.mjs} +164 -276
  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 +143 -230
  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 +165 -279
  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-render-activity-message.tsx +3 -9
  48. package/src/v2/hooks/use-render-custom-messages.tsx +1 -6
  49. package/src/v2/providers/CopilotKitProvider.tsx +2 -6
  50. package/dist/copilotkit-Bm4ox8G0.mjs.map +0 -1
  51. package/dist/copilotkit-BoOnQHlE.cjs.map +0 -1
  52. package/dist/copilotkit-EfopO2gn.d.cts.map +0 -1
  53. package/dist/copilotkit-opur-20s.d.mts.map +0 -1
  54. package/src/components/copilot-provider/__tests__/error-visibility-prod.test.tsx +0 -70
  55. package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.tsx +0 -241
  56. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +0 -327
  57. package/src/v2/hooks/__tests__/use-capabilities.test.tsx +0 -76
  58. 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
@@ -4947,8 +4853,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4947
4853
  useKatexStyles();
4948
4854
  const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
4949
4855
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
4950
- if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
4951
- 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
+ }
4952
4861
  } });
4953
4862
  const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp });
4954
4863
  const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown });
@@ -5048,17 +4957,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5048
4957
  if (timerRef.current !== null) clearTimeout(timerRef.current);
5049
4958
  };
5050
4959
  }, []);
5051
- const handleClick = async (event) => {
5052
- let success = false;
5053
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5054
- if (success) {
5055
- setCopied(true);
5056
- if (timerRef.current !== null) clearTimeout(timerRef.current);
5057
- timerRef.current = setTimeout(() => {
5058
- timerRef.current = null;
5059
- setCopied(false);
5060
- }, 2e3);
5061
- }
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);
5062
4968
  };
5063
4969
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
5064
4970
  "data-testid": "copilot-copy-button",
@@ -5220,8 +5126,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5220
5126
  const mediaParts = (0, react.useMemo)(() => getMediaParts(message.content), [message.content]);
5221
5127
  const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
5222
5128
  const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
5223
- if (flattenedContent) return await (0, _copilotkit_shared.copyToClipboard)(flattenedContent);
5224
- return false;
5129
+ if (flattenedContent) try {
5130
+ await navigator.clipboard.writeText(flattenedContent);
5131
+ } catch (err) {
5132
+ console.error("Failed to copy message:", err);
5133
+ }
5225
5134
  } });
5226
5135
  const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage === null || onEditMessage === void 0 ? void 0 : onEditMessage({ message }) });
5227
5136
  const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
@@ -5311,13 +5220,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5311
5220
  const config = useCopilotChatConfiguration();
5312
5221
  const labels = (_config$labels = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels !== void 0 ? _config$labels : CopilotChatDefaultLabels;
5313
5222
  const [copied, setCopied] = (0, react.useState)(false);
5314
- const handleClick = async (event) => {
5315
- let success = false;
5316
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5317
- if (success) {
5318
- setCopied(true);
5319
- setTimeout(() => setCopied(false), 2e3);
5320
- }
5223
+ const handleClick = (event) => {
5224
+ setCopied(true);
5225
+ setTimeout(() => setCopied(false), 2e3);
5226
+ if (onClick) onClick(event);
5321
5227
  };
5322
5228
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
5323
5229
  "data-testid": "copilot-user-copy-button",
@@ -5427,24 +5333,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5427
5333
  return () => clearInterval(timer);
5428
5334
  }, [isStreaming]);
5429
5335
  const [isOpen, setIsOpen] = (0, react.useState)(isStreaming);
5430
- const userToggledRef = (0, react.useRef)(false);
5431
5336
  (0, react.useEffect)(() => {
5432
- if (isStreaming) {
5433
- userToggledRef.current = false;
5434
- setIsOpen(true);
5435
- } else if (!userToggledRef.current) setIsOpen(false);
5337
+ if (isStreaming) setIsOpen(true);
5338
+ else setIsOpen(false);
5436
5339
  }, [isStreaming]);
5437
- const handleToggle = hasContent ? () => {
5438
- userToggledRef.current = true;
5439
- setIsOpen((prev) => !prev);
5440
- } : void 0;
5441
5340
  const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
5442
5341
  const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
5443
5342
  isOpen,
5444
5343
  label,
5445
5344
  hasContent,
5446
5345
  isStreaming,
5447
- onClick: handleToggle
5346
+ onClick: hasContent ? () => setIsOpen((prev) => !prev) : void 0
5448
5347
  });
5449
5348
  const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
5450
5349
  isStreaming,
@@ -5795,16 +5694,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5795
5694
  const config = useCopilotChatConfiguration();
5796
5695
  const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
5797
5696
  (0, react.useEffect)(() => {
5798
- var _getThreadClone;
5799
5697
  if (!(config === null || config === void 0 ? void 0 : config.agentId)) return;
5800
- const registryAgent = copilotkit.getAgent(config.agentId);
5801
- const agent = (_getThreadClone = getThreadClone(registryAgent, config.threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
5698
+ const agent = copilotkit.getAgent(config.agentId);
5802
5699
  if (!agent) return;
5803
5700
  const subscription = agent.subscribe({ onStateChanged: forceUpdate });
5804
5701
  return () => subscription.unsubscribe();
5805
5702
  }, [
5806
5703
  config === null || config === void 0 ? void 0 : config.agentId,
5807
- config === null || config === void 0 ? void 0 : config.threadId,
5808
5704
  copilotkit,
5809
5705
  forceUpdate
5810
5706
  ]);
@@ -6755,7 +6651,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6755
6651
  }, [threadId, existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId]);
6756
6652
  const { agent } = useAgent({
6757
6653
  agentId: resolvedAgentId,
6758
- threadId: resolvedThreadId,
6759
6654
  throttleMs
6760
6655
  });
6761
6656
  const { copilotkit } = useCopilotKit();
@@ -6806,6 +6701,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6806
6701
  console.error("CopilotChat: connectAgent failed", error);
6807
6702
  }
6808
6703
  };
6704
+ agent.threadId = resolvedThreadId;
6809
6705
  connect(agent);
6810
6706
  return () => {
6811
6707
  detached = true;
@@ -8176,20 +8072,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8176
8072
  /**
8177
8073
  * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
8178
8074
  */
8179
- /**
8180
- * Determine whether a GraphQL error should be suppressed based on its visibility
8181
- * and whether the dev console is active.
8182
- *
8183
- * Returns `null` when the error should be surfaced to the UI, or a log prefix
8184
- * string when the error should be suppressed (logged to console only).
8185
- *
8186
- * Exported for unit testing.
8187
- */
8188
- function getErrorSuppression(visibility, isDev) {
8189
- if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
8190
- if (!isDev && visibility === _copilotkit_shared.ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
8191
- return null;
8192
- }
8193
8075
  const MessagesTapContext = (0, react.createContext)(null);
8194
8076
  function useMessagesTap() {
8195
8077
  const tap = (0, react.useContext)(MessagesTapContext);
@@ -8274,9 +8156,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8274
8156
  const graphQLErrors = error.graphQLErrors;
8275
8157
  const routeError = (gqlError) => {
8276
8158
  const extensions = gqlError.extensions;
8277
- const suppression = getErrorSuppression(extensions === null || extensions === void 0 ? void 0 : extensions.visibility, shouldShowDevConsole(showDevConsole));
8278
- if (suppression) {
8279
- 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);
8280
8166
  return;
8281
8167
  }
8282
8168
  const ckError = createStructuredError(gqlError);
@@ -8293,7 +8179,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8293
8179
  }
8294
8180
  };
8295
8181
  graphQLErrors.forEach(routeError);
8296
- } else {
8182
+ } else if (!shouldShowDevConsole(showDevConsole)) console.error("CopilotKit Error (hidden in production):", error);
8183
+ else {
8297
8184
  const fallbackError = new _copilotkit_shared.CopilotKitError({
8298
8185
  message: (error === null || error === void 0 ? void 0 : error.message) || String(error),
8299
8186
  code: _copilotkit_shared.CopilotKitErrorCode.UNKNOWN
@@ -9273,7 +9160,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
9273
9160
  publicApiKey,
9274
9161
  ...cloud ? { cloud } : {},
9275
9162
  chatApiEndpoint,
9276
- headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
9163
+ headers: props.headers || {},
9277
9164
  properties: props.properties || {},
9278
9165
  transcribeAudioUrl: props.transcribeAudioUrl,
9279
9166
  textToSpeechUrl: props.textToSpeechUrl,
@@ -9690,7 +9577,6 @@ exports.defineToolCallRenderer = defineToolCallRenderer;
9690
9577
  exports.useAgent = useAgent;
9691
9578
  exports.useAgentContext = useAgentContext;
9692
9579
  exports.useAttachments = useAttachments;
9693
- exports.useCapabilities = useCapabilities;
9694
9580
  exports.useComponent = useComponent;
9695
9581
  exports.useConfigureSuggestions = useConfigureSuggestions;
9696
9582
  exports.useCopilotChatConfiguration = useCopilotChatConfiguration;