@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
@@ -3072,7 +3072,7 @@ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
3072
3072
  }, [value, warningMessage]);
3073
3073
  return value;
3074
3074
  }
3075
- 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 }) => {
3075
+ 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 }) => {
3076
3076
  const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
3077
3077
  const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
3078
3078
  const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = (0, react.useState)(false);
@@ -3127,7 +3127,6 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
3127
3127
  ...selfManagedAgents
3128
3128
  }), [agents, selfManagedAgents]);
3129
3129
  const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
3130
- const headers = typeof headersProp === "function" ? headersProp() : headersProp;
3131
3130
  const mergedHeaders = (0, react.useMemo)(() => {
3132
3131
  if (!resolvedPublicKey) return headers;
3133
3132
  if (headers[HEADER_NAME]) return headers;
@@ -3485,200 +3484,6 @@ function useRenderToolCall() {
3485
3484
  ]);
3486
3485
  }
3487
3486
 
3488
- //#endregion
3489
- //#region src/v2/hooks/use-agent.tsx
3490
- let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
3491
- UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
3492
- UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
3493
- UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
3494
- return UseAgentUpdate;
3495
- }({});
3496
- const ALL_UPDATES = [
3497
- UseAgentUpdate.OnMessagesChanged,
3498
- UseAgentUpdate.OnStateChanged,
3499
- UseAgentUpdate.OnRunStatusChanged
3500
- ];
3501
- /**
3502
- * Clone a registry agent for per-thread isolation.
3503
- * Copies agent configuration (transport, headers, etc.) but resets conversation
3504
- * state (messages, threadId, state) so each thread starts fresh.
3505
- */
3506
- function cloneForThread(source, threadId, headers) {
3507
- const clone = source.clone();
3508
- if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
3509
- clone.threadId = threadId;
3510
- clone.setMessages([]);
3511
- clone.setState({});
3512
- if (clone instanceof _ag_ui_client.HttpAgent) clone.headers = { ...headers };
3513
- return clone;
3514
- }
3515
- /**
3516
- * Module-level WeakMap: registryAgent → (threadId → clone).
3517
- * Shared across all useAgent() calls so that every component using the same
3518
- * (agentId, threadId) pair receives the same agent instance. Using WeakMap
3519
- * ensures the clone map is garbage-collected when the registry agent is
3520
- * replaced (e.g. after reconnect or hot-reload).
3521
- */
3522
- const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
3523
- /**
3524
- * Look up an existing per-thread clone without creating one.
3525
- * Returns undefined when no clone has been created yet for this pair.
3526
- */
3527
- function getThreadClone(registryAgent, threadId) {
3528
- if (!registryAgent || !threadId) return void 0;
3529
- return globalThreadCloneMap.get(registryAgent)?.get(threadId);
3530
- }
3531
- function getOrCreateThreadClone(existing, threadId, headers) {
3532
- let byThread = globalThreadCloneMap.get(existing);
3533
- if (!byThread) {
3534
- byThread = /* @__PURE__ */ new Map();
3535
- globalThreadCloneMap.set(existing, byThread);
3536
- }
3537
- const cached = byThread.get(threadId);
3538
- if (cached) return cached;
3539
- const clone = cloneForThread(existing, threadId, headers);
3540
- byThread.set(threadId, clone);
3541
- return clone;
3542
- }
3543
- function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
3544
- agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
3545
- const { copilotkit } = useCopilotKit();
3546
- const providerThrottleMs = copilotkit.defaultThrottleMs;
3547
- const chatConfig = useCopilotChatConfiguration();
3548
- threadId ??= chatConfig?.threadId;
3549
- const effectiveThrottleMs = (0, react.useMemo)(() => {
3550
- const resolved = throttleMs ?? providerThrottleMs ?? 0;
3551
- if (!Number.isFinite(resolved) || resolved < 0) {
3552
- const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
3553
- console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
3554
- return 0;
3555
- }
3556
- return resolved;
3557
- }, [throttleMs, providerThrottleMs]);
3558
- const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
3559
- const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
3560
- const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
3561
- const agent = (0, react.useMemo)(() => {
3562
- const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
3563
- const existing = copilotkit.getAgent(agentId);
3564
- if (existing) {
3565
- provisionalAgentCache.current.delete(cacheKey);
3566
- provisionalAgentCache.current.delete(agentId);
3567
- if (!threadId) return existing;
3568
- return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
3569
- }
3570
- const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
3571
- const status = copilotkit.runtimeConnectionStatus;
3572
- if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
3573
- const cached = provisionalAgentCache.current.get(cacheKey);
3574
- if (cached) {
3575
- cached.headers = { ...copilotkit.headers };
3576
- return cached;
3577
- }
3578
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
3579
- runtimeUrl: copilotkit.runtimeUrl,
3580
- agentId,
3581
- transport: copilotkit.runtimeTransport,
3582
- runtimeMode: "pending"
3583
- });
3584
- provisional.headers = { ...copilotkit.headers };
3585
- if (threadId) provisional.threadId = threadId;
3586
- provisionalAgentCache.current.set(cacheKey, provisional);
3587
- return provisional;
3588
- }
3589
- if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
3590
- const cached = provisionalAgentCache.current.get(cacheKey);
3591
- if (cached) {
3592
- cached.headers = { ...copilotkit.headers };
3593
- return cached;
3594
- }
3595
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
3596
- runtimeUrl: copilotkit.runtimeUrl,
3597
- agentId,
3598
- transport: copilotkit.runtimeTransport,
3599
- runtimeMode: "pending"
3600
- });
3601
- provisional.headers = { ...copilotkit.headers };
3602
- if (threadId) provisional.threadId = threadId;
3603
- provisionalAgentCache.current.set(cacheKey, provisional);
3604
- return provisional;
3605
- }
3606
- const knownAgents = Object.keys(copilotkit.agents ?? {});
3607
- const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
3608
- 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.");
3609
- }, [
3610
- agentId,
3611
- threadId,
3612
- copilotkit.agents,
3613
- copilotkit.runtimeConnectionStatus,
3614
- copilotkit.runtimeUrl,
3615
- copilotkit.runtimeTransport,
3616
- JSON.stringify(copilotkit.headers)
3617
- ]);
3618
- (0, react.useEffect)(() => {
3619
- if (updateFlags.length === 0) return;
3620
- const handlers = {};
3621
- let timerId = null;
3622
- let active = true;
3623
- let batchScheduled = false;
3624
- const batchedForceUpdate = () => {
3625
- if (!active) return;
3626
- if (!batchScheduled) {
3627
- batchScheduled = true;
3628
- queueMicrotask(() => {
3629
- batchScheduled = false;
3630
- if (active) forceUpdate();
3631
- });
3632
- }
3633
- };
3634
- if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
3635
- const ms = effectiveThrottleMs;
3636
- if (ms > 0) {
3637
- let throttleActive = false;
3638
- let pending = false;
3639
- const throttledNotify = () => {
3640
- if (!active) return;
3641
- if (!throttleActive) {
3642
- throttleActive = true;
3643
- pending = false;
3644
- forceUpdate();
3645
- timerId = setTimeout(function trailingEdge() {
3646
- timerId = null;
3647
- if (active && pending) {
3648
- pending = false;
3649
- forceUpdate();
3650
- timerId = setTimeout(trailingEdge, ms);
3651
- } else throttleActive = false;
3652
- }, ms);
3653
- } else pending = true;
3654
- };
3655
- handlers.onMessagesChanged = throttledNotify;
3656
- } else handlers.onMessagesChanged = forceUpdate;
3657
- }
3658
- if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
3659
- if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
3660
- handlers.onRunInitialized = batchedForceUpdate;
3661
- handlers.onRunFinalized = batchedForceUpdate;
3662
- handlers.onRunFailed = batchedForceUpdate;
3663
- }
3664
- const subscription = agent.subscribe(handlers);
3665
- return () => {
3666
- active = false;
3667
- if (timerId !== null) clearTimeout(timerId);
3668
- subscription.unsubscribe();
3669
- };
3670
- }, [
3671
- agent,
3672
- forceUpdate,
3673
- effectiveThrottleMs,
3674
- updateFlags
3675
- ]);
3676
- (0, react.useEffect)(() => {
3677
- if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
3678
- }, [agent, JSON.stringify(copilotkit.headers)]);
3679
- return { agent };
3680
- }
3681
-
3682
3487
  //#endregion
3683
3488
  //#region src/v2/hooks/use-render-custom-messages.tsx
3684
3489
  function useRenderCustomMessages() {
@@ -3696,8 +3501,7 @@ function useRenderCustomMessages() {
3696
3501
  const { message, position } = params;
3697
3502
  const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
3698
3503
  const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
3699
- const registryAgent = copilotkit.getAgent(agentId);
3700
- const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
3504
+ const agent = copilotkit.getAgent(agentId);
3701
3505
  if (!agent) throw new Error("Agent not found");
3702
3506
  const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
3703
3507
  const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
@@ -3729,8 +3533,7 @@ function useRenderCustomMessages() {
3729
3533
  //#region src/v2/hooks/use-render-activity-message.tsx
3730
3534
  function useRenderActivityMessage() {
3731
3535
  const { copilotkit } = useCopilotKit();
3732
- const config = useCopilotChatConfiguration();
3733
- const agentId = config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
3536
+ const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
3734
3537
  const renderers = copilotkit.renderActivityMessages;
3735
3538
  const findRenderer = (0, react.useCallback)((activityType) => {
3736
3539
  if (!renderers.length) return null;
@@ -3746,8 +3549,7 @@ function useRenderActivityMessage() {
3746
3549
  return null;
3747
3550
  }
3748
3551
  const Component = renderer.render;
3749
- const registryAgent = copilotkit.getAgent(agentId);
3750
- const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
3552
+ const agent = copilotkit.getAgent(agentId);
3751
3553
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
3752
3554
  activityType: message.activityType,
3753
3555
  content: parseResult.data,
@@ -3756,7 +3558,6 @@ function useRenderActivityMessage() {
3756
3558
  }, message.id);
3757
3559
  }, [
3758
3560
  agentId,
3759
- config?.threadId,
3760
3561
  copilotkit,
3761
3562
  findRenderer
3762
3563
  ]);
@@ -4197,21 +3998,127 @@ function useHumanInTheLoop(tool, deps) {
4197
3998
  }
4198
3999
 
4199
4000
  //#endregion
4200
- //#region src/v2/hooks/use-capabilities.tsx
4201
- /**
4202
- * Returns the capabilities declared by the given agent (or the default agent).
4203
- * Capabilities are populated from the runtime `/info` response at connection
4204
- * time. The hook reads them synchronously from the agent instance — there is
4205
- * no separate loading state, but the value will be `undefined` until the
4206
- * runtime handshake completes.
4207
- *
4208
- * @param agentId - Optional agent ID. If omitted, uses the default agent.
4209
- * @returns The agent's capabilities, or `undefined` if the agent doesn't
4210
- * declare capabilities.
4211
- */
4212
- function useCapabilities(agentId) {
4213
- const { agent } = useAgent({ agentId });
4214
- if (agent && "capabilities" in agent) return agent.capabilities;
4001
+ //#region src/v2/hooks/use-agent.tsx
4002
+ let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
4003
+ UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
4004
+ UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
4005
+ UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
4006
+ return UseAgentUpdate;
4007
+ }({});
4008
+ const ALL_UPDATES = [
4009
+ UseAgentUpdate.OnMessagesChanged,
4010
+ UseAgentUpdate.OnStateChanged,
4011
+ UseAgentUpdate.OnRunStatusChanged
4012
+ ];
4013
+ function useAgent({ agentId, updates, throttleMs } = {}) {
4014
+ agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
4015
+ const { copilotkit } = useCopilotKit();
4016
+ const providerThrottleMs = copilotkit.defaultThrottleMs;
4017
+ const effectiveThrottleMs = (0, react.useMemo)(() => {
4018
+ const resolved = throttleMs ?? providerThrottleMs ?? 0;
4019
+ if (!Number.isFinite(resolved) || resolved < 0) {
4020
+ const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
4021
+ console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
4022
+ return 0;
4023
+ }
4024
+ return resolved;
4025
+ }, [throttleMs, providerThrottleMs]);
4026
+ const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
4027
+ const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
4028
+ const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
4029
+ const agent = (0, react.useMemo)(() => {
4030
+ const existing = copilotkit.getAgent(agentId);
4031
+ if (existing) {
4032
+ provisionalAgentCache.current.delete(agentId);
4033
+ return existing;
4034
+ }
4035
+ const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
4036
+ const status = copilotkit.runtimeConnectionStatus;
4037
+ if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
4038
+ const cached = provisionalAgentCache.current.get(agentId);
4039
+ if (cached) {
4040
+ cached.headers = { ...copilotkit.headers };
4041
+ return cached;
4042
+ }
4043
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
4044
+ runtimeUrl: copilotkit.runtimeUrl,
4045
+ agentId,
4046
+ transport: copilotkit.runtimeTransport,
4047
+ runtimeMode: "pending"
4048
+ });
4049
+ provisional.headers = { ...copilotkit.headers };
4050
+ provisionalAgentCache.current.set(agentId, provisional);
4051
+ return provisional;
4052
+ }
4053
+ if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
4054
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
4055
+ runtimeUrl: copilotkit.runtimeUrl,
4056
+ agentId,
4057
+ transport: copilotkit.runtimeTransport,
4058
+ runtimeMode: "pending"
4059
+ });
4060
+ provisional.headers = { ...copilotkit.headers };
4061
+ return provisional;
4062
+ }
4063
+ const knownAgents = Object.keys(copilotkit.agents ?? {});
4064
+ const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
4065
+ 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.");
4066
+ }, [
4067
+ agentId,
4068
+ copilotkit.agents,
4069
+ copilotkit.runtimeConnectionStatus,
4070
+ copilotkit.runtimeUrl,
4071
+ copilotkit.runtimeTransport,
4072
+ JSON.stringify(copilotkit.headers)
4073
+ ]);
4074
+ (0, react.useEffect)(() => {
4075
+ if (updateFlags.length === 0) return;
4076
+ const handlers = {};
4077
+ let timerId = null;
4078
+ let active = true;
4079
+ if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
4080
+ const ms = effectiveThrottleMs;
4081
+ if (ms > 0) {
4082
+ let throttleActive = false;
4083
+ let pending = false;
4084
+ const throttledNotify = () => {
4085
+ if (!active) return;
4086
+ if (!throttleActive) {
4087
+ throttleActive = true;
4088
+ pending = false;
4089
+ forceUpdate();
4090
+ timerId = setTimeout(function trailingEdge() {
4091
+ timerId = null;
4092
+ if (active && pending) {
4093
+ pending = false;
4094
+ forceUpdate();
4095
+ timerId = setTimeout(trailingEdge, ms);
4096
+ } else throttleActive = false;
4097
+ }, ms);
4098
+ } else pending = true;
4099
+ };
4100
+ handlers.onMessagesChanged = throttledNotify;
4101
+ } else handlers.onMessagesChanged = forceUpdate;
4102
+ }
4103
+ if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
4104
+ if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
4105
+ handlers.onRunInitialized = forceUpdate;
4106
+ handlers.onRunFinalized = forceUpdate;
4107
+ handlers.onRunFailed = forceUpdate;
4108
+ }
4109
+ const subscription = agent.subscribe(handlers);
4110
+ return () => {
4111
+ active = false;
4112
+ if (timerId !== null) clearTimeout(timerId);
4113
+ subscription.unsubscribe();
4114
+ };
4115
+ }, [
4116
+ agent,
4117
+ forceUpdate,
4118
+ effectiveThrottleMs,
4119
+ updateFlags
4120
+ ]);
4121
+ return { agent };
4215
4122
  }
4216
4123
 
4217
4124
  //#endregion
@@ -4470,8 +4377,7 @@ function isPromiseLike(value) {
4470
4377
  */
4471
4378
  function useInterrupt(config) {
4472
4379
  const { copilotkit } = useCopilotKit();
4473
- const { agent: internalAgent } = useAgent({ agentId: config.agentId });
4474
- const agent = config.agent ?? internalAgent;
4380
+ const { agent } = useAgent({ agentId: config.agentId });
4475
4381
  const [pendingEvent, setPendingEvent] = (0, react.useState)(null);
4476
4382
  const pendingEventRef = (0, react.useRef)(pendingEvent);
4477
4383
  pendingEventRef.current = pendingEvent;
@@ -4866,8 +4772,11 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
4866
4772
  useKatexStyles();
4867
4773
  const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
4868
4774
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
4869
- if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
4870
- return false;
4775
+ if (message.content) try {
4776
+ await navigator.clipboard.writeText(message.content);
4777
+ } catch (err) {
4778
+ console.error("Failed to copy message:", err);
4779
+ }
4871
4780
  } });
4872
4781
  const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp });
4873
4782
  const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown });
@@ -4965,17 +4874,14 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
4965
4874
  if (timerRef.current !== null) clearTimeout(timerRef.current);
4966
4875
  };
4967
4876
  }, []);
4968
- const handleClick = async (event) => {
4969
- let success = false;
4970
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
4971
- if (success) {
4972
- setCopied(true);
4973
- if (timerRef.current !== null) clearTimeout(timerRef.current);
4974
- timerRef.current = setTimeout(() => {
4975
- timerRef.current = null;
4976
- setCopied(false);
4977
- }, 2e3);
4978
- }
4877
+ const handleClick = (event) => {
4878
+ setCopied(true);
4879
+ if (timerRef.current !== null) clearTimeout(timerRef.current);
4880
+ timerRef.current = setTimeout(() => {
4881
+ timerRef.current = null;
4882
+ setCopied(false);
4883
+ }, 2e3);
4884
+ if (onClick) onClick(event);
4979
4885
  };
4980
4886
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
4981
4887
  "data-testid": "copilot-copy-button",
@@ -5128,8 +5034,11 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
5128
5034
  const mediaParts = (0, react.useMemo)(() => getMediaParts(message.content), [message.content]);
5129
5035
  const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
5130
5036
  const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
5131
- if (flattenedContent) return await (0, _copilotkit_shared.copyToClipboard)(flattenedContent);
5132
- return false;
5037
+ if (flattenedContent) try {
5038
+ await navigator.clipboard.writeText(flattenedContent);
5039
+ } catch (err) {
5040
+ console.error("Failed to copy message:", err);
5041
+ }
5133
5042
  } });
5134
5043
  const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage?.({ message }) });
5135
5044
  const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
@@ -5217,13 +5126,10 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
5217
5126
  _CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
5218
5127
  const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
5219
5128
  const [copied, setCopied] = (0, react.useState)(false);
5220
- const handleClick = async (event) => {
5221
- let success = false;
5222
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5223
- if (success) {
5224
- setCopied(true);
5225
- setTimeout(() => setCopied(false), 2e3);
5226
- }
5129
+ const handleClick = (event) => {
5130
+ setCopied(true);
5131
+ setTimeout(() => setCopied(false), 2e3);
5132
+ if (onClick) onClick(event);
5227
5133
  };
5228
5134
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
5229
5135
  "data-testid": "copilot-user-copy-button",
@@ -5330,24 +5236,17 @@ function CopilotChatReasoningMessage({ message, messages, isRunning, header, con
5330
5236
  return () => clearInterval(timer);
5331
5237
  }, [isStreaming]);
5332
5238
  const [isOpen, setIsOpen] = (0, react.useState)(isStreaming);
5333
- const userToggledRef = (0, react.useRef)(false);
5334
5239
  (0, react.useEffect)(() => {
5335
- if (isStreaming) {
5336
- userToggledRef.current = false;
5337
- setIsOpen(true);
5338
- } else if (!userToggledRef.current) setIsOpen(false);
5240
+ if (isStreaming) setIsOpen(true);
5241
+ else setIsOpen(false);
5339
5242
  }, [isStreaming]);
5340
- const handleToggle = hasContent ? () => {
5341
- userToggledRef.current = true;
5342
- setIsOpen((prev) => !prev);
5343
- } : void 0;
5344
5243
  const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
5345
5244
  const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
5346
5245
  isOpen,
5347
5246
  label,
5348
5247
  hasContent,
5349
5248
  isStreaming,
5350
- onClick: handleToggle
5249
+ onClick: hasContent ? () => setIsOpen((prev) => !prev) : void 0
5351
5250
  });
5352
5251
  const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
5353
5252
  isStreaming,
@@ -5694,14 +5593,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
5694
5593
  const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
5695
5594
  (0, react.useEffect)(() => {
5696
5595
  if (!config?.agentId) return;
5697
- const registryAgent = copilotkit.getAgent(config.agentId);
5698
- const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
5596
+ const agent = copilotkit.getAgent(config.agentId);
5699
5597
  if (!agent) return;
5700
5598
  const subscription = agent.subscribe({ onStateChanged: forceUpdate });
5701
5599
  return () => subscription.unsubscribe();
5702
5600
  }, [
5703
5601
  config?.agentId,
5704
- config?.threadId,
5705
5602
  copilotkit,
5706
5603
  forceUpdate
5707
5604
  ]);
@@ -6641,7 +6538,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
6641
6538
  const resolvedThreadId = (0, react.useMemo)(() => threadId ?? existingConfig?.threadId ?? (0, _copilotkit_shared.randomUUID)(), [threadId, existingConfig?.threadId]);
6642
6539
  const { agent } = useAgent({
6643
6540
  agentId: resolvedAgentId,
6644
- threadId: resolvedThreadId,
6645
6541
  throttleMs
6646
6542
  });
6647
6543
  const { copilotkit } = useCopilotKit();
@@ -6688,6 +6584,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
6688
6584
  console.error("CopilotChat: connectAgent failed", error);
6689
6585
  }
6690
6586
  };
6587
+ agent.threadId = resolvedThreadId;
6691
6588
  connect(agent);
6692
6589
  return () => {
6693
6590
  detached = true;
@@ -8051,20 +7948,6 @@ function shouldShowDevConsole(showDevConsole) {
8051
7948
  /**
8052
7949
  * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
8053
7950
  */
8054
- /**
8055
- * Determine whether a GraphQL error should be suppressed based on its visibility
8056
- * and whether the dev console is active.
8057
- *
8058
- * Returns `null` when the error should be surfaced to the UI, or a log prefix
8059
- * string when the error should be suppressed (logged to console only).
8060
- *
8061
- * Exported for unit testing.
8062
- */
8063
- function getErrorSuppression(visibility, isDev) {
8064
- if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
8065
- if (!isDev && visibility === _copilotkit_shared.ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
8066
- return null;
8067
- }
8068
7951
  const MessagesTapContext = (0, react.createContext)(null);
8069
7952
  function useMessagesTap() {
8070
7953
  const tap = (0, react.useContext)(MessagesTapContext);
@@ -8148,9 +8031,12 @@ function CopilotMessages({ children }) {
8148
8031
  const graphQLErrors = error.graphQLErrors;
8149
8032
  const routeError = (gqlError) => {
8150
8033
  const visibility = gqlError.extensions?.visibility;
8151
- const suppression = getErrorSuppression(visibility, shouldShowDevConsole(showDevConsole));
8152
- if (suppression) {
8153
- console.error(suppression, gqlError.message);
8034
+ if (!shouldShowDevConsole(showDevConsole)) {
8035
+ console.error("CopilotKit Error (hidden in production):", gqlError.message);
8036
+ return;
8037
+ }
8038
+ if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) {
8039
+ console.error("CopilotKit Silent Error:", gqlError.message);
8154
8040
  return;
8155
8041
  }
8156
8042
  const ckError = createStructuredError(gqlError);
@@ -8167,7 +8053,8 @@ function CopilotMessages({ children }) {
8167
8053
  }
8168
8054
  };
8169
8055
  graphQLErrors.forEach(routeError);
8170
- } else {
8056
+ } else if (!shouldShowDevConsole(showDevConsole)) console.error("CopilotKit Error (hidden in production):", error);
8057
+ else {
8171
8058
  const fallbackError = new _copilotkit_shared.CopilotKitError({
8172
8059
  message: error?.message || String(error),
8173
8060
  code: _copilotkit_shared.CopilotKitErrorCode.UNKNOWN
@@ -9234,7 +9121,7 @@ function CopilotKitInternal(cpkProps) {
9234
9121
  publicApiKey,
9235
9122
  ...cloud ? { cloud } : {},
9236
9123
  chatApiEndpoint,
9237
- headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
9124
+ headers: props.headers || {},
9238
9125
  properties: props.properties || {},
9239
9126
  transcribeAudioUrl: props.transcribeAudioUrl,
9240
9127
  textToSpeechUrl: props.textToSpeechUrl,
@@ -9874,12 +9761,6 @@ Object.defineProperty(exports, 'useAttachments', {
9874
9761
  return useAttachments;
9875
9762
  }
9876
9763
  });
9877
- Object.defineProperty(exports, 'useCapabilities', {
9878
- enumerable: true,
9879
- get: function () {
9880
- return useCapabilities;
9881
- }
9882
- });
9883
9764
  Object.defineProperty(exports, 'useCoAgentStateRenders', {
9884
9765
  enumerable: true,
9885
9766
  get: function () {
@@ -10000,4 +9881,4 @@ Object.defineProperty(exports, 'useToast', {
10000
9881
  return useToast;
10001
9882
  }
10002
9883
  });
10003
- //# sourceMappingURL=copilotkit-9l47K1Ot.cjs.map
9884
+ //# sourceMappingURL=copilotkit-BkcqmpWt.cjs.map