@copilotkit/react-core 1.80.0 → 1.82.0

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 (54) hide show
  1. package/dist/MarkdownSurfaces-DGpjmPaB.mjs +3531 -0
  2. package/dist/MarkdownSurfaces-DGpjmPaB.mjs.map +1 -0
  3. package/dist/MarkdownSurfaces-FF5za2kU.cjs +3816 -0
  4. package/dist/MarkdownSurfaces-FF5za2kU.cjs.map +1 -0
  5. package/dist/{copilotkit-CWOSXhRO.d.mts → copilotkit-C765tOUi.d.mts} +70 -36
  6. package/dist/copilotkit-C765tOUi.d.mts.map +1 -0
  7. package/dist/{copilotkit-DKICi3nC.cjs → copilotkit-CVvbU9lV.cjs} +2162 -675
  8. package/dist/copilotkit-CVvbU9lV.cjs.map +1 -0
  9. package/dist/{copilotkit-BNLtgOyD.mjs → copilotkit-DDReN1Px.mjs} +2106 -568
  10. package/dist/copilotkit-DDReN1Px.mjs.map +1 -0
  11. package/dist/{copilotkit-Dfw9HzO9.d.cts → copilotkit-wqaNanhw.d.cts} +70 -36
  12. package/dist/copilotkit-wqaNanhw.d.cts.map +1 -0
  13. package/dist/index.cjs +8 -7
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +2 -1
  16. package/dist/index.d.cts.map +1 -1
  17. package/dist/index.d.mts +2 -1
  18. package/dist/index.d.mts.map +1 -1
  19. package/dist/index.mjs +2 -1
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/index.umd.js +4474 -11
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/runtime-context-CrHq-iTf.d.mts +924 -0
  24. package/dist/runtime-context-CrHq-iTf.d.mts.map +1 -0
  25. package/dist/runtime-context-D3NcP9oE.d.cts +924 -0
  26. package/dist/runtime-context-D3NcP9oE.d.cts.map +1 -0
  27. package/dist/v2/generative-ui.cjs +8154 -0
  28. package/dist/v2/generative-ui.cjs.map +1 -0
  29. package/dist/v2/generative-ui.d.cts +4950 -0
  30. package/dist/v2/generative-ui.d.cts.map +1 -0
  31. package/dist/v2/generative-ui.d.mts +4950 -0
  32. package/dist/v2/generative-ui.d.mts.map +1 -0
  33. package/dist/v2/generative-ui.mjs +8140 -0
  34. package/dist/v2/generative-ui.mjs.map +1 -0
  35. package/dist/v2/headless.cjs +10 -1
  36. package/dist/v2/headless.cjs.map +1 -1
  37. package/dist/v2/headless.d.cts +9 -0
  38. package/dist/v2/headless.d.cts.map +1 -1
  39. package/dist/v2/headless.d.mts +9 -0
  40. package/dist/v2/headless.d.mts.map +1 -1
  41. package/dist/v2/headless.mjs +10 -1
  42. package/dist/v2/headless.mjs.map +1 -1
  43. package/dist/v2/index.cjs +65 -4
  44. package/dist/v2/index.css +1 -1
  45. package/dist/v2/index.d.cts +3 -2
  46. package/dist/v2/index.d.mts +3 -2
  47. package/dist/v2/index.mjs +3 -2
  48. package/dist/v2/index.umd.js +4962 -236
  49. package/dist/v2/index.umd.js.map +1 -1
  50. package/package.json +21 -8
  51. package/dist/copilotkit-BNLtgOyD.mjs.map +0 -1
  52. package/dist/copilotkit-CWOSXhRO.d.mts.map +0 -1
  53. package/dist/copilotkit-DKICi3nC.cjs.map +0 -1
  54. package/dist/copilotkit-Dfw9HzO9.d.cts.map +0 -1
@@ -1,32 +1,6 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
1
+ const require_MarkdownSurfaces = require('./MarkdownSurfaces-FF5za2kU.cjs');
28
2
  let react = require("react");
29
- react = __toESM(react);
3
+ react = require_MarkdownSurfaces.__toESM(react);
30
4
  let _copilotkit_core = require("@copilotkit/core");
31
5
  let _ag_ui_client = require("@ag-ui/client");
32
6
  let tailwind_merge = require("tailwind-merge");
@@ -38,360 +12,25 @@ let _radix_ui_react_slot = require("@radix-ui/react-slot");
38
12
  let class_variance_authority = require("class-variance-authority");
39
13
  let clsx = require("clsx");
40
14
  let _radix_ui_react_tooltip = require("@radix-ui/react-tooltip");
41
- _radix_ui_react_tooltip = __toESM(_radix_ui_react_tooltip);
15
+ _radix_ui_react_tooltip = require_MarkdownSurfaces.__toESM(_radix_ui_react_tooltip);
42
16
  let _radix_ui_react_dropdown_menu = require("@radix-ui/react-dropdown-menu");
43
- _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
17
+ _radix_ui_react_dropdown_menu = require_MarkdownSurfaces.__toESM(_radix_ui_react_dropdown_menu);
44
18
  let streamdown = require("streamdown");
45
19
  let _ag_ui_core = require("@ag-ui/core");
46
20
  let zod = require("zod");
47
21
  let _copilotkit_mcp_apps_renderer_activity = require("@copilotkit/mcp-apps-renderer/activity");
48
22
  let _copilotkit_a2ui_renderer = require("@copilotkit/a2ui-renderer");
49
23
  let zod_to_json_schema = require("zod-to-json-schema");
24
+ let _a2ui_web_core_v0_9 = require("@a2ui/web_core/v0_9");
50
25
  let _radix_ui_react_popover = require("@radix-ui/react-popover");
51
- _radix_ui_react_popover = __toESM(_radix_ui_react_popover);
26
+ _radix_ui_react_popover = require_MarkdownSurfaces.__toESM(_radix_ui_react_popover);
52
27
  let react_dom = require("react-dom");
53
28
  let _tanstack_react_virtual = require("@tanstack/react-virtual");
54
29
  let use_stick_to_bottom = require("use-stick-to-bottom");
55
30
  let _copilotkit_web_components_threads_drawer = require("@copilotkit/web-components/threads-drawer");
56
31
  let react_markdown = require("react-markdown");
57
- react_markdown = __toESM(react_markdown);
58
-
59
- //#region src/v2/lib/shallow-stable-ref.ts
60
- /**
61
- * Shallow equality comparison for objects.
62
- */
63
- function shallowEqual(obj1, obj2) {
64
- const keys1 = Object.keys(obj1);
65
- const keys2 = Object.keys(obj2);
66
- if (keys1.length !== keys2.length) return false;
67
- for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
68
- return true;
69
- }
70
- /**
71
- * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
72
- * class instances, and other exotic objects that happen to have typeof "object".
73
- */
74
- function isPlainObject$1(obj) {
75
- return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
76
- }
77
- /**
78
- * Returns the same reference as long as the value is shallowly equal to the
79
- * previous render's value.
80
- *
81
- * - Identical references bail out immediately (O(1)).
82
- * - Plain objects ({}) are shallow-compared key-by-key.
83
- * - Arrays, Dates, class instances, functions, and primitives are compared by
84
- * reference only — shallowEqual is never called on non-plain objects, which
85
- * avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
86
- *
87
- * Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
88
- * equality check isn't defeated by a new object reference on every render.
89
- */
90
- function useShallowStableRef(value) {
91
- const ref = (0, react.useRef)(value);
92
- if (ref.current === value) return ref.current;
93
- if (isPlainObject$1(ref.current) && isPlainObject$1(value)) {
94
- if (shallowEqual(ref.current, value)) return ref.current;
95
- }
96
- ref.current = value;
97
- return ref.current;
98
- }
99
-
100
- //#endregion
101
- //#region src/v2/providers/CopilotChatConfigurationProvider.tsx
102
- const CopilotChatDefaultLabels = {
103
- chatInputPlaceholder: "Type a message...",
104
- chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
105
- chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
106
- chatInputToolbarFinishTranscribeButtonLabel: "Finish",
107
- chatInputToolbarAddButtonLabel: "Add attachments",
108
- chatInputToolbarToolsButtonLabel: "Tools",
109
- chatInputToolbarSendButtonLabel: "Send message",
110
- chatInputToolbarStopButtonLabel: "Stop",
111
- assistantMessageToolbarCopyCodeLabel: "Copy",
112
- assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
113
- assistantMessageToolbarCopyMessageLabel: "Copy",
114
- assistantMessageToolbarInspectorLabel: "View in Inspector",
115
- assistantMessageToolbarInspectorDescription: "Open this message in the Inspector",
116
- assistantMessageToolbarInspectorLocalOnlyLabel: "Local only",
117
- assistantMessageToolbarInspectorLocalOnlyDescription: "Only visible on localhost or loopback hosts in development. Never shown in production.",
118
- assistantMessageToolbarInspectorTitle: "CopilotKit Inspector",
119
- assistantMessageToolbarInspectorHideLabel: "Hide this icon",
120
- assistantMessageToolbarInspectorHideDescription: "Until you reload this page",
121
- assistantMessageToolbarThumbsUpLabel: "Good response",
122
- assistantMessageToolbarThumbsDownLabel: "Bad response",
123
- assistantMessageFeedbackCommentPlaceholder: "Add a comment (optional)",
124
- assistantMessageFeedbackCommentSubmitLabel: "Send comment",
125
- assistantMessageToolbarReadAloudLabel: "Read aloud",
126
- assistantMessageToolbarRegenerateLabel: "Regenerate",
127
- userMessageToolbarCopyMessageLabel: "Copy",
128
- userMessageToolbarEditMessageLabel: "Edit",
129
- userMessageToolbarPreviousBranchLabel: "Previous branch",
130
- userMessageToolbarNextBranchLabel: "Next branch",
131
- chatDisclaimerText: "AI can make mistakes. Please verify important information.",
132
- chatToggleOpenLabel: "Open chat",
133
- chatToggleCloseLabel: "Close chat",
134
- chatScrollToBottomLabel: "Scroll to bottom",
135
- modalHeaderTitle: "CopilotKit Chat",
136
- welcomeMessageText: "How can I help you today?"
137
- };
138
- /**
139
- * Mobile breakpoint below which the chat modal and the thread-list drawer are
140
- * mutually exclusive. At or above this width both surfaces may coexist. This
141
- * mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by
142
- * CopilotChatInput and CopilotSidebarView.
143
- */
144
- const MOBILE_MAX_WIDTH_PX = 767;
145
- /**
146
- * Reports whether the current viewport is in the mobile range (`<768px`), where
147
- * the chat modal and drawer must not be open simultaneously. SSR-safe and
148
- * defensive against environments without `matchMedia` (treated as desktop, so
149
- * no mutual-exclusion constraint is applied).
150
- *
151
- * @returns `true` when the viewport is mobile-width, `false` otherwise.
152
- */
153
- function isMobileViewport() {
154
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
155
- return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;
156
- }
157
- const CopilotChatConfiguration = (0, react.createContext)(null);
158
- const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
159
- const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
160
- const stableLabels = useShallowStableRef(labels);
161
- const mergedLabels = (0, react.useMemo)(() => ({
162
- ...CopilotChatDefaultLabels,
163
- ...parentConfig?.labels,
164
- ...stableLabels
165
- }), [stableLabels, parentConfig?.labels]);
166
- const providerAgentId = (0, _copilotkit_react_core_v2_context.useDefaultAgentId)();
167
- const resolvedAgentId = agentId ?? parentConfig?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
168
- const threadIdPropIsAuthoritative = threadId !== void 0 && hasExplicitThreadId !== false;
169
- const isThreadIdControlled = threadIdPropIsAuthoritative;
170
- const [activeThreadOverride, setActiveThreadOverride] = (0, react.useState)(null);
171
- const resolvedThreadId = (0, react.useMemo)(() => {
172
- if (threadIdPropIsAuthoritative) return threadId;
173
- if (activeThreadOverride) return activeThreadOverride.threadId;
174
- if (parentConfig?.threadId) return parentConfig.threadId;
175
- if (threadId) return threadId;
176
- return (0, _copilotkit_shared.randomUUID)();
177
- }, [
178
- threadIdPropIsAuthoritative,
179
- threadId,
180
- parentConfig?.threadId,
181
- activeThreadOverride
182
- ]);
183
- const copilotkit = (0, react.useContext)(_copilotkit_react_core_v2_context.CopilotKitContext)?.copilotkit;
184
- const openThreadRef = (0, react.useRef)(null);
185
- const latestThreadIdRef = (0, react.useRef)(resolvedThreadId);
186
- latestThreadIdRef.current = resolvedThreadId;
187
- (0, react.useEffect)(() => {
188
- if (copilotkit === void 0) return;
189
- const registration = copilotkit.registerOpenThread({
190
- agentId: resolvedAgentId,
191
- threadId: latestThreadIdRef.current
192
- });
193
- openThreadRef.current = registration;
194
- return () => {
195
- registration.unregister();
196
- openThreadRef.current = null;
197
- };
198
- }, [copilotkit, resolvedAgentId]);
199
- (0, react.useEffect)(() => {
200
- openThreadRef.current?.update(resolvedThreadId);
201
- }, [resolvedThreadId]);
202
- const resolvedHasExplicitThreadId = (threadIdPropIsAuthoritative ? true : activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false) || !!parentConfig?.hasExplicitThreadId;
203
- const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen ?? true);
204
- const hasExplicitDefault = isModalDefaultOpen !== void 0;
205
- const setAndSync = (0, react.useCallback)((open) => {
206
- setInternalModalOpen(open);
207
- parentConfig?.setModalOpen(open);
208
- }, [parentConfig?.setModalOpen]);
209
- const isMounted = (0, react.useRef)(false);
210
- (0, react.useEffect)(() => {
211
- if (!hasExplicitDefault) return;
212
- if (!isMounted.current) {
213
- isMounted.current = true;
214
- return;
215
- }
216
- if (parentConfig?.isModalOpen === void 0) return;
217
- setInternalModalOpen(parentConfig.isModalOpen);
218
- }, [parentConfig?.isModalOpen, hasExplicitDefault]);
219
- const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : parentConfig?.isModalOpen ?? internalModalOpen;
220
- const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : parentConfig?.setModalOpen ?? setInternalModalOpen;
221
- const [ownDrawerOpen, setOwnDrawerOpen] = (0, react.useState)(false);
222
- const [ownDrawerCount, setOwnDrawerCount] = (0, react.useState)(0);
223
- const modalCloseRef = (0, react.useRef)(() => {});
224
- modalCloseRef.current = resolvedSetModalOpen;
225
- const registeredModalClosersRef = (0, react.useRef)([]);
226
- const ownRegisterModalCloser = (0, react.useCallback)((closeModal) => {
227
- registeredModalClosersRef.current.push(closeModal);
228
- return () => {
229
- registeredModalClosersRef.current = registeredModalClosersRef.current.filter((entry) => entry !== closeModal);
230
- };
231
- }, []);
232
- const ownSetDrawerOpen = (0, react.useCallback)((open) => {
233
- setOwnDrawerOpen(open);
234
- if (open && isMobileViewport()) {
235
- const registered = registeredModalClosersRef.current;
236
- (registered.length > 0 ? registered[registered.length - 1] : modalCloseRef.current)(false);
237
- }
238
- }, []);
239
- const ownRegisterDrawer = (0, react.useCallback)(() => {
240
- setOwnDrawerCount((count) => count + 1);
241
- return () => {
242
- setOwnDrawerCount((count) => Math.max(0, count - 1));
243
- };
244
- }, []);
245
- const resolvedDrawerOpen = parentConfig ? parentConfig.drawerOpen : ownDrawerOpen;
246
- const resolvedSetDrawerOpen = parentConfig ? parentConfig.setDrawerOpen : ownSetDrawerOpen;
247
- const resolvedDrawerRegistered = parentConfig ? parentConfig.drawerRegistered : ownDrawerCount > 0;
248
- const resolvedRegisterDrawer = parentConfig ? parentConfig.registerDrawer : ownRegisterDrawer;
249
- const resolvedRegisterModalCloser = parentConfig ? parentConfig.ɵregisterModalCloser : ownRegisterModalCloser;
250
- (0, react.useEffect)(() => {
251
- if (!hasExplicitDefault) return;
252
- return resolvedRegisterModalCloser(resolvedSetModalOpen);
253
- }, [
254
- hasExplicitDefault,
255
- resolvedRegisterModalCloser,
256
- resolvedSetModalOpen
257
- ]);
258
- const isThreadIdControlledRef = (0, react.useRef)(isThreadIdControlled);
259
- isThreadIdControlledRef.current = isThreadIdControlled;
260
- const ownSetActiveThreadId = (0, react.useCallback)((id, options) => {
261
- setActiveThreadOverride({
262
- threadId: id,
263
- explicit: options?.explicit ?? true
264
- });
265
- }, []);
266
- const ownStartNewThread = (0, react.useCallback)(() => {
267
- setActiveThreadOverride({
268
- threadId: (0, _copilotkit_shared.randomUUID)(),
269
- explicit: false
270
- });
271
- }, []);
272
- const parentSetActiveThreadId = parentConfig?.setActiveThreadId;
273
- const parentStartNewThread = parentConfig?.startNewThread;
274
- const resolvedSetActiveThreadId = (0, react.useCallback)((id, options) => {
275
- if (isThreadIdControlledRef.current) {
276
- console.warn("[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
277
- return;
278
- }
279
- if (parentSetActiveThreadId) {
280
- parentSetActiveThreadId(id, options);
281
- return;
282
- }
283
- ownSetActiveThreadId(id, options);
284
- }, [parentSetActiveThreadId, ownSetActiveThreadId]);
285
- const resolvedStartNewThread = (0, react.useCallback)(() => {
286
- if (isThreadIdControlledRef.current) {
287
- console.warn("[CopilotKit] Ignoring startNewThread(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
288
- return;
289
- }
290
- if (parentStartNewThread) {
291
- parentStartNewThread();
292
- return;
293
- }
294
- ownStartNewThread();
295
- }, [parentStartNewThread, ownStartNewThread]);
296
- const setModalOpenWithDrawerExclusion = (0, react.useCallback)((open) => {
297
- if (open && isMobileViewport()) resolvedSetDrawerOpen(false);
298
- resolvedSetModalOpen(open);
299
- }, [resolvedSetModalOpen, resolvedSetDrawerOpen]);
300
- const configurationValue = (0, react.useMemo)(() => ({
301
- labels: mergedLabels,
302
- agentId: resolvedAgentId,
303
- threadId: resolvedThreadId,
304
- hasExplicitThreadId: resolvedHasExplicitThreadId,
305
- isModalOpen: resolvedIsModalOpen,
306
- setModalOpen: setModalOpenWithDrawerExclusion,
307
- drawerOpen: resolvedDrawerOpen,
308
- setDrawerOpen: resolvedSetDrawerOpen,
309
- drawerRegistered: resolvedDrawerRegistered,
310
- registerDrawer: resolvedRegisterDrawer,
311
- ɵregisterModalCloser: resolvedRegisterModalCloser,
312
- setActiveThreadId: resolvedSetActiveThreadId,
313
- startNewThread: resolvedStartNewThread
314
- }), [
315
- mergedLabels,
316
- resolvedAgentId,
317
- resolvedThreadId,
318
- resolvedHasExplicitThreadId,
319
- resolvedIsModalOpen,
320
- setModalOpenWithDrawerExclusion,
321
- resolvedDrawerOpen,
322
- resolvedSetDrawerOpen,
323
- resolvedDrawerRegistered,
324
- resolvedRegisterDrawer,
325
- resolvedRegisterModalCloser,
326
- resolvedSetActiveThreadId,
327
- resolvedStartNewThread
328
- ]);
329
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
330
- value: configurationValue,
331
- children
332
- });
333
- };
334
- const useCopilotChatConfiguration = () => {
335
- return (0, react.useContext)(CopilotChatConfiguration);
336
- };
337
- /**
338
- * Reports modal open/close requests to the host, and — when `open` is
339
- * supplied — makes the modal state of an already-established chat
340
- * configuration **controlled** for the subtree it wraps.
341
- *
342
- * This is deliberately a scope component rather than another mode inside
343
- * {@link CopilotChatConfigurationProvider}. The provider resolves modal state
344
- * across a nested chain (own state, parent sync, drawer mutual-exclusion, the
345
- * modal-closer registry); a controlled branch inside that resolution would add
346
- * a fourth interacting mode. Overriding the context for the subtree instead
347
- * leaves every one of those paths untouched:
348
- *
349
- * - `isModalOpen` is replaced with the host's `open`, so the rendered surface
350
- * follows the prop from the very first frame (no open-then-close flash).
351
- * - `setModalOpen` still calls the underlying setter, so the existing
352
- * parent-sync and drawer mutual-exclusion side effects continue to run, and
353
- * *then* reports the request through `onOpenChange`.
354
- * - The wrapped setter is registered as the modal closer, so the drawer's
355
- * mobile mutual-exclusion reaches the host instead of silently flipping
356
- * state that nothing displays.
357
- *
358
- * A host that supplies `open` and ignores `onOpenChange` gets a modal pinned
359
- * to `open`, which is the standard controlled-component contract. A host that
360
- * supplies only `onOpenChange` is notified while the modal keeps managing
361
- * itself.
362
- *
363
- * Renders `children` unchanged when no chat configuration is in scope.
364
- */
365
- const ControlledModalOpenScope = ({ children, open, onOpenChange }) => {
366
- const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
367
- const parentSetModalOpen = parentConfig?.setModalOpen;
368
- const registerModalCloser = parentConfig?.ɵregisterModalCloser;
369
- const setModalOpen = (0, react.useCallback)((next) => {
370
- parentSetModalOpen?.(next);
371
- onOpenChange?.(next);
372
- }, [parentSetModalOpen, onOpenChange]);
373
- (0, react.useEffect)(() => {
374
- if (!registerModalCloser) return;
375
- return registerModalCloser(setModalOpen);
376
- }, [registerModalCloser, setModalOpen]);
377
- const configurationValue = (0, react.useMemo)(() => parentConfig ? {
378
- ...parentConfig,
379
- isModalOpen: open ?? parentConfig.isModalOpen,
380
- setModalOpen
381
- } : null, [
382
- parentConfig,
383
- open,
384
- setModalOpen
385
- ]);
386
- if (!configurationValue) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
387
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
388
- value: configurationValue,
389
- children
390
- });
391
- };
392
- ControlledModalOpenScope.displayName = "ControlledModalOpenScope";
32
+ react_markdown = require_MarkdownSurfaces.__toESM(react_markdown);
393
33
 
394
- //#endregion
395
34
  //#region src/v2/lib/utils.ts
396
35
  const twMerge$12 = (0, tailwind_merge.extendTailwindMerge)({ prefix: "cpk" });
397
36
  function cn(...inputs) {
@@ -821,7 +460,7 @@ const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function
821
460
  if (prev.$component !== next.$component) return false;
822
461
  const { $slot: _ps, $component: _pc, ...prevRest } = prev;
823
462
  const { $slot: _ns, $component: _nc, ...nextRest } = next;
824
- return shallowEqual(prevRest, nextRest);
463
+ return require_MarkdownSurfaces.shallowEqual(prevRest, nextRest);
825
464
  });
826
465
  /**
827
466
  * Renders a slot value as a memoized React element.
@@ -867,8 +506,8 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
867
506
  const actionsContainerRef = (0, react.useRef)(null);
868
507
  const audioRecorderRef = (0, react.useRef)(null);
869
508
  const slashMenuRef = (0, react.useRef)(null);
870
- const config = useCopilotChatConfiguration();
871
- const labels = config?.labels ?? CopilotChatDefaultLabels;
509
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
510
+ const labels = config?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
872
511
  const previousModalStateRef = (0, react.useRef)(void 0);
873
512
  const measurementCanvasRef = (0, react.useRef)(null);
874
513
  const measurementsRef = (0, react.useRef)({
@@ -1094,37 +733,6 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1094
733
  });
1095
734
  const BoundDisclaimer = renderSlot(disclaimer, CopilotChatInput.Disclaimer, {});
1096
735
  const shouldShowDisclaimer = showDisclaimer ?? positioning === "absolute";
1097
- if (children) {
1098
- const childProps = {
1099
- textArea: BoundTextArea,
1100
- audioRecorder: BoundAudioRecorder,
1101
- sendButton: BoundSendButton,
1102
- startTranscribeButton: BoundStartTranscribeButton,
1103
- cancelTranscribeButton: BoundCancelTranscribeButton,
1104
- finishTranscribeButton: BoundFinishTranscribeButton,
1105
- addMenuButton: BoundAddMenuButton,
1106
- disclaimer: BoundDisclaimer,
1107
- onSubmitMessage,
1108
- onStop,
1109
- isRunning,
1110
- onStartTranscribe,
1111
- onCancelTranscribe,
1112
- onFinishTranscribe,
1113
- onAddFile,
1114
- mode,
1115
- toolsMenu,
1116
- autoFocus,
1117
- positioning,
1118
- keyboardHeight,
1119
- showDisclaimer: shouldShowDisclaimer,
1120
- containerRef
1121
- };
1122
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1123
- "data-copilotkit": true,
1124
- style: { display: "contents" },
1125
- children: children(childProps)
1126
- });
1127
- }
1128
736
  const handleContainerClick = (e) => {
1129
737
  const target = e.target;
1130
738
  if (target.tagName !== "BUTTON" && !target.closest("button") && inputRef.current && mode === "input") inputRef.current.focus();
@@ -1208,7 +816,11 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1208
816
  const grid = gridRef.current;
1209
817
  const addContainer = addButtonContainerRef.current;
1210
818
  const actionsContainer = actionsContainerRef.current;
1211
- if (!textarea || !grid || !addContainer || !actionsContainer) return;
819
+ if (!textarea) return;
820
+ if (!grid || !addContainer || !actionsContainer) {
821
+ adjustTextareaHeight();
822
+ return;
823
+ }
1212
824
  if (measurementsRef.current.singleLineHeight === 0) ensureMeasurements();
1213
825
  const scrollHeight = adjustTextareaHeight();
1214
826
  const baseline = measurementsRef.current.singleLineHeight;
@@ -1312,13 +924,13 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1312
924
  const slashMenu = slashMenuVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1313
925
  "data-testid": "copilot-slash-menu",
1314
926
  role: "listbox",
1315
- "aria-label": "Slash commands",
927
+ "aria-label": labels.chatInputSlashMenuLabel,
1316
928
  ref: slashMenuRef,
1317
929
  className: "cpk:absolute cpk:bottom-full cpk:left-0 cpk:right-0 cpk:z-30 cpk:mb-2 cpk:max-h-64 cpk:overflow-y-auto cpk:rounded-lg cpk:border cpk:border-border cpk:bg-white cpk:shadow-lg cpk:dark:border-[#3a3a3a] cpk:dark:bg-[#1f1f1f]",
1318
930
  style: { maxHeight: `${SLASH_MENU_MAX_VISIBLE_ITEMS * SLASH_MENU_ITEM_HEIGHT_PX}px` },
1319
931
  children: filteredCommands.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1320
932
  className: "cpk:px-3 cpk:py-2 cpk:text-sm cpk:text-muted-foreground",
1321
- children: "No commands found"
933
+ children: labels.chatInputSlashMenuEmptyText
1322
934
  }) : filteredCommands.map((item, index) => {
1323
935
  const isActive = index === slashHighlightIndex;
1324
936
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -1367,6 +979,37 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1367
979
  ]
1368
980
  })
1369
981
  });
982
+ if (children) {
983
+ const childProps = {
984
+ textArea: BoundTextArea,
985
+ audioRecorder: BoundAudioRecorder,
986
+ sendButton: BoundSendButton,
987
+ startTranscribeButton: BoundStartTranscribeButton,
988
+ cancelTranscribeButton: BoundCancelTranscribeButton,
989
+ finishTranscribeButton: BoundFinishTranscribeButton,
990
+ addMenuButton: BoundAddMenuButton,
991
+ disclaimer: BoundDisclaimer,
992
+ onSubmitMessage,
993
+ onStop,
994
+ isRunning,
995
+ onStartTranscribe,
996
+ onCancelTranscribe,
997
+ onFinishTranscribe,
998
+ onAddFile,
999
+ mode,
1000
+ toolsMenu,
1001
+ autoFocus,
1002
+ positioning,
1003
+ keyboardHeight,
1004
+ showDisclaimer: shouldShowDisclaimer,
1005
+ containerRef
1006
+ };
1007
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1008
+ "data-copilotkit": true,
1009
+ style: { display: "contents" },
1010
+ children: children(childProps)
1011
+ });
1012
+ }
1370
1013
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1371
1014
  "data-copilotkit": true,
1372
1015
  ref: containerRef,
@@ -1385,7 +1028,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1385
1028
  }
1386
1029
  (function(_CopilotChatInput) {
1387
1030
  _CopilotChatInput.SendButton = ({ className, children, ...props }) => {
1388
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
1031
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
1389
1032
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1390
1033
  className: "cpk:mr-[10px]",
1391
1034
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
@@ -1401,7 +1044,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1401
1044
  });
1402
1045
  };
1403
1046
  const ToolbarButton = _CopilotChatInput.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => {
1404
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
1047
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
1405
1048
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, {
1406
1049
  asChild: true,
1407
1050
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
@@ -1440,7 +1083,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1440
1083
  ...props
1441
1084
  });
1442
1085
  _CopilotChatInput.AddMenuButton = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {
1443
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
1086
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
1444
1087
  const [mounted, setMounted] = (0, react.useState)(false);
1445
1088
  (0, react.useEffect)(() => setMounted(true), []);
1446
1089
  const menuItems = (0, react.useMemo)(() => {
@@ -1508,7 +1151,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1508
1151
  };
1509
1152
  _CopilotChatInput.TextArea = (0, react.forwardRef)(function TextArea({ style, className, autoFocus, placeholder, ...props }, ref) {
1510
1153
  const internalTextareaRef = (0, react.useRef)(null);
1511
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
1154
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
1512
1155
  (0, react.useImperativeHandle)(ref, () => internalTextareaRef.current);
1513
1156
  (0, react.useEffect)(() => {
1514
1157
  if (autoFocus) internalTextareaRef.current?.focus({ preventScroll: true });
@@ -1529,7 +1172,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
1529
1172
  });
1530
1173
  _CopilotChatInput.AudioRecorder = CopilotChatAudioRecorder;
1531
1174
  _CopilotChatInput.Disclaimer = ({ className, ...props }) => {
1532
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
1175
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
1533
1176
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1534
1177
  className: cn("cpk:text-center cpk:text-xs cpk:text-muted-foreground cpk:py-3 cpk:px-4 cpk:max-w-3xl cpk:mx-auto", className),
1535
1178
  ...props,
@@ -1547,25 +1190,6 @@ CopilotChatInput.AddMenuButton.displayName = "CopilotChatInput.AddMenuButton";
1547
1190
  CopilotChatInput.Disclaimer.displayName = "CopilotChatInput.Disclaimer";
1548
1191
  var CopilotChatInput_default = CopilotChatInput;
1549
1192
 
1550
- //#endregion
1551
- //#region src/v2/hooks/useKatexStyles.ts
1552
- let injected = false;
1553
- /**
1554
- * Dynamically injects KaTeX CSS at runtime to avoid the Next.js
1555
- * "Global CSS cannot be imported from within node_modules" build error.
1556
- *
1557
- * Uses a singleton flag so the stylesheet is only injected once.
1558
- */
1559
- function useKatexStyles() {
1560
- (0, react.useEffect)(() => {
1561
- if (injected || typeof document === "undefined") return;
1562
- injected = true;
1563
- import("katex/dist/katex.min.css").catch(() => {
1564
- console.warn("[CopilotKit] Failed to load katex styles — math content may render without formatting");
1565
- });
1566
- }, []);
1567
- }
1568
-
1569
1193
  //#endregion
1570
1194
  //#region src/v2/hooks/use-render-tool-call.tsx
1571
1195
  /**
@@ -1663,7 +1287,7 @@ function useToolCallRendererNames() {
1663
1287
  */
1664
1288
  function useRenderToolCall() {
1665
1289
  const { copilotkit, executingToolCallIds } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
1666
- const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
1290
+ const agentId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
1667
1291
  const unrenderedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
1668
1292
  const warnedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
1669
1293
  const renderToolCalls = useToolCallRenderers();
@@ -1701,7 +1325,7 @@ function useRenderToolCall() {
1701
1325
 
1702
1326
  //#endregion
1703
1327
  //#region package.json
1704
- var version = "1.80.0";
1328
+ var version = "1.82.0";
1705
1329
 
1706
1330
  //#endregion
1707
1331
  //#region src/v2/components/CopilotKitInspector.tsx
@@ -3006,7 +2630,7 @@ function createA2UIMessageRenderer(options) {
3006
2630
  const groupedOperations = (0, react.useMemo)(() => {
3007
2631
  const groups = /* @__PURE__ */ new Map();
3008
2632
  for (const operation of operations) {
3009
- const surfaceId = getOperationSurfaceId(operation) ?? _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
2633
+ const surfaceId = getOperationSurfaceId$1(operation) ?? _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
3010
2634
  if (!groups.has(surfaceId)) groups.set(surfaceId, []);
3011
2635
  groups.get(surfaceId).push(operation);
3012
2636
  }
@@ -3228,7 +2852,7 @@ function surfaceHasRenderableContent(operations) {
3228
2852
  * @param operation - One A2UI operation, of any shape.
3229
2853
  * @returns The surface id, or null when the operation names none.
3230
2854
  */
3231
- function getOperationSurfaceId(operation) {
2855
+ function getOperationSurfaceId$1(operation) {
3232
2856
  if (!operation || typeof operation !== "object") return null;
3233
2857
  const nested = operation?.createSurface?.surfaceId ?? operation?.updateComponents?.surfaceId ?? operation?.updateDataModel?.surfaceId ?? operation?.deleteSurface?.surfaceId;
3234
2858
  if (typeof nested === "string") return nested;
@@ -3236,19 +2860,6 @@ function getOperationSurfaceId(operation) {
3236
2860
  return null;
3237
2861
  }
3238
2862
 
3239
- //#endregion
3240
- //#region src/v2/types/defineToolCallRenderer.ts
3241
- function defineToolCallRenderer(def) {
3242
- const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
3243
- return {
3244
- name: def.name,
3245
- args: argsSchema,
3246
- render: def.render,
3247
- ...def.agentId ? { agentId: def.agentId } : {},
3248
- ...def.group ? { group: true } : {}
3249
- };
3250
- }
3251
-
3252
2863
  //#endregion
3253
2864
  //#region src/v2/a2ui/A2UIToolCallRenderer.tsx
3254
2865
  /**
@@ -3272,73 +2883,1886 @@ const RENDER_A2UI_TOOL_NAME = "render_a2ui";
3272
2883
  function A2UIBuiltInToolCallRenderer() {
3273
2884
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
3274
2885
  (0, react.useEffect)(() => {
3275
- const renderer = defineToolCallRenderer({
2886
+ const renderer = require_MarkdownSurfaces.defineToolCallRenderer({
3276
2887
  name: RENDER_A2UI_TOOL_NAME,
3277
2888
  args: zod.z.any(),
3278
2889
  render: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {})
3279
2890
  });
3280
- const existing = copilotkit._renderToolCalls ?? [];
3281
- copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
3282
- }, [copilotkit]);
3283
- return null;
2891
+ const existing = copilotkit._renderToolCalls ?? [];
2892
+ copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
2893
+ }, [copilotkit]);
2894
+ return null;
2895
+ }
2896
+
2897
+ //#endregion
2898
+ //#region src/v2/a2ui/A2UICatalogContext.tsx
2899
+ /**
2900
+ * Renders agent context describing the available A2UI catalog and custom components.
2901
+ * Only mount this component when A2UI is enabled.
2902
+ *
2903
+ * The entries are scoped to the agents the runtime applies A2UI to
2904
+ * (`copilotkit.a2uiAgents`, #5369), so agents outside that list don't receive
2905
+ * the catalog/schema/guidelines payload on their runs.
2906
+ *
2907
+ * When `includeSchema` is true, the full component schemas (JSON Schema) are also
2908
+ * sent as context using the same description key as the A2UI middleware, so the
2909
+ * middleware can optionally overwrite it with a server-side schema.
2910
+ */
2911
+ function A2UICatalogContext({ catalog, includeSchema }) {
2912
+ const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
2913
+ const capabilitiesValue = (0, react.useMemo)(() => (0, _copilotkit_a2ui_renderer.buildCatalogContextValue)(catalog, { includeSchema: includeSchema !== false }), [catalog, includeSchema]);
2914
+ const schemaValue = (0, react.useMemo)(() => includeSchema !== false ? JSON.stringify((0, _copilotkit_a2ui_renderer.extractCatalogComponentSchemas)(catalog)) : null, [catalog, includeSchema]);
2915
+ const a2uiAgentsKey = copilotkit?.a2uiAgents?.join(",");
2916
+ (0, react.useLayoutEffect)(() => {
2917
+ if (!copilotkit) return;
2918
+ const agentIds = copilotkit.a2uiAgents;
2919
+ const scope = agentIds ? { agentIds } : {};
2920
+ const ids = [];
2921
+ ids.push(copilotkit.addContext({
2922
+ description: "A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.",
2923
+ value: capabilitiesValue,
2924
+ ...scope
2925
+ }));
2926
+ if (schemaValue) {
2927
+ ids.push(copilotkit.addContext({
2928
+ description: _copilotkit_a2ui_renderer.A2UI_SCHEMA_CONTEXT_DESCRIPTION,
2929
+ value: schemaValue,
2930
+ ...scope
2931
+ }));
2932
+ ids.push(copilotkit.addContext({
2933
+ description: "A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.",
2934
+ value: _copilotkit_shared.A2UI_DEFAULT_GENERATION_GUIDELINES,
2935
+ ...scope
2936
+ }));
2937
+ ids.push(copilotkit.addContext({
2938
+ description: "A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.",
2939
+ value: _copilotkit_shared.A2UI_DEFAULT_DESIGN_GUIDELINES,
2940
+ ...scope
2941
+ }));
2942
+ }
2943
+ return () => {
2944
+ for (const id of ids) copilotkit.removeContext(id);
2945
+ };
2946
+ }, [
2947
+ copilotkit,
2948
+ capabilitiesValue,
2949
+ schemaValue,
2950
+ a2uiAgentsKey
2951
+ ]);
2952
+ return null;
2953
+ }
2954
+
2955
+ //#endregion
2956
+ //#region src/v2/generative-ui/action-message.ts
2957
+ /** Context keys that supply the message's first line, in priority order. */
2958
+ const TEXT_KEYS = ["message", "label"];
2959
+ function isNonEmptyString(value) {
2960
+ return typeof value === "string" && value.trim().length > 0;
2961
+ }
2962
+ /** `choose_plan`, `choose-plan` and `choosePlan` all become "Choose plan". */
2963
+ function humanize(name) {
2964
+ const spaced = name.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").trim();
2965
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
2966
+ }
2967
+ function formatContextValue(value) {
2968
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
2969
+ }
2970
+ /**
2971
+ * Turns a user event that no function handles into the text of a visible
2972
+ * user message.
2973
+ *
2974
+ * The first line is, in order: `userMessage`, `context.message`,
2975
+ * `context.label`, the label of the source component (from `resolveLabel`),
2976
+ * or the event name made readable (`choose_plan` becomes "Choose plan").
2977
+ * Each other context field follows as one `key: value` line. Objects are
2978
+ * written as JSON. `null` and `undefined` fields are skipped.
2979
+ *
2980
+ * @param event - The user event, as sent by a surface.
2981
+ * @param resolveLabel - Finds the visible label of a component by id. Build
2982
+ * one with {@link createComponentLabelResolver}.
2983
+ *
2984
+ * @example
2985
+ * ```ts
2986
+ * buildActionMessageText({
2987
+ * name: "choose_plan",
2988
+ * surfaceId: "plans",
2989
+ * componentId: "team-button",
2990
+ * userMessage: "I pick the Team plan",
2991
+ * context: { seats: 12 },
2992
+ * });
2993
+ * // "I pick the Team plan\n\nseats: 12"
2994
+ * ```
2995
+ */
2996
+ function buildActionMessageText(event, resolveLabel) {
2997
+ const { context, userMessage } = event;
2998
+ const explicit = [userMessage, ...TEXT_KEYS.map((key) => context[key])].find(isNonEmptyString);
2999
+ const resolved = explicit ? void 0 : resolveLabel?.(event.componentId);
3000
+ const head = explicit ?? (isNonEmptyString(resolved) ? resolved.trim() : humanize(event.name));
3001
+ const lines = Object.entries(context).filter(([key, value]) => !TEXT_KEYS.includes(key) && value !== void 0 && value !== null).map(([key, value]) => `${key}: ${formatContextValue(value)}`);
3002
+ return lines.length > 0 ? `${head}\n\n${lines.join("\n")}` : head;
3003
+ }
3004
+ function ownText(component) {
3005
+ if (!component) return void 0;
3006
+ if (isNonEmptyString(component.label)) return component.label;
3007
+ if (isNonEmptyString(component.text)) return component.text;
3008
+ }
3009
+ function childIds(component) {
3010
+ const { child, children } = component;
3011
+ const single = typeof child === "string" ? [child] : [];
3012
+ const multiple = Array.isArray(children) ? children.filter((id) => typeof id === "string") : [];
3013
+ return [...single, ...multiple];
3014
+ }
3015
+ /** The components that an operation adds, inline or in an update. */
3016
+ function componentsOf(operation) {
3017
+ if ("createSurface" in operation) return operation.createSurface.components ?? [];
3018
+ if ("updateComponents" in operation) return operation.updateComponents.components;
3019
+ return [];
3020
+ }
3021
+ /**
3022
+ * Builds a function that finds the visible label of a component on a surface.
3023
+ *
3024
+ * The label is the component's own string `label`, else its string `text`,
3025
+ * else the first `child` or `children` component that has a string `label`
3026
+ * or `text`. When a component id is defined more than once, the last
3027
+ * definition wins, as in the renderer.
3028
+ *
3029
+ * @param operations - The committed operations of the surface.
3030
+ *
3031
+ * @example
3032
+ * ```ts
3033
+ * const resolveLabel = createComponentLabelResolver(surface.operations);
3034
+ * buildActionMessageText(event, resolveLabel);
3035
+ * ```
3036
+ */
3037
+ function createComponentLabelResolver(operations) {
3038
+ const byId = /* @__PURE__ */ new Map();
3039
+ for (const operation of operations) {
3040
+ const components = componentsOf(operation);
3041
+ for (const component of components) byId.set(component.id, component);
3042
+ }
3043
+ return (componentId) => {
3044
+ const component = byId.get(componentId);
3045
+ if (!component) return void 0;
3046
+ const own = ownText(component);
3047
+ if (own) return own;
3048
+ const ids = childIds(component);
3049
+ for (const id of ids) {
3050
+ const text = ownText(byId.get(id));
3051
+ if (text) return text;
3052
+ }
3053
+ };
3054
+ }
3055
+
3056
+ //#endregion
3057
+ //#region src/v2/generative-ui/manifest.ts
3058
+ /**
3059
+ * The built-in functions (the A2UI basic catalog plus calc and series) as
3060
+ * manifest entries. Their args are described by the short signature, not
3061
+ * by a full JSON Schema: the renderer checks them when they run. An app
3062
+ * function of the same name replaces the entry.
3063
+ */
3064
+ function builtInFunctionManifests() {
3065
+ return Object.fromEntries(Object.entries(_copilotkit_shared.GENERATIVE_UI_FUNCTIONS).map(([name, fn]) => [name, {
3066
+ description: fn.description,
3067
+ parameters: {
3068
+ type: "object",
3069
+ description: fn.parameters
3070
+ },
3071
+ returnType: fn.returnType,
3072
+ allowedCallers: fn.allowedCallers,
3073
+ ...fn.requiresUserActivation ? { requiresUserActivation: true } : {}
3074
+ }]));
3075
+ }
3076
+ /**
3077
+ * Builds the per-run manifest. Never contains handlers or renderers.
3078
+ *
3079
+ * - `functions`: the built-in functions, then the declared functions with
3080
+ * exactly one mounted handler.
3081
+ * - `targets`: the chat first, then each mounted `<GenerativeUISurface>`,
3082
+ * with its `description` and its `components` when it has them.
3083
+ */
3084
+ function buildGenerativeUIManifest(runtime, threadId) {
3085
+ const { ui, manager, dispatcher } = runtime;
3086
+ const inlineTargets = manager.getMountedTargets().filter((target) => target.id !== _copilotkit_shared.GENERATIVE_UI_CHAT_TARGET).map(({ id, ...rest }) => ({
3087
+ id,
3088
+ kind: "inline",
3089
+ ...rest
3090
+ }));
3091
+ return {
3092
+ catalogId: ui.id,
3093
+ catalogIds: require_MarkdownSurfaces.catalogIdsOf(ui),
3094
+ components: ui.manifestComponents,
3095
+ functions: {
3096
+ ...Object.fromEntries(Object.entries(builtInFunctionManifests()).filter(([name]) => !ui.functions.has(name))),
3097
+ ...dispatcher.listExposed()
3098
+ },
3099
+ targets: [{
3100
+ id: _copilotkit_shared.GENERATIVE_UI_CHAT_TARGET,
3101
+ kind: "chat"
3102
+ }, ...inlineTargets],
3103
+ surfaces: threadId ? manager.describeSurfaces(threadId) : {}
3104
+ };
3105
+ }
3106
+ /**
3107
+ * Builds the envelope that a run sends as `forwardedProps.copilotkit.ui`,
3108
+ * from the per-run manifest. It has the A2UI v1.0 renderer capabilities
3109
+ * shape: one inline catalog with the id of the UI, and the CopilotKit data
3110
+ * in `metadata.extensions`.
3111
+ *
3112
+ * The inline catalog has no `components` only for the markdown transport
3113
+ * with `includeCatalog: false`. It has `instructions` for the markdown
3114
+ * transport, or when given.
3115
+ *
3116
+ * @param runtime - The generative UI runtime of the provider.
3117
+ * @param threadId - The thread of the run. Its surfaces go in `copilotkit_surfaces`.
3118
+ * @param options - The transport and what to send.
3119
+ *
3120
+ * @example
3121
+ * ```ts
3122
+ * const envelope = buildGenerativeUIEnvelope(runtime, agent.threadId, {
3123
+ * transport: "tool",
3124
+ * includeCatalog: true,
3125
+ * contextSent: false,
3126
+ * });
3127
+ * envelope["v1.0"].supportedCatalogIds; // [runtime.ui.id]
3128
+ * ```
3129
+ */
3130
+ function buildGenerativeUIEnvelope(runtime, threadId, options) {
3131
+ const { transport, includeCatalog, contextSent, action } = options;
3132
+ const manifest = buildGenerativeUIManifest(runtime, threadId);
3133
+ const instructions = options.instructions ?? (transport === "markdown" ? (0, _copilotkit_shared.buildGenerativeUIMarkdownGuidelines)((0, _copilotkit_shared.generativeUIGuideFeatures)(manifest)) : void 0);
3134
+ const omitComponents = transport === "markdown" && !includeCatalog;
3135
+ return {
3136
+ "v1.0": {
3137
+ supportedCatalogIds: manifest.catalogIds ?? [manifest.catalogId],
3138
+ inlineCatalogs: [{
3139
+ catalogId: manifest.catalogId,
3140
+ protocolVersion: "1.0",
3141
+ ...omitComponents ? {} : { components: manifest.components },
3142
+ functions: manifest.functions,
3143
+ ...instructions === void 0 ? {} : { instructions }
3144
+ }]
3145
+ },
3146
+ metadata: { extensions: {
3147
+ copilotkit_format: _copilotkit_shared.COPILOTKIT_UI_ENVELOPE_FORMAT,
3148
+ copilotkit_transport: transport,
3149
+ copilotkit_targets: manifest.targets,
3150
+ copilotkit_surfaces: manifest.surfaces,
3151
+ copilotkit_contextSent: contextSent,
3152
+ ...action === void 0 ? {} : { copilotkit_action: action }
3153
+ } }
3154
+ };
3155
+ }
3156
+
3157
+ //#endregion
3158
+ //#region src/v2/generative-ui/markdown/context.ts
3159
+ /** Objects nested deeper than this show as `object`. */
3160
+ const MAX_OBJECT_DEPTH = 2;
3161
+ /** A prop must appear verbatim in at least this many components to be hoisted. */
3162
+ const COMMON_PROP_MIN_COMPONENTS = 8;
3163
+ /** A JSON Schema of a list of schemas (`anyOf`, `oneOf`), else an empty list. */
3164
+ function schemaList(value) {
3165
+ return Array.isArray(value) ? value.filter(require_MarkdownSurfaces.isRecord) : [];
3166
+ }
3167
+ /**
3168
+ * Puts a top-level union in parentheses, so that `[]` applies to all of
3169
+ * it. A union inside braces needs none.
3170
+ */
3171
+ function asArrayItem(type) {
3172
+ let outside = type;
3173
+ for (let inner = outside.replace(/\{[^{}]*\}/g, ""); inner !== outside;) {
3174
+ outside = inner;
3175
+ inner = outside.replace(/\{[^{}]*\}/g, "");
3176
+ }
3177
+ return outside.includes(" | ") ? `(${type})[]` : `${type}[]`;
3178
+ }
3179
+ /**
3180
+ * A JSON Schema as a short TypeScript-like type, for example
3181
+ * `{ label: string; size?: "sm" | "md" }`.
3182
+ */
3183
+ function compactType(schema, depth) {
3184
+ const ref = (0, _copilotkit_shared.childRefKind)(schema);
3185
+ if (ref === "single") return "componentId";
3186
+ if (ref === "multiple") return "componentId[] | { componentId: string; path: string }";
3187
+ if ("const" in schema) return JSON.stringify(schema.const);
3188
+ if (Array.isArray(schema.enum)) return schema.enum.map((value) => JSON.stringify(value)).join(" | ");
3189
+ const variants = [...schemaList(schema.anyOf), ...schemaList(schema.oneOf)];
3190
+ if (variants.length > 0) return variants.map((variant) => compactType(variant, depth)).join(" | ");
3191
+ return (Array.isArray(schema.type) ? schema.type : [schema.type]).map((type) => {
3192
+ switch (type) {
3193
+ case "string":
3194
+ case "boolean":
3195
+ case "null": return type;
3196
+ case "number":
3197
+ case "integer": return "number";
3198
+ case "array": return require_MarkdownSurfaces.isRecord(schema.items) ? asArrayItem(compactType(schema.items, depth)) : "unknown[]";
3199
+ case "object": return compactObject(schema, depth);
3200
+ default: return "unknown";
3201
+ }
3202
+ }).join(" | ");
3203
+ }
3204
+ /** An object schema as `{ key: type; other?: type }`. */
3205
+ function compactObject(schema, depth) {
3206
+ const properties = require_MarkdownSurfaces.isRecord(schema.properties) ? schema.properties : {};
3207
+ const entries = Object.entries(properties);
3208
+ if (entries.length === 0) return require_MarkdownSurfaces.isRecord(schema.additionalProperties) ? `Record<string, ${compactType(schema.additionalProperties, depth + 1)}>` : "object";
3209
+ if (depth >= MAX_OBJECT_DEPTH) return "object";
3210
+ const required = Array.isArray(schema.required) ? schema.required : [];
3211
+ return `{ ${entries.map(([key, value]) => {
3212
+ const type = require_MarkdownSurfaces.isRecord(value) ? compactType(value, depth + 1) : "unknown";
3213
+ return `${key}${required.includes(key) ? "" : "?"}: ${type}`;
3214
+ }).join("; ")} }`;
3215
+ }
3216
+ /** A schema as its type, with its description after `//`. */
3217
+ function describedType(schema, depth) {
3218
+ const type = compactType(schema, depth);
3219
+ return typeof schema.description === "string" ? `${type} // ${schema.description}` : type;
3220
+ }
3221
+ /** The props of a component: `{ "label": "string", "size?": "..." }`. */
3222
+ function compactProps(schema) {
3223
+ const properties = require_MarkdownSurfaces.isRecord(schema.properties) ? schema.properties : {};
3224
+ const required = Array.isArray(schema.required) ? schema.required : [];
3225
+ const props = {};
3226
+ for (const [key, value] of Object.entries(properties)) {
3227
+ if (!require_MarkdownSurfaces.isRecord(value)) continue;
3228
+ const name = required.includes(key) ? key : `${key}?`;
3229
+ props[name] = describedType(value, 1);
3230
+ }
3231
+ return props;
3232
+ }
3233
+ /**
3234
+ * The prop set worth listing once. Candidates are (key, type) pairs that at
3235
+ * least {@link COMMON_PROP_MIN_COMPONENTS} components carry verbatim. The
3236
+ * candidate subset of each component is a possible common set, scored by
3237
+ * the characters it saves (set size times the components that contain all
3238
+ * of it). `undefined` when no set is shared by enough components.
3239
+ */
3240
+ function findCommonProps(propsList) {
3241
+ const pairKey = (key, type) => `${key}\u0000${type}`;
3242
+ const counts = /* @__PURE__ */ new Map();
3243
+ for (const props of propsList) for (const [key, type] of Object.entries(props)) {
3244
+ const id = pairKey(key, type);
3245
+ counts.set(id, (counts.get(id) ?? 0) + 1);
3246
+ }
3247
+ let best;
3248
+ let bestScore = 0;
3249
+ const seen = /* @__PURE__ */ new Set();
3250
+ for (const props of propsList) {
3251
+ const subset = Object.entries(props).filter(([key, type]) => (counts.get(pairKey(key, type)) ?? 0) >= COMMON_PROP_MIN_COMPONENTS);
3252
+ if (subset.length < 2) continue;
3253
+ const signature = subset.map(([key, type]) => pairKey(key, type)).join("\n");
3254
+ if (seen.has(signature)) continue;
3255
+ seen.add(signature);
3256
+ const members = propsList.filter((other) => subset.every(([key, type]) => other[key] === type)).length;
3257
+ if (members < COMMON_PROP_MIN_COMPONENTS) continue;
3258
+ const score = subset.reduce((total, [key, type]) => total + key.length + type.length, 0) * (members - 1);
3259
+ if (score > bestScore) {
3260
+ bestScore = score;
3261
+ best = Object.fromEntries(subset);
3262
+ }
3263
+ }
3264
+ return best;
3265
+ }
3266
+ /**
3267
+ * The component schema of the markdown transport, from the per-run
3268
+ * manifest. It is smaller than the manifest: each prop is one short type,
3269
+ * and the props that many components share verbatim (the layout props of
3270
+ * the containers) are listed once in `commonProps`; a component that takes
3271
+ * them is flagged `includesCommonProps`.
3272
+ * It has the catalog id, the targets with their descriptions and their
3273
+ * component lists, the functions with their parameters, the components
3274
+ * with their props, events and slots, and the surfaces of the thread. A surface lists the
3275
+ * values that the user set and the operations that the client dropped.
3276
+ *
3277
+ * @param manifest - The manifest from `buildGenerativeUIManifest`.
3278
+ * @returns A JSON-ready object.
3279
+ *
3280
+ * @example
3281
+ * ```ts
3282
+ * const value = JSON.stringify(
3283
+ * buildCompactGenerativeUISchema(buildGenerativeUIManifest(runtime, threadId)),
3284
+ * );
3285
+ * ```
3286
+ */
3287
+ function buildCompactGenerativeUISchema(manifest) {
3288
+ const components = {};
3289
+ for (const [name, component] of Object.entries(manifest.components)) {
3290
+ const events = Object.entries(component.events ?? {}).map(([event, definition]) => [event, definition.description ?? compactType(definition.parameters, 0)]);
3291
+ components[name] = {
3292
+ ...component.description ? { description: component.description } : {},
3293
+ props: compactProps(component.props),
3294
+ ...events.length > 0 ? { events: Object.fromEntries(events) } : {},
3295
+ ...component.slots ? { slots: component.slots } : {}
3296
+ };
3297
+ }
3298
+ const common = findCommonProps(Object.values(components).map((component) => component.props));
3299
+ if (common) {
3300
+ const commonKeys = Object.keys(common);
3301
+ for (const component of Object.values(components)) {
3302
+ if (!commonKeys.every((key) => component.props[key] === common[key])) continue;
3303
+ component.includesCommonProps = true;
3304
+ component.props = Object.fromEntries(Object.entries(component.props).filter(([key]) => !(key in common)));
3305
+ }
3306
+ }
3307
+ const functions = Object.fromEntries(Object.entries(manifest.functions).map(([name, fn]) => {
3308
+ const signature = fn.parameters.description;
3309
+ const hasSignature = typeof signature === "string" && signature.startsWith("{") && Object.keys(fn.parameters).length === 2;
3310
+ const callers = (0, _copilotkit_shared.functionCallers)(fn);
3311
+ return [name, {
3312
+ ...fn.description ? { description: fn.description } : {},
3313
+ parameters: hasSignature ? signature : compactType(fn.parameters, 0),
3314
+ ...callers.agent && _copilotkit_shared.GENERATIVE_UI_AGENT_FUNCTION_CALLS ? { callers: callers.renderer ? "UI or agent" : "agent only" } : {}
3315
+ }];
3316
+ }));
3317
+ return {
3318
+ catalogId: manifest.catalogId,
3319
+ targets: manifest.targets,
3320
+ functions,
3321
+ ...common ? { commonProps: common } : {},
3322
+ components,
3323
+ surfaces: manifest.surfaces
3324
+ };
3325
+ }
3326
+ /**
3327
+ * Registers the two context entries of the markdown transport: the compact
3328
+ * component schema and the fence guideline. Both go only to `agentIds`.
3329
+ *
3330
+ * The schema is built again at each run start and when a
3331
+ * `<GenerativeUISurface>` mounts, unmounts, or changes its description or
3332
+ * its components, so its targets, functions, and surfaces stay current. The surfaces are those of the running thread.
3333
+ *
3334
+ * @param copilotkit - The CopilotKit core of the provider.
3335
+ * @param runtime - The generative UI runtime parts, or null without one.
3336
+ * @param options - `enabled` and `agentIds`.
3337
+ *
3338
+ * @example
3339
+ * ```ts
3340
+ * useGenerativeUIMarkdownContext(copilotkit, core, {
3341
+ * enabled: config?.transport === "markdown" && config.sendContext !== false,
3342
+ * agentIds: config?.agentIds,
3343
+ * });
3344
+ * ```
3345
+ */
3346
+ function useGenerativeUIMarkdownContext(copilotkit, runtime, options) {
3347
+ const { enabled, agentIds } = options;
3348
+ const agentIdsKey = agentIds === void 0 ? "" : JSON.stringify(agentIds);
3349
+ (0, react.useEffect)(() => {
3350
+ if (!runtime || !enabled) return;
3351
+ const scopedAgentIds = agentIdsKey ? JSON.parse(agentIdsKey) : void 0;
3352
+ const scope = scopedAgentIds ? { agentIds: scopedAgentIds } : {};
3353
+ let guidelineId;
3354
+ let guidelineValue;
3355
+ let schemaId;
3356
+ let schemaValue;
3357
+ const refreshSchema = (threadId) => {
3358
+ const manifest = buildGenerativeUIManifest(runtime, threadId);
3359
+ const guideline = (0, _copilotkit_shared.buildGenerativeUIMarkdownGuidelines)((0, _copilotkit_shared.generativeUIGuideFeatures)(manifest));
3360
+ if (guideline !== guidelineValue) {
3361
+ if (guidelineId !== void 0) copilotkit.removeContext(guidelineId);
3362
+ guidelineValue = guideline;
3363
+ guidelineId = copilotkit.addContext({
3364
+ description: _copilotkit_shared.GENERATIVE_UI_MARKDOWN_GUIDELINES_DESCRIPTION,
3365
+ value: guideline,
3366
+ ...scope
3367
+ });
3368
+ }
3369
+ const value = JSON.stringify(buildCompactGenerativeUISchema(manifest));
3370
+ if (value === schemaValue) return;
3371
+ if (schemaId !== void 0) copilotkit.removeContext(schemaId);
3372
+ schemaValue = value;
3373
+ schemaId = copilotkit.addContext({
3374
+ description: _copilotkit_shared.GENERATIVE_UI_MARKDOWN_SCHEMA_CONTEXT_DESCRIPTION,
3375
+ value,
3376
+ ...scope
3377
+ });
3378
+ };
3379
+ refreshSchema(runtime.manager.getActiveThread());
3380
+ let targetsKey = JSON.stringify(runtime.manager.getMountedTargets());
3381
+ const unsubscribeManager = runtime.manager.subscribe(() => {
3382
+ const nextKey = JSON.stringify(runtime.manager.getMountedTargets());
3383
+ if (nextKey === targetsKey) return;
3384
+ targetsKey = nextKey;
3385
+ refreshSchema(runtime.manager.getActiveThread());
3386
+ });
3387
+ const subscription = copilotkit.subscribe({ onAgentRunStarted: ({ agent }) => refreshSchema(agent.threadId) });
3388
+ return () => {
3389
+ subscription.unsubscribe();
3390
+ unsubscribeManager();
3391
+ if (guidelineId !== void 0) copilotkit.removeContext(guidelineId);
3392
+ if (schemaId !== void 0) copilotkit.removeContext(schemaId);
3393
+ };
3394
+ }, [
3395
+ copilotkit,
3396
+ runtime,
3397
+ enabled,
3398
+ agentIdsKey
3399
+ ]);
3400
+ }
3401
+
3402
+ //#endregion
3403
+ //#region src/v2/generative-ui/debug-source.ts
3404
+ /**
3405
+ * What a run of `threadId` sends: its envelope, and the text that goes into
3406
+ * the prompt of the model because of it.
3407
+ *
3408
+ * - Tool transport: the runtime adds the `render_ui` guide. It builds it
3409
+ * from the envelope with `buildGenerativeUIPrompt`, as done here.
3410
+ * - Markdown transport: the provider sends the guideline and the compact
3411
+ * schema as context entries. With `sendContext: false`, the backend builds
3412
+ * its own prompt, usually from the `instructions` of the envelope.
3413
+ */
3414
+ function describeGenerativeUIRun(runtime, threadId, options) {
3415
+ const envelope = buildGenerativeUIEnvelope(runtime, threadId, options);
3416
+ if (options.transport === "tool") return {
3417
+ envelope,
3418
+ prompt: [{
3419
+ title: "render_ui guide",
3420
+ source: "runtime",
3421
+ text: (0, _copilotkit_shared.buildGenerativeUIPrompt)((0, _copilotkit_shared.envelopeToManifest)(envelope))
3422
+ }]
3423
+ };
3424
+ const manifest = buildGenerativeUIManifest(runtime, threadId);
3425
+ if (!options.contextSent) return {
3426
+ envelope,
3427
+ prompt: [{
3428
+ title: "Envelope instructions",
3429
+ source: "backend",
3430
+ text: (0, _copilotkit_shared.envelopeToManifest)(envelope).instructions ?? ""
3431
+ }]
3432
+ };
3433
+ const guideline = (0, _copilotkit_shared.buildGenerativeUIMarkdownGuidelines)((0, _copilotkit_shared.generativeUIGuideFeatures)(manifest));
3434
+ const schema = JSON.stringify(buildCompactGenerativeUISchema(manifest));
3435
+ return {
3436
+ envelope,
3437
+ prompt: [{
3438
+ title: "Markdown guideline",
3439
+ source: "context",
3440
+ text: guideline
3441
+ }, {
3442
+ title: "Component schema",
3443
+ source: "context",
3444
+ text: schema
3445
+ }]
3446
+ };
3447
+ }
3448
+ /** The declared functions, with the JSON Schema of their parameters. */
3449
+ function debugFunctions(runtime) {
3450
+ const functions = {};
3451
+ for (const [name, declared] of runtime.ui.functions) {
3452
+ let parameters = {};
3453
+ try {
3454
+ parameters = require_MarkdownSurfaces.toJsonSchema(declared.parameters);
3455
+ } catch {}
3456
+ functions[name] = {
3457
+ ...declared.description ? { description: declared.description } : {},
3458
+ parameters,
3459
+ handlers: runtime.dispatcher.handlerCount(name)
3460
+ };
3461
+ }
3462
+ return functions;
3463
+ }
3464
+ /**
3465
+ * The debug source that the provider gives core for the inspector. It builds
3466
+ * a snapshot only when the inspector reads one.
3467
+ *
3468
+ * @param runtime - The generative UI parts of the provider.
3469
+ * @param getOptions - The envelope options and agent ids of the current config.
3470
+ * @returns The source, and `recordRun` for each run start.
3471
+ */
3472
+ function createGenerativeUIDebugSource(runtime, getOptions) {
3473
+ const listeners = /* @__PURE__ */ new Set();
3474
+ let lastRun;
3475
+ const notify = () => {
3476
+ for (const listener of [...listeners]) listener();
3477
+ };
3478
+ return {
3479
+ source: {
3480
+ getSnapshot() {
3481
+ const { options, agentIds } = getOptions();
3482
+ const threadId = runtime.manager.getActiveThread();
3483
+ const manifest = buildGenerativeUIManifest(runtime, threadId);
3484
+ return {
3485
+ catalogId: runtime.ui.id,
3486
+ transport: options.transport,
3487
+ ...agentIds ? { agentIds } : {},
3488
+ components: runtime.ui.manifestComponents,
3489
+ componentCatalogs: Object.fromEntries(require_MarkdownSurfaces.componentCatalogIds(runtime.ui)),
3490
+ functions: debugFunctions(runtime),
3491
+ state: { ...runtime.manager.getState() },
3492
+ targets: manifest.targets,
3493
+ activeThreadId: threadId,
3494
+ surfaces: runtime.manager.debugSurfaces(),
3495
+ lastRun,
3496
+ nextRun: {
3497
+ agentId: void 0,
3498
+ threadId,
3499
+ ...describeGenerativeUIRun(runtime, threadId, options)
3500
+ }
3501
+ };
3502
+ },
3503
+ subscribe(listener) {
3504
+ listeners.add(listener);
3505
+ const unsubscribe = runtime.manager.subscribe(listener);
3506
+ return () => {
3507
+ listeners.delete(listener);
3508
+ unsubscribe();
3509
+ };
3510
+ }
3511
+ },
3512
+ recordRun(run) {
3513
+ lastRun = run;
3514
+ notify();
3515
+ }
3516
+ };
3517
+ }
3518
+
3519
+ //#endregion
3520
+ //#region src/v2/generative-ui/dispatcher.ts
3521
+ const messageOf = (error) => error instanceof Error ? error.message : String(error);
3522
+ /**
3523
+ * Creates the registry of functions that generated UI may call.
3524
+ *
3525
+ * A function is callable when it is declared in `getDeclared()` and exactly
3526
+ * one handler is mounted for it with `register`. Names are resolved at call
3527
+ * time and fail closed. Nothing is sent to the agent.
3528
+ * Neither `invoke` nor `listExposed` throws.
3529
+ *
3530
+ * @param options.getDeclared - Returns the declared functions.
3531
+ * @param options.onError - Gets each failed call.
3532
+ *
3533
+ * @example
3534
+ * ```ts
3535
+ * const dispatcher = createGenerativeUIDispatcher({
3536
+ * getDeclared: () => new Map(Object.entries(ui.functions)),
3537
+ * });
3538
+ * const unregister = dispatcher.register("addToCart", handlerRef);
3539
+ * await dispatcher.invoke("addToCart", { productId: "p1" }, origin);
3540
+ * unregister();
3541
+ * ```
3542
+ */
3543
+ /**
3544
+ * True while the browser counts the current task as user-activated (a
3545
+ * click, a key press). Where the API is missing (older browsers, test
3546
+ * environments), the gesture is assumed.
3547
+ */
3548
+ function hasUserActivation() {
3549
+ if (typeof navigator === "undefined") return true;
3550
+ const activation = navigator.userActivation;
3551
+ return activation === void 0 || activation.isActive;
3552
+ }
3553
+ /**
3554
+ * The permissions of a declared function as the manifest states them: the
3555
+ * callers always written out, so a reader needs no default.
3556
+ */
3557
+ function permissionsOf(fn) {
3558
+ const callers = (0, _copilotkit_shared.functionCallers)(fn);
3559
+ return {
3560
+ allowedCallers: callers.renderer && callers.agent ? "rendererOrAgent" : callers.agent ? "agentOnly" : "rendererOnly",
3561
+ ...fn.requiresUserActivation ? { requiresUserActivation: true } : {}
3562
+ };
3563
+ }
3564
+ function createGenerativeUIDispatcher(options) {
3565
+ const handlers = /* @__PURE__ */ new Map();
3566
+ const resolveUnchecked = (name) => {
3567
+ const declared = options.getDeclared().get(name);
3568
+ if (!declared) return {
3569
+ ok: false,
3570
+ error: new require_MarkdownSurfaces.GenerativeUIError("function_not_found", `No generative UI function named "${name}" is declared in createGenerativeUI({ functions })`)
3571
+ };
3572
+ const mounted = [...handlers.get(name) ?? []];
3573
+ const [ref] = mounted;
3574
+ if (!ref) return {
3575
+ ok: false,
3576
+ error: new require_MarkdownSurfaces.GenerativeUIError("function_not_found", `"${name}" is declared, but no useGenerativeUIFunction handler is mounted for it`)
3577
+ };
3578
+ if (mounted.length > 1) return {
3579
+ ok: false,
3580
+ error: new require_MarkdownSurfaces.GenerativeUIError("function_conflict", `"${name}" has ${mounted.length} useGenerativeUIFunction handlers mounted. Mount exactly one.`)
3581
+ };
3582
+ return {
3583
+ ok: true,
3584
+ declared,
3585
+ ref
3586
+ };
3587
+ };
3588
+ const isDeclared = (name) => {
3589
+ try {
3590
+ return options.getDeclared().has(name);
3591
+ } catch {
3592
+ return false;
3593
+ }
3594
+ };
3595
+ const resolve = (name) => {
3596
+ try {
3597
+ return resolveUnchecked(name);
3598
+ } catch (error) {
3599
+ return {
3600
+ ok: false,
3601
+ error: new require_MarkdownSurfaces.GenerativeUIError("handler_failed", `"${name}" could not be resolved: ${messageOf(error)}`)
3602
+ };
3603
+ }
3604
+ };
3605
+ const validateArgs = async (name, schema, args) => {
3606
+ try {
3607
+ const validation = await schema["~standard"].validate(args);
3608
+ if (!validation.issues) return {
3609
+ ok: true,
3610
+ value: validation.value
3611
+ };
3612
+ return {
3613
+ ok: false,
3614
+ error: new require_MarkdownSurfaces.GenerativeUIError("invalid_arguments", `Invalid arguments for "${name}": ${validation.issues.map((i) => `${(i.path ?? []).map((p) => typeof p === "object" ? p.key : p).join(".") || "args"}: ${i.message}`).join("; ")}`)
3615
+ };
3616
+ } catch (error) {
3617
+ return {
3618
+ ok: false,
3619
+ error: new require_MarkdownSurfaces.GenerativeUIError("invalid_arguments", `Invalid arguments for "${name}": ${messageOf(error)}`)
3620
+ };
3621
+ }
3622
+ };
3623
+ const failWith = (name, origin, error) => {
3624
+ try {
3625
+ options.onError?.({
3626
+ name,
3627
+ origin,
3628
+ error
3629
+ });
3630
+ } catch {}
3631
+ return {
3632
+ ok: false,
3633
+ error
3634
+ };
3635
+ };
3636
+ /**
3637
+ * Why `origin` may not call a function with these permissions now, as an
3638
+ * error, or `undefined` when it may. The agent is refused what is for the
3639
+ * renderer; a component is refused what is for the agent, and a gesture
3640
+ * function when the browser counts no user activation.
3641
+ */
3642
+ const callerError = (name, fn, origin) => {
3643
+ const isComponent = "componentId" in origin;
3644
+ if (!isComponent && !_copilotkit_shared.GENERATIVE_UI_AGENT_FUNCTION_CALLS) return new require_MarkdownSurfaces.GenerativeUIError("invalid_function_call", _copilotkit_shared.GENERATIVE_UI_AGENT_FUNCTION_CALLS_OFF_REASON);
3645
+ const problem = (0, _copilotkit_shared.callerProblem)(name, fn, isComponent ? "renderer" : "agent");
3646
+ if (problem !== void 0) return new require_MarkdownSurfaces.GenerativeUIError("invalid_function_call", problem);
3647
+ if (isComponent && fn.requiresUserActivation && !hasUserActivation()) return new require_MarkdownSurfaces.GenerativeUIError("invalid_function_call", `function "${name}" runs only from a user gesture; this event was not one`);
3648
+ };
3649
+ /**
3650
+ * Runs a basic function of the A2UI catalog. They are value functions of
3651
+ * the renderer: the agent cannot call them, and one that needs a user
3652
+ * gesture runs only from an event binding.
3653
+ */
3654
+ const invokeBasic = (name, args, origin) => {
3655
+ const refused = callerError(name, _copilotkit_shared.GENERATIVE_UI_FUNCTIONS[name], origin);
3656
+ if (refused) return failWith(name, origin, refused);
3657
+ if (args !== void 0 && !(typeof args === "object" && args !== null && !Array.isArray(args))) return failWith(name, origin, new require_MarkdownSurfaces.GenerativeUIError("invalid_arguments", `Invalid arguments for "${name}": args must be an object`));
3658
+ try {
3659
+ return {
3660
+ ok: true,
3661
+ result: require_MarkdownSurfaces.BASIC_FUNCTIONS[name](args ?? {})
3662
+ };
3663
+ } catch (error) {
3664
+ return failWith(name, origin, new require_MarkdownSurfaces.GenerativeUIError(error instanceof require_MarkdownSurfaces.ExpressionError ? "invalid_arguments" : "handler_failed", `"${name}" failed: ${messageOf(error)}`));
3665
+ }
3666
+ };
3667
+ return {
3668
+ async invoke(name, args, origin) {
3669
+ const resolved = resolve(name);
3670
+ if (!resolved.ok && resolved.error.code === "function_not_found" && !isDeclared(name) && Object.prototype.hasOwnProperty.call(require_MarkdownSurfaces.BASIC_FUNCTIONS, name)) return invokeBasic(name, args, origin);
3671
+ if (!resolved.ok) return failWith(name, origin, resolved.error);
3672
+ const refused = callerError(name, resolved.declared, origin);
3673
+ if (refused) return failWith(name, origin, refused);
3674
+ const validated = await validateArgs(name, resolved.declared.parameters, args ?? {});
3675
+ if (!validated.ok) return failWith(name, origin, validated.error);
3676
+ try {
3677
+ return {
3678
+ ok: true,
3679
+ result: await resolved.ref.current(validated.value)
3680
+ };
3681
+ } catch (error) {
3682
+ return failWith(name, origin, new require_MarkdownSurfaces.GenerativeUIError("handler_failed", `"${name}" failed: ${messageOf(error)}`));
3683
+ }
3684
+ },
3685
+ listExposed() {
3686
+ let names;
3687
+ try {
3688
+ names = [...options.getDeclared().keys()];
3689
+ } catch {
3690
+ return {};
3691
+ }
3692
+ const listed = {};
3693
+ for (const name of names) {
3694
+ const resolved = resolve(name);
3695
+ if (!resolved.ok) continue;
3696
+ if (!(0, _copilotkit_shared.functionCallers)(resolved.declared).renderer && !_copilotkit_shared.GENERATIVE_UI_AGENT_FUNCTION_CALLS) continue;
3697
+ const { description, parameters, returnType } = resolved.declared;
3698
+ try {
3699
+ listed[name] = {
3700
+ ...description ? { description } : {},
3701
+ parameters: require_MarkdownSurfaces.toJsonSchema(parameters),
3702
+ ...returnType ? { returnType } : {},
3703
+ ...permissionsOf(resolved.declared)
3704
+ };
3705
+ } catch {}
3706
+ }
3707
+ return listed;
3708
+ },
3709
+ register(name, ref) {
3710
+ const mounted = handlers.get(name) ?? /* @__PURE__ */ new Set();
3711
+ mounted.add(ref);
3712
+ handlers.set(name, mounted);
3713
+ return () => {
3714
+ mounted.delete(ref);
3715
+ };
3716
+ },
3717
+ handlerCount: (name) => handlers.get(name)?.size ?? 0
3718
+ };
3719
+ }
3720
+
3721
+ //#endregion
3722
+ //#region src/v2/generative-ui/surface-manager.ts
3723
+ function surfaceKey(threadId, surfaceId) {
3724
+ return `${threadId}::${surfaceId}`;
3725
+ }
3726
+ let creationCounter = 0;
3727
+ const FORBIDDEN_SEGMENTS = new Set([
3728
+ "__proto__",
3729
+ "constructor",
3730
+ "prototype"
3731
+ ]);
3732
+ /** "/a/b/" to "/a/b". The root stays "/". */
3733
+ function normalizePath(path) {
3734
+ return (path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path) || "/";
3735
+ }
3736
+ /** True when `path` is `ancestor` or below it. */
3737
+ function isAtOrBelow(path, ancestor) {
3738
+ if (ancestor === "/") return true;
3739
+ return path === ancestor || path.startsWith(`${ancestor}/`);
3740
+ }
3741
+ /**
3742
+ * Rejections as `"operation <index>: <reason>"` lines, cut to the size that
3743
+ * the envelope reader accepts.
3744
+ */
3745
+ function summarizeRejections(rejections) {
3746
+ return rejections.slice(0, _copilotkit_shared.GENERATIVE_UI_MAX_SUMMARY_REJECTIONS).map(({ index, reason }) => `operation ${index}: ${reason}`.slice(0, _copilotkit_shared.GENERATIVE_UI_MAX_REJECTION_LENGTH));
3747
+ }
3748
+ /**
3749
+ * Framework-agnostic store of generated surfaces. One web_core SurfaceModel per
3750
+ * (threadId, surfaceId), shared by every mount. Applies only newly committed
3751
+ * operations, validates each before applying it, and owns app state and the
3752
+ * data model paths that the user wrote, so agent updates cannot overwrite
3753
+ * them. App state never goes into a surface's data model. Selectors read it
3754
+ * with `getState()`.
3755
+ */
3756
+ var GenerativeUISurfaceManager = class {
3757
+ constructor(ui, options = {}) {
3758
+ this.ui = ui;
3759
+ this.options = options;
3760
+ this.surfaces = /* @__PURE__ */ new Map();
3761
+ this.bookkeeping = /* @__PURE__ */ new Map();
3762
+ this.listeners = /* @__PURE__ */ new Set();
3763
+ this.targets = /* @__PURE__ */ new Map();
3764
+ this.state = {};
3765
+ this.owned = /* @__PURE__ */ new Map();
3766
+ this.deletedKeys = /* @__PURE__ */ new Set();
3767
+ this.linked = /* @__PURE__ */ new Map();
3768
+ this.version = 0;
3769
+ this.subscribe = (listener) => {
3770
+ this.listeners.add(listener);
3771
+ return () => {
3772
+ this.listeners.delete(listener);
3773
+ };
3774
+ };
3775
+ this.getVersion = () => this.version;
3776
+ this.getState = () => this.state;
3777
+ this.webCoreCatalog = new _a2ui_web_core_v0_9.Catalog(ui.id, [...ui.components.keys()].map((name) => ({
3778
+ name,
3779
+ schema: zod.z.any()
3780
+ })), []);
3781
+ }
3782
+ notify() {
3783
+ this.version++;
3784
+ for (const listener of [...this.listeners]) listener();
3785
+ }
3786
+ setActiveThread(threadId) {
3787
+ if (threadId === this.activeThreadId) return;
3788
+ this.activeThreadId = threadId;
3789
+ this.notify();
3790
+ }
3791
+ getActiveThread() {
3792
+ return this.activeThreadId;
3793
+ }
3794
+ ingest(threadId, agentId, content) {
3795
+ const key = surfaceKey(threadId, content.surfaceId);
3796
+ const operations = content.operations ?? [];
3797
+ let surface = this.surfaces.get(key);
3798
+ let book = this.bookkeeping.get(key);
3799
+ let changed = false;
3800
+ if (surface && book && !this.extendsApplied(book, operations)) {
3801
+ this.disposeSurface(key);
3802
+ surface = void 0;
3803
+ book = void 0;
3804
+ }
3805
+ if (!surface || !book) {
3806
+ surface = this.createSurface(key, threadId, agentId, content);
3807
+ this.restoreOwnedValues(surface);
3808
+ book = {
3809
+ appliedCount: 0,
3810
+ lastFingerprint: void 0
3811
+ };
3812
+ this.surfaces.set(key, surface);
3813
+ this.bookkeeping.set(key, book);
3814
+ changed = true;
3815
+ }
3816
+ const serverRejected = content.rejected ?? [];
3817
+ if (surface.clientRejected.length > 0 && (surface.status !== "streaming" && content.status === "streaming" || serverRejected.length < surface.serverRejected.length)) {
3818
+ surface.clientRejected = [];
3819
+ changed = true;
3820
+ }
3821
+ if (operations.length > 0) {
3822
+ const lastFingerprint = JSON.stringify(operations[operations.length - 1]);
3823
+ const isReplay = operations.some((op) => (0, _copilotkit_shared.getOperationKind)(op) === "deleteSurface");
3824
+ for (let index = book.appliedCount; index < operations.length; index++) {
3825
+ this.applyOperation(surface, operations[index], {
3826
+ index,
3827
+ isReplay
3828
+ });
3829
+ changed = true;
3830
+ }
3831
+ book.appliedCount = operations.length;
3832
+ surface.operations = operations;
3833
+ book.lastFingerprint = lastFingerprint;
3834
+ }
3835
+ if (surface.status !== content.status || surface.target !== content.target || surface.serverRejected.length !== serverRejected.length) {
3836
+ surface.status = content.status;
3837
+ surface.target = content.target;
3838
+ surface.serverRejected = serverRejected;
3839
+ changed = true;
3840
+ }
3841
+ if (changed) this.notify();
3842
+ }
3843
+ /** The surface of a `key` (see `surfaceKey`), unless it is deleted. */
3844
+ getSurfaceByKey(key) {
3845
+ const surface = this.surfaces.get(key);
3846
+ return surface && !surface.deleted ? surface : void 0;
3847
+ }
3848
+ getSurface(threadId, surfaceId) {
3849
+ const surface = this.surfaces.get(surfaceKey(threadId, surfaceId));
3850
+ return surface && !surface.deleted ? surface : void 0;
3851
+ }
3852
+ getSurfaceForTarget(target, threadId = this.activeThreadId) {
3853
+ if (!threadId) return void 0;
3854
+ let latest;
3855
+ for (const surface of this.surfaces.values()) {
3856
+ if (surface.threadId !== threadId || surface.target !== target || surface.deleted) continue;
3857
+ if (!latest || surface.createdAt > latest.createdAt) latest = surface;
3858
+ }
3859
+ return latest;
3860
+ }
3861
+ /**
3862
+ * A surface whose first createSurface was rejected, so the chat can show
3863
+ * the error where the surface would be. `undefined` for any other surface.
3864
+ */
3865
+ getFailedSurface(threadId, surfaceId) {
3866
+ const surface = this.surfaces.get(surfaceKey(threadId, surfaceId));
3867
+ return surface?.failed ? surface : void 0;
3868
+ }
3869
+ /**
3870
+ * The surfaces of a thread, for the model. A surface with user-owned
3871
+ * values lists them in `dataModel`, so the model can read what the user
3872
+ * entered. A surface with dropped operations lists them in `rejected`, so
3873
+ * the model can fix them on the next run. A deleted surface, or one that
3874
+ * was never created, has a `status`, so the model knows that the id is
3875
+ * not a live surface.
3876
+ */
3877
+ describeSurfaces(threadId) {
3878
+ const described = {};
3879
+ for (const surface of this.surfaces.values()) {
3880
+ if (surface.threadId !== threadId) continue;
3881
+ const owned = this.owned.get(surface.key);
3882
+ const rejections = [...surface.serverRejected, ...surface.clientRejected];
3883
+ const status = this.deletedKeys.has(surface.key) ? "deleted" : surface.failed ? "failed" : void 0;
3884
+ described[surface.surfaceId] = {
3885
+ target: surface.target,
3886
+ ...owned && owned.size > 0 ? { dataModel: Object.fromEntries(owned) } : {},
3887
+ ...rejections.length > 0 && status !== "deleted" ? { rejected: summarizeRejections(rejections) } : {},
3888
+ ...status ? { status } : {}
3889
+ };
3890
+ }
3891
+ return described;
3892
+ }
3893
+ /** Every surface that is not deleted, oldest first, for the inspector. */
3894
+ debugSurfaces() {
3895
+ return [...this.surfaces.values()].filter((surface) => !surface.deleted).sort((a, b) => a.createdAt - b.createdAt).map((surface) => ({
3896
+ surfaceId: surface.surfaceId,
3897
+ threadId: surface.threadId,
3898
+ agentId: surface.agentId,
3899
+ target: surface.target,
3900
+ status: surface.status,
3901
+ operations: surface.operations,
3902
+ dataModel: surface.model.dataModel.get("/"),
3903
+ userValues: Object.fromEntries(this.owned.get(surface.key) ?? []),
3904
+ rejected: [...surface.serverRejected.map((r) => ({
3905
+ ...r,
3906
+ source: "runtime"
3907
+ })), ...surface.clientRejected.map((r) => ({
3908
+ ...r,
3909
+ source: "browser"
3910
+ }))]
3911
+ }));
3912
+ }
3913
+ /**
3914
+ * Marks a target as mounted. Returns the function that unmounts it. Calling
3915
+ * that function more than once has no effect.
3916
+ *
3917
+ * @param id - The target id.
3918
+ * @param options - The description and the allowed components of this mount.
3919
+ */
3920
+ registerTarget(id, options = {}) {
3921
+ const registration = { ...options };
3922
+ const registrations = this.targets.get(id) ?? /* @__PURE__ */ new Set();
3923
+ registrations.add(registration);
3924
+ this.targets.set(id, registrations);
3925
+ this.notify();
3926
+ let released = false;
3927
+ return () => {
3928
+ if (released) return;
3929
+ released = true;
3930
+ registrations.delete(registration);
3931
+ if (registrations.size === 0) this.targets.delete(id);
3932
+ this.notify();
3933
+ };
3934
+ }
3935
+ /**
3936
+ * The mounted targets. Each has the description and the component list of
3937
+ * its earliest mount that has one.
3938
+ */
3939
+ getMountedTargets() {
3940
+ const mounted = [];
3941
+ for (const [id, registrations] of this.targets) {
3942
+ const description = [...registrations].find((registration) => registration.description !== void 0)?.description;
3943
+ const components = this.targetComponents(id);
3944
+ mounted.push({
3945
+ id,
3946
+ ...description === void 0 ? {} : { description },
3947
+ ...components === void 0 ? {} : { components: [...components] }
3948
+ });
3949
+ }
3950
+ return mounted;
3951
+ }
3952
+ /**
3953
+ * The component list of the earliest mount of `id` that has one.
3954
+ * `undefined` when no mount of `id` limits its components.
3955
+ */
3956
+ targetComponents(id) {
3957
+ return [...this.targets.get(id) ?? /* @__PURE__ */ new Set()].find((registration) => registration.components !== void 0)?.components;
3958
+ }
3959
+ /** The components that `validateOperation` allows on a surface. */
3960
+ allowedComponentsFor(surface) {
3961
+ const components = this.targetComponents(surface.target);
3962
+ return components === void 0 ? void 0 : {
3963
+ target: surface.target,
3964
+ names: new Set(components)
3965
+ };
3966
+ }
3967
+ /** Sets one state key. Notifies only when the value changed. */
3968
+ setState(key, value) {
3969
+ if (Object.hasOwn(this.state, key) && Object.is(this.state[key], value)) return;
3970
+ this.state = {
3971
+ ...this.state,
3972
+ [key]: value
3973
+ };
3974
+ this.notify();
3975
+ }
3976
+ /** Removes one state key. Notifies only when the key was set. */
3977
+ removeState(key) {
3978
+ if (!Object.hasOwn(this.state, key)) return;
3979
+ const { [key]: _removed, ...rest } = this.state;
3980
+ this.state = rest;
3981
+ this.notify();
3982
+ }
3983
+ /**
3984
+ * Makes the surfaces of `surfaceIds` share their data model: a user write
3985
+ * to one of them goes to all of them (see `setOwnedValue`). The markdown
3986
+ * transport links the parts of a chat surface that the prose lift split.
3987
+ * A later call for one of the surfaces replaces its group.
3988
+ *
3989
+ * @param threadId - The thread of the surfaces.
3990
+ * @param surfaceIds - The surface ids of the group. One id clears a link.
3991
+ */
3992
+ linkSurfaces(threadId, surfaceIds) {
3993
+ const keys = new Set(surfaceIds.map((id) => surfaceKey(threadId, id)));
3994
+ for (const key of keys) if (keys.size > 1) this.linked.set(key, keys);
3995
+ else this.linked.delete(key);
3996
+ }
3997
+ /**
3998
+ * Writes a user value into the data model of a surface, and marks `path`
3999
+ * as user-owned. Then agent writes to that path, or below it, are ignored.
4000
+ * An agent write above it keeps the user value. Ownership ends when the
4001
+ * surface is deleted. Does nothing for an unknown or deleted surface. The
4002
+ * surfaces linked to it (see `linkSurfaces`) get the same write.
4003
+ *
4004
+ * @param key - The `key` of the surface.
4005
+ * @param path - An absolute JSON pointer, for example "/form/email".
4006
+ * @param value - The new value. It is copied.
4007
+ * @throws Error when a path segment is "__proto__", "constructor" or
4008
+ * "prototype", or when the path does not fit the data (for example, a
4009
+ * segment above it holds a string).
4010
+ */
4011
+ setOwnedValue(key, path, value) {
4012
+ const normalized = normalizePath(path);
4013
+ const forbidden = normalized.split("/").find((segment) => FORBIDDEN_SEGMENTS.has(segment));
4014
+ if (forbidden !== void 0) throw new Error(`[generativeUI] path segment "${forbidden}" is not allowed in "${path}".`);
4015
+ for (const target of this.linked.get(key) ?? [key]) this.writeOwnedValue(target, normalized, value);
4016
+ }
4017
+ writeOwnedValue(key, path, value) {
4018
+ const surface = this.surfaces.get(key);
4019
+ if (!surface || surface.deleted) return;
4020
+ surface.model.dataModel.set(path, structuredClone(value));
4021
+ const owned = this.owned.get(key) ?? /* @__PURE__ */ new Map();
4022
+ owned.set(path, structuredClone(value));
4023
+ this.owned.set(key, owned);
4024
+ }
4025
+ /**
4026
+ * Writes the user-owned values into the new, empty data model of a rebuilt
4027
+ * surface. The agent operations are applied after it.
4028
+ */
4029
+ restoreOwnedValues(surface) {
4030
+ const owned = this.owned.get(surface.key) ?? /* @__PURE__ */ new Map();
4031
+ for (const [path, value] of owned) surface.model.dataModel.set(path, structuredClone(value));
4032
+ }
4033
+ /**
4034
+ * The value that an agent write puts at `path`, with the user-owned values
4035
+ * below `path` written back into it. `undefined` when `path` is user-owned
4036
+ * or below a user-owned path, so the agent cannot write it. Throws when a
4037
+ * user value does not fit the new value.
4038
+ */
4039
+ mergeOwnedValues(key, path, value) {
4040
+ const merged = { value: structuredClone(value) };
4041
+ const owned = this.owned.get(key);
4042
+ if (!owned) return merged;
4043
+ const ownedPaths = [...owned.keys()];
4044
+ if (ownedPaths.some((ownedPath) => isAtOrBelow(path, ownedPath))) return void 0;
4045
+ const below = ownedPaths.filter((ownedPath) => isAtOrBelow(ownedPath, path));
4046
+ if (below.length === 0) return merged;
4047
+ const scratch = new _a2ui_web_core_v0_9.DataModel({ value: merged.value });
4048
+ const prefix = path === "/" ? "" : path;
4049
+ for (const ownedPath of below) {
4050
+ const relative = ownedPath.slice(prefix.length);
4051
+ scratch.set(`/value${relative}`, structuredClone(owned.get(ownedPath)));
4052
+ }
4053
+ return { value: scratch.get("/value") };
4054
+ }
4055
+ extendsApplied(book, operations) {
4056
+ if (operations.length < book.appliedCount) return false;
4057
+ if (book.appliedCount === 0) return true;
4058
+ return JSON.stringify(operations[book.appliedCount - 1]) === book.lastFingerprint;
4059
+ }
4060
+ createSurface(key, threadId, agentId, content) {
4061
+ return {
4062
+ key,
4063
+ threadId,
4064
+ surfaceId: content.surfaceId,
4065
+ agentId,
4066
+ model: new _a2ui_web_core_v0_9.SurfaceModel(content.surfaceId, this.webCoreCatalog),
4067
+ createdAt: ++creationCounter,
4068
+ target: content.target,
4069
+ status: content.status,
4070
+ deleted: false,
4071
+ failed: false,
4072
+ serverRejected: content.rejected ?? [],
4073
+ clientRejected: [],
4074
+ operations: []
4075
+ };
4076
+ }
4077
+ disposeSurface(key) {
4078
+ this.surfaces.get(key)?.model.dispose();
4079
+ this.surfaces.delete(key);
4080
+ this.bookkeeping.delete(key);
4081
+ }
4082
+ /**
4083
+ * Marks a surface deleted and frees its components and data. The record
4084
+ * stays, so the model is still told about the id and the bookkeeping does
4085
+ * not rebuild the surface for content that was already applied.
4086
+ */
4087
+ closeSurface(surface) {
4088
+ surface.deleted = true;
4089
+ surface.model.dispose();
4090
+ surface.model = new _a2ui_web_core_v0_9.SurfaceModel(surface.surfaceId, this.webCoreCatalog);
4091
+ this.owned.delete(surface.key);
4092
+ this.linked.delete(surface.key);
4093
+ }
4094
+ /** The surfaces of a thread that a part of `surfaceId` reads, for tests. */
4095
+ getLinkedSurfaceIds(threadId, surfaceId) {
4096
+ const keys = this.linked.get(surfaceKey(threadId, surfaceId));
4097
+ if (!keys) return [surfaceId];
4098
+ const prefix = `${threadId}::`;
4099
+ return [...keys].map((key) => key.slice(prefix.length));
4100
+ }
4101
+ /**
4102
+ * Drops the node keys that the app sets: bound props and matched events.
4103
+ * The model does not see them, so a model value for one is ignored, not
4104
+ * rejected. This runs before validation, because validation rejects keys
4105
+ * that are not in the manifest. It never changes the given operation.
4106
+ */
4107
+ dropAppSetKeys(op) {
4108
+ const kind = (0, _copilotkit_shared.getOperationKind)(op);
4109
+ if (kind !== "updateComponents" && kind !== "createSurface") return op;
4110
+ const record = op;
4111
+ const payload = record[kind];
4112
+ const nodes = payload?.components;
4113
+ if (!Array.isArray(nodes)) return op;
4114
+ return {
4115
+ ...record,
4116
+ [kind]: {
4117
+ ...payload,
4118
+ components: nodes.map((node) => this.dropAppSetNodeKeys(node))
4119
+ }
4120
+ };
4121
+ }
4122
+ dropAppSetNodeKeys(node) {
4123
+ if (typeof node !== "object" || node === null || !("component" in node)) return node;
4124
+ const { component } = node;
4125
+ if (typeof component !== "string") return node;
4126
+ const definition = this.ui.components.get(component);
4127
+ if (!definition) return node;
4128
+ return Object.fromEntries(Object.entries(node).filter(([key]) => !Object.hasOwn(definition.selectors, key) && !Object.hasOwn(definition.eventFunctions, key)));
4129
+ }
4130
+ /**
4131
+ * The surfaces that `validateOperation` gets for one operation of the
4132
+ * content of `surface`.
4133
+ *
4134
+ * - `knownSurfaces`: the surface, when it exists before the operation. It
4135
+ * does not exist before its first createSurface, or after a delete.
4136
+ * - `createdSurfaces`: the surface, when a createSurface at this position
4137
+ * uses its id again. That is the case after the first operation, and for
4138
+ * a surface that was deleted before, unless the content replays that
4139
+ * delete.
4140
+ */
4141
+ surfacesFor(surface, kind, position) {
4142
+ const isFirstCreate = kind === "createSurface" && position.index === 0;
4143
+ const exists = !surface.deleted && !isFirstCreate;
4144
+ const isRecreate = this.deletedKeys.has(surface.key) && !position.isReplay;
4145
+ const isUsedAgain = position.index > 0 || isRecreate;
4146
+ return {
4147
+ knownSurfaces: new Set(exists ? [surface.surfaceId] : []),
4148
+ createdSurfaces: new Set(isUsedAgain ? [surface.surfaceId] : [])
4149
+ };
4150
+ }
4151
+ applyOperation(surface, received, position) {
4152
+ const { index } = position;
4153
+ const kind = (0, _copilotkit_shared.getOperationKind)(received);
4154
+ if (kind === "callRendererFunction") return;
4155
+ const reject = (reason) => {
4156
+ if (kind === "createSurface" && index === 0) {
4157
+ this.closeSurface(surface);
4158
+ surface.failed = true;
4159
+ }
4160
+ surface.clientRejected.push({
4161
+ index,
4162
+ reason
4163
+ });
4164
+ this.options.onOperationRejected?.({
4165
+ surfaceId: surface.surfaceId,
4166
+ index,
4167
+ reason
4168
+ });
4169
+ };
4170
+ const targetId = (0, _copilotkit_shared.getOperationSurfaceId)(received);
4171
+ if (targetId !== void 0 && targetId !== surface.surfaceId) return reject(`operation is for surface "${targetId}", not "${surface.surfaceId}"`);
4172
+ const op = this.dropAppSetKeys(received);
4173
+ const validation = (0, _copilotkit_shared.validateOperation)(op, {
4174
+ manifest: {
4175
+ catalogId: this.ui.id,
4176
+ catalogIds: require_MarkdownSurfaces.catalogIdsOf(this.ui),
4177
+ components: this.ui.manifestComponents
4178
+ },
4179
+ ...this.surfacesFor(surface, kind, position),
4180
+ allowedComponents: this.allowedComponentsFor(surface)
4181
+ });
4182
+ if (!validation.ok) return reject(validation.reason);
4183
+ const typed = op;
4184
+ if ("createSurface" in typed) {
4185
+ const { dataModel, components = [] } = typed.createSurface;
4186
+ const problem = this.nodesProblem(components);
4187
+ if (problem) return reject(problem);
4188
+ if (dataModel) {
4189
+ const failure = this.writeAgentData(surface, "/", dataModel);
4190
+ if (failure) return reject(failure);
4191
+ }
4192
+ for (const node of components) this.upsertNode(surface.model, node);
4193
+ return;
4194
+ }
4195
+ if ("updateComponents" in typed) {
4196
+ const nodes = typed.updateComponents.components;
4197
+ const problem = this.nodesProblem(nodes);
4198
+ if (problem) return reject(problem);
4199
+ for (const node of nodes) this.upsertNode(surface.model, node);
4200
+ return;
4201
+ }
4202
+ if ("updateDataModel" in typed) {
4203
+ const { path = "/", value } = typed.updateDataModel;
4204
+ const written = value === null ? void 0 : value;
4205
+ const failure = this.writeAgentData(surface, normalizePath(path), written);
4206
+ if (failure) return reject(failure);
4207
+ return;
4208
+ }
4209
+ if ("deleteSurface" in typed) {
4210
+ this.closeSurface(surface);
4211
+ this.deletedKeys.add(surface.key);
4212
+ }
4213
+ }
4214
+ /** The first node with props of the wrong type, as a reason. */
4215
+ nodesProblem(nodes) {
4216
+ for (const node of nodes) {
4217
+ const problem = this.checkNodeProps(node);
4218
+ if (problem) return `component "${node.id}": ${problem}`;
4219
+ }
4220
+ }
4221
+ /**
4222
+ * Writes an agent value at `path` and keeps the user-owned values. A write
4223
+ * to a user-owned path is ignored, not rejected. Gives the reason when the
4224
+ * value does not fit the data, else `undefined`.
4225
+ */
4226
+ writeAgentData(surface, path, value) {
4227
+ try {
4228
+ const merged = this.mergeOwnedValues(surface.key, path, value);
4229
+ if (merged) surface.model.dataModel.set(path, merged.value);
4230
+ return;
4231
+ } catch (error) {
4232
+ return error instanceof Error ? error.message : String(error);
4233
+ }
4234
+ }
4235
+ checkNodeProps(node) {
4236
+ const definition = this.ui.components.get(node.component);
4237
+ if (!definition) return `unknown component "${node.component}"`;
4238
+ const { id: _id, component: _component, ...rest } = node;
4239
+ const dataProps = Object.fromEntries(Object.entries(rest).filter(([key]) => !definition.events?.[key] && !definition.slots?.[key] && !_copilotkit_shared.A2UI_COMPONENT_ENVELOPE_KEYS.has(key)));
4240
+ if (!definition.props) return void 0;
4241
+ const unknownNow = new Set(Object.keys(definition.selectors));
4242
+ const literals = {};
4243
+ for (const [key, value] of Object.entries(dataProps)) if (require_MarkdownSurfaces.containsDynamicValue(value)) unknownNow.add(key);
4244
+ else literals[key] = value;
4245
+ let result = require_MarkdownSurfaces.validateSchemaSync(definition.props, literals);
4246
+ if (!result.success) {
4247
+ const unset = require_MarkdownSurfaces.withoutRejectedNulls(literals, result.issues);
4248
+ if (unset) result = require_MarkdownSurfaces.validateSchemaSync(definition.props, unset);
4249
+ }
4250
+ if (result.success) return void 0;
4251
+ const issues = result.issues.filter((issue) => {
4252
+ const key = require_MarkdownSurfaces.issueKey(issue);
4253
+ return key === void 0 ? require_MarkdownSurfaces.isAsyncIssue(issue) : !unknownNow.has(key);
4254
+ });
4255
+ return issues.length > 0 ? require_MarkdownSurfaces.formatIssues(issues) : void 0;
4256
+ }
4257
+ upsertNode(model, node) {
4258
+ const { id, component, ...rest } = node;
4259
+ const properties = structuredClone(rest);
4260
+ const existing = model.componentsModel.get(id);
4261
+ if (existing && existing.type === component) {
4262
+ existing.properties = properties;
4263
+ return;
4264
+ }
4265
+ if (existing) model.componentsModel.removeComponent(id);
4266
+ model.componentsModel.addComponent(new _a2ui_web_core_v0_9.ComponentModel(id, component, properties));
4267
+ }
4268
+ };
4269
+
4270
+ //#endregion
4271
+ //#region src/v2/generative-ui/use-generative-ui-root.ts
4272
+ const isDevelopment = () => process.env.NODE_ENV !== "production";
4273
+ /** At most this many function follow-up runs for each user turn. */
4274
+ const MAX_FUNCTION_FOLLOW_UPS = 5;
4275
+ function ingestMessages(manager, agent, messages) {
4276
+ if (!agent.threadId) return;
4277
+ for (const message of messages) if (message.role === "activity" && message.activityType === _copilotkit_shared.GENERATIVE_UI_ACTIVITY_TYPE) manager.ingest(agent.threadId, agent.agentId, message.content);
4278
+ }
4279
+ /** What the envelope of a run says, from the provider config. */
4280
+ function envelopeOptionsFor(config) {
4281
+ if (config.transport === "markdown") return {
4282
+ transport: "markdown",
4283
+ includeCatalog: config.includeCatalog !== false,
4284
+ contextSent: config.sendContext !== false
4285
+ };
4286
+ return {
4287
+ transport: "tool",
4288
+ includeCatalog: true,
4289
+ contextSent: false
4290
+ };
4291
+ }
4292
+ /**
4293
+ * The components of a surface as one `updateComponents` operation, so that
4294
+ * the label of the component that sent an event can be found.
4295
+ */
4296
+ function surfaceComponents(surface) {
4297
+ const components = [...surface.model.componentsModel.entries].map(([id, model]) => ({
4298
+ ...model.properties,
4299
+ id,
4300
+ component: model.type
4301
+ }));
4302
+ return [{
4303
+ version: _copilotkit_shared.A2UI_VERSION,
4304
+ updateComponents: {
4305
+ surfaceId: surface.surfaceId,
4306
+ components
4307
+ }
4308
+ }];
4309
+ }
4310
+ /** True when `value` names a `functionCallId`. */
4311
+ function hasFunctionCallId(value) {
4312
+ return typeof value === "object" && value !== null && "functionCallId" in value && typeof value.functionCallId === "string" && value.functionCallId !== "";
4313
+ }
4314
+ /** The `functionCallId` that a developer message answers, if any. */
4315
+ function answeredCallId(content) {
4316
+ if (!content.includes("rendererFunctionResponse")) return void 0;
4317
+ try {
4318
+ const parsed = JSON.parse(content);
4319
+ const response = typeof parsed === "object" && parsed !== null && "rendererFunctionResponse" in parsed ? parsed.rendererFunctionResponse : void 0;
4320
+ return hasFunctionCallId(response) ? response.functionCallId : void 0;
4321
+ } catch {
4322
+ return;
4323
+ }
4324
+ }
4325
+ /** The function calls that a developer message in `messages` answers. */
4326
+ function answeredCallIds(messages) {
4327
+ const ids = /* @__PURE__ */ new Set();
4328
+ for (const message of messages) {
4329
+ if (message.role !== "developer") continue;
4330
+ const id = answeredCallId(message.content);
4331
+ if (id !== void 0) ids.add(id);
4332
+ }
4333
+ return ids;
4334
+ }
4335
+ /** The id of the last user message. A user turn starts with it. */
4336
+ function lastUserMessageId(messages) {
4337
+ for (let index = messages.length - 1; index >= 0; index--) {
4338
+ const message = messages[index];
4339
+ if (message?.role === "user") return message.id;
4340
+ }
4341
+ }
4342
+ /** The function calls of the tool transport: its function-call activities. */
4343
+ function activityFunctionCalls(messages) {
4344
+ const requests = [];
4345
+ for (const message of messages) {
4346
+ if (!(message.role === "activity" && message.activityType === _copilotkit_shared.GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE) || !hasFunctionCallId(message.content)) continue;
4347
+ requests.push({
4348
+ functionCallId: message.content.functionCallId,
4349
+ operation: {
4350
+ version: _copilotkit_shared.A2UI_VERSION,
4351
+ callRendererFunction: message.content
4352
+ }
4353
+ });
4354
+ }
4355
+ return requests;
4356
+ }
4357
+ /** The function calls of the markdown transport: its fence lines. */
4358
+ function markdownFunctionCalls(calls) {
4359
+ const requests = [];
4360
+ for (const { operation } of calls) {
4361
+ const payload = operation.callRendererFunction;
4362
+ if (!hasFunctionCallId(payload)) continue;
4363
+ requests.push({
4364
+ functionCallId: payload.functionCallId,
4365
+ operation
4366
+ });
4367
+ }
4368
+ return requests;
3284
4369
  }
3285
-
3286
- //#endregion
3287
- //#region src/v2/a2ui/A2UICatalogContext.tsx
4370
+ /** The text of a `rendererFunctionResponse` developer message. */
4371
+ function responseContent(response) {
4372
+ return JSON.stringify({
4373
+ version: _copilotkit_shared.A2UI_VERSION,
4374
+ rendererFunctionResponse: response
4375
+ });
4376
+ }
4377
+ function errorAnswer(functionCallId, code, message) {
4378
+ return {
4379
+ content: responseContent({
4380
+ functionCallId,
4381
+ error: {
4382
+ code,
4383
+ message
4384
+ }
4385
+ }),
4386
+ followUp: true
4387
+ };
4388
+ }
4389
+ const overCapAnswer = (functionCallId) => ({
4390
+ content: responseContent({
4391
+ functionCallId,
4392
+ error: {
4393
+ code: "follow_up_limit",
4394
+ message: `The function did not run. A user turn can have at most ${MAX_FUNCTION_FOLLOW_UPS} function follow-up runs. Wait for the next user message.`
4395
+ }
4396
+ }),
4397
+ followUp: false
4398
+ });
3288
4399
  /**
3289
- * Renders agent context describing the available A2UI catalog and custom components.
3290
- * Only mount this component when A2UI is enabled.
3291
- *
3292
- * The entries are scoped to the agents the runtime applies A2UI to
3293
- * (`copilotkit.a2uiAgents`, #5369), so agents outside that list don't receive
3294
- * the catalog/schema/guidelines payload on their runs.
4400
+ * Runs the functions that the agent calls with `callRendererFunction`, for
4401
+ * both transports, and answers each call.
3295
4402
  *
3296
- * When `includeSchema` is true, the full component schemas (JSON Schema) are also
3297
- * sent as context using the same description key as the A2UI middleware, so the
3298
- * middleware can optionally overwrite it with a server-side schema.
4403
+ * - Each `functionCallId` runs once for each thread. A replay, a sync of
4404
+ * the same messages again, or a call that already has an answer message
4405
+ * does not run it again.
4406
+ * - The answer is a hidden developer message with a `rendererFunctionResponse`.
4407
+ * The answers go to the agent only when it is not running. Then one
4408
+ * follow-up run starts for all of them.
4409
+ * - A user turn has at most {@link MAX_FUNCTION_FOLLOW_UPS} follow-up runs.
4410
+ * A call after that does not run. It gets a `follow_up_limit` error and
4411
+ * starts no follow-up run.
3299
4412
  */
3300
- function A2UICatalogContext({ catalog, includeSchema }) {
3301
- const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
3302
- const capabilitiesValue = (0, react.useMemo)(() => (0, _copilotkit_a2ui_renderer.buildCatalogContextValue)(catalog), [catalog]);
3303
- const schemaValue = (0, react.useMemo)(() => includeSchema !== false ? JSON.stringify((0, _copilotkit_a2ui_renderer.extractCatalogComponentSchemas)(catalog)) : null, [catalog, includeSchema]);
3304
- const a2uiAgentsKey = copilotkit?.a2uiAgents?.join(",");
3305
- (0, react.useLayoutEffect)(() => {
3306
- if (!copilotkit) return;
3307
- const agentIds = copilotkit.a2uiAgents;
3308
- const scope = agentIds ? { agentIds } : {};
3309
- const ids = [];
3310
- ids.push(copilotkit.addContext({
3311
- description: "A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.",
3312
- value: capabilitiesValue,
3313
- ...scope
3314
- }));
3315
- if (schemaValue) {
3316
- ids.push(copilotkit.addContext({
3317
- description: _copilotkit_a2ui_renderer.A2UI_SCHEMA_CONTEXT_DESCRIPTION,
3318
- value: schemaValue,
3319
- ...scope
3320
- }));
3321
- ids.push(copilotkit.addContext({
3322
- description: "A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.",
3323
- value: _copilotkit_shared.A2UI_DEFAULT_GENERATION_GUIDELINES,
3324
- ...scope
3325
- }));
3326
- ids.push(copilotkit.addContext({
3327
- description: "A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.",
3328
- value: _copilotkit_shared.A2UI_DEFAULT_DESIGN_GUIDELINES,
3329
- ...scope
3330
- }));
4413
+ function createFunctionCallRunner(options) {
4414
+ const { copilotkit, dispatcher, manifest } = options;
4415
+ const threads = /* @__PURE__ */ new Map();
4416
+ const threadState = (threadId) => {
4417
+ let state = threads.get(threadId);
4418
+ if (!state) {
4419
+ state = {
4420
+ done: /* @__PURE__ */ new Set(),
4421
+ pending: [],
4422
+ turn: void 0,
4423
+ followUps: 0,
4424
+ flushing: false
4425
+ };
4426
+ threads.set(threadId, state);
3331
4427
  }
3332
- return () => {
3333
- for (const id of ids) copilotkit.removeContext(id);
4428
+ return state;
4429
+ };
4430
+ const answer = async (request) => {
4431
+ const { functionCallId } = request;
4432
+ const validation = (0, _copilotkit_shared.validateOperation)(request.operation, {
4433
+ manifest,
4434
+ knownSurfaces: /* @__PURE__ */ new Set()
4435
+ });
4436
+ if (!validation.ok) return errorAnswer(functionCallId, "invalid_arguments", validation.reason);
4437
+ const operation = request.operation;
4438
+ if (!("callRendererFunction" in operation)) return errorAnswer(functionCallId, "invalid_arguments", "the operation is not a callRendererFunction");
4439
+ const { callFunction } = operation.callRendererFunction;
4440
+ const name = callFunction["@call"];
4441
+ const result = await dispatcher.invoke(name, callFunction.args ?? {}, { functionCallId });
4442
+ if (!result.ok) return errorAnswer(functionCallId, result.error.code, result.error.message);
4443
+ try {
4444
+ return {
4445
+ content: responseContent({
4446
+ functionCallId,
4447
+ value: result.result ?? null
4448
+ }),
4449
+ followUp: true
4450
+ };
4451
+ } catch (cause) {
4452
+ return errorAnswer(functionCallId, "handler_failed", `The result of "${name}" is not JSON: ${cause instanceof Error ? cause.message : String(cause)}`);
4453
+ }
4454
+ };
4455
+ /**
4456
+ * Adds the pending answers of a thread to the agent, then starts one
4457
+ * follow-up run. It waits while the agent runs: the next read of the
4458
+ * thread, at the end of the run, flushes again.
4459
+ */
4460
+ const flush = async (agent, threadId, state) => {
4461
+ if (state.flushing) return;
4462
+ state.flushing = true;
4463
+ try {
4464
+ while (state.pending.length > 0) {
4465
+ const batch = [...state.pending];
4466
+ const answers = await Promise.all(batch);
4467
+ await copilotkit.waitForPendingFrameworkUpdates();
4468
+ if (agent.isRunning || agent.threadId !== threadId) return;
4469
+ if (state.pending.length > batch.length) continue;
4470
+ state.pending = [];
4471
+ for (const { content } of answers) agent.addMessage({
4472
+ id: (0, _copilotkit_shared.randomUUID)(),
4473
+ role: "developer",
4474
+ content
4475
+ });
4476
+ if (!answers.some((item) => item.followUp)) continue;
4477
+ state.followUps++;
4478
+ await copilotkit.runAgent({ agent });
4479
+ }
4480
+ } catch (error) {
4481
+ if (isDevelopment()) console.warn("[generativeUI] function follow-up run failed:", error);
4482
+ } finally {
4483
+ state.flushing = false;
4484
+ }
4485
+ };
4486
+ return { run(agent, requests, messages, running) {
4487
+ const { threadId } = agent;
4488
+ if (!threadId) return;
4489
+ const state = threadState(threadId);
4490
+ const turn = lastUserMessageId(messages);
4491
+ if (turn !== state.turn) {
4492
+ state.turn = turn;
4493
+ state.followUps = 0;
4494
+ }
4495
+ const isNew = (request) => !state.done.has(request.functionCallId);
4496
+ const fresh = requests.filter(isNew);
4497
+ const answered = fresh.length > 0 ? answeredCallIds(messages) : /* @__PURE__ */ new Set();
4498
+ for (const request of fresh) {
4499
+ const { functionCallId } = request;
4500
+ if (state.done.has(functionCallId)) continue;
4501
+ state.done.add(functionCallId);
4502
+ if (answered.has(functionCallId)) continue;
4503
+ const isOverCap = state.followUps >= MAX_FUNCTION_FOLLOW_UPS;
4504
+ state.pending.push(isOverCap ? Promise.resolve(overCapAnswer(functionCallId)) : answer(request));
4505
+ }
4506
+ if (!running) flush(agent, threadId, state);
4507
+ } };
4508
+ }
4509
+ /** Provider-side wiring: manager, dispatcher, agent subscriptions, envelope. */
4510
+ function useGenerativeUIRoot(copilotkit, config) {
4511
+ const configRef = (0, react.useRef)(config);
4512
+ configRef.current = config;
4513
+ const ui = config?.ui;
4514
+ const transport = config?.transport ?? "tool";
4515
+ const theme = require_MarkdownSurfaces.useShallowStableRef(config?.theme);
4516
+ const core = (0, react.useMemo)(() => {
4517
+ if (!ui) return null;
4518
+ const reportError = (info) => {
4519
+ try {
4520
+ configRef.current?.errorBoundary?.onError?.(info);
4521
+ } catch (hostError) {
4522
+ if (isDevelopment()) console.error("[generativeUI] errorBoundary.onError threw:", hostError);
4523
+ }
4524
+ if (isDevelopment()) console.warn(`[generativeUI] ${info.kind} error in ${info.surfaceId}${info.componentId ? `/${info.componentId}` : ""}: ${info.error?.message}`);
4525
+ };
4526
+ const manager = new GenerativeUISurfaceManager(ui, { onOperationRejected: ({ surfaceId, index, reason }) => reportError({
4527
+ kind: "operation",
4528
+ surfaceId,
4529
+ error: /* @__PURE__ */ new Error(`operation ${index} rejected: ${reason}`)
4530
+ }) });
4531
+ const dispatcher = createGenerativeUIDispatcher({
4532
+ getDeclared: () => ui.functions,
4533
+ onError: ({ name, origin, error }) => {
4534
+ if ("functionCallId" in origin) {
4535
+ if (isDevelopment()) console.warn(`[generativeUI] function call ${origin.functionCallId} to "${name}" failed: ${error.message}`);
4536
+ return;
4537
+ }
4538
+ reportError({
4539
+ kind: "function",
4540
+ ...origin,
4541
+ error
4542
+ });
4543
+ }
4544
+ });
4545
+ const functionCalls = createFunctionCallRunner({
4546
+ copilotkit,
4547
+ dispatcher,
4548
+ manifest: {
4549
+ catalogId: ui.id,
4550
+ catalogIds: require_MarkdownSurfaces.catalogIdsOf(ui),
4551
+ components: ui.manifestComponents
4552
+ }
4553
+ });
4554
+ const forwardingAgents = /* @__PURE__ */ new Set();
4555
+ /**
4556
+ * The action of a user event, as an envelope entry scoped to the agent
4557
+ * the user acted on, for the run that the event starts: the structured
4558
+ * form of the user message. It is set before the run starts and dropped
4559
+ * when the run is over, so a suggestion request or a follow-up run
4560
+ * (both read the properties with no run start) does not carry the same
4561
+ * action again, and another agent never gets a click meant for this one.
4562
+ * The entry comes after the shared envelope, so it wins for its agent;
4563
+ * `refreshActions` keeps it last when the shared envelope is set again.
4564
+ */
4565
+ const actions = /* @__PURE__ */ new Map();
4566
+ const dropAction = (agent) => {
4567
+ const entry = actions.get(agent);
4568
+ if (!entry) return;
4569
+ entry.subscription.unsubscribe();
4570
+ copilotkit.removeScopedProperties(entry.id);
4571
+ actions.delete(agent);
4572
+ };
4573
+ const setAction = (agent, action) => {
4574
+ const previous = actions.get(agent);
4575
+ previous?.subscription.unsubscribe();
4576
+ if (previous) copilotkit.removeScopedProperties(previous.id);
4577
+ actions.delete(agent);
4578
+ const latest = configRef.current;
4579
+ if (!latest) return;
4580
+ const envelope = buildGenerativeUIEnvelope({
4581
+ ui,
4582
+ manager,
4583
+ dispatcher
4584
+ }, agent.threadId, {
4585
+ ...envelopeOptionsFor(latest),
4586
+ action
4587
+ });
4588
+ const id = copilotkit.addScopedProperties({
4589
+ properties: { [_copilotkit_shared.COPILOTKIT_FORWARDED_PROPS_KEY]: { ui: envelope } },
4590
+ agentIds: agent.agentId === void 0 ? latest.agentIds : [agent.agentId]
4591
+ });
4592
+ const subscription = agent.subscribe({
4593
+ onRunFinalized: () => dropAction(agent),
4594
+ onRunFailed: () => dropAction(agent)
4595
+ });
4596
+ actions.set(agent, {
4597
+ id,
4598
+ action,
4599
+ subscription
4600
+ });
4601
+ };
4602
+ const refreshActions = () => {
4603
+ for (const [agent, { action }] of [...actions]) setAction(agent, action);
4604
+ };
4605
+ const dropAllActions = () => {
4606
+ for (const agent of [...actions.keys()]) dropAction(agent);
4607
+ };
4608
+ const forwardEvent = async (event, agentId) => {
4609
+ const fail = (message) => {
4610
+ const error = new require_MarkdownSurfaces.GenerativeUIError("event_forward_failed", message);
4611
+ reportError({
4612
+ kind: "event",
4613
+ surfaceId: event.surfaceId,
4614
+ componentId: event.componentId,
4615
+ error
4616
+ });
4617
+ return {
4618
+ ok: false,
4619
+ error
4620
+ };
4621
+ };
4622
+ const agent = copilotkit.getAgent(agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID);
4623
+ if (!agent) return fail(`No agent "${agentId}" to receive "${event.name}"`);
4624
+ if (agent.isRunning || forwardingAgents.has(agent)) return {
4625
+ ok: false,
4626
+ error: new require_MarkdownSurfaces.GenerativeUIError("agent_busy", `"${event.name}" was not sent: the agent is running`)
4627
+ };
4628
+ forwardingAgents.add(agent);
4629
+ try {
4630
+ const surface = agent.threadId ? manager.getSurface(agent.threadId, event.surfaceId) : void 0;
4631
+ const resolveLabel = surface ? createComponentLabelResolver(surfaceComponents(surface)) : void 0;
4632
+ agent.addMessage({
4633
+ id: (0, _copilotkit_shared.randomUUID)(),
4634
+ role: "user",
4635
+ content: buildActionMessageText(event, resolveLabel)
4636
+ });
4637
+ setAction(agent, (0, _copilotkit_shared.toA2UIActionMessage)(event));
4638
+ await copilotkit.runAgent({ agent });
4639
+ return {
4640
+ ok: true,
4641
+ result: void 0
4642
+ };
4643
+ } catch (cause) {
4644
+ return fail(`Forwarding "${event.name}" failed: ${cause instanceof Error ? cause.message : String(cause)}`);
4645
+ } finally {
4646
+ forwardingAgents.delete(agent);
4647
+ dropAction(agent);
4648
+ }
4649
+ };
4650
+ return {
4651
+ manager,
4652
+ dispatcher,
4653
+ ui,
4654
+ forwardEvent,
4655
+ reportError,
4656
+ functionCalls,
4657
+ refreshActions,
4658
+ dropAllActions
4659
+ };
4660
+ }, [ui, copilotkit]);
4661
+ const runtime = (0, react.useMemo)(() => {
4662
+ if (!core) return null;
4663
+ const { manager, dispatcher, forwardEvent, reportError } = core;
4664
+ return {
4665
+ manager,
4666
+ dispatcher,
4667
+ ui: core.ui,
4668
+ forwardEvent,
4669
+ reportError,
4670
+ transport,
4671
+ theme,
4672
+ get config() {
4673
+ return configRef.current ?? { ui: core.ui };
4674
+ },
4675
+ get errorFallback() {
4676
+ return configRef.current?.errorBoundary?.fallback;
4677
+ }
3334
4678
  };
3335
4679
  }, [
3336
- copilotkit,
3337
- capabilitiesValue,
3338
- schemaValue,
3339
- a2uiAgentsKey
4680
+ core,
4681
+ transport,
4682
+ theme
3340
4683
  ]);
3341
- return null;
4684
+ (0, react.useEffect)(() => {
4685
+ if (!core) return;
4686
+ const watched = /* @__PURE__ */ new WeakSet();
4687
+ const agentSubscriptions = [];
4688
+ let envelopeId;
4689
+ const debug = createGenerativeUIDebugSource(core, () => {
4690
+ const latest = configRef.current ?? { ui: core.ui };
4691
+ return {
4692
+ options: envelopeOptionsFor(latest),
4693
+ agentIds: latest.agentIds
4694
+ };
4695
+ });
4696
+ copilotkit.ɵsetGenerativeUIDebugSource(debug.source);
4697
+ const removeEnvelope = () => {
4698
+ if (envelopeId === void 0) return;
4699
+ copilotkit.removeScopedProperties(envelopeId);
4700
+ envelopeId = void 0;
4701
+ };
4702
+ /**
4703
+ * Sets the shared envelope of the run. The action entries of the agents
4704
+ * with a user event under way (see `forwardEvent`) are set again after
4705
+ * it, so they stay the last entries and win for their agents.
4706
+ */
4707
+ const setEnvelope = (agent, latest) => {
4708
+ removeEnvelope();
4709
+ const run = describeGenerativeUIRun(core, agent.threadId, envelopeOptionsFor(latest));
4710
+ envelopeId = copilotkit.addScopedProperties({
4711
+ properties: { [_copilotkit_shared.COPILOTKIT_FORWARDED_PROPS_KEY]: { ui: run.envelope } },
4712
+ agentIds: latest.agentIds
4713
+ });
4714
+ core.refreshActions();
4715
+ if (!latest.agentIds || latest.agentIds.includes(agent.agentId ?? "")) debug.recordRun({
4716
+ ...run,
4717
+ agentId: agent.agentId,
4718
+ threadId: agent.threadId,
4719
+ startedAt: Date.now()
4720
+ });
4721
+ };
4722
+ /**
4723
+ * The tool transport reads the surface activity messages. The markdown
4724
+ * transport reads the ```a2ui fences of the assistant messages, and
4725
+ * builds the surfaces of the thread from them again on each change.
4726
+ * Both give their function calls to the one runner.
4727
+ */
4728
+ const readMessages = (agent, messages, running) => {
4729
+ const requests = activityFunctionCalls(messages);
4730
+ const { threadId } = agent;
4731
+ if (configRef.current?.transport !== "markdown") ingestMessages(core.manager, agent, messages);
4732
+ else if (threadId) {
4733
+ core.manager.setActiveThread(threadId);
4734
+ const calls = require_MarkdownSurfaces.getMarkdownSurfaceSource(core).sync(threadId, agent.agentId, messages, { running });
4735
+ requests.push(...markdownFunctionCalls(calls));
4736
+ }
4737
+ core.functionCalls.run(agent, requests, messages, running);
4738
+ };
4739
+ const subscription = copilotkit.subscribe({ onAgentRunStarted: ({ agent }) => {
4740
+ core.manager.setActiveThread(agent.threadId);
4741
+ const latest = configRef.current;
4742
+ if (latest) setEnvelope(agent, latest);
4743
+ if (!watched.has(agent)) {
4744
+ watched.add(agent);
4745
+ agentSubscriptions.push(agent.subscribe({
4746
+ onMessagesChanged: ({ messages }) => readMessages(agent, messages, agent.isRunning),
4747
+ onRunFinalized: () => readMessages(agent, agent.messages, false),
4748
+ onRunFailed: () => readMessages(agent, agent.messages, false)
4749
+ }));
4750
+ }
4751
+ readMessages(agent, agent.messages, true);
4752
+ } });
4753
+ return () => {
4754
+ subscription.unsubscribe();
4755
+ for (const s of agentSubscriptions) s.unsubscribe();
4756
+ core.dropAllActions();
4757
+ removeEnvelope();
4758
+ if (copilotkit.ɵgenerativeUIDebugSource === debug.source) copilotkit.ɵsetGenerativeUIDebugSource(void 0);
4759
+ };
4760
+ }, [core, copilotkit]);
4761
+ useGenerativeUIMarkdownContext(copilotkit, core, {
4762
+ enabled: config?.transport === "markdown" && config.sendContext !== false,
4763
+ agentIds: config?.agentIds
4764
+ });
4765
+ return runtime;
3342
4766
  }
3343
4767
 
3344
4768
  //#endregion
@@ -3483,7 +4907,7 @@ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
3483
4907
  return value;
3484
4908
  }
3485
4909
  /** Provide a shared core instance and synchronize runtime, tool, and UI configuration. */
3486
- const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, mcpApps, defaultThrottleMs, debug, learning }) => {
4910
+ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, generativeUI, mcpApps, defaultThrottleMs, debug, learning }) => {
3487
4911
  const learningConfig = (0, react.useMemo)(() => toLearningConfig(learning), [learning]);
3488
4912
  const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
3489
4913
  const [inspectorVisible, setInspectorVisible] = (0, react.useState)(false);
@@ -3505,6 +4929,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3505
4929
  const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;
3506
4930
  const a2uiCatalogProvided = !!a2ui?.catalog;
3507
4931
  const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;
4932
+ const generativeUIActive = !!generativeUI?.ui;
3508
4933
  const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
3509
4934
  const [runtimeEntitlements, setRuntimeEntitlements] = (0, react.useState)(void 0);
3510
4935
  const [runtimeEntitlementRetryPending, setRuntimeEntitlementRetryPending] = (0, react.useState)(false);
@@ -3558,10 +4983,12 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3558
4983
  loadingComponent: a2ui?.loadingComponent,
3559
4984
  recovery: a2ui?.recovery
3560
4985
  }));
4986
+ if (generativeUIActive) renderers.push(require_MarkdownSurfaces.createGenerativeUIActivityRenderer(), require_MarkdownSurfaces.createGenerativeUIFunctionCallActivityRenderer());
3561
4987
  return renderers;
3562
4988
  }, [
3563
4989
  a2uiActive,
3564
4990
  openGenUIActive,
4991
+ generativeUIActive,
3565
4992
  a2ui,
3566
4993
  filteredCatalog,
3567
4994
  mcpAppsAllowSameOrigin
@@ -3728,6 +5155,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3728
5155
  if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
3729
5156
  }
3730
5157
  const copilotkit = copilotkitRef.current;
5158
+ const generativeUIRuntime = useGenerativeUIRoot(copilotkit, generativeUI);
3731
5159
  (0, react.useEffect)(() => {
3732
5160
  if (!rawCatalog) return;
3733
5161
  if (!(rawCatalog instanceof _copilotkit_a2ui_renderer.Catalog)) return;
@@ -3966,6 +5394,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3966
5394
  value: licenseContextValue,
3967
5395
  children: [
3968
5396
  a2uiActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuiltInToolCallRenderer, {}),
5397
+ generativeUIActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.GenerativeUIToolCallRenderer, {}),
3969
5398
  a2uiActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UICatalogContext, {
3970
5399
  catalog: filteredCatalog,
3971
5400
  includeSchema: a2ui?.includeSchema
@@ -3974,7 +5403,10 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3974
5403
  value: inspectorContextValue,
3975
5404
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_react_core_v2_context.CopilotKitAgentIdContext.Provider, {
3976
5405
  value: agentId,
3977
- children
5406
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.GenerativeUIRuntimeContext.Provider, {
5407
+ value: generativeUIRuntime,
5408
+ children
5409
+ })
3978
5410
  }), shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, {
3979
5411
  core: copilotkit,
3980
5412
  openRequest: inspectorOpenRequest,
@@ -3995,7 +5427,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3995
5427
  //#region src/v2/hooks/use-render-custom-messages.tsx
3996
5428
  function useRenderCustomMessages() {
3997
5429
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
3998
- const config = useCopilotChatConfiguration();
5430
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
3999
5431
  if (!config) return null;
4000
5432
  const { agentId, threadId } = config;
4001
5433
  const customMessageRenderers = copilotkit.renderCustomMessages.filter((renderer) => renderer.agentId === void 0 || renderer.agentId === agentId).sort((a, b) => {
@@ -4040,7 +5472,7 @@ function useRenderCustomMessages() {
4040
5472
  //#region src/v2/hooks/use-render-activity-message.tsx
4041
5473
  function useRenderActivityMessage() {
4042
5474
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
4043
- const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
5475
+ const agentId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
4044
5476
  const renderers = copilotkit.renderActivityMessages;
4045
5477
  const findRenderer = (0, react.useCallback)((activityType) => {
4046
5478
  if (!renderers.length) return null;
@@ -4398,7 +5830,7 @@ function useRenderTool(config, deps) {
4398
5830
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
4399
5831
  const depsVersion = useDepsVersion(deps);
4400
5832
  (0, react.useEffect)(() => {
4401
- const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
5833
+ const renderer = config.name === "*" && !config.parameters ? require_MarkdownSurfaces.defineToolCallRenderer({
4402
5834
  name: "*",
4403
5835
  render: (props) => config.render({
4404
5836
  ...props,
@@ -4406,7 +5838,7 @@ function useRenderTool(config, deps) {
4406
5838
  }),
4407
5839
  ...config.agentId ? { agentId: config.agentId } : {},
4408
5840
  group: config.group
4409
- }) : defineToolCallRenderer({
5841
+ }) : require_MarkdownSurfaces.defineToolCallRenderer({
4410
5842
  name: config.name,
4411
5843
  args: config.parameters,
4412
5844
  render: (props) => {
@@ -4572,14 +6004,14 @@ function ToolCallRow({ name, parameters, result, status, appearance, className,
4572
6004
  const line = appearance === "line";
4573
6005
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4574
6006
  "data-copilotkit": true,
4575
- className: (0, tailwind_merge.twMerge)(!line && "cpk:border-t cpk:border-border", className),
6007
+ className: (0, tailwind_merge.twMerge)(appearance === "card" && "cpk:border-t cpk:border-border", className),
4576
6008
  ...props,
4577
6009
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
4578
6010
  type: "button",
4579
6011
  "aria-expanded": open,
4580
6012
  "aria-controls": detailsId,
4581
6013
  onClick: () => setOpen((value) => !value),
4582
- className: (0, tailwind_merge.twMerge)("cpk:group/row cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:gap-2 cpk:border-none cpk:bg-transparent cpk:text-left cpk:text-[13px] cpk:text-inherit cpk:transition-colors cpk:hover:bg-accent/60 cpk:focus-visible:outline-2 cpk:focus-visible:-outline-offset-2 cpk:focus-visible:outline-ring", line ? "cpk:-mx-1.5 cpk:w-[calc(100%+0.75rem)] cpk:rounded-md cpk:px-1.5 cpk:py-1" : "cpk:w-full cpk:px-3.5 cpk:py-2"),
6014
+ className: (0, tailwind_merge.twMerge)("cpk:group/row cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:gap-2 cpk:border-none cpk:bg-transparent cpk:text-left cpk:text-[13px] cpk:text-inherit cpk:transition-colors cpk:hover:bg-accent/60 cpk:focus-visible:outline-2 cpk:focus-visible:-outline-offset-2 cpk:focus-visible:outline-ring", line ? "cpk:-mx-1.5 cpk:w-[calc(100%+0.75rem)] cpk:rounded-md cpk:px-1.5 cpk:py-1" : appearance === "stack" ? "cpk:w-full cpk:px-3.5 cpk:py-2.5" : "cpk:w-full cpk:px-3.5 cpk:py-2"),
4583
6015
  children: [
4584
6016
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status }),
4585
6017
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -4619,7 +6051,8 @@ function ToolCallRow({ name, parameters, result, status, appearance, className,
4619
6051
  *
4620
6052
  * Each call is drawn by its registered renderer. CopilotKit's built-in card
4621
6053
  * (`useDefaultRenderTool`) draws a compact row inside the card and line
4622
- * appearances; a custom wildcard renderer draws whatever it draws.
6054
+ * appearances and an open stack; a custom wildcard renderer draws whatever it
6055
+ * draws.
4623
6056
  */
4624
6057
  function CopilotChatToolCallGroup({ calls, renderCall, appearance = "card", isActive = false, className, ...props }) {
4625
6058
  const [open, setOpen] = (0, react.useState)(false);
@@ -4698,11 +6131,6 @@ function CopilotChatToolCallGroup({ calls, renderCall, appearance = "card", isAc
4698
6131
  });
4699
6132
  }
4700
6133
  if (appearance === "stack") {
4701
- if (calls.length === 1) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4702
- ...groupProps,
4703
- className: (0, tailwind_merge.twMerge)("cpk:py-1", className),
4704
- children: renderCall(latest)
4705
- });
4706
6134
  const behind = open ? 0 : Math.min(calls.length - 1, 2);
4707
6135
  const layer = "cpk:rounded-xl cpk:border cpk:border-border cpk:bg-card cpk:text-card-foreground";
4708
6136
  const latestStatus = entryStatus(latest, isActive);
@@ -4716,68 +6144,88 @@ function CopilotChatToolCallGroup({ calls, renderCall, appearance = "card", isAc
4716
6144
  },
4717
6145
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4718
6146
  className: "cpk:relative cpk:isolate",
4719
- children: [Array.from({ length: behind }, (_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4720
- "aria-hidden": "true",
4721
- className: (0, tailwind_merge.twMerge)(layer, "cpk:absolute cpk:inset-0"),
4722
- style: {
4723
- transform: `translateY(${(index + 1) * 6}px) scaleX(${1 - (index + 1) * .045})`,
4724
- zIndex: -1 - index,
4725
- opacity: 1 - (index + 1) * .28
4726
- }
4727
- }, index)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4728
- type: "button",
4729
- "aria-expanded": open,
4730
- "aria-controls": open ? bodyId : void 0,
4731
- onClick: () => setOpen((value) => !value),
4732
- className: (0, tailwind_merge.twMerge)("cpk:relative cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:text-left cpk:transition-colors cpk:focus-visible:outline-2 cpk:focus-visible:outline-ring", open ? "cpk:mb-1 cpk:gap-1.5 cpk:rounded-md cpk:border-none cpk:bg-transparent cpk:p-0 cpk:py-0.5 cpk:text-xs cpk:text-muted-foreground cpk:hover:text-foreground" : (0, tailwind_merge.twMerge)(layer, "cpk:w-full cpk:gap-2 cpk:px-3.5 cpk:py-2.5 cpk:text-[13px] cpk:shadow-[0_1px_2px_rgb(0_0_0/0.04)] cpk:hover:bg-accent")),
4733
- children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
4734
- pluralize(calls.length, "tool call"),
4735
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }),
4736
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
4737
- open: true,
4738
- className: "cpk:-rotate-90"
4739
- }),
4740
- "Collapse"
4741
- ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4742
- className: "cpk:flex cpk:min-w-0 cpk:flex-1 cpk:items-center cpk:gap-2 cpk:animate-[cpk-stack-drop_260ms_cubic-bezier(0.16,1,0.3,1)] cpk:motion-reduce:animate-none",
4743
- children: [
4744
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status: latestStatus }),
4745
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4746
- className: (0, tailwind_merge.twMerge)("cpk:shrink-0 cpk:font-mono cpk:font-medium cpk:text-foreground", latestStatus === "running" && "cpk-shimmer"),
4747
- children: latest.toolCall.function.name
4748
- }),
4749
- latestPreview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4750
- className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-muted-foreground",
4751
- children: latestPreview
4752
- })
4753
- ]
4754
- }, latest.toolCall.id), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4755
- className: "cpk:ml-2 cpk:inline-flex cpk:shrink-0 cpk:items-center cpk:gap-2 cpk:text-xs cpk:text-muted-foreground",
4756
- children: [
6147
+ children: [
6148
+ Array.from({ length: behind }, (_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6149
+ "aria-hidden": "true",
6150
+ className: (0, tailwind_merge.twMerge)(layer, "cpk:absolute cpk:inset-0"),
6151
+ style: {
6152
+ transform: `translateY(${(index + 1) * 6}px) scaleX(${1 - (index + 1) * .045})`,
6153
+ zIndex: -1 - index,
6154
+ opacity: 1 - (index + 1) * .28
6155
+ }
6156
+ }, index)),
6157
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6158
+ type: "button",
6159
+ "aria-expanded": open,
6160
+ "aria-controls": open ? bodyId : void 0,
6161
+ onClick: () => setOpen((value) => !value),
6162
+ className: (0, tailwind_merge.twMerge)("cpk:relative cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:text-left cpk:transition-colors cpk:focus-visible:outline-2 cpk:focus-visible:outline-ring", open ? "cpk:mb-1.5 cpk:w-full cpk:gap-1.5 cpk:rounded-md cpk:border-none cpk:bg-transparent cpk:p-0 cpk:py-0.5 cpk:text-xs cpk:text-muted-foreground cpk:hover:text-foreground" : (0, tailwind_merge.twMerge)(layer, "cpk:w-full cpk:gap-2 cpk:px-3.5 cpk:py-2.5 cpk:text-[13px] cpk:shadow-[0_1px_2px_rgb(0_0_0/0.04)] cpk:hover:bg-accent")),
6163
+ children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
6164
+ pluralize(calls.length, "tool call"),
4757
6165
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }),
4758
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4759
- className: "cpk:tabular-nums",
4760
- children: pluralize(calls.length, "call")
4761
- }),
4762
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
4763
- open: false,
4764
- className: "cpk:rotate-90"
6166
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6167
+ className: "cpk:ml-auto cpk:inline-flex cpk:items-center cpk:gap-1",
6168
+ children: ["Collapse", /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
6169
+ open: true,
6170
+ className: "cpk:-rotate-90"
6171
+ })]
4765
6172
  })
4766
- ]
4767
- })] })
4768
- })]
6173
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6174
+ className: "cpk:flex cpk:min-w-0 cpk:flex-1 cpk:items-center cpk:gap-2 cpk:animate-[cpk-stack-drop_260ms_cubic-bezier(0.16,1,0.3,1)] cpk:motion-reduce:animate-none",
6175
+ children: [
6176
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status: latestStatus }),
6177
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6178
+ className: (0, tailwind_merge.twMerge)("cpk:shrink-0 cpk:font-mono cpk:font-medium cpk:text-foreground", latestStatus === "running" && "cpk-shimmer"),
6179
+ children: latest.toolCall.function.name
6180
+ }),
6181
+ latestPreview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6182
+ className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-muted-foreground",
6183
+ children: latestPreview
6184
+ }),
6185
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6186
+ className: "cpk:sr-only",
6187
+ children: statusLabels[latestStatus]
6188
+ })
6189
+ ]
6190
+ }, latest.toolCall.id), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6191
+ className: "cpk:ml-2 cpk:inline-flex cpk:shrink-0 cpk:items-center cpk:gap-2 cpk:text-xs cpk:text-muted-foreground",
6192
+ children: [
6193
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }),
6194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6195
+ className: "cpk:tabular-nums",
6196
+ children: pluralize(calls.length, "call")
6197
+ }),
6198
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
6199
+ open: false,
6200
+ className: "cpk:rotate-90"
6201
+ })
6202
+ ]
6203
+ })] })
6204
+ }),
6205
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6206
+ "aria-live": "polite",
6207
+ className: "cpk:sr-only",
6208
+ children: open ? "" : `${latest.toolCall.function.name}: ${statusLabels[latestStatus]}`
6209
+ })
6210
+ ]
4769
6211
  }), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4770
6212
  id: bodyId,
4771
- className: "cpk:[&>*]:animate-[cpk-stack-fan_300ms_cubic-bezier(0.16,1,0.3,1)_both] cpk:motion-reduce:[&>*]:animate-none",
4772
- children: calls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall(call) }, call.toolCall.id))
6213
+ className: "cpk:grid cpk:gap-1.5",
6214
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallGroupContext.Provider, {
6215
+ value: {
6216
+ appearance: "stack",
6217
+ failedIds,
6218
+ active: isActive
6219
+ },
6220
+ children: calls.map((call, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6221
+ className: (0, tailwind_merge.twMerge)(layer, "cpk:overflow-hidden cpk:shadow-[0_1px_2px_rgb(0_0_0/0.04)] cpk:animate-[cpk-stack-fan_240ms_cubic-bezier(0.16,1,0.3,1)_both] cpk:motion-reduce:animate-none"),
6222
+ style: { animationDelay: `${index * 30}ms` },
6223
+ children: renderCall(call)
6224
+ }, call.toolCall.id))
6225
+ })
4773
6226
  })]
4774
6227
  });
4775
6228
  }
4776
- if (calls.length === 1) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4777
- ...groupProps,
4778
- className: (0, tailwind_merge.twMerge)("cpk:py-1", className),
4779
- children: renderCall(latest)
4780
- });
4781
6229
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4782
6230
  ...groupProps,
4783
6231
  className: (0, tailwind_merge.twMerge)("cpk:my-3 cpk:overflow-hidden cpk:rounded-xl cpk:border cpk:border-border cpk:bg-card cpk:text-card-foreground", className),
@@ -4800,7 +6248,7 @@ function CopilotChatToolCallGroup({ calls, renderCall, appearance = "card", isAc
4800
6248
  className: "cpk:ml-auto cpk:flex cpk:shrink-0 cpk:items-center cpk:gap-2 cpk:pl-2 cpk:text-xs cpk:text-muted-foreground",
4801
6249
  children: [status === "failed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4802
6250
  className: "cpk:tabular-nums",
4803
- children: status === "running" ? `${done} done` : statusLabels[status]
6251
+ children: status !== "running" ? statusLabels[status] : done > 0 && `${done} done`
4804
6252
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, { open })]
4805
6253
  })
4806
6254
  ]
@@ -5125,7 +6573,7 @@ function useAgent({ agentId, threadId, runtimeAgentId, updates, throttleMs } = {
5125
6573
  if (threadId != null && runtimeAgentId == null) throw new Error(`useAgent: \`threadId\` requires \`runtimeAgentId\`. A threadId is written onto a single agent, but an agent resolved by agentId alone is shared, so scoping a thread to it would clobber other useAgent callers. Pass a distinct local \`agentId\` and the runtime agent to route to, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${agentId ?? "default"}", threadId }).`);
5126
6574
  if (runtimeAgentId != null && threadId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires \`threadId\`. A proxied agent exists to scope a thread to a private instance; without a threadId it behaves like the shared agent while adding a registration and a local agentId to keep unique. Either pass the thread, e.g. useAgent({ agentId: "${agentId ?? "chat-1"}", runtimeAgentId: "${runtimeAgentId}", threadId }), or bind to the agent directly with useAgent({ agentId: "${runtimeAgentId}" }).`);
5127
6575
  if (runtimeAgentId != null && agentId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires an explicit \`agentId\`. The proxied agent is registered under \`agentId\`, and the usual fallbacks (chat configuration, then "${_copilotkit_shared.DEFAULT_AGENT_ID}") name agents that already exist — registering over one throws or shadows it. Pick a local id for this hook, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${runtimeAgentId}", threadId }).`);
5128
- const chatConfig = useCopilotChatConfiguration();
6576
+ const chatConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
5129
6577
  const providerAgentId = (0, _copilotkit_react_core_v2_context.useDefaultAgentId)();
5130
6578
  const resolvedAgentId = agentId ?? chatConfig?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
5131
6579
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
@@ -5355,7 +6803,7 @@ function useAgentContext(context) {
5355
6803
  //#region src/v2/hooks/use-suggestions.tsx
5356
6804
  function useSuggestions({ agentId } = {}) {
5357
6805
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
5358
- const config = useCopilotChatConfiguration();
6806
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
5359
6807
  const providerAgentId = (0, _copilotkit_react_core_v2_context.useDefaultAgentId)();
5360
6808
  const resolvedAgentId = (0, react.useMemo)(() => agentId ?? config?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [
5361
6809
  agentId,
@@ -5413,7 +6861,7 @@ function useSuggestions({ agentId } = {}) {
5413
6861
  //#region src/v2/hooks/use-configure-suggestions.tsx
5414
6862
  function useConfigureSuggestions(config, deps) {
5415
6863
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
5416
- const chatConfig = useCopilotChatConfiguration();
6864
+ const chatConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
5417
6865
  const extraDeps = deps ?? [];
5418
6866
  const resolvedConsumerAgentId = (0, react.useMemo)(() => chatConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [chatConfig?.agentId]);
5419
6867
  const rawConsumerAgentId = (0, react.useMemo)(() => config ? config.consumerAgentId : void 0, [config]);
@@ -6252,7 +7700,7 @@ function useLearnFromUserAction() {
6252
7700
  * ```
6253
7701
  */
6254
7702
  function useLearnFromUserActionInCurrentThread() {
6255
- const config = useCopilotChatConfiguration();
7703
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
6256
7704
  const learnFromUserAction = useLearnFromUserAction();
6257
7705
  return (0, react.useCallback)(async (input) => {
6258
7706
  const threadId = config?.threadId;
@@ -6622,7 +8070,7 @@ function useLearningContainers({ threadId, learningContainers }) {
6622
8070
  * Intelligence runtimes.
6623
8071
  */
6624
8072
  function useLearningContainersInCurrentThread({ learningContainers }) {
6625
- const threadId = useCopilotChatConfiguration()?.threadId;
8073
+ const threadId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.threadId;
6626
8074
  if (!threadId) throw new Error("useLearningContainersInCurrentThread must be used within a thread context (no active threadId). Wrap the component in <CopilotChat>, <CopilotSidebar>, or <CopilotChatConfigurationProvider>, or use `useLearningContainers()` and pass `threadId` explicitly.");
6627
8075
  useLearningContainers({
6628
8076
  threadId,
@@ -6974,7 +8422,7 @@ function InspectorKiteIcon({ className, ...props }) {
6974
8422
  });
6975
8423
  }
6976
8424
  function CopilotChatInspectorButton({ title, className, onClick, onPointerDown, onPointerEnter, onPointerLeave, onKeyDown, disabled, ...props }) {
6977
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
8425
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
6978
8426
  const { isInspectorEnabled } = useCopilotKitInspector();
6979
8427
  const hidden = useInspectorShortcutsHidden();
6980
8428
  const [open, setOpen] = (0, react.useState)(false);
@@ -7445,7 +8893,7 @@ function WorkText({ messageId, children }) {
7445
8893
  * assistant message subscribe to chat configuration changes.
7446
8894
  */
7447
8895
  function BoundInspectorButton({ inspectorButton, messageId, openInspector, ...props }) {
7448
- const chatConfiguration = useCopilotChatConfiguration();
8896
+ const chatConfiguration = require_MarkdownSurfaces.useCopilotChatConfiguration();
7449
8897
  return renderSlot(inspectorButton, CopilotChatAssistantMessage.InspectorButton, {
7450
8898
  ...props,
7451
8899
  onClick: () => openInspector({
@@ -7490,7 +8938,7 @@ function nextFocusable(element, skip) {
7490
8938
  * control after the thumb, and Enter or Escape inside it returns to the thumb.
7491
8939
  */
7492
8940
  function FeedbackCommentPopover({ feedbackComment, comment, savedComment, rating, anchor, messageId }) {
7493
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
8941
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7494
8942
  const contentRef = (0, react.useRef)(null);
7495
8943
  const focusInside = () => contentRef.current?.contains(document.activeElement) ?? false;
7496
8944
  const { focusRequest, takeFocusRequest, inputRef } = comment;
@@ -7560,7 +9008,7 @@ function FeedbackCommentPopover({ feedbackComment, comment, savedComment, rating
7560
9008
  });
7561
9009
  }
7562
9010
  function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, onThumbsUp, onThumbsDown, onReadAloud, onRegenerate, additionalToolbarItems, toolbarVisible = true, markdownRenderer, toolbar, copyButton, inspectorButton, thumbsUpButton, thumbsDownButton, readAloudButton, regenerateButton, feedbackComment: feedbackCommentSlot, toolCallsView, children, className, ...props }) {
7563
- useKatexStyles();
9011
+ require_MarkdownSurfaces.useKatexStyles();
7564
9012
  const { isInspectorEnabled, openInspector } = useCopilotKitInspector();
7565
9013
  const shortcutsHidden = useInspectorShortcutsHidden();
7566
9014
  const showInspectorShortcut = isInspectorEnabled && !shortcutsHidden;
@@ -7635,7 +9083,10 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7635
9083
  }
7636
9084
  };
7637
9085
  };
7638
- const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
9086
+ const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, {
9087
+ content: message.content || "",
9088
+ messageId: message.id
9089
+ });
7639
9090
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
7640
9091
  if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
7641
9092
  return false;
@@ -7745,11 +9196,19 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7745
9196
  });
7746
9197
  }
7747
9198
  (function(_CopilotChatAssistantMessage) {
7748
- _CopilotChatAssistantMessage.MarkdownRenderer = ({ content, className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(streamdown.Streamdown, {
7749
- className,
7750
- ...props,
7751
- children: content ?? ""
7752
- });
9199
+ _CopilotChatAssistantMessage.MarkdownRenderer = ({ content, className, messageId, ...props }) => {
9200
+ if (require_MarkdownSurfaces.useGenerativeUIRuntime()?.transport === "markdown" && messageId !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.MarkdownSurfaces, {
9201
+ content: content ?? "",
9202
+ messageId,
9203
+ className,
9204
+ ...props
9205
+ });
9206
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(streamdown.Streamdown, {
9207
+ className,
9208
+ ...props,
9209
+ children: content ?? ""
9210
+ });
9211
+ };
7753
9212
  _CopilotChatAssistantMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7754
9213
  "data-testid": "copilot-assistant-toolbar",
7755
9214
  className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]", className),
@@ -7779,7 +9238,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7779
9238
  });
7780
9239
  };
7781
9240
  _CopilotChatAssistantMessage.CopyButton = ({ className, title, onClick, ...props }) => {
7782
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9241
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7783
9242
  const [copied, setCopied] = (0, react.useState)(false);
7784
9243
  const timerRef = (0, react.useRef)(null);
7785
9244
  (0, react.useEffect)(() => {
@@ -7810,7 +9269,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7810
9269
  };
7811
9270
  _CopilotChatAssistantMessage.InspectorButton = CopilotChatInspectorButton;
7812
9271
  _CopilotChatAssistantMessage.ThumbsUpButton = ({ title, ...props }) => {
7813
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9272
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7814
9273
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
7815
9274
  "data-testid": "copilot-thumbs-up-button",
7816
9275
  title: title || labels.assistantMessageToolbarThumbsUpLabel,
@@ -7822,7 +9281,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7822
9281
  });
7823
9282
  };
7824
9283
  _CopilotChatAssistantMessage.ThumbsDownButton = ({ title, ...props }) => {
7825
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9284
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7826
9285
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
7827
9286
  "data-testid": "copilot-thumbs-down-button",
7828
9287
  title: title || labels.assistantMessageToolbarThumbsDownLabel,
@@ -7834,7 +9293,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7834
9293
  });
7835
9294
  };
7836
9295
  _CopilotChatAssistantMessage.FeedbackComment = ({ value, savedComment, inputRef, onChange, onSubmit, onEditingChange, onLeave, className }) => {
7837
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9296
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7838
9297
  const changed = value.trim() !== savedComment;
7839
9298
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
7840
9299
  "data-testid": "copilot-feedback-comment",
@@ -7869,7 +9328,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7869
9328
  });
7870
9329
  };
7871
9330
  _CopilotChatAssistantMessage.ReadAloudButton = ({ title, ...props }) => {
7872
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9331
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7873
9332
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
7874
9333
  "data-testid": "copilot-read-aloud-button",
7875
9334
  title: title || labels.assistantMessageToolbarReadAloudLabel,
@@ -7878,7 +9337,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
7878
9337
  });
7879
9338
  };
7880
9339
  _CopilotChatAssistantMessage.RegenerateButton = ({ title, ...props }) => {
7881
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9340
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7882
9341
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
7883
9342
  "data-testid": "copilot-regenerate-button",
7884
9343
  title: title || labels.assistantMessageToolbarRegenerateLabel,
@@ -7900,7 +9359,13 @@ var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
7900
9359
 
7901
9360
  //#endregion
7902
9361
  //#region src/v2/components/chat/Lightbox.tsx
9362
+ /**
9363
+ * A full-screen preview portalled to `document.body`. It closes on Escape, a
9364
+ * click on the backdrop, or its close button, which is named by
9365
+ * `labels.attachmentPreviewCloseButtonLabel`.
9366
+ */
7903
9367
  function Lightbox({ onClose, children }) {
9368
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
7904
9369
  (0, react.useEffect)(() => {
7905
9370
  const handleKey = (e) => {
7906
9371
  if (e.key === "Escape") onClose();
@@ -7915,7 +9380,7 @@ function Lightbox({ onClose, children }) {
7915
9380
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7916
9381
  onClick: onClose,
7917
9382
  className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
7918
- "aria-label": "Close preview",
9383
+ "aria-label": labels.attachmentPreviewCloseButtonLabel,
7919
9384
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:w-5 cpk:h-5" })
7920
9385
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7921
9386
  onClick: (e) => e.stopPropagation(),
@@ -8169,7 +9634,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
8169
9634
  })] });
8170
9635
  };
8171
9636
  _CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
8172
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9637
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
8173
9638
  const [copied, setCopied] = (0, react.useState)(false);
8174
9639
  const handleClick = async (event) => {
8175
9640
  let success = false;
@@ -8189,7 +9654,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
8189
9654
  });
8190
9655
  };
8191
9656
  _CopilotChatUserMessage.EditButton = ({ className, title, ...props }) => {
8192
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9657
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
8193
9658
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
8194
9659
  "data-testid": "copilot-edit-button",
8195
9660
  title: title || labels.userMessageToolbarEditMessageLabel,
@@ -8199,7 +9664,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
8199
9664
  });
8200
9665
  };
8201
9666
  _CopilotChatUserMessage.BranchNavigation = ({ className, currentBranch = 0, numberOfBranches = 1, onSwitchToBranch, message, ...props }) => {
8202
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
9667
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
8203
9668
  if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) return null;
8204
9669
  const canGoPrev = currentBranch > 0;
8205
9670
  const canGoNext = currentBranch < numberOfBranches - 1;
@@ -8268,7 +9733,14 @@ function formatDuration$1(seconds) {
8268
9733
  if (secs === 0) return `${mins} minute${mins > 1 ? "s" : ""}`;
8269
9734
  return `${mins}m ${secs}s`;
8270
9735
  }
9736
+ /**
9737
+ * A reasoning message as a collapsible block. While the model reasons it is
9738
+ * open and the header shows `labels.reasoningMessageThinkingLabel`; when
9739
+ * streaming ends it collapses and the header reads "Thought for …". The
9740
+ * `header` slot also receives `elapsedSeconds`.
9741
+ */
8271
9742
  function CopilotChatReasoningMessage({ message, messages, isRunning, isLatest: isLatestProp, header, contentView, toggle, children, className, ...props }) {
9743
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
8272
9744
  const isLatest = isLatestProp ?? messages?.[messages.length - 1]?.id === message.id;
8273
9745
  const isStreaming = !!(isRunning && isLatest);
8274
9746
  const hasContent = !!(message.content && message.content.length > 0);
@@ -8298,12 +9770,13 @@ function CopilotChatReasoningMessage({ message, messages, isRunning, isLatest: i
8298
9770
  userToggledRef.current = true;
8299
9771
  setIsOpen((prev) => !prev);
8300
9772
  } : void 0;
8301
- const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration$1(elapsed)}`;
9773
+ const label = isStreaming ? labels.reasoningMessageThinkingLabel : `Thought for ${formatDuration$1(elapsed)}`;
8302
9774
  const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
8303
9775
  isOpen,
8304
9776
  label,
8305
9777
  hasContent,
8306
9778
  isStreaming,
9779
+ elapsedSeconds: elapsed,
8307
9780
  onClick: handleToggle
8308
9781
  });
8309
9782
  const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
@@ -8335,7 +9808,7 @@ function CopilotChatReasoningMessage({ message, messages, isRunning, isLatest: i
8335
9808
  });
8336
9809
  }
8337
9810
  (function(_CopilotChatReasoningMessage) {
8338
- _CopilotChatReasoningMessage.Header = ({ isOpen, label = "Thoughts", hasContent, isStreaming, className, children: headerChildren, ...headerProps }) => {
9811
+ _CopilotChatReasoningMessage.Header = ({ isOpen, label = "Thoughts", hasContent, isStreaming, elapsedSeconds: _elapsedSeconds, className, children: headerChildren, ...headerProps }) => {
8339
9812
  const isExpandable = !!hasContent;
8340
9813
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8341
9814
  type: "button",
@@ -8820,7 +10293,7 @@ const isToolCallLikeMessage = (m) => {
8820
10293
  function IntelligenceIndicator(props) {
8821
10294
  const { message, agentId, label = "CopilotKit Intelligence", intelligenceIndicator } = props;
8822
10295
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
8823
- const config = useCopilotChatConfiguration();
10296
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
8824
10297
  const { agent } = useAgent({
8825
10298
  agentId,
8826
10299
  updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
@@ -9076,7 +10549,7 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
9076
10549
  const renderCustomMessage = useRenderCustomMessages();
9077
10550
  const { renderActivityMessage } = useRenderActivityMessage();
9078
10551
  const { copilotkit, showIntelligenceIndicator = true } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
9079
- const config = useCopilotChatConfiguration();
10552
+ const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
9080
10553
  const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
9081
10554
  (0, react.useEffect)(() => {
9082
10555
  if (!config?.agentId) return;
@@ -9611,7 +11084,12 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
9611
11084
 
9612
11085
  //#endregion
9613
11086
  //#region src/v2/components/chat/CopilotChatAttachmentQueue.tsx
11087
+ /**
11088
+ * The attachments queued in the composer, each with a preview and a remove
11089
+ * button named by `labels.attachmentRemoveButtonLabel`.
11090
+ */
9614
11091
  const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className }) => {
11092
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
9615
11093
  if (attachments.length === 0) return null;
9616
11094
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9617
11095
  "data-testid": "copilot-attachment-queue",
@@ -9626,7 +11104,7 @@ const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className
9626
11104
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9627
11105
  onClick: () => onRemoveAttachment(attachment.id),
9628
11106
  className: cn("cpk:absolute cpk:bg-black/60 cpk:text-white cpk:border-none cpk:rounded-full cpk:w-5 cpk:h-5 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:text-[10px] cpk:z-20", isMedia ? "cpk:top-1 cpk:right-1" : "cpk:top-1.5 cpk:right-1.5"),
9629
- "aria-label": "Remove attachment",
11107
+ "aria-label": labels.attachmentRemoveButtonLabel,
9630
11108
  children: "✕"
9631
11109
  })
9632
11110
  ]
@@ -9682,7 +11160,13 @@ function AudioPreview({ attachment }) {
9682
11160
  })]
9683
11161
  });
9684
11162
  }
11163
+ /**
11164
+ * A video thumbnail with a play button, named by
11165
+ * `labels.attachmentPlayVideoButtonLabel`, that opens the full player in a
11166
+ * lightbox.
11167
+ */
9685
11168
  function VideoPreview({ attachment }) {
11169
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
9686
11170
  const src = (0, _copilotkit_shared.getSourceUrl)(attachment.source);
9687
11171
  const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
9688
11172
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -9703,7 +11187,7 @@ function VideoPreview({ attachment }) {
9703
11187
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9704
11188
  onClick: openLightbox,
9705
11189
  className: "cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:z-10 cpk:cursor-pointer cpk:bg-black/20 cpk:border-none cpk:p-0",
9706
- "aria-label": "Play video",
11190
+ "aria-label": labels.attachmentPlayVideoButtonLabel,
9707
11191
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9708
11192
  className: "cpk:w-8 cpk:h-8 cpk:rounded-full cpk:bg-black/60 cpk:flex cpk:items-center cpk:justify-center",
9709
11193
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Play, { className: "cpk:w-4 cpk:h-4 cpk:text-white cpk:ml-0.5" })
@@ -9983,7 +11467,7 @@ function DropOverlay() {
9983
11467
  });
9984
11468
  }
9985
11469
  function CopilotChatView({ messageView, input, scrollView, suggestionView, welcomeScreen, messages = [], autoScroll = true, isRunning = false, suggestions, suggestionLoadingIndexes, onSelectSuggestion, onSubmitMessage, onStop, inputMode, inputValue, onInputChange, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, attachments, onRemoveAttachment, onAddFile, dragOver, onDragOver, onDragLeave, onDrop, isConnecting = false, hasExplicitThreadId = false, disclaimer, intelligenceIndicator, children, className, ...props }) {
9986
- const configuredThreadId = useCopilotChatConfiguration()?.threadId;
11470
+ const configuredThreadId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.threadId;
9987
11471
  const [fallbackThreadId, setFallbackThreadId] = (0, react.useState)(messages[0]?.id);
9988
11472
  const previousMessageIds = (0, react.useRef)(/* @__PURE__ */ new Set());
9989
11473
  (0, react.useEffect)(() => {
@@ -10419,7 +11903,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
10419
11903
  });
10420
11904
  };
10421
11905
  _CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => {
10422
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
11906
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
10423
11907
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
10424
11908
  "data-testid": "copilot-scroll-to-bottom",
10425
11909
  variant: "outline",
@@ -10435,7 +11919,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
10435
11919
  ...props
10436
11920
  });
10437
11921
  _CopilotChatView.WelcomeMessage = ({ className, ...props }) => {
10438
- const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
11922
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
10439
11923
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
10440
11924
  className: cn("cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center", className),
10441
11925
  ...props,
@@ -10685,8 +12169,8 @@ function useInspectorThreadOverride(args) {
10685
12169
 
10686
12170
  //#endregion
10687
12171
  //#region src/v2/components/chat/CopilotChat.tsx
10688
- function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isModalDefaultOpen, attachments: attachmentsConfig, onError, throttleMs, ...props }) {
10689
- const existingConfig = useCopilotChatConfiguration();
12172
+ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isModalDefaultOpen, attachments: attachmentsConfig, onError, throttleMs, generativeUISurface, ...props }) {
12173
+ const existingConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
10690
12174
  const inspector = useCopilotKitInspector();
10691
12175
  const inspectorContextValue = (0, react.useMemo)(() => ({
10692
12176
  ...inspector,
@@ -10790,6 +12274,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
10790
12274
  const pendingRunActivityReconnectRef = (0, react.useRef)(false);
10791
12275
  const runActivityReconnectGenerationRef = (0, react.useRef)(0);
10792
12276
  const activeLocalRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
12277
+ const observedLocalRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
10793
12278
  const recentlyLocalRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
10794
12279
  const activeWakeRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
10795
12280
  const recentlyWakeRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
@@ -10821,7 +12306,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
10821
12306
  }, []);
10822
12307
  const isLocalActiveRunActivity = (0, react.useCallback)((notification) => {
10823
12308
  if (notification.agentId && notification.agentId !== resolvedAgentId) return false;
10824
- if (!notification.runId || !activeLocalRunIdsRef.current.has(notification.runId) && !recentlyLocalRunIdsRef.current.has(notification.runId)) return false;
12309
+ if (!notification.runId || !activeLocalRunIdsRef.current.has(notification.runId) && !observedLocalRunIdsRef.current.has(notification.runId) && !recentlyLocalRunIdsRef.current.has(notification.runId)) return false;
10825
12310
  const eventType = notification.eventType.toUpperCase();
10826
12311
  return eventType === "RUN_STARTED" || eventType === "RUN_FINISHED" || eventType === "RUN_ERROR";
10827
12312
  }, [resolvedAgentId]);
@@ -11020,6 +12505,16 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11020
12505
  pendingWakeRunIdRef.current = notification.runId;
11021
12506
  startRunActivityReconnectRef.current?.(generation);
11022
12507
  });
12508
+ const observedLocalRunIds = observedLocalRunIdsRef.current;
12509
+ const localRunSubscription = agent.subscribe({
12510
+ onRunInitialized: ({ input }) => {
12511
+ observedLocalRunIds.add(input.runId);
12512
+ },
12513
+ onRunFinalized: ({ input }) => {
12514
+ observedLocalRunIds.delete(input.runId);
12515
+ rememberRecentlyLocalRunId(input.runId);
12516
+ }
12517
+ });
11023
12518
  return () => {
11024
12519
  detached = true;
11025
12520
  pendingRunActivityReconnectRef.current = false;
@@ -11032,6 +12527,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11032
12527
  if (wakeReconnectActive) agent.detachActiveRun().catch(() => {});
11033
12528
  activeWakeRunIdsRef.current.clear();
11034
12529
  subscription.unsubscribe();
12530
+ localRunSubscription.unsubscribe();
11035
12531
  if (ownsStandaloneStore) {
11036
12532
  threadStore.setContext(null);
11037
12533
  threadStore.stop();
@@ -11050,6 +12546,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11050
12546
  copilotkit.threadEndpoints?.realtimeMetadata,
11051
12547
  standaloneRunActivityStore,
11052
12548
  isLocalActiveRunActivity,
12549
+ rememberRecentlyLocalRunId,
11053
12550
  rememberRecentlyWakeRunId
11054
12551
  ]);
11055
12552
  const waitForActiveRunToSettle = (0, react.useCallback)(async () => {
@@ -11264,8 +12761,8 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11264
12761
  return () => clearTimeout(timer);
11265
12762
  }
11266
12763
  }, [transcriptionError]);
11267
- const stableMessageView = useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
11268
- const stableSuggestionView = useShallowStableRef(providedSuggestionView);
12764
+ const stableMessageView = require_MarkdownSurfaces.useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
12765
+ const stableSuggestionView = require_MarkdownSurfaces.useShallowStableRef(providedSuggestionView);
11269
12766
  const handleAddFile = (0, react.useCallback)(() => {
11270
12767
  setTimeout(() => {
11271
12768
  fileInputRef.current?.click();
@@ -11326,7 +12823,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11326
12823
  isConnecting,
11327
12824
  hasExplicitThreadId
11328
12825
  });
11329
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
12826
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
11330
12827
  agentId: resolvedAgentId,
11331
12828
  threadId: resolvedThreadId,
11332
12829
  hasExplicitThreadId,
@@ -11364,7 +12861,10 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
11364
12861
  value: lastUserMessageState,
11365
12862
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspectorContextProvider, {
11366
12863
  value: inspectorContextValue,
11367
- children: RenderedChatView
12864
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.GenerativeUIChatSlotContext.Provider, {
12865
+ value: generativeUISurface,
12866
+ children: RenderedChatView
12867
+ })
11368
12868
  })
11369
12869
  })
11370
12870
  ]
@@ -11395,8 +12895,8 @@ const ICON_WRAPPER_BASE = "cpk:pointer-events-none cpk:absolute cpk:inset-0 cpk:
11395
12895
  const BUTTON_BASE_CLASSES = cn("copilotKitButton", "cpk:fixed cpk:bottom-6 cpk:right-6 cpk:z-[1100] cpk:flex cpk:h-14 cpk:w-14 cpk:items-center cpk:justify-center", "cpk:rounded-full cpk:border cpk:border-primary cpk:bg-primary cpk:text-primary-foreground", "cpk:shadow-sm cpk:transition-all cpk:duration-200 cpk:ease-out", "cpk:hover:scale-[1.04] cpk:hover:shadow-md", "cpk:cursor-pointer", "cpk:active:scale-[0.96]", "cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-primary/50 cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background", "cpk:disabled:pointer-events-none cpk:disabled:opacity-60");
11396
12896
  const CopilotChatToggleButton = react.default.forwardRef(function CopilotChatToggleButton({ openIcon, closeIcon, className, ...buttonProps }, ref) {
11397
12897
  const { onClick, type, disabled, ...restProps } = buttonProps;
11398
- const configuration = useCopilotChatConfiguration();
11399
- const labels = configuration?.labels ?? CopilotChatDefaultLabels;
12898
+ const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
12899
+ const labels = configuration?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
11400
12900
  const [fallbackOpen, setFallbackOpen] = (0, react.useState)(false);
11401
12901
  const isOpen = configuration?.isModalOpen ?? fallbackOpen;
11402
12902
  const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
@@ -11512,8 +13012,8 @@ function useIsMobileViewport() {
11512
13012
  return isMobile;
11513
13013
  }
11514
13014
  function CopilotModalHeader({ title, titleContent, closeButton, drawerLauncher, children, className, ...rest }) {
11515
- const configuration = useCopilotChatConfiguration();
11516
- const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
13015
+ const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
13016
+ const fallbackTitle = configuration?.labels.modalHeaderTitle ?? require_MarkdownSurfaces.CopilotChatDefaultLabels.modalHeaderTitle;
11517
13017
  const resolvedTitle = title ?? fallbackTitle;
11518
13018
  const isMobile = useIsMobileViewport();
11519
13019
  const drawerRegistered = (configuration?.drawerRegistered ?? false) && isMobile;
@@ -11568,28 +13068,34 @@ CopilotModalHeader.displayName = "CopilotModalHeader";
11568
13068
  ...props,
11569
13069
  children
11570
13070
  });
11571
- _CopilotModalHeader.CloseButton = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11572
- type: "button",
11573
- "data-testid": "copilot-close-button",
11574
- className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
11575
- "aria-label": "Close",
11576
- ...props,
11577
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {
11578
- className: "cpk:h-4 cpk:w-4",
11579
- "aria-hidden": "true"
11580
- })
11581
- });
11582
- _CopilotModalHeader.DrawerLauncher = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11583
- type: "button",
11584
- "data-testid": "copilot-threads-drawer-launcher",
11585
- className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
11586
- "aria-label": "Open threads",
11587
- ...props,
11588
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PanelLeftOpen, {
11589
- className: "cpk:h-4 cpk:w-4",
11590
- "aria-hidden": "true"
11591
- })
11592
- });
13071
+ _CopilotModalHeader.CloseButton = ({ className, ...props }) => {
13072
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
13073
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
13074
+ type: "button",
13075
+ "data-testid": "copilot-close-button",
13076
+ className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
13077
+ "aria-label": labels.modalHeaderCloseButtonLabel,
13078
+ ...props,
13079
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {
13080
+ className: "cpk:h-4 cpk:w-4",
13081
+ "aria-hidden": "true"
13082
+ })
13083
+ });
13084
+ };
13085
+ _CopilotModalHeader.DrawerLauncher = ({ className, ...props }) => {
13086
+ const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
13087
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
13088
+ type: "button",
13089
+ "data-testid": "copilot-threads-drawer-launcher",
13090
+ className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
13091
+ "aria-label": labels.modalHeaderThreadsButtonLabel,
13092
+ ...props,
13093
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PanelLeftOpen, {
13094
+ className: "cpk:h-4 cpk:w-4",
13095
+ "aria-hidden": "true"
13096
+ })
13097
+ });
13098
+ };
11593
13099
  })(CopilotModalHeader || (CopilotModalHeader = {}));
11594
13100
  CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
11595
13101
  CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
@@ -11599,6 +13105,10 @@ CopilotModalHeader.DrawerLauncher.displayName = "CopilotModalHeader.DrawerLaunch
11599
13105
  //#region src/v2/components/chat/CopilotSidebarView.tsx
11600
13106
  const DEFAULT_SIDEBAR_WIDTH = 480;
11601
13107
  const SIDEBAR_TRANSITION_MS = 260;
13108
+ /**
13109
+ * The chat in a side panel: a `complementary` region named by
13110
+ * `labels.sidebarLabel`, with a header, the chat view and a toggle button.
13111
+ */
11602
13112
  function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, position = "right", ...props }) {
11603
13113
  const { open, onOpenChange } = useModalOpenControl();
11604
13114
  const hasOpenControl = open !== void 0 || onOpenChange !== void 0;
@@ -11609,9 +13119,9 @@ function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, p
11609
13119
  position,
11610
13120
  ...props
11611
13121
  });
11612
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
13122
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
11613
13123
  isModalDefaultOpen: open ?? defaultOpen,
11614
- children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ControlledModalOpenScope, {
13124
+ children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.ControlledModalOpenScope, {
11615
13125
  open,
11616
13126
  onOpenChange,
11617
13127
  children: internal
@@ -11619,7 +13129,8 @@ function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, p
11619
13129
  });
11620
13130
  }
11621
13131
  function CopilotSidebarViewInternal({ header, toggleButton, width, position = "right", ...props }) {
11622
- const isSidebarOpen = useCopilotChatConfiguration()?.isModalOpen ?? false;
13132
+ const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
13133
+ const isSidebarOpen = configuration?.isModalOpen ?? false;
11623
13134
  const sidebarRef = (0, react.useRef)(null);
11624
13135
  const [sidebarWidth, setSidebarWidth] = (0, react.useState)(width ?? DEFAULT_SIDEBAR_WIDTH);
11625
13136
  const widthToCss = (w) => {
@@ -11684,7 +13195,7 @@ function CopilotSidebarViewInternal({ header, toggleButton, width, position = "r
11684
13195
  paddingBottom: "env(safe-area-inset-bottom)"
11685
13196
  },
11686
13197
  "aria-hidden": !isSidebarOpen,
11687
- "aria-label": "Copilot chat sidebar",
13198
+ "aria-label": configuration?.labels.sidebarLabel ?? require_MarkdownSurfaces.CopilotChatDefaultLabels.sidebarLabel,
11688
13199
  role: "complementary",
11689
13200
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11690
13201
  className: "cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden",
@@ -11752,9 +13263,9 @@ function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToC
11752
13263
  className,
11753
13264
  ...restProps
11754
13265
  });
11755
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
13266
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
11756
13267
  isModalDefaultOpen: open ?? defaultOpen,
11757
- children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ControlledModalOpenScope, {
13268
+ children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.ControlledModalOpenScope, {
11758
13269
  open,
11759
13270
  onOpenChange,
11760
13271
  children: internal
@@ -11762,10 +13273,10 @@ function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToC
11762
13273
  });
11763
13274
  }
11764
13275
  function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOutsideToClose, className, ...restProps }) {
11765
- const configuration = useCopilotChatConfiguration();
13276
+ const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
11766
13277
  const isPopupOpen = configuration?.isModalOpen ?? false;
11767
13278
  const setModalOpen = configuration?.setModalOpen;
11768
- const labels = configuration?.labels ?? CopilotChatDefaultLabels;
13279
+ const labels = configuration?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
11769
13280
  const containerRef = (0, react.useRef)(null);
11770
13281
  const [isRendered, setIsRendered] = (0, react.useState)(isPopupOpen);
11771
13282
  const [isAnimatingOut, setIsAnimatingOut] = (0, react.useState)(false);
@@ -12068,7 +13579,7 @@ function findChatInput(origin) {
12068
13579
  * ```
12069
13580
  */
12070
13581
  function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, recentLabel, collapsible, onCollapseChange, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
12071
- const configuration = useCopilotChatConfiguration();
13582
+ const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
12072
13583
  const { status, checkFeature } = (0, _copilotkit_react_core_v2_context.useLicenseContext)();
12073
13584
  const licensePresent = status === "valid" || status === "expiring";
12074
13585
  const featureLicensed = checkFeature("threads");
@@ -12327,7 +13838,7 @@ CopilotThreadsDrawer.displayName = "CopilotThreadsDrawer";
12327
13838
  * Catch-all (`"*"`) tool-call renderer that shows CopilotKit's default
12328
13839
  * tool-call card for any tool without a dedicated renderer.
12329
13840
  */
12330
- const WildcardToolCallRender = defineToolCallRenderer({
13841
+ const WildcardToolCallRender = require_MarkdownSurfaces.defineToolCallRenderer({
12331
13842
  name: "*",
12332
13843
  group: true,
12333
13844
  render: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(props) })
@@ -13944,7 +15455,7 @@ const usePredictStateSubscription = (agent) => {
13944
15455
  };
13945
15456
  function CopilotListenersAgentSubscription() {
13946
15457
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
13947
- const configAgentId = useCopilotChatConfiguration()?.agentId;
15458
+ const configAgentId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.agentId;
13948
15459
  const { agent } = useAgent({ agentId: (0, react.useMemo)(() => {
13949
15460
  const requested = configAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
13950
15461
  const registered = copilotkit.agents ?? {};
@@ -14456,7 +15967,7 @@ function CopilotKitInternal(cpkProps) {
14456
15967
  setInternalErrorHandler,
14457
15968
  removeInternalErrorHandler
14458
15969
  ]);
14459
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
15970
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
14460
15971
  agentId: props.agent ?? "default",
14461
15972
  threadId,
14462
15973
  hasExplicitThreadId: isThreadIdExplicit,
@@ -14567,12 +16078,6 @@ Object.defineProperty(exports, 'CopilotChatAudioRecorder', {
14567
16078
  return CopilotChatAudioRecorder;
14568
16079
  }
14569
16080
  });
14570
- Object.defineProperty(exports, 'CopilotChatConfigurationProvider', {
14571
- enumerable: true,
14572
- get: function () {
14573
- return CopilotChatConfigurationProvider;
14574
- }
14575
- });
14576
16081
  Object.defineProperty(exports, 'CopilotChatInput_default', {
14577
16082
  enumerable: true,
14578
16083
  get: function () {
@@ -14813,12 +16318,6 @@ Object.defineProperty(exports, 'WildcardToolCallRender', {
14813
16318
  return WildcardToolCallRender;
14814
16319
  }
14815
16320
  });
14816
- Object.defineProperty(exports, '__toESM', {
14817
- enumerable: true,
14818
- get: function () {
14819
- return __toESM;
14820
- }
14821
- });
14822
16321
  Object.defineProperty(exports, 'createA2UIMessageRenderer', {
14823
16322
  enumerable: true,
14824
16323
  get: function () {
@@ -14831,12 +16330,6 @@ Object.defineProperty(exports, 'defaultCopilotContextCategories', {
14831
16330
  return defaultCopilotContextCategories;
14832
16331
  }
14833
16332
  });
14834
- Object.defineProperty(exports, 'defineToolCallRenderer', {
14835
- enumerable: true,
14836
- get: function () {
14837
- return defineToolCallRenderer;
14838
- }
14839
- });
14840
16333
  Object.defineProperty(exports, 'getIntelligenceTurnAnchors', {
14841
16334
  enumerable: true,
14842
16335
  get: function () {
@@ -14909,12 +16402,6 @@ Object.defineProperty(exports, 'useConfigureSuggestions', {
14909
16402
  return useConfigureSuggestions;
14910
16403
  }
14911
16404
  });
14912
- Object.defineProperty(exports, 'useCopilotChatConfiguration', {
14913
- enumerable: true,
14914
- get: function () {
14915
- return useCopilotChatConfiguration;
14916
- }
14917
- });
14918
16405
  Object.defineProperty(exports, 'useCopilotContext', {
14919
16406
  enumerable: true,
14920
16407
  get: function () {
@@ -15041,4 +16528,4 @@ Object.defineProperty(exports, 'useToast', {
15041
16528
  return useToast;
15042
16529
  }
15043
16530
  });
15044
- //# sourceMappingURL=copilotkit-DKICi3nC.cjs.map
16531
+ //# sourceMappingURL=copilotkit-CVvbU9lV.cjs.map