@copilotkit/react-core 1.61.1 → 1.61.2

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 (41) hide show
  1. package/dist/{copilotkit-UY-H6Kx7.mjs → copilotkit-Be-o2UaU.mjs} +210 -119
  2. package/dist/copilotkit-Be-o2UaU.mjs.map +1 -0
  3. package/dist/{copilotkit-M1FiciGd.d.mts → copilotkit-Bpt1c_-q.d.mts} +79 -71
  4. package/dist/copilotkit-Bpt1c_-q.d.mts.map +1 -0
  5. package/dist/{copilotkit-BCJDP8qd.cjs → copilotkit-CTCjVxkH.cjs} +199 -108
  6. package/dist/copilotkit-CTCjVxkH.cjs.map +1 -0
  7. package/dist/{copilotkit-CEdu_aie.d.cts → copilotkit-ClqbUuGX.d.cts} +79 -71
  8. package/dist/copilotkit-ClqbUuGX.d.cts.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts +1 -1
  14. package/dist/index.d.mts.map +1 -1
  15. package/dist/index.mjs +1 -1
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/index.umd.js +167 -94
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/v2/context.d.cts +5 -1
  20. package/dist/v2/context.d.cts.map +1 -1
  21. package/dist/v2/context.d.mts +5 -1
  22. package/dist/v2/context.d.mts.map +1 -1
  23. package/dist/v2/headless.cjs +167 -93
  24. package/dist/v2/headless.cjs.map +1 -1
  25. package/dist/v2/headless.d.cts +76 -68
  26. package/dist/v2/headless.d.cts.map +1 -1
  27. package/dist/v2/headless.d.mts +76 -68
  28. package/dist/v2/headless.d.mts.map +1 -1
  29. package/dist/v2/headless.mjs +168 -94
  30. package/dist/v2/headless.mjs.map +1 -1
  31. package/dist/v2/index.cjs +1 -1
  32. package/dist/v2/index.d.cts +2 -2
  33. package/dist/v2/index.d.mts +2 -2
  34. package/dist/v2/index.mjs +1 -1
  35. package/dist/v2/index.umd.js +198 -107
  36. package/dist/v2/index.umd.js.map +1 -1
  37. package/package.json +6 -6
  38. package/dist/copilotkit-BCJDP8qd.cjs.map +0 -1
  39. package/dist/copilotkit-CEdu_aie.d.cts.map +0 -1
  40. package/dist/copilotkit-M1FiciGd.d.mts.map +0 -1
  41. package/dist/copilotkit-UY-H6Kx7.mjs.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import * as React$1 from "react";
2
2
  import React, { createContext, forwardRef, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { CopilotKitCore, CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, isRunCompletionAware, ɵcreateThreadStore, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
4
- import { HttpAgent } from "@ag-ui/client";
4
+ import { HttpAgent, buildResumeArray, isInterruptExpired, randomUUID } 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, copyToClipboard, createLicenseContextValue, dataToUUID, exceedsMaxSize, formatFileSize, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, matchesAcceptFilter, parseJson, partialJSONParse, randomId, randomUUID as randomUUID$1, 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";
@@ -157,7 +157,7 @@ const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId,
157
157
  const resolvedThreadId = useMemo(() => {
158
158
  if (threadId) return threadId;
159
159
  if (parentConfig?.threadId) return parentConfig.threadId;
160
- return randomUUID();
160
+ return randomUUID$1();
161
161
  }, [threadId, parentConfig?.threadId]);
162
162
  const resolvedHasExplicitThreadId = (hasExplicitThreadId !== void 0 ? hasExplicitThreadId : !!threadId) || !!parentConfig?.hasExplicitThreadId;
163
163
  const [internalModalOpen, setInternalModalOpen] = useState(isModalDefaultOpen ?? true);
@@ -1490,10 +1490,20 @@ function useRenderTool(config, deps) {
1490
1490
  }) : defineToolCallRenderer({
1491
1491
  name: config.name,
1492
1492
  args: config.parameters,
1493
- render: (props) => config.render({
1494
- ...props,
1495
- parameters: props.args
1496
- }),
1493
+ render: (props) => {
1494
+ if (props.status === ToolCallStatus.InProgress) return config.render({
1495
+ ...props,
1496
+ parameters: props.args
1497
+ });
1498
+ if (props.status === ToolCallStatus.Executing) return config.render({
1499
+ ...props,
1500
+ parameters: props.args
1501
+ });
1502
+ return config.render({
1503
+ ...props,
1504
+ parameters: props.args
1505
+ });
1506
+ },
1497
1507
  ...config.agentId ? { agentId: config.agentId } : {}
1498
1508
  });
1499
1509
  copilotkit.addHookRenderToolCall(renderer);
@@ -3531,6 +3541,10 @@ function A2UICatalogContext({ catalog, includeSchema }) {
3531
3541
 
3532
3542
  //#endregion
3533
3543
  //#region src/v2/providers/CopilotKitProvider.tsx
3544
+ const zodToJsonSchemaAdapter = (schema, options) => {
3545
+ const refStrategy = options?.$refStrategy;
3546
+ return zodToJsonSchema(schema, refStrategy === "root" || refStrategy === "relative" || refStrategy === "none" || refStrategy === "seen" ? { $refStrategy: refStrategy } : {});
3547
+ };
3534
3548
  const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
3535
3549
  const COPILOT_CLOUD_CHAT_URL$1 = "https://api.cloud.copilotkit.ai/copilotkit/v1";
3536
3550
  const EMPTY_HEADERS = Object.freeze({});
@@ -3561,6 +3575,8 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3561
3575
  const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = useState(false);
3562
3576
  const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = useState(false);
3563
3577
  const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;
3578
+ const a2uiCatalogProvided = !!a2ui?.catalog;
3579
+ const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;
3564
3580
  const [runtimeLicenseStatus, setRuntimeLicenseStatus] = useState(void 0);
3565
3581
  useEffect(() => {
3566
3582
  if (typeof window === "undefined") return;
@@ -3591,7 +3607,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3591
3607
  content: OpenGenerativeUIContentSchema,
3592
3608
  render: OpenGenerativeUIActivityRenderer
3593
3609
  });
3594
- if (runtimeA2UIEnabled) renderers.unshift(createA2UIMessageRenderer({
3610
+ if (a2uiActive) renderers.unshift(createA2UIMessageRenderer({
3595
3611
  theme: a2ui?.theme ?? viewerTheme,
3596
3612
  catalog: a2ui?.catalog,
3597
3613
  loadingComponent: a2ui?.loadingComponent,
@@ -3599,7 +3615,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3599
3615
  }));
3600
3616
  return renderers;
3601
3617
  }, [
3602
- runtimeA2UIEnabled,
3618
+ a2uiActive,
3603
3619
  openGenUIActive,
3604
3620
  a2ui
3605
3621
  ]);
@@ -3786,7 +3802,10 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3786
3802
  copilotkit.setRuntimeTransport(useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto");
3787
3803
  copilotkit.setHeaders(mergedHeaders);
3788
3804
  copilotkit.setCredentials(credentials);
3789
- copilotkit.setProperties(properties);
3805
+ copilotkit.setProperties(a2uiCatalogProvided ? {
3806
+ ...properties,
3807
+ a2uiCatalogAvailable: true
3808
+ } : properties);
3790
3809
  copilotkit.setAgents__unsafe_dev_only(mergedAgents);
3791
3810
  copilotkit.setDebug(debug);
3792
3811
  }, [
@@ -3795,6 +3814,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3795
3814
  mergedHeaders,
3796
3815
  credentials,
3797
3816
  properties,
3817
+ a2uiCatalogProvided,
3798
3818
  mergedAgents,
3799
3819
  useSingleEndpoint,
3800
3820
  debug
@@ -3842,7 +3862,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3842
3862
  return JSON.stringify(sandboxFunctionsList.map((fn) => ({
3843
3863
  name: fn.name,
3844
3864
  description: fn.description,
3845
- parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema })
3865
+ parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema: zodToJsonSchemaAdapter })
3846
3866
  })));
3847
3867
  }, [sandboxFunctionsList]);
3848
3868
  useLayoutEffect(() => {
@@ -3863,7 +3883,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3863
3883
  copilotkit,
3864
3884
  executingToolCallIds
3865
3885
  }), [copilotkit, executingToolCallIds]);
3866
- const licenseContextValue = useMemo(() => createLicenseContextValue(null), []);
3886
+ const licenseContextValue = useMemo(() => createLicenseContextValue(runtimeLicenseStatus), [runtimeLicenseStatus]);
3867
3887
  return /* @__PURE__ */ jsx(SandboxFunctionsContext.Provider, {
3868
3888
  value: sandboxFunctionsList,
3869
3889
  children: /* @__PURE__ */ jsx(CopilotKitContext.Provider, {
@@ -3871,8 +3891,8 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3871
3891
  children: /* @__PURE__ */ jsxs(LicenseContext.Provider, {
3872
3892
  value: licenseContextValue,
3873
3893
  children: [
3874
- runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UIBuiltInToolCallRenderer, {}),
3875
- runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UICatalogContext, {
3894
+ a2uiActive && /* @__PURE__ */ jsx(A2UIBuiltInToolCallRenderer, {}),
3895
+ a2uiActive && /* @__PURE__ */ jsx(A2UICatalogContext, {
3876
3896
  catalog: a2ui?.catalog,
3877
3897
  includeSchema: a2ui?.includeSchema
3878
3898
  }),
@@ -3950,16 +3970,20 @@ function useRenderActivityMessage() {
3950
3970
  const renderActivityMessage = useCallback((message) => {
3951
3971
  const renderer = findRenderer(message.activityType);
3952
3972
  if (!renderer) return null;
3953
- const parseResult = renderer.content.safeParse(message.content);
3954
- if (!parseResult.success) {
3955
- console.warn(`Failed to parse content for activity message '${message.activityType}':`, parseResult.error);
3973
+ const parseResult = renderer.content["~standard"].validate(message.content);
3974
+ if (parseResult instanceof Promise) {
3975
+ console.warn(`Async content validation is not supported for activity message '${message.activityType}'`);
3976
+ return null;
3977
+ }
3978
+ if (parseResult.issues) {
3979
+ console.warn(`Failed to parse content for activity message '${message.activityType}':`, parseResult.issues);
3956
3980
  return null;
3957
3981
  }
3958
3982
  const Component = renderer.render;
3959
3983
  const agent = copilotkit.getAgent(agentId);
3960
3984
  return /* @__PURE__ */ jsx(Component, {
3961
3985
  activityType: message.activityType,
3962
- content: parseResult.data,
3986
+ content: parseResult.value,
3963
3987
  message,
3964
3988
  agent
3965
3989
  }, message.id);
@@ -4195,7 +4219,7 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4195
4219
  if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
4196
4220
  const cached = provisionalAgentCache.current.get(agentId);
4197
4221
  if (cached) {
4198
- cached.headers = { ...copilotkit.headers };
4222
+ copilotkit.applyHeadersToAgent(cached);
4199
4223
  return cached;
4200
4224
  }
4201
4225
  const provisional = new ProxiedCopilotRuntimeAgent({
@@ -4204,14 +4228,14 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4204
4228
  transport: copilotkit.runtimeTransport,
4205
4229
  runtimeMode: "pending"
4206
4230
  });
4207
- provisional.headers = { ...copilotkit.headers };
4231
+ copilotkit.applyHeadersToAgent(provisional);
4208
4232
  provisionalAgentCache.current.set(agentId, provisional);
4209
4233
  return provisional;
4210
4234
  }
4211
4235
  if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
4212
4236
  const cached = provisionalAgentCache.current.get(agentId);
4213
4237
  if (cached) {
4214
- cached.headers = { ...copilotkit.headers };
4238
+ copilotkit.applyHeadersToAgent(cached);
4215
4239
  return cached;
4216
4240
  }
4217
4241
  const provisional = new ProxiedCopilotRuntimeAgent({
@@ -4220,7 +4244,7 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4220
4244
  transport: copilotkit.runtimeTransport,
4221
4245
  runtimeMode: "pending"
4222
4246
  });
4223
- provisional.headers = { ...copilotkit.headers };
4247
+ copilotkit.applyHeadersToAgent(provisional);
4224
4248
  provisionalAgentCache.current.set(agentId, provisional);
4225
4249
  return provisional;
4226
4250
  }
@@ -4271,7 +4295,7 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4271
4295
  updateFlags
4272
4296
  ]);
4273
4297
  useEffect(() => {
4274
- if (agent instanceof HttpAgent) agent.headers = { ...copilotkit.headers };
4298
+ if (agent instanceof HttpAgent) copilotkit.applyHeadersToAgent(agent);
4275
4299
  }, [agent, JSON.stringify(copilotkit.headers)]);
4276
4300
  const chatConfig = useCopilotChatConfiguration();
4277
4301
  const configThreadId = chatConfig?.threadId;
@@ -4548,114 +4572,165 @@ const INTERRUPT_EVENT_NAME = "on_interrupt";
4548
4572
  function isPromiseLike(value) {
4549
4573
  return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
4550
4574
  }
4575
+ /** Derive the legacy-compatible `event` for any pending interrupt. */
4576
+ function toLegacyEvent(pending) {
4577
+ if (pending.kind === "legacy") return pending.event;
4578
+ return {
4579
+ name: INTERRUPT_EVENT_NAME,
4580
+ value: pending.interrupts[0]
4581
+ };
4582
+ }
4551
4583
  /**
4552
- * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.
4553
- *
4554
- * The hook listens to custom events on the active agent, stores interrupt payloads per run,
4555
- * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume
4556
- * execution with user-provided data.
4557
- *
4558
- * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.
4559
- * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.
4560
- *
4561
- * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.
4562
- * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.
4563
- *
4564
- * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.
4565
- * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).
4566
- * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).
4567
- * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always
4568
- * either the handler's resolved return value or `null` (including when no handler is provided,
4569
- * when filtering skips the interrupt, or when handler execution fails).
4570
- *
4571
- * @example
4572
- * ```tsx
4573
- * import { useInterrupt } from "@copilotkit/react-core/v2";
4584
+ * Handles agent interrupts with optional filtering, preprocessing, and resume behavior.
4574
4585
  *
4575
- * function InterruptUI() {
4576
- * useInterrupt({
4577
- * render: ({ event, resolve }) => (
4578
- * <div>
4579
- * <p>{event.value.question}</p>
4580
- * <button onClick={() => resolve({ approved: true })}>Approve</button>
4581
- * <button onClick={() => resolve({ approved: false })}>Reject</button>
4582
- * </div>
4583
- * ),
4584
- * });
4586
+ * Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with
4587
+ * `outcome.type === "interrupt"`) and the legacy custom-event flow
4588
+ * (`on_interrupt`). For standard interrupts, `render` receives `interrupt`
4589
+ * (the primary one) and `interrupts` (the full open set); call `resolve(payload)`
4590
+ * to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt
4591
+ * and, once every open interrupt is addressed, submits a single spec `resume`
4592
+ * array via `copilotkit.runAgent`.
4585
4593
  *
4586
- * return null;
4587
- * }
4588
- * ```
4594
+ * - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.
4595
+ * - `renderInChat: false`: the hook returns the interrupt element for manual placement.
4589
4596
  *
4590
4597
  * @example
4591
4598
  * ```tsx
4592
- * import { useInterrupt } from "@copilotkit/react-core/v2";
4593
- *
4594
- * function CustomPanel() {
4595
- * const interruptElement = useInterrupt({
4596
- * renderInChat: false,
4597
- * enabled: (event) => event.value.startsWith("approval:"),
4598
- * handler: async ({ event }) => ({ label: event.value.toUpperCase() }),
4599
- * render: ({ event, result, resolve }) => (
4600
- * <aside>
4601
- * <strong>{result?.label ?? ""}</strong>
4602
- * <button onClick={() => resolve({ value: event.value })}>Continue</button>
4603
- * </aside>
4604
- * ),
4605
- * });
4606
- *
4607
- * return <>{interruptElement}</>;
4608
- * }
4599
+ * useInterrupt({
4600
+ * render: ({ interrupt, resolve, cancel }) => (
4601
+ * <div>
4602
+ * <p>{interrupt?.message}</p>
4603
+ * <button onClick={() => resolve({ approved: true })}>Approve</button>
4604
+ * <button onClick={() => cancel()}>Cancel</button>
4605
+ * </div>
4606
+ * ),
4607
+ * });
4609
4608
  * ```
4610
4609
  */
4611
4610
  function useInterrupt(config) {
4612
4611
  const { copilotkit } = useCopilotKit();
4613
4612
  const { agent } = useAgent({ agentId: config.agentId });
4614
- const [pendingEvent, setPendingEvent] = useState(null);
4615
- const pendingEventRef = useRef(pendingEvent);
4616
- pendingEventRef.current = pendingEvent;
4613
+ const [pending, setPending] = useState(null);
4614
+ const pendingRef = useRef(pending);
4615
+ pendingRef.current = pending;
4617
4616
  const [handlerResult, setHandlerResult] = useState(null);
4617
+ const responsesRef = useRef({});
4618
4618
  useEffect(() => {
4619
- let localInterrupt = null;
4619
+ let localLegacy = null;
4620
+ let localStandard = null;
4620
4621
  const subscription = agent.subscribe({
4621
4622
  onCustomEvent: ({ event }) => {
4622
- if (event.name === INTERRUPT_EVENT_NAME) localInterrupt = {
4623
+ if (event.name === INTERRUPT_EVENT_NAME) localLegacy = {
4623
4624
  name: event.name,
4624
4625
  value: event.value
4625
4626
  };
4626
4627
  },
4628
+ onRunFinishedEvent: (params) => {
4629
+ if (params.outcome === "interrupt") localStandard = params.interrupts;
4630
+ },
4627
4631
  onRunStartedEvent: () => {
4628
- localInterrupt = null;
4629
- setPendingEvent(null);
4632
+ localLegacy = null;
4633
+ localStandard = null;
4634
+ responsesRef.current = {};
4635
+ setPending(null);
4630
4636
  },
4631
4637
  onRunFinalized: () => {
4632
- if (localInterrupt) {
4633
- setPendingEvent(localInterrupt);
4634
- localInterrupt = null;
4635
- }
4638
+ if (localStandard && localStandard.length > 0) setPending({
4639
+ kind: "standard",
4640
+ interrupts: localStandard
4641
+ });
4642
+ else if (localLegacy) setPending({
4643
+ kind: "legacy",
4644
+ event: localLegacy
4645
+ });
4646
+ localLegacy = null;
4647
+ localStandard = null;
4636
4648
  },
4637
4649
  onRunFailed: () => {
4638
- localInterrupt = null;
4639
- setPendingEvent(null);
4650
+ localLegacy = null;
4651
+ localStandard = null;
4652
+ responsesRef.current = {};
4653
+ setPending(null);
4640
4654
  }
4641
4655
  });
4642
4656
  return () => subscription.unsubscribe();
4643
4657
  }, [agent]);
4644
- const resolve = useCallback(async (response) => {
4658
+ const submitStandardIfComplete = useCallback(async (interrupts) => {
4659
+ if (!interrupts.every((i) => responsesRef.current[i.id])) return;
4660
+ const expired = interrupts.find((i) => isInterruptExpired(i));
4661
+ if (expired) {
4662
+ console.error(`[CopilotKit] useInterrupt: interrupt ${expired.id} expired at ${expired.expiresAt}; not resuming.`);
4663
+ responsesRef.current = {};
4664
+ setPending(null);
4665
+ return;
4666
+ }
4667
+ const resume = buildResumeArray(interrupts, responsesRef.current);
4668
+ for (const i of interrupts) {
4669
+ if (!i.toolCallId) continue;
4670
+ const response = responsesRef.current[i.id];
4671
+ const content = response.status === "cancelled" ? { status: "cancelled" } : response.payload ?? { status: "resolved" };
4672
+ agent.addMessage({
4673
+ id: randomUUID(),
4674
+ role: "tool",
4675
+ toolCallId: i.toolCallId,
4676
+ content: JSON.stringify(content)
4677
+ });
4678
+ }
4679
+ responsesRef.current = {};
4645
4680
  try {
4681
+ return await copilotkit.runAgent({
4682
+ agent,
4683
+ resume
4684
+ });
4685
+ } catch (err) {
4686
+ console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
4687
+ setPending(null);
4688
+ throw err;
4689
+ }
4690
+ }, [agent, copilotkit]);
4691
+ const resolve = useCallback(async (payload, interruptId) => {
4692
+ const current = pendingRef.current;
4693
+ if (!current) return;
4694
+ if (current.kind === "legacy") try {
4646
4695
  return await copilotkit.runAgent({
4647
4696
  agent,
4648
4697
  forwardedProps: { command: {
4649
- resume: response,
4650
- interruptEvent: pendingEventRef.current?.value
4698
+ resume: payload,
4699
+ interruptEvent: current.event.value
4651
4700
  } }
4652
4701
  });
4653
4702
  } catch (err) {
4654
4703
  console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
4655
- setPendingEvent(null);
4704
+ setPending(null);
4656
4705
  throw err;
4657
4706
  }
4658
- }, [agent, copilotkit]);
4707
+ if (current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
4708
+ const id = interruptId ?? current.interrupts[0]?.id;
4709
+ if (!id) return;
4710
+ responsesRef.current[id] = {
4711
+ status: "resolved",
4712
+ payload
4713
+ };
4714
+ return submitStandardIfComplete(current.interrupts);
4715
+ }, [
4716
+ agent,
4717
+ copilotkit,
4718
+ submitStandardIfComplete
4719
+ ]);
4720
+ const cancel = useCallback(async (interruptId) => {
4721
+ const current = pendingRef.current;
4722
+ if (!current) return;
4723
+ if (current.kind === "legacy") {
4724
+ console.warn("[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.");
4725
+ setPending(null);
4726
+ return;
4727
+ }
4728
+ if (current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
4729
+ const id = interruptId ?? current.interrupts[0]?.id;
4730
+ if (!id) return;
4731
+ responsesRef.current[id] = { status: "cancelled" };
4732
+ return submitStandardIfComplete(current.interrupts);
4733
+ }, [submitStandardIfComplete]);
4659
4734
  const renderRef = useRef(config.render);
4660
4735
  renderRef.current = config.render;
4661
4736
  const enabledRef = useRef(config.enabled);
@@ -4664,6 +4739,8 @@ function useInterrupt(config) {
4664
4739
  handlerRef.current = config.handler;
4665
4740
  const resolveRef = useRef(resolve);
4666
4741
  resolveRef.current = resolve;
4742
+ const cancelRef = useRef(cancel);
4743
+ cancelRef.current = cancel;
4667
4744
  const isEnabled = (event) => {
4668
4745
  const predicate = enabledRef.current;
4669
4746
  if (!predicate) return true;
@@ -4675,11 +4752,12 @@ function useInterrupt(config) {
4675
4752
  }
4676
4753
  };
4677
4754
  useEffect(() => {
4678
- if (!pendingEvent) {
4755
+ if (!pending) {
4679
4756
  setHandlerResult(null);
4680
4757
  return;
4681
4758
  }
4682
- if (!isEnabled(pendingEvent)) {
4759
+ const legacyEvent = toLegacyEvent(pending);
4760
+ if (!isEnabled(legacyEvent)) {
4683
4761
  setHandlerResult(null);
4684
4762
  return;
4685
4763
  }
@@ -4692,8 +4770,11 @@ function useInterrupt(config) {
4692
4770
  let maybePromise;
4693
4771
  try {
4694
4772
  maybePromise = handler({
4695
- event: pendingEvent,
4696
- resolve: resolveRef.current
4773
+ event: legacyEvent,
4774
+ interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
4775
+ interrupts: pending.kind === "standard" ? pending.interrupts : [],
4776
+ resolve: resolveRef.current,
4777
+ cancel: cancelRef.current
4697
4778
  });
4698
4779
  } catch (err) {
4699
4780
  console.error("[CopilotKit] useInterrupt handler threw; result will be null:", err);
@@ -4712,19 +4793,24 @@ function useInterrupt(config) {
4712
4793
  return () => {
4713
4794
  cancelled = true;
4714
4795
  };
4715
- }, [pendingEvent]);
4796
+ }, [pending]);
4716
4797
  const element = useMemo(() => {
4717
- if (!pendingEvent) return null;
4718
- if (!isEnabled(pendingEvent)) return null;
4798
+ if (!pending) return null;
4799
+ const legacyEvent = toLegacyEvent(pending);
4800
+ if (!isEnabled(legacyEvent)) return null;
4719
4801
  return renderRef.current({
4720
- event: pendingEvent,
4802
+ event: legacyEvent,
4803
+ interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
4804
+ interrupts: pending.kind === "standard" ? pending.interrupts : [],
4721
4805
  result: handlerResult,
4722
- resolve
4806
+ resolve,
4807
+ cancel
4723
4808
  });
4724
4809
  }, [
4725
- pendingEvent,
4810
+ pending,
4726
4811
  handlerResult,
4727
- resolve
4812
+ resolve,
4813
+ cancel
4728
4814
  ]);
4729
4815
  useEffect(() => {
4730
4816
  if (config.renderInChat === false) return;
@@ -4760,9 +4846,9 @@ function useThreadStoreSelector(store, selector) {
4760
4846
  * current without polling — thread creates, renames, archives, and deletes
4761
4847
  * from any client are reflected immediately.
4762
4848
  *
4763
- * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
4764
- * promises that resolve once the platform confirms the operation and reject
4765
- * with an `Error` on failure.
4849
+ * Mutation methods (`renameThread`, `archiveThread`, `unarchiveThread`,
4850
+ * `deleteThread`) return promises that resolve once the platform confirms the
4851
+ * operation and reject with an `Error` on failure.
4766
4852
  *
4767
4853
  * @param input - Agent identifier and optional list controls.
4768
4854
  * @returns Thread list state and stable mutation callbacks.
@@ -4889,6 +4975,7 @@ function useThreads$1({ agentId, includeArchived, limit }) {
4889
4975
  }, [threadMutationsError]);
4890
4976
  const renameThread = useMemo(() => guardMutation((threadId, name) => store.renameThread(threadId, name)), [store, guardMutation]);
4891
4977
  const archiveThread = useMemo(() => guardMutation((threadId) => store.archiveThread(threadId)), [store, guardMutation]);
4978
+ const unarchiveThread = useMemo(() => guardMutation((threadId) => store.unarchiveThread(threadId)), [store, guardMutation]);
4892
4979
  const deleteThread = useMemo(() => guardMutation((threadId) => store.deleteThread(threadId)), [store, guardMutation]);
4893
4980
  return {
4894
4981
  threads,
@@ -4899,6 +4986,7 @@ function useThreads$1({ agentId, includeArchived, limit }) {
4899
4986
  fetchMoreThreads: useCallback(() => store.fetchNextPage(), [store]),
4900
4987
  renameThread,
4901
4988
  archiveThread,
4989
+ unarchiveThread,
4902
4990
  deleteThread
4903
4991
  };
4904
4992
  }
@@ -4932,7 +5020,7 @@ async function recordAnnotation(args) {
4932
5020
  const body = {
4933
5021
  type,
4934
5022
  threadId,
4935
- clientEventId: args.clientEventId ?? randomUUID(),
5023
+ clientEventId: args.clientEventId ?? randomUUID$1(),
4936
5024
  ...payload !== void 0 ? { payload } : {},
4937
5025
  ...occurredAt !== void 0 ? { occurredAt } : {}
4938
5026
  };
@@ -5110,7 +5198,7 @@ function useAttachments({ config }) {
5110
5198
  continue;
5111
5199
  }
5112
5200
  const modality = getModalityFromMimeType(file.type);
5113
- const placeholderId = randomUUID();
5201
+ const placeholderId = randomUUID$1();
5114
5202
  const placeholder = {
5115
5203
  id: placeholderId,
5116
5204
  type: modality,
@@ -7621,7 +7709,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7621
7709
  const existingConfig = useCopilotChatConfiguration();
7622
7710
  const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;
7623
7711
  const providedThreadId = threadId ?? existingConfig?.threadId;
7624
- const resolvedThreadId = useMemo(() => providedThreadId ?? randomUUID(), [providedThreadId]);
7712
+ const resolvedThreadId = useMemo(() => providedThreadId ?? randomUUID$1(), [providedThreadId]);
7625
7713
  const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
7626
7714
  const { agent } = useAgent({
7627
7715
  agentId: resolvedAgentId,
@@ -7696,8 +7784,10 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7696
7784
  hasExplicitThreadId
7697
7785
  ]);
7698
7786
  const waitForActiveRunToSettle = useCallback(async () => {
7699
- if (agent.isRunning && isRunCompletionAware(agent) && agent.activeRunCompletionPromise) try {
7700
- await agent.activeRunCompletionPromise;
7787
+ const maybeAware = agent;
7788
+ const activeRunCompletionPromise = isRunCompletionAware(maybeAware) ? maybeAware.activeRunCompletionPromise : void 0;
7789
+ if (agent.isRunning && activeRunCompletionPromise) try {
7790
+ await activeRunCompletionPromise;
7701
7791
  } catch (error) {
7702
7792
  console.error("CopilotChat: in-flight run rejected while queuing send", error);
7703
7793
  }
@@ -7732,12 +7822,12 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7732
7822
  }
7733
7823
  });
7734
7824
  agent.addMessage({
7735
- id: randomUUID(),
7825
+ id: randomUUID$1(),
7736
7826
  role: "user",
7737
7827
  content: contentParts
7738
7828
  });
7739
7829
  } else agent.addMessage({
7740
- id: randomUUID(),
7830
+ id: randomUUID$1(),
7741
7831
  role: "user",
7742
7832
  content: value
7743
7833
  });
@@ -7754,7 +7844,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7754
7844
  const handleSelectSuggestion = useCallback(async (suggestion) => {
7755
7845
  await waitForActiveRunToSettle();
7756
7846
  agent.addMessage({
7757
- id: randomUUID(),
7847
+ id: randomUUID$1(),
7758
7848
  role: "user",
7759
7849
  content: suggestion.message
7760
7850
  });
@@ -9675,7 +9765,7 @@ function useCoAgentStateRenders() {
9675
9765
  //#region src/context/threads-context.tsx
9676
9766
  const ThreadsContext = createContext(void 0);
9677
9767
  function ThreadsProvider({ children, threadId: explicitThreadId }) {
9678
- const [internalThreadId, setInternalThreadId] = useState(() => randomUUID());
9768
+ const [internalThreadId, setInternalThreadId] = useState(() => randomUUID$1());
9679
9769
  const [internalIsExplicit, setInternalIsExplicit] = useState(false);
9680
9770
  const threadId = explicitThreadId ?? internalThreadId;
9681
9771
  const isThreadIdExplicit = explicitThreadId != null || internalIsExplicit;
@@ -10136,6 +10226,7 @@ function CopilotKit({ children, ...props }) {
10136
10226
  const showInspector = shouldShowDevConsole(props.enableInspector);
10137
10227
  const publicApiKey = props.publicApiKey || props.publicLicenseKey;
10138
10228
  const renderArr = useMemo(() => [{ render: CoAgentStateRenderBridge }], []);
10229
+ const { onError: _onError, ...v2Props } = props;
10139
10230
  return /* @__PURE__ */ jsx(ToastProvider, {
10140
10231
  enabled,
10141
10232
  children: /* @__PURE__ */ jsx(CopilotErrorBoundary, {
@@ -10144,7 +10235,7 @@ function CopilotKit({ children, ...props }) {
10144
10235
  children: /* @__PURE__ */ jsx(ThreadsProvider, {
10145
10236
  threadId: props.threadId,
10146
10237
  children: /* @__PURE__ */ jsx(CopilotKitProvider, {
10147
- ...props,
10238
+ ...v2Props,
10148
10239
  showDevConsole: showInspector,
10149
10240
  renderCustomMessages: renderArr,
10150
10241
  useSingleEndpoint: props.useSingleEndpoint ?? true,
@@ -10443,7 +10534,7 @@ function CopilotKitInternal(cpkProps) {
10443
10534
  });
10444
10535
  }, [setAuthStates]);
10445
10536
  const handleSetRegisteredActions = useCallback((actionConfig) => {
10446
- const key = actionConfig.action.name || randomUUID();
10537
+ const key = actionConfig.action.name || randomUUID$1();
10447
10538
  setRegisteredActionConfigs((prev) => {
10448
10539
  const newMap = new Map(prev);
10449
10540
  newMap.set(key, actionConfig);
@@ -10629,4 +10720,4 @@ function validateProps(props) {
10629
10720
 
10630
10721
  //#endregion
10631
10722
  export { useAgent as $, INTELLIGENCE_TURN_HEAD as A, CopilotChatToolCallsView as B, CopilotChatToggleButton as C, useCopilotChatConfiguration as Ct, CopilotChatView_default as D, CopilotChat as E, CopilotChatSuggestionPill as F, useLearnFromUserAction as G, useLearningContainers as H, CopilotChatReasoningMessage_default as I, useConfigureSuggestions as J, useThreads$1 as K, CopilotChatUserMessage_default as L, getIntelligenceTurnAnchors as M, IntelligenceIndicatorView as N, CopilotChatAttachmentQueue as O, CopilotChatSuggestionView as P, UseAgentUpdate as Q, CopilotChatAttachmentRenderer as R, CopilotModalHeader as S, CopilotChatConfigurationProvider as St, DefaultOpenIcon as T, useAttachments as U, useLearningContainersInCurrentThread as V, useLearnFromUserActionInCurrentThread as W, useAgentContext as X, useSuggestions as Y, useCapabilities as Z, WildcardToolCallRender as _, useCopilotKit as _t, ThreadsProvider as a, CopilotKitProvider as at, CopilotPopupView as b, AudioRecorderError as bt, CoAgentStateRendersProvider as c, useSandboxFunctions as ct, shouldShowDevConsole as d, MCPAppsActivityType as dt, useHumanInTheLoop as et, useToast as f, CopilotKitInspector as ft, useCopilotContext as g, defineToolCallRenderer as gt, CopilotContext as h, useRenderTool as ht, ThreadsContext as i, useRenderCustomMessages as it, IntelligenceIndicator as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, MCPAppsActivityContentSchema as lt, useCopilotMessagesContext as m, useDefaultRenderTool as mt, defaultCopilotContextCategories as n, useFrontendTool as nt, useThreads as o, createA2UIMessageRenderer as ot, CopilotMessagesContext as p, useRenderToolCall as pt, useInterrupt as q, CoAgentStateRenderBridge as r, useRenderActivityMessage as rt, CoAgentStateRendersContext as s, SandboxFunctionsContext as st, CopilotKit as t, useComponent as tt, useAsyncCallback as u, MCPAppsActivityRenderer as ut, CopilotPopup as v, CopilotKitCoreReact as vt, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotChatAudioRecorder as xt, CopilotSidebar as y, CopilotChatInput_default as yt, CopilotChatAssistantMessage_default as z };
10632
- //# sourceMappingURL=copilotkit-UY-H6Kx7.mjs.map
10723
+ //# sourceMappingURL=copilotkit-Be-o2UaU.mjs.map