@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
@@ -4,7 +4,7 @@ import { CopilotKitCore, CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRu
4
4
  import { HttpAgent } from "@ag-ui/client";
5
5
  import { extendTailwindMerge, twMerge } from "tailwind-merge";
6
6
  import { ArrowUp, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronRightIcon, Copy, Edit, Loader2, MessageCircle, Mic, Play, Plus, RefreshCw, Square, ThumbsDown, ThumbsUp, Upload, Volume2, X } from "lucide-react";
7
- import { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES, COPILOT_CLOUD_API_URL, COPILOT_CLOUD_CHAT_URL, COPILOT_CLOUD_PUBLIC_API_KEY_HEADER, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitRemoteEndpointDiscoveryError, DEFAULT_AGENT_ID, ErrorVisibility, MissingPublicApiKeyError, Severity, TranscriptionErrorCode, TranscriptionErrorCode as TranscriptionErrorCode$1, copyToClipboard, createLicenseContextValue, dataToUUID, exceedsMaxSize, formatFileSize, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, matchesAcceptFilter, parseJson, partialJSONParse, randomId, randomUUID, readFileAsBase64, schemaToJsonSchema } from "@copilotkit/shared";
7
+ import { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES, COPILOT_CLOUD_API_URL, COPILOT_CLOUD_CHAT_URL, COPILOT_CLOUD_PUBLIC_API_KEY_HEADER, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitRemoteEndpointDiscoveryError, DEFAULT_AGENT_ID, ErrorVisibility, MissingPublicApiKeyError, Severity, TranscriptionErrorCode, TranscriptionErrorCode as TranscriptionErrorCode$1, createLicenseContextValue, dataToUUID, exceedsMaxSize, formatFileSize, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, matchesAcceptFilter, parseJson, partialJSONParse, randomId, randomUUID, readFileAsBase64, schemaToJsonSchema } from "@copilotkit/shared";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Slot } from "@radix-ui/react-slot";
10
10
  import { cva } from "class-variance-authority";
@@ -3042,7 +3042,7 @@ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
3042
3042
  }, [value, warningMessage]);
3043
3043
  return value;
3044
3044
  }
3045
- 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 }) => {
3045
+ 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 }) => {
3046
3046
  const [shouldRenderInspector, setShouldRenderInspector] = useState(false);
3047
3047
  const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = useState(false);
3048
3048
  const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = useState(false);
@@ -3097,7 +3097,6 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
3097
3097
  ...selfManagedAgents
3098
3098
  }), [agents, selfManagedAgents]);
3099
3099
  const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
3100
- const headers = typeof headersProp === "function" ? headersProp() : headersProp;
3101
3100
  const mergedHeaders = useMemo(() => {
3102
3101
  if (!resolvedPublicKey) return headers;
3103
3102
  if (headers[HEADER_NAME]) return headers;
@@ -3455,200 +3454,6 @@ function useRenderToolCall() {
3455
3454
  ]);
3456
3455
  }
3457
3456
 
3458
- //#endregion
3459
- //#region src/v2/hooks/use-agent.tsx
3460
- let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
3461
- UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
3462
- UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
3463
- UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
3464
- return UseAgentUpdate;
3465
- }({});
3466
- const ALL_UPDATES = [
3467
- UseAgentUpdate.OnMessagesChanged,
3468
- UseAgentUpdate.OnStateChanged,
3469
- UseAgentUpdate.OnRunStatusChanged
3470
- ];
3471
- /**
3472
- * Clone a registry agent for per-thread isolation.
3473
- * Copies agent configuration (transport, headers, etc.) but resets conversation
3474
- * state (messages, threadId, state) so each thread starts fresh.
3475
- */
3476
- function cloneForThread(source, threadId, headers) {
3477
- const clone = source.clone();
3478
- if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
3479
- clone.threadId = threadId;
3480
- clone.setMessages([]);
3481
- clone.setState({});
3482
- if (clone instanceof HttpAgent) clone.headers = { ...headers };
3483
- return clone;
3484
- }
3485
- /**
3486
- * Module-level WeakMap: registryAgent → (threadId → clone).
3487
- * Shared across all useAgent() calls so that every component using the same
3488
- * (agentId, threadId) pair receives the same agent instance. Using WeakMap
3489
- * ensures the clone map is garbage-collected when the registry agent is
3490
- * replaced (e.g. after reconnect or hot-reload).
3491
- */
3492
- const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
3493
- /**
3494
- * Look up an existing per-thread clone without creating one.
3495
- * Returns undefined when no clone has been created yet for this pair.
3496
- */
3497
- function getThreadClone(registryAgent, threadId) {
3498
- if (!registryAgent || !threadId) return void 0;
3499
- return globalThreadCloneMap.get(registryAgent)?.get(threadId);
3500
- }
3501
- function getOrCreateThreadClone(existing, threadId, headers) {
3502
- let byThread = globalThreadCloneMap.get(existing);
3503
- if (!byThread) {
3504
- byThread = /* @__PURE__ */ new Map();
3505
- globalThreadCloneMap.set(existing, byThread);
3506
- }
3507
- const cached = byThread.get(threadId);
3508
- if (cached) return cached;
3509
- const clone = cloneForThread(existing, threadId, headers);
3510
- byThread.set(threadId, clone);
3511
- return clone;
3512
- }
3513
- function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
3514
- agentId ??= DEFAULT_AGENT_ID;
3515
- const { copilotkit } = useCopilotKit();
3516
- const providerThrottleMs = copilotkit.defaultThrottleMs;
3517
- const chatConfig = useCopilotChatConfiguration();
3518
- threadId ??= chatConfig?.threadId;
3519
- const effectiveThrottleMs = useMemo(() => {
3520
- const resolved = throttleMs ?? providerThrottleMs ?? 0;
3521
- if (!Number.isFinite(resolved) || resolved < 0) {
3522
- const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
3523
- console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
3524
- return 0;
3525
- }
3526
- return resolved;
3527
- }, [throttleMs, providerThrottleMs]);
3528
- const [, forceUpdate] = useReducer((x) => x + 1, 0);
3529
- const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
3530
- const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
3531
- const agent = useMemo(() => {
3532
- const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
3533
- const existing = copilotkit.getAgent(agentId);
3534
- if (existing) {
3535
- provisionalAgentCache.current.delete(cacheKey);
3536
- provisionalAgentCache.current.delete(agentId);
3537
- if (!threadId) return existing;
3538
- return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
3539
- }
3540
- const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
3541
- const status = copilotkit.runtimeConnectionStatus;
3542
- if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
3543
- const cached = provisionalAgentCache.current.get(cacheKey);
3544
- if (cached) {
3545
- cached.headers = { ...copilotkit.headers };
3546
- return cached;
3547
- }
3548
- const provisional = new ProxiedCopilotRuntimeAgent({
3549
- runtimeUrl: copilotkit.runtimeUrl,
3550
- agentId,
3551
- transport: copilotkit.runtimeTransport,
3552
- runtimeMode: "pending"
3553
- });
3554
- provisional.headers = { ...copilotkit.headers };
3555
- if (threadId) provisional.threadId = threadId;
3556
- provisionalAgentCache.current.set(cacheKey, provisional);
3557
- return provisional;
3558
- }
3559
- if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
3560
- const cached = provisionalAgentCache.current.get(cacheKey);
3561
- if (cached) {
3562
- cached.headers = { ...copilotkit.headers };
3563
- return cached;
3564
- }
3565
- const provisional = new ProxiedCopilotRuntimeAgent({
3566
- runtimeUrl: copilotkit.runtimeUrl,
3567
- agentId,
3568
- transport: copilotkit.runtimeTransport,
3569
- runtimeMode: "pending"
3570
- });
3571
- provisional.headers = { ...copilotkit.headers };
3572
- if (threadId) provisional.threadId = threadId;
3573
- provisionalAgentCache.current.set(cacheKey, provisional);
3574
- return provisional;
3575
- }
3576
- const knownAgents = Object.keys(copilotkit.agents ?? {});
3577
- const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
3578
- 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.");
3579
- }, [
3580
- agentId,
3581
- threadId,
3582
- copilotkit.agents,
3583
- copilotkit.runtimeConnectionStatus,
3584
- copilotkit.runtimeUrl,
3585
- copilotkit.runtimeTransport,
3586
- JSON.stringify(copilotkit.headers)
3587
- ]);
3588
- useEffect(() => {
3589
- if (updateFlags.length === 0) return;
3590
- const handlers = {};
3591
- let timerId = null;
3592
- let active = true;
3593
- let batchScheduled = false;
3594
- const batchedForceUpdate = () => {
3595
- if (!active) return;
3596
- if (!batchScheduled) {
3597
- batchScheduled = true;
3598
- queueMicrotask(() => {
3599
- batchScheduled = false;
3600
- if (active) forceUpdate();
3601
- });
3602
- }
3603
- };
3604
- if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
3605
- const ms = effectiveThrottleMs;
3606
- if (ms > 0) {
3607
- let throttleActive = false;
3608
- let pending = false;
3609
- const throttledNotify = () => {
3610
- if (!active) return;
3611
- if (!throttleActive) {
3612
- throttleActive = true;
3613
- pending = false;
3614
- forceUpdate();
3615
- timerId = setTimeout(function trailingEdge() {
3616
- timerId = null;
3617
- if (active && pending) {
3618
- pending = false;
3619
- forceUpdate();
3620
- timerId = setTimeout(trailingEdge, ms);
3621
- } else throttleActive = false;
3622
- }, ms);
3623
- } else pending = true;
3624
- };
3625
- handlers.onMessagesChanged = throttledNotify;
3626
- } else handlers.onMessagesChanged = forceUpdate;
3627
- }
3628
- if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
3629
- if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
3630
- handlers.onRunInitialized = batchedForceUpdate;
3631
- handlers.onRunFinalized = batchedForceUpdate;
3632
- handlers.onRunFailed = batchedForceUpdate;
3633
- }
3634
- const subscription = agent.subscribe(handlers);
3635
- return () => {
3636
- active = false;
3637
- if (timerId !== null) clearTimeout(timerId);
3638
- subscription.unsubscribe();
3639
- };
3640
- }, [
3641
- agent,
3642
- forceUpdate,
3643
- effectiveThrottleMs,
3644
- updateFlags
3645
- ]);
3646
- useEffect(() => {
3647
- if (agent instanceof HttpAgent) agent.headers = { ...copilotkit.headers };
3648
- }, [agent, JSON.stringify(copilotkit.headers)]);
3649
- return { agent };
3650
- }
3651
-
3652
3457
  //#endregion
3653
3458
  //#region src/v2/hooks/use-render-custom-messages.tsx
3654
3459
  function useRenderCustomMessages() {
@@ -3666,8 +3471,7 @@ function useRenderCustomMessages() {
3666
3471
  const { message, position } = params;
3667
3472
  const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
3668
3473
  const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
3669
- const registryAgent = copilotkit.getAgent(agentId);
3670
- const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
3474
+ const agent = copilotkit.getAgent(agentId);
3671
3475
  if (!agent) throw new Error("Agent not found");
3672
3476
  const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
3673
3477
  const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
@@ -3699,8 +3503,7 @@ function useRenderCustomMessages() {
3699
3503
  //#region src/v2/hooks/use-render-activity-message.tsx
3700
3504
  function useRenderActivityMessage() {
3701
3505
  const { copilotkit } = useCopilotKit();
3702
- const config = useCopilotChatConfiguration();
3703
- const agentId = config?.agentId ?? DEFAULT_AGENT_ID;
3506
+ const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
3704
3507
  const renderers = copilotkit.renderActivityMessages;
3705
3508
  const findRenderer = useCallback((activityType) => {
3706
3509
  if (!renderers.length) return null;
@@ -3716,8 +3519,7 @@ function useRenderActivityMessage() {
3716
3519
  return null;
3717
3520
  }
3718
3521
  const Component = renderer.render;
3719
- const registryAgent = copilotkit.getAgent(agentId);
3720
- const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
3522
+ const agent = copilotkit.getAgent(agentId);
3721
3523
  return /* @__PURE__ */ jsx(Component, {
3722
3524
  activityType: message.activityType,
3723
3525
  content: parseResult.data,
@@ -3726,7 +3528,6 @@ function useRenderActivityMessage() {
3726
3528
  }, message.id);
3727
3529
  }, [
3728
3530
  agentId,
3729
- config?.threadId,
3730
3531
  copilotkit,
3731
3532
  findRenderer
3732
3533
  ]);
@@ -4167,21 +3968,127 @@ function useHumanInTheLoop(tool, deps) {
4167
3968
  }
4168
3969
 
4169
3970
  //#endregion
4170
- //#region src/v2/hooks/use-capabilities.tsx
4171
- /**
4172
- * Returns the capabilities declared by the given agent (or the default agent).
4173
- * Capabilities are populated from the runtime `/info` response at connection
4174
- * time. The hook reads them synchronously from the agent instance — there is
4175
- * no separate loading state, but the value will be `undefined` until the
4176
- * runtime handshake completes.
4177
- *
4178
- * @param agentId - Optional agent ID. If omitted, uses the default agent.
4179
- * @returns The agent's capabilities, or `undefined` if the agent doesn't
4180
- * declare capabilities.
4181
- */
4182
- function useCapabilities(agentId) {
4183
- const { agent } = useAgent({ agentId });
4184
- if (agent && "capabilities" in agent) return agent.capabilities;
3971
+ //#region src/v2/hooks/use-agent.tsx
3972
+ let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
3973
+ UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
3974
+ UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
3975
+ UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
3976
+ return UseAgentUpdate;
3977
+ }({});
3978
+ const ALL_UPDATES = [
3979
+ UseAgentUpdate.OnMessagesChanged,
3980
+ UseAgentUpdate.OnStateChanged,
3981
+ UseAgentUpdate.OnRunStatusChanged
3982
+ ];
3983
+ function useAgent({ agentId, updates, throttleMs } = {}) {
3984
+ agentId ??= DEFAULT_AGENT_ID;
3985
+ const { copilotkit } = useCopilotKit();
3986
+ const providerThrottleMs = copilotkit.defaultThrottleMs;
3987
+ const effectiveThrottleMs = useMemo(() => {
3988
+ const resolved = throttleMs ?? providerThrottleMs ?? 0;
3989
+ if (!Number.isFinite(resolved) || resolved < 0) {
3990
+ const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
3991
+ console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
3992
+ return 0;
3993
+ }
3994
+ return resolved;
3995
+ }, [throttleMs, providerThrottleMs]);
3996
+ const [, forceUpdate] = useReducer((x) => x + 1, 0);
3997
+ const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
3998
+ const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
3999
+ const agent = useMemo(() => {
4000
+ const existing = copilotkit.getAgent(agentId);
4001
+ if (existing) {
4002
+ provisionalAgentCache.current.delete(agentId);
4003
+ return existing;
4004
+ }
4005
+ const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
4006
+ const status = copilotkit.runtimeConnectionStatus;
4007
+ if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
4008
+ const cached = provisionalAgentCache.current.get(agentId);
4009
+ if (cached) {
4010
+ cached.headers = { ...copilotkit.headers };
4011
+ return cached;
4012
+ }
4013
+ const provisional = new ProxiedCopilotRuntimeAgent({
4014
+ runtimeUrl: copilotkit.runtimeUrl,
4015
+ agentId,
4016
+ transport: copilotkit.runtimeTransport,
4017
+ runtimeMode: "pending"
4018
+ });
4019
+ provisional.headers = { ...copilotkit.headers };
4020
+ provisionalAgentCache.current.set(agentId, provisional);
4021
+ return provisional;
4022
+ }
4023
+ if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
4024
+ const provisional = new ProxiedCopilotRuntimeAgent({
4025
+ runtimeUrl: copilotkit.runtimeUrl,
4026
+ agentId,
4027
+ transport: copilotkit.runtimeTransport,
4028
+ runtimeMode: "pending"
4029
+ });
4030
+ provisional.headers = { ...copilotkit.headers };
4031
+ return provisional;
4032
+ }
4033
+ const knownAgents = Object.keys(copilotkit.agents ?? {});
4034
+ const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
4035
+ 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.");
4036
+ }, [
4037
+ agentId,
4038
+ copilotkit.agents,
4039
+ copilotkit.runtimeConnectionStatus,
4040
+ copilotkit.runtimeUrl,
4041
+ copilotkit.runtimeTransport,
4042
+ JSON.stringify(copilotkit.headers)
4043
+ ]);
4044
+ useEffect(() => {
4045
+ if (updateFlags.length === 0) return;
4046
+ const handlers = {};
4047
+ let timerId = null;
4048
+ let active = true;
4049
+ if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
4050
+ const ms = effectiveThrottleMs;
4051
+ if (ms > 0) {
4052
+ let throttleActive = false;
4053
+ let pending = false;
4054
+ const throttledNotify = () => {
4055
+ if (!active) return;
4056
+ if (!throttleActive) {
4057
+ throttleActive = true;
4058
+ pending = false;
4059
+ forceUpdate();
4060
+ timerId = setTimeout(function trailingEdge() {
4061
+ timerId = null;
4062
+ if (active && pending) {
4063
+ pending = false;
4064
+ forceUpdate();
4065
+ timerId = setTimeout(trailingEdge, ms);
4066
+ } else throttleActive = false;
4067
+ }, ms);
4068
+ } else pending = true;
4069
+ };
4070
+ handlers.onMessagesChanged = throttledNotify;
4071
+ } else handlers.onMessagesChanged = forceUpdate;
4072
+ }
4073
+ if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
4074
+ if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
4075
+ handlers.onRunInitialized = forceUpdate;
4076
+ handlers.onRunFinalized = forceUpdate;
4077
+ handlers.onRunFailed = forceUpdate;
4078
+ }
4079
+ const subscription = agent.subscribe(handlers);
4080
+ return () => {
4081
+ active = false;
4082
+ if (timerId !== null) clearTimeout(timerId);
4083
+ subscription.unsubscribe();
4084
+ };
4085
+ }, [
4086
+ agent,
4087
+ forceUpdate,
4088
+ effectiveThrottleMs,
4089
+ updateFlags
4090
+ ]);
4091
+ return { agent };
4185
4092
  }
4186
4093
 
4187
4094
  //#endregion
@@ -4440,8 +4347,7 @@ function isPromiseLike(value) {
4440
4347
  */
4441
4348
  function useInterrupt(config) {
4442
4349
  const { copilotkit } = useCopilotKit();
4443
- const { agent: internalAgent } = useAgent({ agentId: config.agentId });
4444
- const agent = config.agent ?? internalAgent;
4350
+ const { agent } = useAgent({ agentId: config.agentId });
4445
4351
  const [pendingEvent, setPendingEvent] = useState(null);
4446
4352
  const pendingEventRef = useRef(pendingEvent);
4447
4353
  pendingEventRef.current = pendingEvent;
@@ -4836,8 +4742,11 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
4836
4742
  useKatexStyles();
4837
4743
  const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
4838
4744
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
4839
- if (message.content) return await copyToClipboard(message.content);
4840
- return false;
4745
+ if (message.content) try {
4746
+ await navigator.clipboard.writeText(message.content);
4747
+ } catch (err) {
4748
+ console.error("Failed to copy message:", err);
4749
+ }
4841
4750
  } });
4842
4751
  const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp });
4843
4752
  const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown });
@@ -4935,17 +4844,14 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
4935
4844
  if (timerRef.current !== null) clearTimeout(timerRef.current);
4936
4845
  };
4937
4846
  }, []);
4938
- const handleClick = async (event) => {
4939
- let success = false;
4940
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
4941
- if (success) {
4942
- setCopied(true);
4943
- if (timerRef.current !== null) clearTimeout(timerRef.current);
4944
- timerRef.current = setTimeout(() => {
4945
- timerRef.current = null;
4946
- setCopied(false);
4947
- }, 2e3);
4948
- }
4847
+ const handleClick = (event) => {
4848
+ setCopied(true);
4849
+ if (timerRef.current !== null) clearTimeout(timerRef.current);
4850
+ timerRef.current = setTimeout(() => {
4851
+ timerRef.current = null;
4852
+ setCopied(false);
4853
+ }, 2e3);
4854
+ if (onClick) onClick(event);
4949
4855
  };
4950
4856
  return /* @__PURE__ */ jsx(ToolbarButton, {
4951
4857
  "data-testid": "copilot-copy-button",
@@ -5098,8 +5004,11 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
5098
5004
  const mediaParts = useMemo(() => getMediaParts(message.content), [message.content]);
5099
5005
  const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
5100
5006
  const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
5101
- if (flattenedContent) return await copyToClipboard(flattenedContent);
5102
- return false;
5007
+ if (flattenedContent) try {
5008
+ await navigator.clipboard.writeText(flattenedContent);
5009
+ } catch (err) {
5010
+ console.error("Failed to copy message:", err);
5011
+ }
5103
5012
  } });
5104
5013
  const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage?.({ message }) });
5105
5014
  const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
@@ -5187,13 +5096,10 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
5187
5096
  _CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
5188
5097
  const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
5189
5098
  const [copied, setCopied] = useState(false);
5190
- const handleClick = async (event) => {
5191
- let success = false;
5192
- if (onClick) success = await Promise.resolve(onClick(event)) === true;
5193
- if (success) {
5194
- setCopied(true);
5195
- setTimeout(() => setCopied(false), 2e3);
5196
- }
5099
+ const handleClick = (event) => {
5100
+ setCopied(true);
5101
+ setTimeout(() => setCopied(false), 2e3);
5102
+ if (onClick) onClick(event);
5197
5103
  };
5198
5104
  return /* @__PURE__ */ jsx(ToolbarButton, {
5199
5105
  "data-testid": "copilot-user-copy-button",
@@ -5300,24 +5206,17 @@ function CopilotChatReasoningMessage({ message, messages, isRunning, header, con
5300
5206
  return () => clearInterval(timer);
5301
5207
  }, [isStreaming]);
5302
5208
  const [isOpen, setIsOpen] = useState(isStreaming);
5303
- const userToggledRef = useRef(false);
5304
5209
  useEffect(() => {
5305
- if (isStreaming) {
5306
- userToggledRef.current = false;
5307
- setIsOpen(true);
5308
- } else if (!userToggledRef.current) setIsOpen(false);
5210
+ if (isStreaming) setIsOpen(true);
5211
+ else setIsOpen(false);
5309
5212
  }, [isStreaming]);
5310
- const handleToggle = hasContent ? () => {
5311
- userToggledRef.current = true;
5312
- setIsOpen((prev) => !prev);
5313
- } : void 0;
5314
5213
  const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
5315
5214
  const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
5316
5215
  isOpen,
5317
5216
  label,
5318
5217
  hasContent,
5319
5218
  isStreaming,
5320
- onClick: handleToggle
5219
+ onClick: hasContent ? () => setIsOpen((prev) => !prev) : void 0
5321
5220
  });
5322
5221
  const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
5323
5222
  isStreaming,
@@ -5664,14 +5563,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
5664
5563
  const [, forceUpdate] = useReducer((x) => x + 1, 0);
5665
5564
  useEffect(() => {
5666
5565
  if (!config?.agentId) return;
5667
- const registryAgent = copilotkit.getAgent(config.agentId);
5668
- const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
5566
+ const agent = copilotkit.getAgent(config.agentId);
5669
5567
  if (!agent) return;
5670
5568
  const subscription = agent.subscribe({ onStateChanged: forceUpdate });
5671
5569
  return () => subscription.unsubscribe();
5672
5570
  }, [
5673
5571
  config?.agentId,
5674
- config?.threadId,
5675
5572
  copilotkit,
5676
5573
  forceUpdate
5677
5574
  ]);
@@ -6611,7 +6508,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
6611
6508
  const resolvedThreadId = useMemo(() => threadId ?? existingConfig?.threadId ?? randomUUID(), [threadId, existingConfig?.threadId]);
6612
6509
  const { agent } = useAgent({
6613
6510
  agentId: resolvedAgentId,
6614
- threadId: resolvedThreadId,
6615
6511
  throttleMs
6616
6512
  });
6617
6513
  const { copilotkit } = useCopilotKit();
@@ -6658,6 +6554,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
6658
6554
  console.error("CopilotChat: connectAgent failed", error);
6659
6555
  }
6660
6556
  };
6557
+ agent.threadId = resolvedThreadId;
6661
6558
  connect(agent);
6662
6559
  return () => {
6663
6560
  detached = true;
@@ -8021,20 +7918,6 @@ function shouldShowDevConsole(showDevConsole) {
8021
7918
  /**
8022
7919
  * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
8023
7920
  */
8024
- /**
8025
- * Determine whether a GraphQL error should be suppressed based on its visibility
8026
- * and whether the dev console is active.
8027
- *
8028
- * Returns `null` when the error should be surfaced to the UI, or a log prefix
8029
- * string when the error should be suppressed (logged to console only).
8030
- *
8031
- * Exported for unit testing.
8032
- */
8033
- function getErrorSuppression(visibility, isDev) {
8034
- if (visibility === ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
8035
- if (!isDev && visibility === ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
8036
- return null;
8037
- }
8038
7921
  const MessagesTapContext = createContext(null);
8039
7922
  function useMessagesTap() {
8040
7923
  const tap = useContext(MessagesTapContext);
@@ -8118,9 +8001,12 @@ function CopilotMessages({ children }) {
8118
8001
  const graphQLErrors = error.graphQLErrors;
8119
8002
  const routeError = (gqlError) => {
8120
8003
  const visibility = gqlError.extensions?.visibility;
8121
- const suppression = getErrorSuppression(visibility, shouldShowDevConsole(showDevConsole));
8122
- if (suppression) {
8123
- console.error(suppression, gqlError.message);
8004
+ if (!shouldShowDevConsole(showDevConsole)) {
8005
+ console.error("CopilotKit Error (hidden in production):", gqlError.message);
8006
+ return;
8007
+ }
8008
+ if (visibility === ErrorVisibility.SILENT) {
8009
+ console.error("CopilotKit Silent Error:", gqlError.message);
8124
8010
  return;
8125
8011
  }
8126
8012
  const ckError = createStructuredError(gqlError);
@@ -8137,7 +8023,8 @@ function CopilotMessages({ children }) {
8137
8023
  }
8138
8024
  };
8139
8025
  graphQLErrors.forEach(routeError);
8140
- } else {
8026
+ } else if (!shouldShowDevConsole(showDevConsole)) console.error("CopilotKit Error (hidden in production):", error);
8027
+ else {
8141
8028
  const fallbackError = new CopilotKitError({
8142
8029
  message: error?.message || String(error),
8143
8030
  code: CopilotKitErrorCode.UNKNOWN
@@ -9204,7 +9091,7 @@ function CopilotKitInternal(cpkProps) {
9204
9091
  publicApiKey,
9205
9092
  ...cloud ? { cloud } : {},
9206
9093
  chatApiEndpoint,
9207
- headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
9094
+ headers: props.headers || {},
9208
9095
  properties: props.properties || {},
9209
9096
  transcribeAudioUrl: props.transcribeAudioUrl,
9210
9097
  textToSpeechUrl: props.textToSpeechUrl,
@@ -9550,5 +9437,5 @@ function validateProps(props) {
9550
9437
  }
9551
9438
 
9552
9439
  //#endregion
9553
- export { CopilotKitProvider as $, CopilotChatSuggestionView as A, useConfigureSuggestions as B, CopilotChatToggleButton as C, CopilotChatView_default as D, CopilotChat as E, CopilotChatAssistantMessage_default as F, useRenderTool as G, useCapabilities as H, CopilotChatToolCallsView as I, useRenderActivityMessage as J, useComponent as K, useAttachments as L, CopilotChatReasoningMessage_default as M, CopilotChatUserMessage_default as N, CopilotChatAttachmentQueue as O, CopilotChatAttachmentRenderer as P, useRenderToolCall as Q, useThreads$1 as R, CopilotModalHeader as S, DefaultOpenIcon as T, useHumanInTheLoop as U, useSuggestions as V, useDefaultRenderTool as W, UseAgentUpdate as X, useRenderCustomMessages as Y, useAgent as Z, WildcardToolCallRender as _, ThreadsProvider as a, SandboxFunctionsContext as at, CopilotPopupView as b, CoAgentStateRendersProvider as c, MCPAppsActivityRenderer as ct, shouldShowDevConsole as d, CopilotChatInput_default as dt, useCopilotKit as et, useToast as f, AudioRecorderError as ft, useCopilotContext as g, CopilotContext as h, useCopilotChatConfiguration as ht, ThreadsContext as i, createA2UIMessageRenderer as it, CopilotChatSuggestionPill as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, MCPAppsActivityType as lt, useCopilotMessagesContext as m, CopilotChatConfigurationProvider as mt, defaultCopilotContextCategories as n, useAgentContext as nt, useThreads as o, useSandboxFunctions as ot, CopilotMessagesContext as p, CopilotChatAudioRecorder as pt, useFrontendTool as q, CoAgentStateRenderBridge as r, defineToolCallRenderer as rt, CoAgentStateRendersContext as s, MCPAppsActivityContentSchema as st, CopilotKit as t, CopilotKitCoreReact as tt, useAsyncCallback as u, CopilotKitInspector as ut, CopilotPopup as v, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotSidebar as y, useInterrupt as z };
9554
- //# sourceMappingURL=copilotkit-a2pL_KeT.mjs.map
9440
+ export { useCopilotKit as $, CopilotChatSuggestionView as A, useConfigureSuggestions as B, CopilotChatToggleButton as C, CopilotChatView_default as D, CopilotChat as E, CopilotChatAssistantMessage_default as F, useDefaultRenderTool as G, UseAgentUpdate as H, CopilotChatToolCallsView as I, useFrontendTool as J, useRenderTool as K, useAttachments as L, CopilotChatReasoningMessage_default as M, CopilotChatUserMessage_default as N, CopilotChatAttachmentQueue as O, CopilotChatAttachmentRenderer as P, CopilotKitProvider as Q, useThreads$1 as R, CopilotModalHeader as S, DefaultOpenIcon as T, useAgent as U, useSuggestions as V, useHumanInTheLoop as W, useRenderCustomMessages as X, useRenderActivityMessage as Y, useRenderToolCall as Z, WildcardToolCallRender as _, ThreadsProvider as a, useSandboxFunctions as at, CopilotPopupView as b, CoAgentStateRendersProvider as c, MCPAppsActivityType as ct, shouldShowDevConsole as d, AudioRecorderError as dt, CopilotKitCoreReact as et, useToast as f, CopilotChatAudioRecorder as ft, useCopilotContext as g, CopilotContext as h, ThreadsContext as i, SandboxFunctionsContext as it, CopilotChatSuggestionPill as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, CopilotKitInspector as lt, useCopilotMessagesContext as m, useCopilotChatConfiguration as mt, defaultCopilotContextCategories as n, defineToolCallRenderer as nt, useThreads as o, MCPAppsActivityContentSchema as ot, CopilotMessagesContext as p, CopilotChatConfigurationProvider as pt, useComponent as q, CoAgentStateRenderBridge as r, createA2UIMessageRenderer as rt, CoAgentStateRendersContext as s, MCPAppsActivityRenderer as st, CopilotKit as t, useAgentContext as tt, useAsyncCallback as u, CopilotChatInput_default as ut, CopilotPopup as v, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotSidebar as y, useInterrupt as z };
9441
+ //# sourceMappingURL=copilotkit-C7n8Umv9.mjs.map