@copilotkit/react-core 1.80.0 → 1.81.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.
- package/dist/MarkdownSurfaces-D-OkjUpU.cjs +3807 -0
- package/dist/MarkdownSurfaces-D-OkjUpU.cjs.map +1 -0
- package/dist/MarkdownSurfaces-L67964_B.mjs +3522 -0
- package/dist/MarkdownSurfaces-L67964_B.mjs.map +1 -0
- package/dist/{copilotkit-CWOSXhRO.d.mts → copilotkit-BEcaM4L4.d.mts} +25 -34
- package/dist/copilotkit-BEcaM4L4.d.mts.map +1 -0
- package/dist/{copilotkit-DKICi3nC.cjs → copilotkit-BjllYYjw.cjs} +2022 -600
- package/dist/copilotkit-BjllYYjw.cjs.map +1 -0
- package/dist/{copilotkit-Dfw9HzO9.d.cts → copilotkit-D9jIImy9.d.cts} +25 -34
- package/dist/copilotkit-D9jIImy9.d.cts.map +1 -0
- package/dist/{copilotkit-BNLtgOyD.mjs → copilotkit-fKrKqoiP.mjs} +1966 -493
- package/dist/copilotkit-fKrKqoiP.mjs.map +1 -0
- package/dist/index.cjs +8 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +4463 -9
- package/dist/index.umd.js.map +1 -1
- package/dist/runtime-context-CrHq-iTf.d.mts +924 -0
- package/dist/runtime-context-CrHq-iTf.d.mts.map +1 -0
- package/dist/runtime-context-D3NcP9oE.d.cts +924 -0
- package/dist/runtime-context-D3NcP9oE.d.cts.map +1 -0
- package/dist/v2/generative-ui.cjs +8154 -0
- package/dist/v2/generative-ui.cjs.map +1 -0
- package/dist/v2/generative-ui.d.cts +4950 -0
- package/dist/v2/generative-ui.d.cts.map +1 -0
- package/dist/v2/generative-ui.d.mts +4950 -0
- package/dist/v2/generative-ui.d.mts.map +1 -0
- package/dist/v2/generative-ui.mjs +8140 -0
- package/dist/v2/generative-ui.mjs.map +1 -0
- package/dist/v2/index.cjs +65 -4
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +3 -2
- package/dist/v2/index.d.mts +3 -2
- package/dist/v2/index.mjs +3 -2
- package/dist/v2/index.umd.js +4832 -180
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +21 -8
- package/dist/copilotkit-BNLtgOyD.mjs.map +0 -1
- package/dist/copilotkit-CWOSXhRO.d.mts.map +0 -1
- package/dist/copilotkit-DKICi3nC.cjs.map +0 -1
- package/dist/copilotkit-Dfw9HzO9.d.cts.map +0 -1
|
@@ -1,32 +1,6 @@
|
|
|
1
|
-
|
|
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-D-OkjUpU.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
|
|
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;
|
|
@@ -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.
|
|
1328
|
+
var version = "1.81.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;
|
|
@@ -3237,108 +2861,1908 @@ function getOperationSurfaceId(operation) {
|
|
|
3237
2861
|
}
|
|
3238
2862
|
|
|
3239
2863
|
//#endregion
|
|
3240
|
-
//#region src/v2/
|
|
3241
|
-
|
|
3242
|
-
|
|
2864
|
+
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
2865
|
+
/**
|
|
2866
|
+
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
2867
|
+
*/
|
|
2868
|
+
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
2869
|
+
/**
|
|
2870
|
+
* Registers a no-op renderer for the `render_a2ui` tool call so its raw streamed
|
|
2871
|
+
* args are never surfaced in the transcript.
|
|
2872
|
+
*
|
|
2873
|
+
* The generation skeleton / retry / failure UX is NO LONGER owned here (OSS-162):
|
|
2874
|
+
* the A2UI middleware drives the whole lifecycle on the `a2ui-surface` activity
|
|
2875
|
+
* (one stable messageId, building → retrying → failed → painted), rendered in
|
|
2876
|
+
* place by `createA2UIMessageRenderer`. Owning a skeleton per tool call caused a
|
|
2877
|
+
* duplicate skeleton on retries / multi-call generations and a skeleton that
|
|
2878
|
+
* lingered after the surface painted — both fixed by retiring it here.
|
|
2879
|
+
*
|
|
2880
|
+
* Users can still override with their own `useRenderTool({ name: "render_a2ui" })`
|
|
2881
|
+
* (hook-based entries take priority over this prop-based registration).
|
|
2882
|
+
*/
|
|
2883
|
+
function A2UIBuiltInToolCallRenderer() {
|
|
2884
|
+
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
2885
|
+
(0, react.useEffect)(() => {
|
|
2886
|
+
const renderer = require_MarkdownSurfaces.defineToolCallRenderer({
|
|
2887
|
+
name: RENDER_A2UI_TOOL_NAME,
|
|
2888
|
+
args: zod.z.any(),
|
|
2889
|
+
render: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {})
|
|
2890
|
+
});
|
|
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), [catalog]);
|
|
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
|
+
};
|
|
3243
4286
|
return {
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
...def.agentId ? { agentId: def.agentId } : {},
|
|
3248
|
-
...def.group ? { group: true } : {}
|
|
4287
|
+
transport: "tool",
|
|
4288
|
+
includeCatalog: true,
|
|
4289
|
+
contextSent: false
|
|
3249
4290
|
};
|
|
3250
4291
|
}
|
|
3251
|
-
|
|
3252
|
-
//#endregion
|
|
3253
|
-
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
3254
|
-
/**
|
|
3255
|
-
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
3256
|
-
*/
|
|
3257
|
-
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
3258
4292
|
/**
|
|
3259
|
-
*
|
|
3260
|
-
*
|
|
3261
|
-
*
|
|
3262
|
-
* The generation skeleton / retry / failure UX is NO LONGER owned here (OSS-162):
|
|
3263
|
-
* the A2UI middleware drives the whole lifecycle on the `a2ui-surface` activity
|
|
3264
|
-
* (one stable messageId, building → retrying → failed → painted), rendered in
|
|
3265
|
-
* place by `createA2UIMessageRenderer`. Owning a skeleton per tool call caused a
|
|
3266
|
-
* duplicate skeleton on retries / multi-call generations and a skeleton that
|
|
3267
|
-
* lingered after the surface painted — both fixed by retiring it here.
|
|
3268
|
-
*
|
|
3269
|
-
* Users can still override with their own `useRenderTool({ name: "render_a2ui" })`
|
|
3270
|
-
* (hook-based entries take priority over this prop-based registration).
|
|
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.
|
|
3271
4295
|
*/
|
|
3272
|
-
function
|
|
3273
|
-
const
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
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
|
+
}
|
|
3279
4353
|
});
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
}, [copilotkit]);
|
|
3283
|
-
return null;
|
|
4354
|
+
}
|
|
4355
|
+
return requests;
|
|
3284
4356
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
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;
|
|
4369
|
+
}
|
|
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
|
-
*
|
|
3290
|
-
*
|
|
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
|
-
*
|
|
3297
|
-
*
|
|
3298
|
-
*
|
|
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
|
|
3301
|
-
const { copilotkit } =
|
|
3302
|
-
const
|
|
3303
|
-
const
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
a2uiAgentsKey
|
|
4680
|
+
core,
|
|
4681
|
+
transport,
|
|
4682
|
+
theme
|
|
3340
4683
|
]);
|
|
3341
|
-
|
|
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) => {
|
|
@@ -5125,7 +6557,7 @@ function useAgent({ agentId, threadId, runtimeAgentId, updates, throttleMs } = {
|
|
|
5125
6557
|
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
6558
|
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
6559
|
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();
|
|
6560
|
+
const chatConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
5129
6561
|
const providerAgentId = (0, _copilotkit_react_core_v2_context.useDefaultAgentId)();
|
|
5130
6562
|
const resolvedAgentId = agentId ?? chatConfig?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
5131
6563
|
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
@@ -5355,7 +6787,7 @@ function useAgentContext(context) {
|
|
|
5355
6787
|
//#region src/v2/hooks/use-suggestions.tsx
|
|
5356
6788
|
function useSuggestions({ agentId } = {}) {
|
|
5357
6789
|
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
5358
|
-
const config = useCopilotChatConfiguration();
|
|
6790
|
+
const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
5359
6791
|
const providerAgentId = (0, _copilotkit_react_core_v2_context.useDefaultAgentId)();
|
|
5360
6792
|
const resolvedAgentId = (0, react.useMemo)(() => agentId ?? config?.agentId ?? providerAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [
|
|
5361
6793
|
agentId,
|
|
@@ -5413,7 +6845,7 @@ function useSuggestions({ agentId } = {}) {
|
|
|
5413
6845
|
//#region src/v2/hooks/use-configure-suggestions.tsx
|
|
5414
6846
|
function useConfigureSuggestions(config, deps) {
|
|
5415
6847
|
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
5416
|
-
const chatConfig = useCopilotChatConfiguration();
|
|
6848
|
+
const chatConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
5417
6849
|
const extraDeps = deps ?? [];
|
|
5418
6850
|
const resolvedConsumerAgentId = (0, react.useMemo)(() => chatConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID, [chatConfig?.agentId]);
|
|
5419
6851
|
const rawConsumerAgentId = (0, react.useMemo)(() => config ? config.consumerAgentId : void 0, [config]);
|
|
@@ -6252,7 +7684,7 @@ function useLearnFromUserAction() {
|
|
|
6252
7684
|
* ```
|
|
6253
7685
|
*/
|
|
6254
7686
|
function useLearnFromUserActionInCurrentThread() {
|
|
6255
|
-
const config = useCopilotChatConfiguration();
|
|
7687
|
+
const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
6256
7688
|
const learnFromUserAction = useLearnFromUserAction();
|
|
6257
7689
|
return (0, react.useCallback)(async (input) => {
|
|
6258
7690
|
const threadId = config?.threadId;
|
|
@@ -6622,7 +8054,7 @@ function useLearningContainers({ threadId, learningContainers }) {
|
|
|
6622
8054
|
* Intelligence runtimes.
|
|
6623
8055
|
*/
|
|
6624
8056
|
function useLearningContainersInCurrentThread({ learningContainers }) {
|
|
6625
|
-
const threadId = useCopilotChatConfiguration()?.threadId;
|
|
8057
|
+
const threadId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.threadId;
|
|
6626
8058
|
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
8059
|
useLearningContainers({
|
|
6628
8060
|
threadId,
|
|
@@ -6974,7 +8406,7 @@ function InspectorKiteIcon({ className, ...props }) {
|
|
|
6974
8406
|
});
|
|
6975
8407
|
}
|
|
6976
8408
|
function CopilotChatInspectorButton({ title, className, onClick, onPointerDown, onPointerEnter, onPointerLeave, onKeyDown, disabled, ...props }) {
|
|
6977
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
8409
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
6978
8410
|
const { isInspectorEnabled } = useCopilotKitInspector();
|
|
6979
8411
|
const hidden = useInspectorShortcutsHidden();
|
|
6980
8412
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -7445,7 +8877,7 @@ function WorkText({ messageId, children }) {
|
|
|
7445
8877
|
* assistant message subscribe to chat configuration changes.
|
|
7446
8878
|
*/
|
|
7447
8879
|
function BoundInspectorButton({ inspectorButton, messageId, openInspector, ...props }) {
|
|
7448
|
-
const chatConfiguration = useCopilotChatConfiguration();
|
|
8880
|
+
const chatConfiguration = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
7449
8881
|
return renderSlot(inspectorButton, CopilotChatAssistantMessage.InspectorButton, {
|
|
7450
8882
|
...props,
|
|
7451
8883
|
onClick: () => openInspector({
|
|
@@ -7490,7 +8922,7 @@ function nextFocusable(element, skip) {
|
|
|
7490
8922
|
* control after the thumb, and Enter or Escape inside it returns to the thumb.
|
|
7491
8923
|
*/
|
|
7492
8924
|
function FeedbackCommentPopover({ feedbackComment, comment, savedComment, rating, anchor, messageId }) {
|
|
7493
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
8925
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7494
8926
|
const contentRef = (0, react.useRef)(null);
|
|
7495
8927
|
const focusInside = () => contentRef.current?.contains(document.activeElement) ?? false;
|
|
7496
8928
|
const { focusRequest, takeFocusRequest, inputRef } = comment;
|
|
@@ -7560,7 +8992,7 @@ function FeedbackCommentPopover({ feedbackComment, comment, savedComment, rating
|
|
|
7560
8992
|
});
|
|
7561
8993
|
}
|
|
7562
8994
|
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();
|
|
8995
|
+
require_MarkdownSurfaces.useKatexStyles();
|
|
7564
8996
|
const { isInspectorEnabled, openInspector } = useCopilotKitInspector();
|
|
7565
8997
|
const shortcutsHidden = useInspectorShortcutsHidden();
|
|
7566
8998
|
const showInspectorShortcut = isInspectorEnabled && !shortcutsHidden;
|
|
@@ -7635,7 +9067,10 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7635
9067
|
}
|
|
7636
9068
|
};
|
|
7637
9069
|
};
|
|
7638
|
-
const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, {
|
|
9070
|
+
const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, {
|
|
9071
|
+
content: message.content || "",
|
|
9072
|
+
messageId: message.id
|
|
9073
|
+
});
|
|
7639
9074
|
const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
|
|
7640
9075
|
if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
|
|
7641
9076
|
return false;
|
|
@@ -7745,11 +9180,19 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7745
9180
|
});
|
|
7746
9181
|
}
|
|
7747
9182
|
(function(_CopilotChatAssistantMessage) {
|
|
7748
|
-
_CopilotChatAssistantMessage.MarkdownRenderer = ({ content, className, ...props }) =>
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
9183
|
+
_CopilotChatAssistantMessage.MarkdownRenderer = ({ content, className, messageId, ...props }) => {
|
|
9184
|
+
if (require_MarkdownSurfaces.useGenerativeUIRuntime()?.transport === "markdown" && messageId !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.MarkdownSurfaces, {
|
|
9185
|
+
content: content ?? "",
|
|
9186
|
+
messageId,
|
|
9187
|
+
className,
|
|
9188
|
+
...props
|
|
9189
|
+
});
|
|
9190
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(streamdown.Streamdown, {
|
|
9191
|
+
className,
|
|
9192
|
+
...props,
|
|
9193
|
+
children: content ?? ""
|
|
9194
|
+
});
|
|
9195
|
+
};
|
|
7753
9196
|
_CopilotChatAssistantMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7754
9197
|
"data-testid": "copilot-assistant-toolbar",
|
|
7755
9198
|
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 +9222,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7779
9222
|
});
|
|
7780
9223
|
};
|
|
7781
9224
|
_CopilotChatAssistantMessage.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
7782
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9225
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7783
9226
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
7784
9227
|
const timerRef = (0, react.useRef)(null);
|
|
7785
9228
|
(0, react.useEffect)(() => {
|
|
@@ -7810,7 +9253,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7810
9253
|
};
|
|
7811
9254
|
_CopilotChatAssistantMessage.InspectorButton = CopilotChatInspectorButton;
|
|
7812
9255
|
_CopilotChatAssistantMessage.ThumbsUpButton = ({ title, ...props }) => {
|
|
7813
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9256
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7814
9257
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
7815
9258
|
"data-testid": "copilot-thumbs-up-button",
|
|
7816
9259
|
title: title || labels.assistantMessageToolbarThumbsUpLabel,
|
|
@@ -7822,7 +9265,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7822
9265
|
});
|
|
7823
9266
|
};
|
|
7824
9267
|
_CopilotChatAssistantMessage.ThumbsDownButton = ({ title, ...props }) => {
|
|
7825
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9268
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7826
9269
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
7827
9270
|
"data-testid": "copilot-thumbs-down-button",
|
|
7828
9271
|
title: title || labels.assistantMessageToolbarThumbsDownLabel,
|
|
@@ -7834,7 +9277,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7834
9277
|
});
|
|
7835
9278
|
};
|
|
7836
9279
|
_CopilotChatAssistantMessage.FeedbackComment = ({ value, savedComment, inputRef, onChange, onSubmit, onEditingChange, onLeave, className }) => {
|
|
7837
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9280
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7838
9281
|
const changed = value.trim() !== savedComment;
|
|
7839
9282
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
7840
9283
|
"data-testid": "copilot-feedback-comment",
|
|
@@ -7869,7 +9312,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7869
9312
|
});
|
|
7870
9313
|
};
|
|
7871
9314
|
_CopilotChatAssistantMessage.ReadAloudButton = ({ title, ...props }) => {
|
|
7872
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9315
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7873
9316
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
7874
9317
|
"data-testid": "copilot-read-aloud-button",
|
|
7875
9318
|
title: title || labels.assistantMessageToolbarReadAloudLabel,
|
|
@@ -7878,7 +9321,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, o
|
|
|
7878
9321
|
});
|
|
7879
9322
|
};
|
|
7880
9323
|
_CopilotChatAssistantMessage.RegenerateButton = ({ title, ...props }) => {
|
|
7881
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9324
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
7882
9325
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
7883
9326
|
"data-testid": "copilot-regenerate-button",
|
|
7884
9327
|
title: title || labels.assistantMessageToolbarRegenerateLabel,
|
|
@@ -8169,7 +9612,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
|
|
|
8169
9612
|
})] });
|
|
8170
9613
|
};
|
|
8171
9614
|
_CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
8172
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9615
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
8173
9616
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
8174
9617
|
const handleClick = async (event) => {
|
|
8175
9618
|
let success = false;
|
|
@@ -8189,7 +9632,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
|
|
|
8189
9632
|
});
|
|
8190
9633
|
};
|
|
8191
9634
|
_CopilotChatUserMessage.EditButton = ({ className, title, ...props }) => {
|
|
8192
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9635
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
8193
9636
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
8194
9637
|
"data-testid": "copilot-edit-button",
|
|
8195
9638
|
title: title || labels.userMessageToolbarEditMessageLabel,
|
|
@@ -8199,7 +9642,7 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
|
|
|
8199
9642
|
});
|
|
8200
9643
|
};
|
|
8201
9644
|
_CopilotChatUserMessage.BranchNavigation = ({ className, currentBranch = 0, numberOfBranches = 1, onSwitchToBranch, message, ...props }) => {
|
|
8202
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
9645
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
8203
9646
|
if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) return null;
|
|
8204
9647
|
const canGoPrev = currentBranch > 0;
|
|
8205
9648
|
const canGoNext = currentBranch < numberOfBranches - 1;
|
|
@@ -8820,7 +10263,7 @@ const isToolCallLikeMessage = (m) => {
|
|
|
8820
10263
|
function IntelligenceIndicator(props) {
|
|
8821
10264
|
const { message, agentId, label = "CopilotKit Intelligence", intelligenceIndicator } = props;
|
|
8822
10265
|
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
8823
|
-
const config = useCopilotChatConfiguration();
|
|
10266
|
+
const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
8824
10267
|
const { agent } = useAgent({
|
|
8825
10268
|
agentId,
|
|
8826
10269
|
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
@@ -9076,7 +10519,7 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
9076
10519
|
const renderCustomMessage = useRenderCustomMessages();
|
|
9077
10520
|
const { renderActivityMessage } = useRenderActivityMessage();
|
|
9078
10521
|
const { copilotkit, showIntelligenceIndicator = true } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
9079
|
-
const config = useCopilotChatConfiguration();
|
|
10522
|
+
const config = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
9080
10523
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
9081
10524
|
(0, react.useEffect)(() => {
|
|
9082
10525
|
if (!config?.agentId) return;
|
|
@@ -9983,7 +11426,7 @@ function DropOverlay() {
|
|
|
9983
11426
|
});
|
|
9984
11427
|
}
|
|
9985
11428
|
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;
|
|
11429
|
+
const configuredThreadId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.threadId;
|
|
9987
11430
|
const [fallbackThreadId, setFallbackThreadId] = (0, react.useState)(messages[0]?.id);
|
|
9988
11431
|
const previousMessageIds = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
9989
11432
|
(0, react.useEffect)(() => {
|
|
@@ -10419,7 +11862,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
10419
11862
|
});
|
|
10420
11863
|
};
|
|
10421
11864
|
_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => {
|
|
10422
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
11865
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
10423
11866
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
10424
11867
|
"data-testid": "copilot-scroll-to-bottom",
|
|
10425
11868
|
variant: "outline",
|
|
@@ -10435,7 +11878,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
10435
11878
|
...props
|
|
10436
11879
|
});
|
|
10437
11880
|
_CopilotChatView.WelcomeMessage = ({ className, ...props }) => {
|
|
10438
|
-
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
11881
|
+
const labels = require_MarkdownSurfaces.useCopilotChatConfiguration()?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
10439
11882
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
|
|
10440
11883
|
className: cn("cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center", className),
|
|
10441
11884
|
...props,
|
|
@@ -10685,8 +12128,8 @@ function useInspectorThreadOverride(args) {
|
|
|
10685
12128
|
|
|
10686
12129
|
//#endregion
|
|
10687
12130
|
//#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();
|
|
12131
|
+
function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isModalDefaultOpen, attachments: attachmentsConfig, onError, throttleMs, generativeUISurface, ...props }) {
|
|
12132
|
+
const existingConfig = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
10690
12133
|
const inspector = useCopilotKitInspector();
|
|
10691
12134
|
const inspectorContextValue = (0, react.useMemo)(() => ({
|
|
10692
12135
|
...inspector,
|
|
@@ -11264,8 +12707,8 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
|
|
|
11264
12707
|
return () => clearTimeout(timer);
|
|
11265
12708
|
}
|
|
11266
12709
|
}, [transcriptionError]);
|
|
11267
|
-
const stableMessageView = useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
|
|
11268
|
-
const stableSuggestionView = useShallowStableRef(providedSuggestionView);
|
|
12710
|
+
const stableMessageView = require_MarkdownSurfaces.useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
|
|
12711
|
+
const stableSuggestionView = require_MarkdownSurfaces.useShallowStableRef(providedSuggestionView);
|
|
11269
12712
|
const handleAddFile = (0, react.useCallback)(() => {
|
|
11270
12713
|
setTimeout(() => {
|
|
11271
12714
|
fileInputRef.current?.click();
|
|
@@ -11326,7 +12769,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
|
|
|
11326
12769
|
isConnecting,
|
|
11327
12770
|
hasExplicitThreadId
|
|
11328
12771
|
});
|
|
11329
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
12772
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
|
|
11330
12773
|
agentId: resolvedAgentId,
|
|
11331
12774
|
threadId: resolvedThreadId,
|
|
11332
12775
|
hasExplicitThreadId,
|
|
@@ -11364,7 +12807,10 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
|
|
|
11364
12807
|
value: lastUserMessageState,
|
|
11365
12808
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspectorContextProvider, {
|
|
11366
12809
|
value: inspectorContextValue,
|
|
11367
|
-
children:
|
|
12810
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.GenerativeUIChatSlotContext.Provider, {
|
|
12811
|
+
value: generativeUISurface,
|
|
12812
|
+
children: RenderedChatView
|
|
12813
|
+
})
|
|
11368
12814
|
})
|
|
11369
12815
|
})
|
|
11370
12816
|
]
|
|
@@ -11395,8 +12841,8 @@ const ICON_WRAPPER_BASE = "cpk:pointer-events-none cpk:absolute cpk:inset-0 cpk:
|
|
|
11395
12841
|
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
12842
|
const CopilotChatToggleButton = react.default.forwardRef(function CopilotChatToggleButton({ openIcon, closeIcon, className, ...buttonProps }, ref) {
|
|
11397
12843
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
11398
|
-
const configuration = useCopilotChatConfiguration();
|
|
11399
|
-
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
12844
|
+
const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
12845
|
+
const labels = configuration?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
11400
12846
|
const [fallbackOpen, setFallbackOpen] = (0, react.useState)(false);
|
|
11401
12847
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
11402
12848
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
@@ -11512,8 +12958,8 @@ function useIsMobileViewport() {
|
|
|
11512
12958
|
return isMobile;
|
|
11513
12959
|
}
|
|
11514
12960
|
function CopilotModalHeader({ title, titleContent, closeButton, drawerLauncher, children, className, ...rest }) {
|
|
11515
|
-
const configuration = useCopilotChatConfiguration();
|
|
11516
|
-
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
12961
|
+
const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
12962
|
+
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? require_MarkdownSurfaces.CopilotChatDefaultLabels.modalHeaderTitle;
|
|
11517
12963
|
const resolvedTitle = title ?? fallbackTitle;
|
|
11518
12964
|
const isMobile = useIsMobileViewport();
|
|
11519
12965
|
const drawerRegistered = (configuration?.drawerRegistered ?? false) && isMobile;
|
|
@@ -11609,9 +13055,9 @@ function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, p
|
|
|
11609
13055
|
position,
|
|
11610
13056
|
...props
|
|
11611
13057
|
});
|
|
11612
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
13058
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
|
|
11613
13059
|
isModalDefaultOpen: open ?? defaultOpen,
|
|
11614
|
-
children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ControlledModalOpenScope, {
|
|
13060
|
+
children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.ControlledModalOpenScope, {
|
|
11615
13061
|
open,
|
|
11616
13062
|
onOpenChange,
|
|
11617
13063
|
children: internal
|
|
@@ -11619,7 +13065,7 @@ function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, p
|
|
|
11619
13065
|
});
|
|
11620
13066
|
}
|
|
11621
13067
|
function CopilotSidebarViewInternal({ header, toggleButton, width, position = "right", ...props }) {
|
|
11622
|
-
const isSidebarOpen = useCopilotChatConfiguration()?.isModalOpen ?? false;
|
|
13068
|
+
const isSidebarOpen = require_MarkdownSurfaces.useCopilotChatConfiguration()?.isModalOpen ?? false;
|
|
11623
13069
|
const sidebarRef = (0, react.useRef)(null);
|
|
11624
13070
|
const [sidebarWidth, setSidebarWidth] = (0, react.useState)(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
11625
13071
|
const widthToCss = (w) => {
|
|
@@ -11752,9 +13198,9 @@ function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToC
|
|
|
11752
13198
|
className,
|
|
11753
13199
|
...restProps
|
|
11754
13200
|
});
|
|
11755
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
13201
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
|
|
11756
13202
|
isModalDefaultOpen: open ?? defaultOpen,
|
|
11757
|
-
children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ControlledModalOpenScope, {
|
|
13203
|
+
children: hasOpenControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.ControlledModalOpenScope, {
|
|
11758
13204
|
open,
|
|
11759
13205
|
onOpenChange,
|
|
11760
13206
|
children: internal
|
|
@@ -11762,10 +13208,10 @@ function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToC
|
|
|
11762
13208
|
});
|
|
11763
13209
|
}
|
|
11764
13210
|
function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOutsideToClose, className, ...restProps }) {
|
|
11765
|
-
const configuration = useCopilotChatConfiguration();
|
|
13211
|
+
const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
11766
13212
|
const isPopupOpen = configuration?.isModalOpen ?? false;
|
|
11767
13213
|
const setModalOpen = configuration?.setModalOpen;
|
|
11768
|
-
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
13214
|
+
const labels = configuration?.labels ?? require_MarkdownSurfaces.CopilotChatDefaultLabels;
|
|
11769
13215
|
const containerRef = (0, react.useRef)(null);
|
|
11770
13216
|
const [isRendered, setIsRendered] = (0, react.useState)(isPopupOpen);
|
|
11771
13217
|
const [isAnimatingOut, setIsAnimatingOut] = (0, react.useState)(false);
|
|
@@ -12068,7 +13514,7 @@ function findChatInput(origin) {
|
|
|
12068
13514
|
* ```
|
|
12069
13515
|
*/
|
|
12070
13516
|
function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, recentLabel, collapsible, onCollapseChange, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
|
|
12071
|
-
const configuration = useCopilotChatConfiguration();
|
|
13517
|
+
const configuration = require_MarkdownSurfaces.useCopilotChatConfiguration();
|
|
12072
13518
|
const { status, checkFeature } = (0, _copilotkit_react_core_v2_context.useLicenseContext)();
|
|
12073
13519
|
const licensePresent = status === "valid" || status === "expiring";
|
|
12074
13520
|
const featureLicensed = checkFeature("threads");
|
|
@@ -12327,7 +13773,7 @@ CopilotThreadsDrawer.displayName = "CopilotThreadsDrawer";
|
|
|
12327
13773
|
* Catch-all (`"*"`) tool-call renderer that shows CopilotKit's default
|
|
12328
13774
|
* tool-call card for any tool without a dedicated renderer.
|
|
12329
13775
|
*/
|
|
12330
|
-
const WildcardToolCallRender = defineToolCallRenderer({
|
|
13776
|
+
const WildcardToolCallRender = require_MarkdownSurfaces.defineToolCallRenderer({
|
|
12331
13777
|
name: "*",
|
|
12332
13778
|
group: true,
|
|
12333
13779
|
render: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(props) })
|
|
@@ -13944,7 +15390,7 @@ const usePredictStateSubscription = (agent) => {
|
|
|
13944
15390
|
};
|
|
13945
15391
|
function CopilotListenersAgentSubscription() {
|
|
13946
15392
|
const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
13947
|
-
const configAgentId = useCopilotChatConfiguration()?.agentId;
|
|
15393
|
+
const configAgentId = require_MarkdownSurfaces.useCopilotChatConfiguration()?.agentId;
|
|
13948
15394
|
const { agent } = useAgent({ agentId: (0, react.useMemo)(() => {
|
|
13949
15395
|
const requested = configAgentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
13950
15396
|
const registered = copilotkit.agents ?? {};
|
|
@@ -14456,7 +15902,7 @@ function CopilotKitInternal(cpkProps) {
|
|
|
14456
15902
|
setInternalErrorHandler,
|
|
14457
15903
|
removeInternalErrorHandler
|
|
14458
15904
|
]);
|
|
14459
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
15905
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MarkdownSurfaces.CopilotChatConfigurationProvider, {
|
|
14460
15906
|
agentId: props.agent ?? "default",
|
|
14461
15907
|
threadId,
|
|
14462
15908
|
hasExplicitThreadId: isThreadIdExplicit,
|
|
@@ -14567,12 +16013,6 @@ Object.defineProperty(exports, 'CopilotChatAudioRecorder', {
|
|
|
14567
16013
|
return CopilotChatAudioRecorder;
|
|
14568
16014
|
}
|
|
14569
16015
|
});
|
|
14570
|
-
Object.defineProperty(exports, 'CopilotChatConfigurationProvider', {
|
|
14571
|
-
enumerable: true,
|
|
14572
|
-
get: function () {
|
|
14573
|
-
return CopilotChatConfigurationProvider;
|
|
14574
|
-
}
|
|
14575
|
-
});
|
|
14576
16016
|
Object.defineProperty(exports, 'CopilotChatInput_default', {
|
|
14577
16017
|
enumerable: true,
|
|
14578
16018
|
get: function () {
|
|
@@ -14813,12 +16253,6 @@ Object.defineProperty(exports, 'WildcardToolCallRender', {
|
|
|
14813
16253
|
return WildcardToolCallRender;
|
|
14814
16254
|
}
|
|
14815
16255
|
});
|
|
14816
|
-
Object.defineProperty(exports, '__toESM', {
|
|
14817
|
-
enumerable: true,
|
|
14818
|
-
get: function () {
|
|
14819
|
-
return __toESM;
|
|
14820
|
-
}
|
|
14821
|
-
});
|
|
14822
16256
|
Object.defineProperty(exports, 'createA2UIMessageRenderer', {
|
|
14823
16257
|
enumerable: true,
|
|
14824
16258
|
get: function () {
|
|
@@ -14831,12 +16265,6 @@ Object.defineProperty(exports, 'defaultCopilotContextCategories', {
|
|
|
14831
16265
|
return defaultCopilotContextCategories;
|
|
14832
16266
|
}
|
|
14833
16267
|
});
|
|
14834
|
-
Object.defineProperty(exports, 'defineToolCallRenderer', {
|
|
14835
|
-
enumerable: true,
|
|
14836
|
-
get: function () {
|
|
14837
|
-
return defineToolCallRenderer;
|
|
14838
|
-
}
|
|
14839
|
-
});
|
|
14840
16268
|
Object.defineProperty(exports, 'getIntelligenceTurnAnchors', {
|
|
14841
16269
|
enumerable: true,
|
|
14842
16270
|
get: function () {
|
|
@@ -14909,12 +16337,6 @@ Object.defineProperty(exports, 'useConfigureSuggestions', {
|
|
|
14909
16337
|
return useConfigureSuggestions;
|
|
14910
16338
|
}
|
|
14911
16339
|
});
|
|
14912
|
-
Object.defineProperty(exports, 'useCopilotChatConfiguration', {
|
|
14913
|
-
enumerable: true,
|
|
14914
|
-
get: function () {
|
|
14915
|
-
return useCopilotChatConfiguration;
|
|
14916
|
-
}
|
|
14917
|
-
});
|
|
14918
16340
|
Object.defineProperty(exports, 'useCopilotContext', {
|
|
14919
16341
|
enumerable: true,
|
|
14920
16342
|
get: function () {
|
|
@@ -15041,4 +16463,4 @@ Object.defineProperty(exports, 'useToast', {
|
|
|
15041
16463
|
return useToast;
|
|
15042
16464
|
}
|
|
15043
16465
|
});
|
|
15044
|
-
//# sourceMappingURL=copilotkit-
|
|
16466
|
+
//# sourceMappingURL=copilotkit-BjllYYjw.cjs.map
|