@copilotkit/react-core 1.57.0 → 1.57.1-canary.1778272612

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 (86) hide show
  1. package/dist/{copilotkit-CPe2-340.mjs → copilotkit-3XTEoVQO.mjs} +1367 -1200
  2. package/dist/copilotkit-3XTEoVQO.mjs.map +1 -0
  3. package/dist/{copilotkit-DFaI4j2r.d.mts → copilotkit-BCJ2yvV6.d.mts} +68 -8
  4. package/dist/copilotkit-BCJ2yvV6.d.mts.map +1 -0
  5. package/dist/{copilotkit-Dg4r4Gi_.d.cts → copilotkit-CBbSvze0.d.cts} +68 -8
  6. package/dist/copilotkit-CBbSvze0.d.cts.map +1 -0
  7. package/dist/{copilotkit-DGbvw8n2.cjs → copilotkit-Dnj9pi4m.cjs} +1369 -1196
  8. package/dist/copilotkit-Dnj9pi4m.cjs.map +1 -0
  9. package/dist/index.cjs +2 -5
  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 +2 -5
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/index.umd.js +733 -610
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/v2/context.cjs +135 -0
  18. package/dist/v2/context.cjs.map +1 -0
  19. package/dist/v2/context.d.cts +148 -0
  20. package/dist/v2/context.d.cts.map +1 -0
  21. package/dist/v2/context.d.mts +148 -0
  22. package/dist/v2/context.d.mts.map +1 -0
  23. package/dist/v2/context.mjs +129 -0
  24. package/dist/v2/context.mjs.map +1 -0
  25. package/dist/v2/headless.cjs +1043 -0
  26. package/dist/v2/headless.cjs.map +1 -0
  27. package/dist/v2/headless.d.cts +605 -0
  28. package/dist/v2/headless.d.cts.map +1 -0
  29. package/dist/v2/headless.d.mts +512 -0
  30. package/dist/v2/headless.d.mts.map +1 -0
  31. package/dist/v2/headless.mjs +997 -0
  32. package/dist/v2/headless.mjs.map +1 -0
  33. package/dist/v2/index.cjs +2 -1
  34. package/dist/v2/index.css +1 -1
  35. package/dist/v2/index.d.cts +2 -2
  36. package/dist/v2/index.d.mts +2 -2
  37. package/dist/v2/index.mjs +2 -2
  38. package/dist/v2/index.umd.js +1385 -1204
  39. package/dist/v2/index.umd.js.map +1 -1
  40. package/package.json +14 -6
  41. package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +5 -6
  42. package/src/hooks/use-copilot-chat_internal.ts +0 -1
  43. package/src/v2/components/chat/CopilotChat.tsx +2 -1
  44. package/src/v2/components/chat/CopilotChatMessageView.tsx +24 -9
  45. package/src/v2/components/chat/CopilotChatView.tsx +2 -2
  46. package/src/v2/components/chat/CopilotSidebar.tsx +5 -1
  47. package/src/v2/components/chat/CopilotSidebarView.tsx +24 -10
  48. package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +1 -3
  49. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +29 -25
  50. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.tsx +159 -0
  51. package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.tsx +5 -60
  52. package/src/v2/components/index.ts +1 -0
  53. package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +286 -0
  54. package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +464 -0
  55. package/src/v2/components/intelligence-indicator/index.ts +2 -0
  56. package/src/v2/context.ts +62 -0
  57. package/src/v2/headless.ts +42 -0
  58. package/src/v2/hooks/__tests__/standard-schema.test.tsx +2 -2
  59. package/src/v2/hooks/__tests__/use-agent-context.test.tsx +3 -3
  60. package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +3 -3
  61. package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +85 -85
  62. package/src/v2/hooks/__tests__/use-interrupt.test.tsx +2 -2
  63. package/src/v2/hooks/__tests__/use-render-tool.test.tsx +2 -2
  64. package/src/v2/hooks/__tests__/use-threads.test.tsx +2 -2
  65. package/src/v2/hooks/__tests__/zod-regression.test.tsx +2 -2
  66. package/src/v2/hooks/use-agent-context.tsx +1 -1
  67. package/src/v2/hooks/use-agent.tsx +9 -118
  68. package/src/v2/hooks/use-configure-suggestions.tsx +1 -1
  69. package/src/v2/hooks/use-default-render-tool.tsx +18 -1
  70. package/src/v2/hooks/use-frontend-tool.tsx +2 -2
  71. package/src/v2/hooks/use-human-in-the-loop.tsx +1 -1
  72. package/src/v2/hooks/use-interrupt.tsx +1 -1
  73. package/src/v2/hooks/use-render-activity-message.tsx +3 -11
  74. package/src/v2/hooks/use-render-custom-messages.tsx +1 -6
  75. package/src/v2/hooks/use-render-tool-call.tsx +36 -6
  76. package/src/v2/hooks/use-render-tool.tsx +2 -2
  77. package/src/v2/hooks/use-suggestions.tsx +1 -1
  78. package/src/v2/hooks/use-threads.tsx +1 -1
  79. package/src/v2/providers/CopilotKitProvider.tsx +19 -59
  80. package/src/v2/styles/globals.css +118 -0
  81. package/tsdown.config.ts +75 -0
  82. package/dist/copilotkit-CPe2-340.mjs.map +0 -1
  83. package/dist/copilotkit-DFaI4j2r.d.mts.map +0 -1
  84. package/dist/copilotkit-DGbvw8n2.cjs.map +0 -1
  85. package/dist/copilotkit-Dg4r4Gi_.d.cts.map +0 -1
  86. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +0 -333
@@ -0,0 +1,1043 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) {
14
+ __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ }
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
26
+ }) : target, mod));
27
+
28
+ //#endregion
29
+ let _copilotkit_react_core_v2_context = require("@copilotkit/react-core/v2/context");
30
+ let react = require("react");
31
+ react = __toESM(react);
32
+ let _copilotkit_shared = require("@copilotkit/shared");
33
+ let tailwind_merge = require("tailwind-merge");
34
+ let react_jsx_runtime = require("react/jsx-runtime");
35
+ let _ag_ui_client = require("@ag-ui/client");
36
+ let _copilotkit_core = require("@copilotkit/core");
37
+
38
+ //#region src/v2/lib/slots.tsx
39
+ /**
40
+ * Shallow equality comparison for objects.
41
+ */
42
+ function shallowEqual(obj1, obj2) {
43
+ const keys1 = Object.keys(obj1);
44
+ const keys2 = Object.keys(obj2);
45
+ if (keys1.length !== keys2.length) return false;
46
+ for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
47
+ return true;
48
+ }
49
+ /**
50
+ * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
51
+ * class instances, and other exotic objects that happen to have typeof "object".
52
+ */
53
+ function isPlainObject(obj) {
54
+ return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
55
+ }
56
+ /**
57
+ * Returns the same reference as long as the value is shallowly equal to the
58
+ * previous render's value.
59
+ *
60
+ * - Identical references bail out immediately (O(1)).
61
+ * - Plain objects ({}) are shallow-compared key-by-key.
62
+ * - Arrays, Dates, class instances, functions, and primitives are compared by
63
+ * reference only — shallowEqual is never called on non-plain objects, which
64
+ * avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
65
+ *
66
+ * Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
67
+ * equality check isn't defeated by a new object reference on every render.
68
+ */
69
+ function useShallowStableRef(value) {
70
+ const ref = (0, react.useRef)(value);
71
+ if (ref.current === value) return ref.current;
72
+ if (isPlainObject(ref.current) && isPlainObject(value)) {
73
+ if (shallowEqual(ref.current, value)) return ref.current;
74
+ }
75
+ ref.current = value;
76
+ return ref.current;
77
+ }
78
+ /**
79
+ * Check if a value is a React component type (function, class, forwardRef, memo, etc.)
80
+ */
81
+ function isReactComponentType(value) {
82
+ if (typeof value === "function") return true;
83
+ if (value && typeof value === "object" && "$$typeof" in value && !react.default.isValidElement(value)) return true;
84
+ return false;
85
+ }
86
+ /**
87
+ * Internal function to render a slot value as a React element (non-memoized).
88
+ */
89
+ function renderSlotElement(slot, DefaultComponent, props) {
90
+ if (typeof slot === "string") {
91
+ const existingClassName = props.className;
92
+ return react.default.createElement(DefaultComponent, {
93
+ ...props,
94
+ className: (0, tailwind_merge.twMerge)(existingClassName, slot)
95
+ });
96
+ }
97
+ if (isReactComponentType(slot)) return react.default.createElement(slot, props);
98
+ if (slot && typeof slot === "object" && !react.default.isValidElement(slot)) return react.default.createElement(DefaultComponent, {
99
+ ...props,
100
+ ...slot
101
+ });
102
+ return react.default.createElement(DefaultComponent, props);
103
+ }
104
+ /**
105
+ * Internal memoized wrapper component for renderSlot.
106
+ * Uses forwardRef to support ref forwarding.
107
+ */
108
+ const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function MemoizedSlotWrapper(props, ref) {
109
+ const { $slot, $component, ...rest } = props;
110
+ return renderSlotElement($slot, $component, ref !== null ? {
111
+ ...rest,
112
+ ref
113
+ } : rest);
114
+ }), (prev, next) => {
115
+ if (prev.$slot !== next.$slot) return false;
116
+ if (prev.$component !== next.$component) return false;
117
+ const { $slot: _ps, $component: _pc, ...prevRest } = prev;
118
+ const { $slot: _ns, $component: _nc, ...nextRest } = next;
119
+ return shallowEqual(prevRest, nextRest);
120
+ });
121
+
122
+ //#endregion
123
+ //#region src/v2/providers/CopilotChatConfigurationProvider.tsx
124
+ const CopilotChatDefaultLabels = {
125
+ chatInputPlaceholder: "Type a message...",
126
+ chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
127
+ chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
128
+ chatInputToolbarFinishTranscribeButtonLabel: "Finish",
129
+ chatInputToolbarAddButtonLabel: "Add attachments",
130
+ chatInputToolbarToolsButtonLabel: "Tools",
131
+ assistantMessageToolbarCopyCodeLabel: "Copy",
132
+ assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
133
+ assistantMessageToolbarCopyMessageLabel: "Copy",
134
+ assistantMessageToolbarThumbsUpLabel: "Good response",
135
+ assistantMessageToolbarThumbsDownLabel: "Bad response",
136
+ assistantMessageToolbarReadAloudLabel: "Read aloud",
137
+ assistantMessageToolbarRegenerateLabel: "Regenerate",
138
+ userMessageToolbarCopyMessageLabel: "Copy",
139
+ userMessageToolbarEditMessageLabel: "Edit",
140
+ chatDisclaimerText: "AI can make mistakes. Please verify important information.",
141
+ chatToggleOpenLabel: "Open chat",
142
+ chatToggleCloseLabel: "Close chat",
143
+ modalHeaderTitle: "CopilotKit Chat",
144
+ welcomeMessageText: "How can I help you today?"
145
+ };
146
+ const CopilotChatConfiguration = (0, react.createContext)(null);
147
+ const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
148
+ const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
149
+ const stableLabels = useShallowStableRef(labels);
150
+ const mergedLabels = (0, react.useMemo)(() => ({
151
+ ...CopilotChatDefaultLabels,
152
+ ...parentConfig?.labels,
153
+ ...stableLabels
154
+ }), [stableLabels, parentConfig?.labels]);
155
+ const resolvedAgentId = agentId ?? parentConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
156
+ const resolvedThreadId = (0, react.useMemo)(() => {
157
+ if (threadId) return threadId;
158
+ if (parentConfig?.threadId) return parentConfig.threadId;
159
+ return (0, _copilotkit_shared.randomUUID)();
160
+ }, [threadId, parentConfig?.threadId]);
161
+ const resolvedHasExplicitThreadId = (hasExplicitThreadId !== void 0 ? hasExplicitThreadId : !!threadId) || !!parentConfig?.hasExplicitThreadId;
162
+ const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen ?? true);
163
+ const hasExplicitDefault = isModalDefaultOpen !== void 0;
164
+ const setAndSync = (0, react.useCallback)((open) => {
165
+ setInternalModalOpen(open);
166
+ parentConfig?.setModalOpen(open);
167
+ }, [parentConfig?.setModalOpen]);
168
+ const isMounted = (0, react.useRef)(false);
169
+ (0, react.useEffect)(() => {
170
+ if (!hasExplicitDefault) return;
171
+ if (!isMounted.current) {
172
+ isMounted.current = true;
173
+ return;
174
+ }
175
+ if (parentConfig?.isModalOpen === void 0) return;
176
+ setInternalModalOpen(parentConfig.isModalOpen);
177
+ }, [parentConfig?.isModalOpen, hasExplicitDefault]);
178
+ const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : parentConfig?.isModalOpen ?? internalModalOpen;
179
+ const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : parentConfig?.setModalOpen ?? setInternalModalOpen;
180
+ const configurationValue = (0, react.useMemo)(() => ({
181
+ labels: mergedLabels,
182
+ agentId: resolvedAgentId,
183
+ threadId: resolvedThreadId,
184
+ hasExplicitThreadId: resolvedHasExplicitThreadId,
185
+ isModalOpen: resolvedIsModalOpen,
186
+ setModalOpen: resolvedSetModalOpen
187
+ }), [
188
+ mergedLabels,
189
+ resolvedAgentId,
190
+ resolvedThreadId,
191
+ resolvedHasExplicitThreadId,
192
+ resolvedIsModalOpen,
193
+ resolvedSetModalOpen
194
+ ]);
195
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
196
+ value: configurationValue,
197
+ children
198
+ });
199
+ };
200
+ const useCopilotChatConfiguration = () => {
201
+ return (0, react.useContext)(CopilotChatConfiguration);
202
+ };
203
+
204
+ //#endregion
205
+ //#region src/v2/hooks/use-agent.tsx
206
+ let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
207
+ UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
208
+ UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
209
+ UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
210
+ return UseAgentUpdate;
211
+ }({});
212
+ const ALL_UPDATES = [
213
+ UseAgentUpdate.OnMessagesChanged,
214
+ UseAgentUpdate.OnStateChanged,
215
+ UseAgentUpdate.OnRunStatusChanged
216
+ ];
217
+ function useAgent({ agentId, updates, throttleMs } = {}) {
218
+ agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
219
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
220
+ const providerThrottleMs = copilotkit.defaultThrottleMs;
221
+ const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
222
+ const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
223
+ const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
224
+ const agent = (0, react.useMemo)(() => {
225
+ const existing = copilotkit.getAgent(agentId);
226
+ if (existing) {
227
+ provisionalAgentCache.current.delete(agentId);
228
+ return existing;
229
+ }
230
+ const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
231
+ const status = copilotkit.runtimeConnectionStatus;
232
+ if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
233
+ const cached = provisionalAgentCache.current.get(agentId);
234
+ if (cached) {
235
+ cached.headers = { ...copilotkit.headers };
236
+ return cached;
237
+ }
238
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
239
+ runtimeUrl: copilotkit.runtimeUrl,
240
+ agentId,
241
+ transport: copilotkit.runtimeTransport,
242
+ runtimeMode: "pending"
243
+ });
244
+ provisional.headers = { ...copilotkit.headers };
245
+ provisionalAgentCache.current.set(agentId, provisional);
246
+ return provisional;
247
+ }
248
+ if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
249
+ const cached = provisionalAgentCache.current.get(agentId);
250
+ if (cached) {
251
+ cached.headers = { ...copilotkit.headers };
252
+ return cached;
253
+ }
254
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
255
+ runtimeUrl: copilotkit.runtimeUrl,
256
+ agentId,
257
+ transport: copilotkit.runtimeTransport,
258
+ runtimeMode: "pending"
259
+ });
260
+ provisional.headers = { ...copilotkit.headers };
261
+ provisionalAgentCache.current.set(agentId, provisional);
262
+ return provisional;
263
+ }
264
+ const knownAgents = Object.keys(copilotkit.agents ?? {});
265
+ const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
266
+ 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.");
267
+ }, [
268
+ agentId,
269
+ copilotkit.agents,
270
+ copilotkit.runtimeConnectionStatus,
271
+ copilotkit.runtimeUrl,
272
+ copilotkit.runtimeTransport,
273
+ JSON.stringify(copilotkit.headers)
274
+ ]);
275
+ (0, react.useEffect)(() => {
276
+ if (updateFlags.length === 0) return;
277
+ let active = true;
278
+ const handlers = {};
279
+ let batchScheduled = false;
280
+ const batchedForceUpdate = () => {
281
+ if (!active) return;
282
+ if (!batchScheduled) {
283
+ batchScheduled = true;
284
+ queueMicrotask(() => {
285
+ batchScheduled = false;
286
+ if (active) forceUpdate();
287
+ });
288
+ }
289
+ };
290
+ if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = batchedForceUpdate;
291
+ if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
292
+ if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
293
+ handlers.onRunInitialized = batchedForceUpdate;
294
+ handlers.onRunFinalized = batchedForceUpdate;
295
+ handlers.onRunFailed = batchedForceUpdate;
296
+ handlers.onRunErrorEvent = batchedForceUpdate;
297
+ }
298
+ const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
299
+ return () => {
300
+ active = false;
301
+ subscription.unsubscribe();
302
+ };
303
+ }, [
304
+ agent,
305
+ forceUpdate,
306
+ throttleMs,
307
+ providerThrottleMs,
308
+ updateFlags
309
+ ]);
310
+ (0, react.useEffect)(() => {
311
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
312
+ }, [agent, JSON.stringify(copilotkit.headers)]);
313
+ return { agent };
314
+ }
315
+
316
+ //#endregion
317
+ //#region src/v2/hooks/use-frontend-tool.tsx
318
+ const EMPTY_DEPS = [];
319
+ function useFrontendTool(tool, deps) {
320
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
321
+ const extraDeps = deps ?? EMPTY_DEPS;
322
+ (0, react.useEffect)(() => {
323
+ const name = tool.name;
324
+ if (copilotkit.getTool({
325
+ toolName: name,
326
+ agentId: tool.agentId
327
+ })) {
328
+ console.warn(`Tool '${name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`);
329
+ copilotkit.removeTool(name, tool.agentId);
330
+ }
331
+ copilotkit.addTool(tool);
332
+ if (tool.render) copilotkit.addHookRenderToolCall({
333
+ name,
334
+ args: tool.parameters,
335
+ agentId: tool.agentId,
336
+ render: tool.render
337
+ });
338
+ return () => {
339
+ copilotkit.removeTool(name, tool.agentId);
340
+ };
341
+ }, [
342
+ tool.name,
343
+ tool.available,
344
+ copilotkit,
345
+ JSON.stringify(extraDeps)
346
+ ]);
347
+ }
348
+
349
+ //#endregion
350
+ //#region src/v2/hooks/use-component.tsx
351
+ /**
352
+ * Registers a React component as a frontend tool renderer in chat.
353
+ *
354
+ * This hook is a convenience wrapper around `useFrontendTool` that:
355
+ * - builds a model-facing tool description,
356
+ * - forwards optional schema parameters (any Standard Schema V1 compatible library),
357
+ * - renders your component with tool call parameters.
358
+ *
359
+ * Use this when you want to display a typed visual component for a tool call
360
+ * without manually wiring a full frontend tool object.
361
+ *
362
+ * When `parameters` is provided, render props are inferred from the schema.
363
+ * When omitted, the render component may accept any props.
364
+ *
365
+ * @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.
366
+ * @param config - Tool registration config.
367
+ * @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).
368
+ *
369
+ * @example
370
+ * ```tsx
371
+ * // Without parameters — render accepts any props
372
+ * useComponent({
373
+ * name: "showGreeting",
374
+ * render: ({ message }: { message: string }) => <div>{message}</div>,
375
+ * });
376
+ * ```
377
+ *
378
+ * @example
379
+ * ```tsx
380
+ * // With parameters — render props inferred from schema
381
+ * useComponent({
382
+ * name: "showWeatherCard",
383
+ * parameters: z.object({ city: z.string() }),
384
+ * render: ({ city }) => <div>{city}</div>,
385
+ * });
386
+ * ```
387
+ *
388
+ * @example
389
+ * ```tsx
390
+ * useComponent(
391
+ * {
392
+ * name: "renderProfile",
393
+ * parameters: z.object({ userId: z.string() }),
394
+ * render: ProfileCard,
395
+ * agentId: "support-agent",
396
+ * },
397
+ * [selectedAgentId],
398
+ * );
399
+ * ```
400
+ */
401
+ function useComponent(config, deps) {
402
+ const prefix = `Use this tool to display the "${config.name}" component in the chat. This tool renders a visual UI component for the user.`;
403
+ const fullDescription = config.description ? `${prefix}\n\n${config.description}` : prefix;
404
+ useFrontendTool({
405
+ name: config.name,
406
+ description: fullDescription,
407
+ parameters: config.parameters,
408
+ render: ({ args }) => {
409
+ const Component = config.render;
410
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...args });
411
+ },
412
+ agentId: config.agentId
413
+ }, deps);
414
+ }
415
+
416
+ //#endregion
417
+ //#region src/v2/hooks/use-human-in-the-loop.tsx
418
+ function useHumanInTheLoop(tool, deps) {
419
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
420
+ const resolvePromiseRef = (0, react.useRef)(null);
421
+ const respond = (0, react.useCallback)(async (result) => {
422
+ if (resolvePromiseRef.current) {
423
+ resolvePromiseRef.current(result);
424
+ resolvePromiseRef.current = null;
425
+ }
426
+ }, []);
427
+ const handler = (0, react.useCallback)(async () => {
428
+ return new Promise((resolve) => {
429
+ resolvePromiseRef.current = resolve;
430
+ });
431
+ }, []);
432
+ const RenderComponent = (0, react.useCallback)((props) => {
433
+ const ToolComponent = tool.render;
434
+ if (props.status === "inProgress") {
435
+ const enhancedProps = {
436
+ ...props,
437
+ name: tool.name,
438
+ description: tool.description || "",
439
+ respond: void 0
440
+ };
441
+ return react.default.createElement(ToolComponent, enhancedProps);
442
+ } else if (props.status === "executing") {
443
+ const enhancedProps = {
444
+ ...props,
445
+ name: tool.name,
446
+ description: tool.description || "",
447
+ respond
448
+ };
449
+ return react.default.createElement(ToolComponent, enhancedProps);
450
+ } else if (props.status === "complete") {
451
+ const enhancedProps = {
452
+ ...props,
453
+ name: tool.name,
454
+ description: tool.description || "",
455
+ respond: void 0
456
+ };
457
+ return react.default.createElement(ToolComponent, enhancedProps);
458
+ }
459
+ return react.default.createElement(ToolComponent, props);
460
+ }, [
461
+ tool.render,
462
+ tool.name,
463
+ tool.description,
464
+ respond
465
+ ]);
466
+ useFrontendTool({
467
+ ...tool,
468
+ handler,
469
+ render: RenderComponent
470
+ }, deps);
471
+ (0, react.useEffect)(() => {
472
+ return () => {
473
+ copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
474
+ };
475
+ }, [
476
+ copilotkit,
477
+ tool.name,
478
+ tool.agentId
479
+ ]);
480
+ }
481
+
482
+ //#endregion
483
+ //#region src/v2/hooks/use-interrupt.tsx
484
+ const INTERRUPT_EVENT_NAME = "on_interrupt";
485
+ function isPromiseLike(value) {
486
+ return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
487
+ }
488
+ /**
489
+ * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.
490
+ *
491
+ * The hook listens to custom events on the active agent, stores interrupt payloads per run,
492
+ * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume
493
+ * execution with user-provided data.
494
+ *
495
+ * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.
496
+ * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.
497
+ *
498
+ * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.
499
+ * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.
500
+ *
501
+ * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.
502
+ * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).
503
+ * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).
504
+ * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always
505
+ * either the handler's resolved return value or `null` (including when no handler is provided,
506
+ * when filtering skips the interrupt, or when handler execution fails).
507
+ *
508
+ * @example
509
+ * ```tsx
510
+ * import { useInterrupt } from "@copilotkit/react-core/v2";
511
+ *
512
+ * function InterruptUI() {
513
+ * useInterrupt({
514
+ * render: ({ event, resolve }) => (
515
+ * <div>
516
+ * <p>{event.value.question}</p>
517
+ * <button onClick={() => resolve({ approved: true })}>Approve</button>
518
+ * <button onClick={() => resolve({ approved: false })}>Reject</button>
519
+ * </div>
520
+ * ),
521
+ * });
522
+ *
523
+ * return null;
524
+ * }
525
+ * ```
526
+ *
527
+ * @example
528
+ * ```tsx
529
+ * import { useInterrupt } from "@copilotkit/react-core/v2";
530
+ *
531
+ * function CustomPanel() {
532
+ * const interruptElement = useInterrupt({
533
+ * renderInChat: false,
534
+ * enabled: (event) => event.value.startsWith("approval:"),
535
+ * handler: async ({ event }) => ({ label: event.value.toUpperCase() }),
536
+ * render: ({ event, result, resolve }) => (
537
+ * <aside>
538
+ * <strong>{result?.label ?? ""}</strong>
539
+ * <button onClick={() => resolve({ value: event.value })}>Continue</button>
540
+ * </aside>
541
+ * ),
542
+ * });
543
+ *
544
+ * return <>{interruptElement}</>;
545
+ * }
546
+ * ```
547
+ */
548
+ function useInterrupt(config) {
549
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
550
+ const { agent } = useAgent({ agentId: config.agentId });
551
+ const [pendingEvent, setPendingEvent] = (0, react.useState)(null);
552
+ const pendingEventRef = (0, react.useRef)(pendingEvent);
553
+ pendingEventRef.current = pendingEvent;
554
+ const [handlerResult, setHandlerResult] = (0, react.useState)(null);
555
+ (0, react.useEffect)(() => {
556
+ let localInterrupt = null;
557
+ const subscription = agent.subscribe({
558
+ onCustomEvent: ({ event }) => {
559
+ if (event.name === INTERRUPT_EVENT_NAME) localInterrupt = {
560
+ name: event.name,
561
+ value: event.value
562
+ };
563
+ },
564
+ onRunStartedEvent: () => {
565
+ localInterrupt = null;
566
+ setPendingEvent(null);
567
+ },
568
+ onRunFinalized: () => {
569
+ if (localInterrupt) {
570
+ setPendingEvent(localInterrupt);
571
+ localInterrupt = null;
572
+ }
573
+ },
574
+ onRunFailed: () => {
575
+ localInterrupt = null;
576
+ }
577
+ });
578
+ return () => subscription.unsubscribe();
579
+ }, [agent]);
580
+ const resolve = (0, react.useCallback)((response) => {
581
+ setPendingEvent(null);
582
+ copilotkit.runAgent({
583
+ agent,
584
+ forwardedProps: { command: {
585
+ resume: response,
586
+ interruptEvent: pendingEventRef.current?.value
587
+ } }
588
+ });
589
+ }, [agent, copilotkit]);
590
+ (0, react.useEffect)(() => {
591
+ if (!pendingEvent) {
592
+ setHandlerResult(null);
593
+ return;
594
+ }
595
+ if (config.enabled && !config.enabled(pendingEvent)) {
596
+ setHandlerResult(null);
597
+ return;
598
+ }
599
+ const handler = config.handler;
600
+ if (!handler) {
601
+ setHandlerResult(null);
602
+ return;
603
+ }
604
+ let cancelled = false;
605
+ const maybePromise = handler({
606
+ event: pendingEvent,
607
+ resolve
608
+ });
609
+ if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => {
610
+ if (!cancelled) setHandlerResult(resolved);
611
+ }).catch(() => {
612
+ if (!cancelled) setHandlerResult(null);
613
+ });
614
+ else setHandlerResult(maybePromise);
615
+ return () => {
616
+ cancelled = true;
617
+ };
618
+ }, [
619
+ pendingEvent,
620
+ config.enabled,
621
+ config.handler,
622
+ resolve
623
+ ]);
624
+ const element = (0, react.useMemo)(() => {
625
+ if (!pendingEvent) return null;
626
+ if (config.enabled && !config.enabled(pendingEvent)) return null;
627
+ return config.render({
628
+ event: pendingEvent,
629
+ result: handlerResult,
630
+ resolve
631
+ });
632
+ }, [
633
+ pendingEvent,
634
+ handlerResult,
635
+ config.enabled,
636
+ config.render,
637
+ resolve
638
+ ]);
639
+ (0, react.useEffect)(() => {
640
+ if (config.renderInChat === false) return;
641
+ copilotkit.setInterruptElement(element);
642
+ return () => copilotkit.setInterruptElement(null);
643
+ }, [
644
+ element,
645
+ config.renderInChat,
646
+ copilotkit
647
+ ]);
648
+ if (config.renderInChat === false) return element;
649
+ }
650
+
651
+ //#endregion
652
+ //#region src/v2/hooks/use-suggestions.tsx
653
+ function useSuggestions({ agentId } = {}) {
654
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
655
+ const config = useCopilotChatConfiguration();
656
+ const resolvedAgentId = (0, react.useMemo)(() => agentId ?? config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [agentId, config?.agentId]);
657
+ const [suggestions, setSuggestions] = (0, react.useState)(() => {
658
+ return copilotkit.getSuggestions(resolvedAgentId).suggestions;
659
+ });
660
+ const [isLoading, setIsLoading] = (0, react.useState)(() => {
661
+ return copilotkit.getSuggestions(resolvedAgentId).isLoading;
662
+ });
663
+ (0, react.useEffect)(() => {
664
+ const result = copilotkit.getSuggestions(resolvedAgentId);
665
+ setSuggestions(result.suggestions);
666
+ setIsLoading(result.isLoading);
667
+ }, [copilotkit, resolvedAgentId]);
668
+ (0, react.useEffect)(() => {
669
+ const subscription = copilotkit.subscribe({
670
+ onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {
671
+ if (changedAgentId !== resolvedAgentId) return;
672
+ setSuggestions(suggestions);
673
+ },
674
+ onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {
675
+ if (changedAgentId !== resolvedAgentId) return;
676
+ setIsLoading(true);
677
+ },
678
+ onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {
679
+ if (changedAgentId !== resolvedAgentId) return;
680
+ setIsLoading(false);
681
+ },
682
+ onSuggestionsConfigChanged: () => {
683
+ const result = copilotkit.getSuggestions(resolvedAgentId);
684
+ setSuggestions(result.suggestions);
685
+ setIsLoading(result.isLoading);
686
+ }
687
+ });
688
+ return () => {
689
+ subscription.unsubscribe();
690
+ };
691
+ }, [copilotkit, resolvedAgentId]);
692
+ return {
693
+ suggestions,
694
+ reloadSuggestions: (0, react.useCallback)(() => {
695
+ copilotkit.reloadSuggestions(resolvedAgentId);
696
+ }, [copilotkit, resolvedAgentId]),
697
+ clearSuggestions: (0, react.useCallback)(() => {
698
+ copilotkit.clearSuggestions(resolvedAgentId);
699
+ }, [copilotkit, resolvedAgentId]),
700
+ isLoading
701
+ };
702
+ }
703
+
704
+ //#endregion
705
+ //#region src/v2/hooks/use-configure-suggestions.tsx
706
+ function useConfigureSuggestions(config, deps) {
707
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
708
+ const chatConfig = useCopilotChatConfiguration();
709
+ const extraDeps = deps ?? [];
710
+ const resolvedConsumerAgentId = (0, react.useMemo)(() => chatConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [chatConfig?.agentId]);
711
+ const rawConsumerAgentId = (0, react.useMemo)(() => config ? config.consumerAgentId : void 0, [config]);
712
+ const normalizationCacheRef = (0, react.useRef)({
713
+ serialized: null,
714
+ config: null
715
+ });
716
+ const { normalizedConfig, serializedConfig } = (0, react.useMemo)(() => {
717
+ if (!config) {
718
+ normalizationCacheRef.current = {
719
+ serialized: null,
720
+ config: null
721
+ };
722
+ return {
723
+ normalizedConfig: null,
724
+ serializedConfig: null
725
+ };
726
+ }
727
+ if (config.available === "disabled") {
728
+ normalizationCacheRef.current = {
729
+ serialized: null,
730
+ config: null
731
+ };
732
+ return {
733
+ normalizedConfig: null,
734
+ serializedConfig: null
735
+ };
736
+ }
737
+ let built;
738
+ if (isDynamicConfig(config)) built = { ...config };
739
+ else {
740
+ const normalizedSuggestions = normalizeStaticSuggestions(config.suggestions);
741
+ built = {
742
+ ...config,
743
+ suggestions: normalizedSuggestions
744
+ };
745
+ }
746
+ const serialized = JSON.stringify(built);
747
+ const cache = normalizationCacheRef.current;
748
+ if (cache.serialized === serialized && cache.config) return {
749
+ normalizedConfig: cache.config,
750
+ serializedConfig: serialized
751
+ };
752
+ normalizationCacheRef.current = {
753
+ serialized,
754
+ config: built
755
+ };
756
+ return {
757
+ normalizedConfig: built,
758
+ serializedConfig: serialized
759
+ };
760
+ }, [
761
+ config,
762
+ resolvedConsumerAgentId,
763
+ ...extraDeps
764
+ ]);
765
+ const latestConfigRef = (0, react.useRef)(null);
766
+ latestConfigRef.current = normalizedConfig;
767
+ const previousSerializedConfigRef = (0, react.useRef)(null);
768
+ const targetAgentId = (0, react.useMemo)(() => {
769
+ if (!normalizedConfig) return resolvedConsumerAgentId;
770
+ const consumer = normalizedConfig.consumerAgentId;
771
+ if (!consumer || consumer === "*") return resolvedConsumerAgentId;
772
+ return consumer;
773
+ }, [normalizedConfig, resolvedConsumerAgentId]);
774
+ const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
775
+ const isDynamicConfigType = (0, react.useMemo)(() => !!normalizedConfig && "instructions" in normalizedConfig, [normalizedConfig]);
776
+ const requestReload = (0, react.useCallback)(() => {
777
+ if (!normalizedConfig) return;
778
+ if (isGlobalConfig) {
779
+ const seen = /* @__PURE__ */ new Set();
780
+ const agents = Object.values(copilotkit.agents ?? {});
781
+ for (const entry of agents) {
782
+ const agentId = entry.agentId;
783
+ if (!agentId) continue;
784
+ seen.add(agentId);
785
+ if (!entry.isRunning) copilotkit.reloadSuggestions(agentId);
786
+ }
787
+ if (targetAgentId && !seen.has(targetAgentId)) copilotkit.reloadSuggestions(targetAgentId);
788
+ return;
789
+ }
790
+ if (!targetAgentId) return;
791
+ copilotkit.reloadSuggestions(targetAgentId);
792
+ }, [
793
+ copilotkit,
794
+ isGlobalConfig,
795
+ normalizedConfig,
796
+ targetAgentId
797
+ ]);
798
+ (0, react.useEffect)(() => {
799
+ if (!serializedConfig || !latestConfigRef.current) return;
800
+ const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);
801
+ requestReload();
802
+ return () => {
803
+ copilotkit.removeSuggestionsConfig(id);
804
+ };
805
+ }, [
806
+ copilotkit,
807
+ serializedConfig,
808
+ requestReload
809
+ ]);
810
+ (0, react.useEffect)(() => {
811
+ if (!normalizedConfig) {
812
+ previousSerializedConfigRef.current = null;
813
+ return;
814
+ }
815
+ if (serializedConfig && previousSerializedConfigRef.current === serializedConfig) return;
816
+ if (serializedConfig) previousSerializedConfigRef.current = serializedConfig;
817
+ requestReload();
818
+ }, [
819
+ normalizedConfig,
820
+ requestReload,
821
+ serializedConfig
822
+ ]);
823
+ (0, react.useEffect)(() => {
824
+ if (!normalizedConfig || extraDeps.length === 0) return;
825
+ requestReload();
826
+ }, [
827
+ extraDeps.length,
828
+ normalizedConfig,
829
+ requestReload,
830
+ ...extraDeps
831
+ ]);
832
+ (0, react.useEffect)(() => {
833
+ if (!normalizedConfig || !isDynamicConfigType) return;
834
+ if (!targetAgentId) return;
835
+ if (!!copilotkit.getAgent(targetAgentId)) return;
836
+ const subscription = copilotkit.subscribe({ onAgentsChanged: () => {
837
+ if (copilotkit.getAgent(targetAgentId)) {
838
+ requestReload();
839
+ subscription.unsubscribe();
840
+ }
841
+ } });
842
+ return () => {
843
+ subscription.unsubscribe();
844
+ };
845
+ }, [
846
+ copilotkit,
847
+ normalizedConfig,
848
+ isDynamicConfigType,
849
+ targetAgentId,
850
+ requestReload
851
+ ]);
852
+ }
853
+ function isDynamicConfig(config) {
854
+ return "instructions" in config;
855
+ }
856
+ function normalizeStaticSuggestions(suggestions) {
857
+ return suggestions.map((suggestion) => ({
858
+ ...suggestion,
859
+ isLoading: suggestion.isLoading ?? false
860
+ }));
861
+ }
862
+
863
+ //#endregion
864
+ //#region src/v2/hooks/use-agent-context.tsx
865
+ function useAgentContext(context) {
866
+ const { description, value } = context;
867
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
868
+ const stringValue = (0, react.useMemo)(() => {
869
+ if (typeof value === "string") return value;
870
+ return JSON.stringify(value);
871
+ }, [value]);
872
+ (0, react.useLayoutEffect)(() => {
873
+ if (!copilotkit) return;
874
+ const id = copilotkit.addContext({
875
+ description,
876
+ value: stringValue
877
+ });
878
+ return () => {
879
+ copilotkit.removeContext(id);
880
+ };
881
+ }, [
882
+ description,
883
+ stringValue,
884
+ copilotkit
885
+ ]);
886
+ }
887
+
888
+ //#endregion
889
+ //#region src/v2/hooks/use-threads.tsx
890
+ function useThreadStoreSelector(store, selector) {
891
+ return (0, react.useSyncExternalStore)((0, react.useCallback)((onStoreChange) => {
892
+ const subscription = store.select(selector).subscribe(onStoreChange);
893
+ return () => subscription.unsubscribe();
894
+ }, [store, selector]), () => selector(store.getState()));
895
+ }
896
+ /**
897
+ * React hook for listing and managing Intelligence platform threads.
898
+ *
899
+ * On mount the hook fetches the thread list for the runtime-authenticated user
900
+ * and the given `agentId`. When the Intelligence platform exposes a WebSocket
901
+ * URL, it also opens a realtime subscription so the `threads` array stays
902
+ * current without polling — thread creates, renames, archives, and deletes
903
+ * from any client are reflected immediately.
904
+ *
905
+ * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
906
+ * promises that resolve once the platform confirms the operation and reject
907
+ * with an `Error` on failure.
908
+ *
909
+ * @param input - Agent identifier and optional list controls.
910
+ * @returns Thread list state and stable mutation callbacks.
911
+ *
912
+ * @example
913
+ * ```tsx
914
+ * import { useThreads } from "@copilotkit/react-core";
915
+ *
916
+ * function ThreadList() {
917
+ * const { threads, isLoading, renameThread, deleteThread } = useThreads({
918
+ * agentId: "agent-1",
919
+ * });
920
+ *
921
+ * if (isLoading) return <p>Loading…</p>;
922
+ *
923
+ * return (
924
+ * <ul>
925
+ * {threads.map((t) => (
926
+ * <li key={t.id}>
927
+ * {t.name ?? "Untitled"}
928
+ * <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
929
+ * <button onClick={() => deleteThread(t.id)}>Delete</button>
930
+ * </li>
931
+ * ))}
932
+ * </ul>
933
+ * );
934
+ * }
935
+ * ```
936
+ */
937
+ function useThreads({ agentId, includeArchived, limit }) {
938
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
939
+ const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
940
+ const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
941
+ const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
942
+ id,
943
+ agentId,
944
+ name,
945
+ archived,
946
+ createdAt,
947
+ updatedAt,
948
+ ...lastRunAt !== void 0 ? { lastRunAt } : {}
949
+ })), [coreThreads]);
950
+ const storeIsLoading = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsIsLoading);
951
+ const storeError = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsError);
952
+ const hasMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectHasNextPage);
953
+ const isFetchingMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsFetchingNextPage);
954
+ const headersKey = (0, react.useMemo)(() => {
955
+ return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
956
+ }, [copilotkit.headers]);
957
+ const runtimeError = (0, react.useMemo)(() => {
958
+ if (copilotkit.runtimeUrl) return null;
959
+ return /* @__PURE__ */ new Error("Runtime URL is not configured");
960
+ }, [copilotkit.runtimeUrl]);
961
+ const [hasDispatchedContext, setHasDispatchedContext] = (0, react.useState)(false);
962
+ const preConnectLoading = !!copilotkit.runtimeUrl && !hasDispatchedContext;
963
+ const isLoading = runtimeError ? false : preConnectLoading || storeIsLoading;
964
+ const error = runtimeError ?? storeError;
965
+ (0, react.useEffect)(() => {
966
+ store.start();
967
+ return () => {
968
+ store.stop();
969
+ };
970
+ }, [store]);
971
+ const runtimeStatus = copilotkit.runtimeConnectionStatus;
972
+ (0, react.useEffect)(() => {
973
+ copilotkit.registerThreadStore(agentId, store);
974
+ return () => {
975
+ copilotkit.unregisterThreadStore(agentId);
976
+ };
977
+ }, [
978
+ copilotkit,
979
+ agentId,
980
+ store
981
+ ]);
982
+ (0, react.useEffect)(() => {
983
+ if (!copilotkit.runtimeUrl) {
984
+ store.setContext(null);
985
+ return;
986
+ }
987
+ if (runtimeStatus !== _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected) return;
988
+ const context = {
989
+ runtimeUrl: copilotkit.runtimeUrl,
990
+ headers: { ...copilotkit.headers },
991
+ wsUrl: copilotkit.intelligence?.wsUrl,
992
+ agentId,
993
+ includeArchived,
994
+ limit
995
+ };
996
+ store.setContext(context);
997
+ setHasDispatchedContext(true);
998
+ }, [
999
+ store,
1000
+ copilotkit.runtimeUrl,
1001
+ runtimeStatus,
1002
+ headersKey,
1003
+ copilotkit.intelligence?.wsUrl,
1004
+ agentId,
1005
+ includeArchived,
1006
+ limit
1007
+ ]);
1008
+ const renameThread = (0, react.useCallback)((threadId, name) => store.renameThread(threadId, name), [store]);
1009
+ const archiveThread = (0, react.useCallback)((threadId) => store.archiveThread(threadId), [store]);
1010
+ const deleteThread = (0, react.useCallback)((threadId) => store.deleteThread(threadId), [store]);
1011
+ return {
1012
+ threads,
1013
+ isLoading,
1014
+ error,
1015
+ hasMoreThreads,
1016
+ isFetchingMoreThreads,
1017
+ fetchMoreThreads: (0, react.useCallback)(() => store.fetchNextPage(), [store]),
1018
+ renameThread,
1019
+ archiveThread,
1020
+ deleteThread
1021
+ };
1022
+ }
1023
+
1024
+ //#endregion
1025
+ exports.CopilotChatConfigurationProvider = CopilotChatConfigurationProvider;
1026
+ exports.CopilotChatDefaultLabels = CopilotChatDefaultLabels;
1027
+ Object.defineProperty(exports, 'CopilotKitCoreReact', {
1028
+ enumerable: true,
1029
+ get: function () {
1030
+ return _copilotkit_react_core_v2_context.CopilotKitCoreReact;
1031
+ }
1032
+ });
1033
+ exports.useAgent = useAgent;
1034
+ exports.useAgentContext = useAgentContext;
1035
+ exports.useComponent = useComponent;
1036
+ exports.useConfigureSuggestions = useConfigureSuggestions;
1037
+ exports.useCopilotChatConfiguration = useCopilotChatConfiguration;
1038
+ exports.useFrontendTool = useFrontendTool;
1039
+ exports.useHumanInTheLoop = useHumanInTheLoop;
1040
+ exports.useInterrupt = useInterrupt;
1041
+ exports.useSuggestions = useSuggestions;
1042
+ exports.useThreads = useThreads;
1043
+ //# sourceMappingURL=headless.cjs.map