@copilotkit/react-core 1.61.2 → 1.62.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/{copilotkit-Be-o2UaU.mjs → copilotkit-BtRkFsNR.mjs} +941 -404
- package/dist/copilotkit-BtRkFsNR.mjs.map +1 -0
- package/dist/{copilotkit-CTCjVxkH.cjs → copilotkit-CdpDZi3i.cjs} +943 -400
- package/dist/copilotkit-CdpDZi3i.cjs.map +1 -0
- package/dist/{copilotkit-ClqbUuGX.d.cts → copilotkit-Cga6AHO0.d.cts} +429 -149
- package/dist/copilotkit-Cga6AHO0.d.cts.map +1 -0
- package/dist/{copilotkit-Bpt1c_-q.d.mts → copilotkit-DnLpJ2Cl.d.mts} +429 -149
- package/dist/copilotkit-DnLpJ2Cl.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +193 -176
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +156 -11
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.d.cts +111 -1
- package/dist/v2/headless.d.cts.map +1 -1
- package/dist/v2/headless.d.mts +111 -1
- package/dist/v2/headless.d.mts.map +1 -1
- package/dist/v2/headless.mjs +157 -12
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +2 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/index.umd.js +949 -412
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +8 -6
- package/dist/copilotkit-Be-o2UaU.mjs.map +0 -1
- package/dist/copilotkit-Bpt1c_-q.d.mts.map +0 -1
- package/dist/copilotkit-CTCjVxkH.cjs.map +0 -1
- package/dist/copilotkit-ClqbUuGX.d.cts.map +0 -1
package/dist/v2/index.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
(function(global, factory) {
|
|
4
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./index.css'), require('@copilotkit/core'), require('@ag-ui/client'), require('react'), require('tailwind-merge'), require('lucide-react'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('@radix-ui/react-slot'), require('class-variance-authority'), require('clsx'), require('@radix-ui/react-tooltip'), require('@radix-ui/react-dropdown-menu'), require('streamdown'), require('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('@tanstack/react-virtual'), require('use-stick-to-bottom')) :
|
|
5
|
-
typeof define === 'function' && define.amd ? define(['exports', './index.css', '@copilotkit/core', '@ag-ui/client', 'react', 'tailwind-merge', 'lucide-react', '@copilotkit/shared', 'react/jsx-runtime', '@radix-ui/react-slot', 'class-variance-authority', 'clsx', '@radix-ui/react-tooltip', '@radix-ui/react-dropdown-menu', 'streamdown', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', '@tanstack/react-virtual', 'use-stick-to-bottom'], factory) :
|
|
6
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCoreV2 = {}), global.src_v2_index_css,global.CopilotKitCore,global.AgUIClient,global.React,global.tailwindMerge,global.lucideReact,global.CopilotKitShared,global.ReactJsxRuntime,global.RadixReactSlot,global.classVarianceAuthority,global.clsx,global.RadixReactTooltip,global.RadixReactDropdownMenu,global.streamdown,global.Zod,global.LitLabsReact,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global._tanstack_react_virtual,global.useStickToBottom));
|
|
7
|
-
})(this, function(exports, src_v2_index_css, _copilotkit_core, _ag_ui_client, react, tailwind_merge, lucide_react, _copilotkit_shared, react_jsx_runtime, _radix_ui_react_slot, class_variance_authority, clsx, _radix_ui_react_tooltip, _radix_ui_react_dropdown_menu, streamdown, zod, _lit_labs_react, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, _tanstack_react_virtual, use_stick_to_bottom) {
|
|
4
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./index.css'), require('@copilotkit/core'), require('@ag-ui/client'), require('react'), require('tailwind-merge'), require('lucide-react'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('@radix-ui/react-slot'), require('class-variance-authority'), require('clsx'), require('@radix-ui/react-tooltip'), require('@radix-ui/react-dropdown-menu'), require('streamdown'), require('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('@tanstack/react-virtual'), require('use-stick-to-bottom'), require('@copilotkit/web-components/threads-drawer')) :
|
|
5
|
+
typeof define === 'function' && define.amd ? define(['exports', './index.css', '@copilotkit/core', '@ag-ui/client', 'react', 'tailwind-merge', 'lucide-react', '@copilotkit/shared', 'react/jsx-runtime', '@radix-ui/react-slot', 'class-variance-authority', 'clsx', '@radix-ui/react-tooltip', '@radix-ui/react-dropdown-menu', 'streamdown', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', '@tanstack/react-virtual', 'use-stick-to-bottom', '@copilotkit/web-components/threads-drawer'], factory) :
|
|
6
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCoreV2 = {}), global.src_v2_index_css,global.CopilotKitCore,global.AgUIClient,global.React,global.tailwindMerge,global.lucideReact,global.CopilotKitShared,global.ReactJsxRuntime,global.RadixReactSlot,global.classVarianceAuthority,global.clsx,global.RadixReactTooltip,global.RadixReactDropdownMenu,global.streamdown,global.Zod,global.LitLabsReact,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global._tanstack_react_virtual,global.useStickToBottom,global._copilotkit_web_components_threads_drawer));
|
|
7
|
+
})(this, function(exports, src_v2_index_css, _copilotkit_core, _ag_ui_client, react, tailwind_merge, lucide_react, _copilotkit_shared, react_jsx_runtime, _radix_ui_react_slot, class_variance_authority, clsx, _radix_ui_react_tooltip, _radix_ui_react_dropdown_menu, streamdown, zod, _lit_labs_react, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, _tanstack_react_virtual, use_stick_to_bottom, _copilotkit_web_components_threads_drawer) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -160,6 +160,25 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
160
160
|
modalHeaderTitle: "CopilotKit Chat",
|
|
161
161
|
welcomeMessageText: "How can I help you today?"
|
|
162
162
|
};
|
|
163
|
+
/**
|
|
164
|
+
* Mobile breakpoint below which the chat modal and the thread-list drawer are
|
|
165
|
+
* mutually exclusive. At or above this width both surfaces may coexist. This
|
|
166
|
+
* mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by
|
|
167
|
+
* CopilotChatInput and CopilotSidebarView.
|
|
168
|
+
*/
|
|
169
|
+
const MOBILE_MAX_WIDTH_PX = 767;
|
|
170
|
+
/**
|
|
171
|
+
* Reports whether the current viewport is in the mobile range (`<768px`), where
|
|
172
|
+
* the chat modal and drawer must not be open simultaneously. SSR-safe and
|
|
173
|
+
* defensive against environments without `matchMedia` (treated as desktop, so
|
|
174
|
+
* no mutual-exclusion constraint is applied).
|
|
175
|
+
*
|
|
176
|
+
* @returns `true` when the viewport is mobile-width, `false` otherwise.
|
|
177
|
+
*/
|
|
178
|
+
function isMobileViewport() {
|
|
179
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
180
|
+
return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;
|
|
181
|
+
}
|
|
163
182
|
const CopilotChatConfiguration = (0, react.createContext)(null);
|
|
164
183
|
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
|
|
165
184
|
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
@@ -170,12 +189,22 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
170
189
|
...stableLabels
|
|
171
190
|
}), [stableLabels, parentConfig?.labels]);
|
|
172
191
|
const resolvedAgentId = agentId ?? parentConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
192
|
+
const threadIdPropIsAuthoritative = threadId !== void 0 && hasExplicitThreadId !== false;
|
|
193
|
+
const isThreadIdControlled = threadIdPropIsAuthoritative;
|
|
194
|
+
const [activeThreadOverride, setActiveThreadOverride] = (0, react.useState)(null);
|
|
173
195
|
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
174
|
-
if (
|
|
196
|
+
if (threadIdPropIsAuthoritative) return threadId;
|
|
197
|
+
if (activeThreadOverride) return activeThreadOverride.threadId;
|
|
175
198
|
if (parentConfig?.threadId) return parentConfig.threadId;
|
|
199
|
+
if (threadId) return threadId;
|
|
176
200
|
return (0, _copilotkit_shared.randomUUID)();
|
|
177
|
-
}, [
|
|
178
|
-
|
|
201
|
+
}, [
|
|
202
|
+
threadIdPropIsAuthoritative,
|
|
203
|
+
threadId,
|
|
204
|
+
parentConfig?.threadId,
|
|
205
|
+
activeThreadOverride
|
|
206
|
+
]);
|
|
207
|
+
const resolvedHasExplicitThreadId = (threadIdPropIsAuthoritative ? true : activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false) || !!parentConfig?.hasExplicitThreadId;
|
|
179
208
|
const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen ?? true);
|
|
180
209
|
const hasExplicitDefault = isModalDefaultOpen !== void 0;
|
|
181
210
|
const setAndSync = (0, react.useCallback)((open) => {
|
|
@@ -194,20 +223,113 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
194
223
|
}, [parentConfig?.isModalOpen, hasExplicitDefault]);
|
|
195
224
|
const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : parentConfig?.isModalOpen ?? internalModalOpen;
|
|
196
225
|
const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : parentConfig?.setModalOpen ?? setInternalModalOpen;
|
|
226
|
+
const [ownDrawerOpen, setOwnDrawerOpen] = (0, react.useState)(false);
|
|
227
|
+
const [ownDrawerCount, setOwnDrawerCount] = (0, react.useState)(0);
|
|
228
|
+
const modalCloseRef = (0, react.useRef)(() => {});
|
|
229
|
+
modalCloseRef.current = resolvedSetModalOpen;
|
|
230
|
+
const registeredModalClosersRef = (0, react.useRef)([]);
|
|
231
|
+
const ownRegisterModalCloser = (0, react.useCallback)((closeModal) => {
|
|
232
|
+
registeredModalClosersRef.current.push(closeModal);
|
|
233
|
+
return () => {
|
|
234
|
+
registeredModalClosersRef.current = registeredModalClosersRef.current.filter((entry) => entry !== closeModal);
|
|
235
|
+
};
|
|
236
|
+
}, []);
|
|
237
|
+
const ownSetDrawerOpen = (0, react.useCallback)((open) => {
|
|
238
|
+
setOwnDrawerOpen(open);
|
|
239
|
+
if (open && isMobileViewport()) {
|
|
240
|
+
const registered = registeredModalClosersRef.current;
|
|
241
|
+
(registered.length > 0 ? registered[registered.length - 1] : modalCloseRef.current)(false);
|
|
242
|
+
}
|
|
243
|
+
}, []);
|
|
244
|
+
const ownRegisterDrawer = (0, react.useCallback)(() => {
|
|
245
|
+
setOwnDrawerCount((count) => count + 1);
|
|
246
|
+
return () => {
|
|
247
|
+
setOwnDrawerCount((count) => Math.max(0, count - 1));
|
|
248
|
+
};
|
|
249
|
+
}, []);
|
|
250
|
+
const resolvedDrawerOpen = parentConfig ? parentConfig.drawerOpen : ownDrawerOpen;
|
|
251
|
+
const resolvedSetDrawerOpen = parentConfig ? parentConfig.setDrawerOpen : ownSetDrawerOpen;
|
|
252
|
+
const resolvedDrawerRegistered = parentConfig ? parentConfig.drawerRegistered : ownDrawerCount > 0;
|
|
253
|
+
const resolvedRegisterDrawer = parentConfig ? parentConfig.registerDrawer : ownRegisterDrawer;
|
|
254
|
+
const resolvedRegisterModalCloser = parentConfig ? parentConfig.ɵregisterModalCloser : ownRegisterModalCloser;
|
|
255
|
+
(0, react.useEffect)(() => {
|
|
256
|
+
if (!hasExplicitDefault) return;
|
|
257
|
+
return resolvedRegisterModalCloser(resolvedSetModalOpen);
|
|
258
|
+
}, [
|
|
259
|
+
hasExplicitDefault,
|
|
260
|
+
resolvedRegisterModalCloser,
|
|
261
|
+
resolvedSetModalOpen
|
|
262
|
+
]);
|
|
263
|
+
const isThreadIdControlledRef = (0, react.useRef)(isThreadIdControlled);
|
|
264
|
+
isThreadIdControlledRef.current = isThreadIdControlled;
|
|
265
|
+
const ownSetActiveThreadId = (0, react.useCallback)((id, options) => {
|
|
266
|
+
setActiveThreadOverride({
|
|
267
|
+
threadId: id,
|
|
268
|
+
explicit: options?.explicit ?? true
|
|
269
|
+
});
|
|
270
|
+
}, []);
|
|
271
|
+
const ownStartNewThread = (0, react.useCallback)(() => {
|
|
272
|
+
setActiveThreadOverride({
|
|
273
|
+
threadId: (0, _copilotkit_shared.randomUUID)(),
|
|
274
|
+
explicit: false
|
|
275
|
+
});
|
|
276
|
+
}, []);
|
|
277
|
+
const parentSetActiveThreadId = parentConfig?.setActiveThreadId;
|
|
278
|
+
const parentStartNewThread = parentConfig?.startNewThread;
|
|
279
|
+
const resolvedSetActiveThreadId = (0, react.useCallback)((id, options) => {
|
|
280
|
+
if (isThreadIdControlledRef.current) {
|
|
281
|
+
console.warn("[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (parentSetActiveThreadId) {
|
|
285
|
+
parentSetActiveThreadId(id, options);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
ownSetActiveThreadId(id, options);
|
|
289
|
+
}, [parentSetActiveThreadId, ownSetActiveThreadId]);
|
|
290
|
+
const resolvedStartNewThread = (0, react.useCallback)(() => {
|
|
291
|
+
if (isThreadIdControlledRef.current) {
|
|
292
|
+
console.warn("[CopilotKit] Ignoring startNewThread(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (parentStartNewThread) {
|
|
296
|
+
parentStartNewThread();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
ownStartNewThread();
|
|
300
|
+
}, [parentStartNewThread, ownStartNewThread]);
|
|
301
|
+
const setModalOpenWithDrawerExclusion = (0, react.useCallback)((open) => {
|
|
302
|
+
if (open && isMobileViewport()) resolvedSetDrawerOpen(false);
|
|
303
|
+
resolvedSetModalOpen(open);
|
|
304
|
+
}, [resolvedSetModalOpen, resolvedSetDrawerOpen]);
|
|
197
305
|
const configurationValue = (0, react.useMemo)(() => ({
|
|
198
306
|
labels: mergedLabels,
|
|
199
307
|
agentId: resolvedAgentId,
|
|
200
308
|
threadId: resolvedThreadId,
|
|
201
309
|
hasExplicitThreadId: resolvedHasExplicitThreadId,
|
|
202
310
|
isModalOpen: resolvedIsModalOpen,
|
|
203
|
-
setModalOpen:
|
|
311
|
+
setModalOpen: setModalOpenWithDrawerExclusion,
|
|
312
|
+
drawerOpen: resolvedDrawerOpen,
|
|
313
|
+
setDrawerOpen: resolvedSetDrawerOpen,
|
|
314
|
+
drawerRegistered: resolvedDrawerRegistered,
|
|
315
|
+
registerDrawer: resolvedRegisterDrawer,
|
|
316
|
+
ɵregisterModalCloser: resolvedRegisterModalCloser,
|
|
317
|
+
setActiveThreadId: resolvedSetActiveThreadId,
|
|
318
|
+
startNewThread: resolvedStartNewThread
|
|
204
319
|
}), [
|
|
205
320
|
mergedLabels,
|
|
206
321
|
resolvedAgentId,
|
|
207
322
|
resolvedThreadId,
|
|
208
323
|
resolvedHasExplicitThreadId,
|
|
209
324
|
resolvedIsModalOpen,
|
|
210
|
-
|
|
325
|
+
setModalOpenWithDrawerExclusion,
|
|
326
|
+
resolvedDrawerOpen,
|
|
327
|
+
resolvedSetDrawerOpen,
|
|
328
|
+
resolvedDrawerRegistered,
|
|
329
|
+
resolvedRegisterDrawer,
|
|
330
|
+
resolvedRegisterModalCloser,
|
|
331
|
+
resolvedSetActiveThreadId,
|
|
332
|
+
resolvedStartNewThread
|
|
211
333
|
]);
|
|
212
334
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
|
|
213
335
|
value: configurationValue,
|
|
@@ -1128,7 +1250,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1128
1250
|
},
|
|
1129
1251
|
...props,
|
|
1130
1252
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1131
|
-
className: "cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:
|
|
1253
|
+
className: "cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-4 cpk:pointer-events-auto",
|
|
1132
1254
|
children: inputPill
|
|
1133
1255
|
}), shouldShowDisclaimer && BoundDisclaimer]
|
|
1134
1256
|
});
|
|
@@ -1398,325 +1520,43 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1398
1520
|
*
|
|
1399
1521
|
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
1400
1522
|
* MessageChannel task runs first, committing the pending state and running
|
|
1401
|
-
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
1402
|
-
* call then reads fresh context.
|
|
1403
|
-
*/
|
|
1404
|
-
async waitForPendingFrameworkUpdates() {
|
|
1405
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1406
|
-
}
|
|
1407
|
-
};
|
|
1408
|
-
|
|
1409
|
-
//#endregion
|
|
1410
|
-
//#region src/v2/context.ts
|
|
1411
|
-
const CopilotKitContext = (0, react.createContext)(null);
|
|
1412
|
-
const useCopilotKit = () => {
|
|
1413
|
-
const context = (0, react.useContext)(CopilotKitContext);
|
|
1414
|
-
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1415
|
-
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1416
|
-
(0, react.useEffect)(() => {
|
|
1417
|
-
const subscription = context.copilotkit.subscribe({
|
|
1418
|
-
onRuntimeConnectionStatusChanged: () => {
|
|
1419
|
-
forceUpdate();
|
|
1420
|
-
},
|
|
1421
|
-
onHeadersChanged: () => {
|
|
1422
|
-
forceUpdate();
|
|
1423
|
-
}
|
|
1424
|
-
});
|
|
1425
|
-
return () => {
|
|
1426
|
-
subscription.unsubscribe();
|
|
1427
|
-
};
|
|
1428
|
-
}, []);
|
|
1429
|
-
return context;
|
|
1430
|
-
};
|
|
1431
|
-
const LicenseContext = (0, react.createContext)({
|
|
1432
|
-
status: null,
|
|
1433
|
-
license: null,
|
|
1434
|
-
checkFeature: () => true,
|
|
1435
|
-
getLimit: () => null
|
|
1436
|
-
});
|
|
1437
|
-
const useLicenseContext = () => (0, react.useContext)(LicenseContext);
|
|
1438
|
-
|
|
1439
|
-
//#endregion
|
|
1440
|
-
//#region src/v2/types/defineToolCallRenderer.ts
|
|
1441
|
-
function defineToolCallRenderer(def) {
|
|
1442
|
-
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
1443
|
-
return {
|
|
1444
|
-
name: def.name,
|
|
1445
|
-
args: argsSchema,
|
|
1446
|
-
render: def.render,
|
|
1447
|
-
...def.agentId ? { agentId: def.agentId } : {}
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
//#endregion
|
|
1452
|
-
//#region src/v2/hooks/use-render-tool.tsx
|
|
1453
|
-
const EMPTY_DEPS$1 = [];
|
|
1454
|
-
/**
|
|
1455
|
-
* Registers a renderer entry in CopilotKit's `renderToolCalls` registry.
|
|
1456
|
-
*
|
|
1457
|
-
* Key behavior:
|
|
1458
|
-
* - deduplicates by `agentId:name` (latest registration wins),
|
|
1459
|
-
* - keeps renderer entries on cleanup so historical chat tool calls can still render,
|
|
1460
|
-
* - refreshes registration when `deps` change.
|
|
1461
|
-
*
|
|
1462
|
-
* @typeParam S - Schema type describing tool call parameters.
|
|
1463
|
-
* @param config - Renderer config for wildcard or named tools.
|
|
1464
|
-
* @param deps - Optional dependencies to refresh registration.
|
|
1465
|
-
*
|
|
1466
|
-
* @example
|
|
1467
|
-
* ```tsx
|
|
1468
|
-
* useRenderTool(
|
|
1469
|
-
* {
|
|
1470
|
-
* name: "searchDocs",
|
|
1471
|
-
* parameters: z.object({ query: z.string() }),
|
|
1472
|
-
* render: ({ status, parameters, result }) => {
|
|
1473
|
-
* if (status === "executing") return <div>Searching {parameters.query}</div>;
|
|
1474
|
-
* if (status === "complete") return <div>{result}</div>;
|
|
1475
|
-
* return <div>Preparing...</div>;
|
|
1476
|
-
* },
|
|
1477
|
-
* },
|
|
1478
|
-
* [],
|
|
1479
|
-
* );
|
|
1480
|
-
* ```
|
|
1481
|
-
*
|
|
1482
|
-
* @example
|
|
1483
|
-
* ```tsx
|
|
1484
|
-
* useRenderTool(
|
|
1485
|
-
* {
|
|
1486
|
-
* name: "summarize",
|
|
1487
|
-
* parameters: z.object({ text: z.string() }),
|
|
1488
|
-
* agentId: "research-agent",
|
|
1489
|
-
* render: ({ name, status }) => <div>{name}: {status}</div>,
|
|
1490
|
-
* },
|
|
1491
|
-
* [selectedAgentId],
|
|
1492
|
-
* );
|
|
1493
|
-
* ```
|
|
1494
|
-
*/
|
|
1495
|
-
function useRenderTool(config, deps) {
|
|
1496
|
-
const { copilotkit } = useCopilotKit();
|
|
1497
|
-
const extraDeps = deps ?? EMPTY_DEPS$1;
|
|
1498
|
-
(0, react.useEffect)(() => {
|
|
1499
|
-
const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
|
|
1500
|
-
name: "*",
|
|
1501
|
-
render: (props) => config.render({
|
|
1502
|
-
...props,
|
|
1503
|
-
parameters: props.args
|
|
1504
|
-
}),
|
|
1505
|
-
...config.agentId ? { agentId: config.agentId } : {}
|
|
1506
|
-
}) : defineToolCallRenderer({
|
|
1507
|
-
name: config.name,
|
|
1508
|
-
args: config.parameters,
|
|
1509
|
-
render: (props) => {
|
|
1510
|
-
if (props.status === _copilotkit_core.ToolCallStatus.InProgress) return config.render({
|
|
1511
|
-
...props,
|
|
1512
|
-
parameters: props.args
|
|
1513
|
-
});
|
|
1514
|
-
if (props.status === _copilotkit_core.ToolCallStatus.Executing) return config.render({
|
|
1515
|
-
...props,
|
|
1516
|
-
parameters: props.args
|
|
1517
|
-
});
|
|
1518
|
-
return config.render({
|
|
1519
|
-
...props,
|
|
1520
|
-
parameters: props.args
|
|
1521
|
-
});
|
|
1522
|
-
},
|
|
1523
|
-
...config.agentId ? { agentId: config.agentId } : {}
|
|
1524
|
-
});
|
|
1525
|
-
copilotkit.addHookRenderToolCall(renderer);
|
|
1526
|
-
}, [
|
|
1527
|
-
config.name,
|
|
1528
|
-
copilotkit,
|
|
1529
|
-
JSON.stringify(extraDeps)
|
|
1530
|
-
]);
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
//#endregion
|
|
1534
|
-
//#region src/v2/hooks/use-default-render-tool.tsx
|
|
1535
|
-
/**
|
|
1536
|
-
* Module-level dedup set so an unknown status value only emits a console
|
|
1537
|
-
* warning the FIRST time we encounter it. Otherwise a stuck/unmapped status
|
|
1538
|
-
* would log on every re-render (potentially many per second).
|
|
1539
|
-
*/
|
|
1540
|
-
const warnedUnknownStatuses = /* @__PURE__ */ new Set();
|
|
1541
|
-
/**
|
|
1542
|
-
* Map a {@link ToolCallStatus} enum value to the documented string-union
|
|
1543
|
-
* status the {@link DefaultRenderProps} contract exposes. Unknown / future
|
|
1544
|
-
* enum members log a warning (once per distinct value) and fall back to
|
|
1545
|
-
* `"inProgress"`.
|
|
1546
|
-
*/
|
|
1547
|
-
function mapToolCallStatus(status) {
|
|
1548
|
-
switch (status) {
|
|
1549
|
-
case _copilotkit_core.ToolCallStatus.Complete: return "complete";
|
|
1550
|
-
case _copilotkit_core.ToolCallStatus.Executing: return "executing";
|
|
1551
|
-
case _copilotkit_core.ToolCallStatus.InProgress: return "inProgress";
|
|
1552
|
-
default: {
|
|
1553
|
-
const key = String(status);
|
|
1554
|
-
if (!warnedUnknownStatuses.has(key)) {
|
|
1555
|
-
warnedUnknownStatuses.add(key);
|
|
1556
|
-
console.warn(`[CopilotKit] Unknown ToolCallStatus "${key}" in default tool-call renderer; falling back to "inProgress".`);
|
|
1557
|
-
}
|
|
1558
|
-
return "inProgress";
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
/**
|
|
1563
|
-
* Convert the framework-internal renderer props (`args`, enum status) into
|
|
1564
|
-
* the documented {@link DefaultRenderProps} shape (`parameters`, string-union
|
|
1565
|
-
* status) so a user `config.render` always sees the documented contract.
|
|
1566
|
-
*/
|
|
1567
|
-
function adaptRendererProps(props) {
|
|
1568
|
-
return {
|
|
1569
|
-
name: props.name,
|
|
1570
|
-
toolCallId: props.toolCallId,
|
|
1571
|
-
parameters: props.args,
|
|
1572
|
-
status: mapToolCallStatus(props.status),
|
|
1573
|
-
result: props.result
|
|
1574
|
-
};
|
|
1575
|
-
}
|
|
1576
|
-
/**
|
|
1577
|
-
* Registers a wildcard (`"*"`) tool-call renderer via `useRenderTool`.
|
|
1578
|
-
*
|
|
1579
|
-
* - Call with no config to use CopilotKit's built-in default tool-call card.
|
|
1580
|
-
* - Pass `config.render` to replace the default UI with your own fallback renderer.
|
|
1581
|
-
*
|
|
1582
|
-
* This is useful when you want a generic renderer for tools that do not have a
|
|
1583
|
-
* dedicated `useRenderTool({ name: "..." })` registration.
|
|
1584
|
-
*
|
|
1585
|
-
* @param config - Optional custom wildcard render function.
|
|
1586
|
-
* @param deps - Optional dependencies to refresh registration.
|
|
1587
|
-
*
|
|
1588
|
-
* @example
|
|
1589
|
-
* ```tsx
|
|
1590
|
-
* useDefaultRenderTool();
|
|
1591
|
-
* ```
|
|
1592
|
-
*
|
|
1593
|
-
* @example
|
|
1594
|
-
* ```tsx
|
|
1595
|
-
* useDefaultRenderTool({
|
|
1596
|
-
* render: ({ name, status }) => <div>{name}: {status}</div>,
|
|
1597
|
-
* });
|
|
1598
|
-
* ```
|
|
1599
|
-
*
|
|
1600
|
-
* @example
|
|
1601
|
-
* ```tsx
|
|
1602
|
-
* useDefaultRenderTool(
|
|
1603
|
-
* {
|
|
1604
|
-
* render: ({ name, result }) => (
|
|
1605
|
-
* <ToolEventRow title={name} payload={result} compact={compactMode} />
|
|
1606
|
-
* ),
|
|
1607
|
-
* },
|
|
1608
|
-
* [compactMode],
|
|
1609
|
-
* );
|
|
1610
|
-
* ```
|
|
1611
|
-
*/
|
|
1612
|
-
function useDefaultRenderTool(config, deps) {
|
|
1613
|
-
const userRender = config?.render;
|
|
1614
|
-
useRenderTool({
|
|
1615
|
-
name: "*",
|
|
1616
|
-
render: userRender ? (raw) => userRender(adaptRendererProps(raw)) : (raw) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(raw) })
|
|
1617
|
-
}, deps);
|
|
1618
|
-
}
|
|
1619
|
-
/**
|
|
1620
|
-
* Guarded JSON.stringify used inside the expanded `<pre>` blocks. A circular
|
|
1621
|
-
* reference would otherwise crash the entire React tree on render.
|
|
1622
|
-
*/
|
|
1623
|
-
function safeStringifyForPre(value) {
|
|
1624
|
-
try {
|
|
1625
|
-
return JSON.stringify(value, null, 2);
|
|
1626
|
-
} catch (err) {
|
|
1627
|
-
console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for default renderer; falling back to String():", err);
|
|
1628
|
-
try {
|
|
1629
|
-
return String(value);
|
|
1630
|
-
} catch (innerErr) {
|
|
1631
|
-
console.warn("[CopilotKit] safeStringifyForPre: value could not be stringified:", innerErr);
|
|
1632
|
-
return "[unserializable]";
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
function DefaultToolCallRenderer({ name, toolCallId, parameters, status, result }) {
|
|
1637
|
-
const [isExpanded, setIsExpanded] = (0, react.useState)(false);
|
|
1638
|
-
const isActive = status === "inProgress" || status === "executing";
|
|
1639
|
-
const isComplete = status === "complete";
|
|
1640
|
-
const statusLabel = isActive ? "Running" : isComplete ? "Done" : status;
|
|
1641
|
-
const dotClassName = isActive ? "cpk:bg-amber-500" : isComplete ? "cpk:bg-emerald-500" : "cpk:bg-zinc-400";
|
|
1642
|
-
const badgeClassName = isActive ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : isComplete ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300";
|
|
1643
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1644
|
-
"data-testid": "copilot-tool-render",
|
|
1645
|
-
"data-tool-name": name,
|
|
1646
|
-
"data-tool-call-id": toolCallId,
|
|
1647
|
-
"data-status": status,
|
|
1648
|
-
"data-args": safeStringifyForAttr(parameters),
|
|
1649
|
-
"data-result": safeStringifyForAttr(result),
|
|
1650
|
-
className: "cpk:mt-2 cpk:pb-2",
|
|
1651
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1652
|
-
className: "cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:bg-white/70 cpk:p-4 cpk:shadow-sm cpk:backdrop-blur cpk:dark:border-zinc-800/60 cpk:dark:bg-zinc-900/50",
|
|
1653
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1654
|
-
type: "button",
|
|
1655
|
-
"aria-expanded": isExpanded,
|
|
1656
|
-
onClick: () => setIsExpanded(!isExpanded),
|
|
1657
|
-
className: "cpk:flex cpk:w-full cpk:cursor-pointer cpk:select-none cpk:items-center cpk:justify-between cpk:gap-2.5 cpk:border-none cpk:bg-transparent cpk:p-0 cpk:m-0 cpk:text-left cpk:text-inherit",
|
|
1658
|
-
style: { font: "inherit" },
|
|
1659
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1660
|
-
className: "cpk:flex cpk:min-w-0 cpk:items-center cpk:gap-2",
|
|
1661
|
-
children: [
|
|
1662
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
1663
|
-
className: `cpk:h-3.5 cpk:w-3.5 cpk:flex-shrink-0 cpk:text-zinc-500 cpk:transition-transform cpk:dark:text-zinc-400 ${isExpanded ? "cpk:rotate-90" : ""}`,
|
|
1664
|
-
fill: "none",
|
|
1665
|
-
viewBox: "0 0 24 24",
|
|
1666
|
-
strokeWidth: 2,
|
|
1667
|
-
stroke: "currentColor",
|
|
1668
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1669
|
-
strokeLinecap: "round",
|
|
1670
|
-
strokeLinejoin: "round",
|
|
1671
|
-
d: "M8.25 4.5l7.5 7.5-7.5 7.5"
|
|
1672
|
-
})
|
|
1673
|
-
}),
|
|
1674
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `cpk:inline-block cpk:h-2 cpk:w-2 cpk:flex-shrink-0 cpk:rounded-full ${dotClassName}` }),
|
|
1675
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1676
|
-
"data-testid": "copilot-tool-render-name",
|
|
1677
|
-
className: "cpk:truncate cpk:text-[13px] cpk:font-semibold cpk:text-zinc-900 cpk:dark:text-zinc-100",
|
|
1678
|
-
children: name
|
|
1679
|
-
})
|
|
1680
|
-
]
|
|
1681
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1682
|
-
"data-testid": "copilot-tool-render-status",
|
|
1683
|
-
className: `cpk:inline-flex cpk:flex-shrink-0 cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-0.5 cpk:text-[11px] cpk:font-medium ${badgeClassName}`,
|
|
1684
|
-
children: statusLabel
|
|
1685
|
-
})]
|
|
1686
|
-
}), isExpanded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1687
|
-
className: "cpk:mt-3 cpk:grid cpk:gap-3",
|
|
1688
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1689
|
-
className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
1690
|
-
children: "Arguments"
|
|
1691
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
1692
|
-
className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
|
|
1693
|
-
children: safeStringifyForPre(parameters ?? {})
|
|
1694
|
-
})] }), result !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1695
|
-
className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
1696
|
-
children: "Result"
|
|
1697
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
1698
|
-
className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
|
|
1699
|
-
children: typeof result === "string" ? result : safeStringifyForPre(result)
|
|
1700
|
-
})] })]
|
|
1701
|
-
})]
|
|
1702
|
-
})
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
function safeStringifyForAttr(value) {
|
|
1706
|
-
if (value === void 0 || value === null) return "";
|
|
1707
|
-
if (typeof value === "string") return value;
|
|
1708
|
-
try {
|
|
1709
|
-
return JSON.stringify(value);
|
|
1710
|
-
} catch (err) {
|
|
1711
|
-
console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for data-* attribute; falling back to String():", err);
|
|
1712
|
-
try {
|
|
1713
|
-
return String(value);
|
|
1714
|
-
} catch (innerErr) {
|
|
1715
|
-
console.warn("[CopilotKit] safeStringifyForAttr: value could not be stringified:", innerErr);
|
|
1716
|
-
return "";
|
|
1717
|
-
}
|
|
1523
|
+
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
1524
|
+
* call then reads fresh context.
|
|
1525
|
+
*/
|
|
1526
|
+
async waitForPendingFrameworkUpdates() {
|
|
1527
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1718
1528
|
}
|
|
1719
|
-
}
|
|
1529
|
+
};
|
|
1530
|
+
|
|
1531
|
+
//#endregion
|
|
1532
|
+
//#region src/v2/context.ts
|
|
1533
|
+
const CopilotKitContext = (0, react.createContext)(null);
|
|
1534
|
+
const useCopilotKit = () => {
|
|
1535
|
+
const context = (0, react.useContext)(CopilotKitContext);
|
|
1536
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1537
|
+
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1538
|
+
(0, react.useEffect)(() => {
|
|
1539
|
+
const subscription = context.copilotkit.subscribe({
|
|
1540
|
+
onRuntimeConnectionStatusChanged: () => {
|
|
1541
|
+
forceUpdate();
|
|
1542
|
+
},
|
|
1543
|
+
onHeadersChanged: () => {
|
|
1544
|
+
forceUpdate();
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
return () => {
|
|
1548
|
+
subscription.unsubscribe();
|
|
1549
|
+
};
|
|
1550
|
+
}, []);
|
|
1551
|
+
return context;
|
|
1552
|
+
};
|
|
1553
|
+
const LicenseContext = (0, react.createContext)({
|
|
1554
|
+
status: null,
|
|
1555
|
+
license: null,
|
|
1556
|
+
checkFeature: () => true,
|
|
1557
|
+
getLimit: () => null
|
|
1558
|
+
});
|
|
1559
|
+
const useLicenseContext = () => (0, react.useContext)(LicenseContext);
|
|
1720
1560
|
|
|
1721
1561
|
//#endregion
|
|
1722
1562
|
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
@@ -1772,10 +1612,13 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1772
1612
|
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1773
1613
|
return (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1774
1614
|
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1615
|
+
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1616
|
+
if (!renderConfig) return null;
|
|
1617
|
+
const RenderComponent = renderConfig.render;
|
|
1775
1618
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
1776
1619
|
toolCall,
|
|
1777
1620
|
toolMessage,
|
|
1778
|
-
RenderComponent
|
|
1621
|
+
RenderComponent,
|
|
1779
1622
|
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
1780
1623
|
}, toolCall.id);
|
|
1781
1624
|
}, [
|
|
@@ -1784,15 +1627,6 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1784
1627
|
agentId
|
|
1785
1628
|
]);
|
|
1786
1629
|
}
|
|
1787
|
-
function defaultToolCallRenderAdapter(props) {
|
|
1788
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, {
|
|
1789
|
-
name: props.name,
|
|
1790
|
-
toolCallId: props.toolCallId,
|
|
1791
|
-
parameters: props.args,
|
|
1792
|
-
status: mapToolCallStatus(props.status),
|
|
1793
|
-
result: props.result
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
1630
|
|
|
1797
1631
|
//#endregion
|
|
1798
1632
|
//#region src/v2/components/CopilotKitInspector.tsx
|
|
@@ -3274,7 +3108,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3274
3108
|
...A2UILifecycleFields
|
|
3275
3109
|
}).passthrough();
|
|
3276
3110
|
function createA2UIMessageRenderer(options) {
|
|
3277
|
-
const { theme, catalog, loadingComponent, recovery } = options;
|
|
3111
|
+
const { theme, catalog, loadingComponent, recovery, onAction } = options;
|
|
3278
3112
|
const showAfterMs = recovery?.showAfterMs ?? 2e3;
|
|
3279
3113
|
const showAfterAttempts = recovery?.showAfterAttempts ?? 2;
|
|
3280
3114
|
const optionDebugExposure = recovery?.debugExposure ?? "collapsed";
|
|
@@ -3350,6 +3184,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3350
3184
|
agent,
|
|
3351
3185
|
copilotkit,
|
|
3352
3186
|
catalog,
|
|
3187
|
+
onAction,
|
|
3353
3188
|
onReady: markSurfaceReady
|
|
3354
3189
|
}, surfaceId))
|
|
3355
3190
|
});
|
|
@@ -3370,29 +3205,60 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3370
3205
|
};
|
|
3371
3206
|
}
|
|
3372
3207
|
/**
|
|
3208
|
+
* Orchestrates a single A2UI user action: runs the optional `onAction`
|
|
3209
|
+
* interceptor first, then forwards to the agent unless the interceptor
|
|
3210
|
+
* suppressed it (returned `null`). Exported for unit testing; the wiring lives
|
|
3211
|
+
* in {@link ReactSurfaceHost}.
|
|
3212
|
+
*/
|
|
3213
|
+
async function runA2UIAction({ message, agent, copilotkit, onAction }) {
|
|
3214
|
+
if (!agent) return;
|
|
3215
|
+
const action = message.userAction;
|
|
3216
|
+
const forward = async (forwardAction) => {
|
|
3217
|
+
const a2uiAction = forwardAction !== void 0 ? {
|
|
3218
|
+
...message,
|
|
3219
|
+
userAction: forwardAction
|
|
3220
|
+
} : message;
|
|
3221
|
+
try {
|
|
3222
|
+
copilotkit.setProperties({
|
|
3223
|
+
...copilotkit.properties,
|
|
3224
|
+
a2uiAction
|
|
3225
|
+
});
|
|
3226
|
+
await copilotkit.runAgent({ agent });
|
|
3227
|
+
} finally {
|
|
3228
|
+
if (copilotkit.properties) {
|
|
3229
|
+
const { a2uiAction: _omit, ...rest } = copilotkit.properties;
|
|
3230
|
+
copilotkit.setProperties(rest);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
};
|
|
3234
|
+
if (onAction && action) {
|
|
3235
|
+
const result = await onAction(action, forward);
|
|
3236
|
+
if (result === null) return;
|
|
3237
|
+
if (result) {
|
|
3238
|
+
await forward(result);
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
await forward();
|
|
3243
|
+
}
|
|
3244
|
+
/**
|
|
3373
3245
|
* Renders a single A2UI surface using the React renderer.
|
|
3374
3246
|
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
|
|
3375
3247
|
*/
|
|
3376
|
-
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog, onReady }) {
|
|
3248
|
+
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog, onAction, onReady }) {
|
|
3377
3249
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3378
3250
|
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
3379
3251
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
3380
|
-
onAction: (0, react.useCallback)(
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
if (copilotkit.properties) {
|
|
3391
|
-
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
3392
|
-
copilotkit.setProperties(rest);
|
|
3393
|
-
}
|
|
3394
|
-
}
|
|
3395
|
-
}, [agent, copilotkit]),
|
|
3252
|
+
onAction: (0, react.useCallback)((message) => runA2UIAction({
|
|
3253
|
+
message,
|
|
3254
|
+
agent,
|
|
3255
|
+
copilotkit,
|
|
3256
|
+
onAction
|
|
3257
|
+
}), [
|
|
3258
|
+
agent,
|
|
3259
|
+
copilotkit,
|
|
3260
|
+
onAction
|
|
3261
|
+
]),
|
|
3396
3262
|
theme,
|
|
3397
3263
|
catalog,
|
|
3398
3264
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
@@ -3463,6 +3329,18 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3463
3329
|
return operation?.createSurface?.surfaceId ?? operation?.updateComponents?.surfaceId ?? operation?.updateDataModel?.surfaceId ?? operation?.deleteSurface?.surfaceId ?? null;
|
|
3464
3330
|
}
|
|
3465
3331
|
|
|
3332
|
+
//#endregion
|
|
3333
|
+
//#region src/v2/types/defineToolCallRenderer.ts
|
|
3334
|
+
function defineToolCallRenderer(def) {
|
|
3335
|
+
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
3336
|
+
return {
|
|
3337
|
+
name: def.name,
|
|
3338
|
+
args: argsSchema,
|
|
3339
|
+
render: def.render,
|
|
3340
|
+
...def.agentId ? { agentId: def.agentId } : {}
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3466
3344
|
//#endregion
|
|
3467
3345
|
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
3468
3346
|
/**
|
|
@@ -4016,10 +3894,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4016
3894
|
|
|
4017
3895
|
//#endregion
|
|
4018
3896
|
//#region src/v2/hooks/use-frontend-tool.tsx
|
|
4019
|
-
const EMPTY_DEPS = [];
|
|
3897
|
+
const EMPTY_DEPS$1 = [];
|
|
4020
3898
|
function useFrontendTool(tool, deps) {
|
|
4021
3899
|
const { copilotkit } = useCopilotKit();
|
|
4022
|
-
const extraDeps = deps ?? EMPTY_DEPS;
|
|
3900
|
+
const extraDeps = deps ?? EMPTY_DEPS$1;
|
|
4023
3901
|
(0, react.useEffect)(() => {
|
|
4024
3902
|
const name = tool.name;
|
|
4025
3903
|
if (copilotkit.getTool({
|
|
@@ -4057,63 +3935,333 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4057
3935
|
* - forwards optional schema parameters (any Standard Schema V1 compatible library),
|
|
4058
3936
|
* - renders your component with tool call parameters.
|
|
4059
3937
|
*
|
|
4060
|
-
* Use this when you want to display a typed visual component for a tool call
|
|
4061
|
-
* without manually wiring a full frontend tool object.
|
|
3938
|
+
* Use this when you want to display a typed visual component for a tool call
|
|
3939
|
+
* without manually wiring a full frontend tool object.
|
|
3940
|
+
*
|
|
3941
|
+
* When `parameters` is provided, render props are inferred from the schema.
|
|
3942
|
+
* When omitted, the render component may accept any props.
|
|
3943
|
+
*
|
|
3944
|
+
* @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.
|
|
3945
|
+
* @param config - Tool registration config.
|
|
3946
|
+
* @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).
|
|
3947
|
+
*
|
|
3948
|
+
* @example
|
|
3949
|
+
* ```tsx
|
|
3950
|
+
* // Without parameters — render accepts any props
|
|
3951
|
+
* useComponent({
|
|
3952
|
+
* name: "showGreeting",
|
|
3953
|
+
* render: ({ message }: { message: string }) => <div>{message}</div>,
|
|
3954
|
+
* });
|
|
3955
|
+
* ```
|
|
3956
|
+
*
|
|
3957
|
+
* @example
|
|
3958
|
+
* ```tsx
|
|
3959
|
+
* // With parameters — render props inferred from schema
|
|
3960
|
+
* useComponent({
|
|
3961
|
+
* name: "showWeatherCard",
|
|
3962
|
+
* parameters: z.object({ city: z.string() }),
|
|
3963
|
+
* render: ({ city }) => <div>{city}</div>,
|
|
3964
|
+
* });
|
|
3965
|
+
* ```
|
|
3966
|
+
*
|
|
3967
|
+
* @example
|
|
3968
|
+
* ```tsx
|
|
3969
|
+
* useComponent(
|
|
3970
|
+
* {
|
|
3971
|
+
* name: "renderProfile",
|
|
3972
|
+
* parameters: z.object({ userId: z.string() }),
|
|
3973
|
+
* render: ProfileCard,
|
|
3974
|
+
* agentId: "support-agent",
|
|
3975
|
+
* },
|
|
3976
|
+
* [selectedAgentId],
|
|
3977
|
+
* );
|
|
3978
|
+
* ```
|
|
3979
|
+
*/
|
|
3980
|
+
function useComponent(config, deps) {
|
|
3981
|
+
const prefix = `Use this tool to display the "${config.name}" component in the chat. This tool renders a visual UI component for the user.`;
|
|
3982
|
+
const fullDescription = config.description ? `${prefix}\n\n${config.description}` : prefix;
|
|
3983
|
+
useFrontendTool({
|
|
3984
|
+
name: config.name,
|
|
3985
|
+
description: fullDescription,
|
|
3986
|
+
parameters: config.parameters,
|
|
3987
|
+
render: ({ args }) => {
|
|
3988
|
+
const Component = config.render;
|
|
3989
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...args });
|
|
3990
|
+
},
|
|
3991
|
+
agentId: config.agentId,
|
|
3992
|
+
followUp: config.followUp
|
|
3993
|
+
}, deps);
|
|
3994
|
+
}
|
|
3995
|
+
|
|
3996
|
+
//#endregion
|
|
3997
|
+
//#region src/v2/hooks/use-render-tool.tsx
|
|
3998
|
+
const EMPTY_DEPS = [];
|
|
3999
|
+
/**
|
|
4000
|
+
* Registers a renderer entry in CopilotKit's `renderToolCalls` registry.
|
|
4001
|
+
*
|
|
4002
|
+
* Key behavior:
|
|
4003
|
+
* - deduplicates by `agentId:name` (latest registration wins),
|
|
4004
|
+
* - keeps renderer entries on cleanup so historical chat tool calls can still render,
|
|
4005
|
+
* - refreshes registration when `deps` change.
|
|
4006
|
+
*
|
|
4007
|
+
* @typeParam S - Schema type describing tool call parameters.
|
|
4008
|
+
* @param config - Renderer config for wildcard or named tools.
|
|
4009
|
+
* @param deps - Optional dependencies to refresh registration.
|
|
4010
|
+
*
|
|
4011
|
+
* @example
|
|
4012
|
+
* ```tsx
|
|
4013
|
+
* useRenderTool(
|
|
4014
|
+
* {
|
|
4015
|
+
* name: "searchDocs",
|
|
4016
|
+
* parameters: z.object({ query: z.string() }),
|
|
4017
|
+
* render: ({ status, parameters, result }) => {
|
|
4018
|
+
* if (status === "executing") return <div>Searching {parameters.query}</div>;
|
|
4019
|
+
* if (status === "complete") return <div>{result}</div>;
|
|
4020
|
+
* return <div>Preparing...</div>;
|
|
4021
|
+
* },
|
|
4022
|
+
* },
|
|
4023
|
+
* [],
|
|
4024
|
+
* );
|
|
4025
|
+
* ```
|
|
4026
|
+
*
|
|
4027
|
+
* @example
|
|
4028
|
+
* ```tsx
|
|
4029
|
+
* useRenderTool(
|
|
4030
|
+
* {
|
|
4031
|
+
* name: "summarize",
|
|
4032
|
+
* parameters: z.object({ text: z.string() }),
|
|
4033
|
+
* agentId: "research-agent",
|
|
4034
|
+
* render: ({ name, status }) => <div>{name}: {status}</div>,
|
|
4035
|
+
* },
|
|
4036
|
+
* [selectedAgentId],
|
|
4037
|
+
* );
|
|
4038
|
+
* ```
|
|
4039
|
+
*/
|
|
4040
|
+
function useRenderTool(config, deps) {
|
|
4041
|
+
const { copilotkit } = useCopilotKit();
|
|
4042
|
+
const extraDeps = deps ?? EMPTY_DEPS;
|
|
4043
|
+
(0, react.useEffect)(() => {
|
|
4044
|
+
const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
|
|
4045
|
+
name: "*",
|
|
4046
|
+
render: (props) => config.render({
|
|
4047
|
+
...props,
|
|
4048
|
+
parameters: props.args
|
|
4049
|
+
}),
|
|
4050
|
+
...config.agentId ? { agentId: config.agentId } : {}
|
|
4051
|
+
}) : defineToolCallRenderer({
|
|
4052
|
+
name: config.name,
|
|
4053
|
+
args: config.parameters,
|
|
4054
|
+
render: (props) => {
|
|
4055
|
+
if (props.status === _copilotkit_core.ToolCallStatus.InProgress) return config.render({
|
|
4056
|
+
...props,
|
|
4057
|
+
parameters: props.args
|
|
4058
|
+
});
|
|
4059
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Executing) return config.render({
|
|
4060
|
+
...props,
|
|
4061
|
+
parameters: props.args
|
|
4062
|
+
});
|
|
4063
|
+
return config.render({
|
|
4064
|
+
...props,
|
|
4065
|
+
parameters: props.args
|
|
4066
|
+
});
|
|
4067
|
+
},
|
|
4068
|
+
...config.agentId ? { agentId: config.agentId } : {}
|
|
4069
|
+
});
|
|
4070
|
+
copilotkit.addHookRenderToolCall(renderer);
|
|
4071
|
+
}, [
|
|
4072
|
+
config.name,
|
|
4073
|
+
copilotkit,
|
|
4074
|
+
JSON.stringify(extraDeps)
|
|
4075
|
+
]);
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
//#endregion
|
|
4079
|
+
//#region src/v2/hooks/use-default-render-tool.tsx
|
|
4080
|
+
/**
|
|
4081
|
+
* Module-level dedup set so an unknown status value only emits a console
|
|
4082
|
+
* warning the FIRST time we encounter it. Otherwise a stuck/unmapped status
|
|
4083
|
+
* would log on every re-render (potentially many per second).
|
|
4084
|
+
*/
|
|
4085
|
+
const warnedUnknownStatuses = /* @__PURE__ */ new Set();
|
|
4086
|
+
/**
|
|
4087
|
+
* Map a {@link ToolCallStatus} enum value to the documented string-union
|
|
4088
|
+
* status the {@link DefaultRenderProps} contract exposes. Unknown / future
|
|
4089
|
+
* enum members log a warning (once per distinct value) and fall back to
|
|
4090
|
+
* `"inProgress"`.
|
|
4091
|
+
*/
|
|
4092
|
+
function mapToolCallStatus(status) {
|
|
4093
|
+
switch (status) {
|
|
4094
|
+
case _copilotkit_core.ToolCallStatus.Complete: return "complete";
|
|
4095
|
+
case _copilotkit_core.ToolCallStatus.Executing: return "executing";
|
|
4096
|
+
case _copilotkit_core.ToolCallStatus.InProgress: return "inProgress";
|
|
4097
|
+
default: {
|
|
4098
|
+
const key = String(status);
|
|
4099
|
+
if (!warnedUnknownStatuses.has(key)) {
|
|
4100
|
+
warnedUnknownStatuses.add(key);
|
|
4101
|
+
console.warn(`[CopilotKit] Unknown ToolCallStatus "${key}" in default tool-call renderer; falling back to "inProgress".`);
|
|
4102
|
+
}
|
|
4103
|
+
return "inProgress";
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
/**
|
|
4108
|
+
* Convert the framework-internal renderer props (`args`, enum status) into
|
|
4109
|
+
* the documented {@link DefaultRenderProps} shape (`parameters`, string-union
|
|
4110
|
+
* status) so a user `config.render` always sees the documented contract.
|
|
4111
|
+
*/
|
|
4112
|
+
function adaptRendererProps(props) {
|
|
4113
|
+
return {
|
|
4114
|
+
name: props.name,
|
|
4115
|
+
toolCallId: props.toolCallId,
|
|
4116
|
+
parameters: props.args,
|
|
4117
|
+
status: mapToolCallStatus(props.status),
|
|
4118
|
+
result: props.result
|
|
4119
|
+
};
|
|
4120
|
+
}
|
|
4121
|
+
/**
|
|
4122
|
+
* Registers a wildcard (`"*"`) tool-call renderer via `useRenderTool`.
|
|
4123
|
+
*
|
|
4124
|
+
* - Call with no config to use CopilotKit's built-in default tool-call card.
|
|
4125
|
+
* - Pass `config.render` to replace the default UI with your own fallback renderer.
|
|
4062
4126
|
*
|
|
4063
|
-
*
|
|
4064
|
-
*
|
|
4127
|
+
* This is useful when you want a generic renderer for tools that do not have a
|
|
4128
|
+
* dedicated `useRenderTool({ name: "..." })` registration.
|
|
4065
4129
|
*
|
|
4066
|
-
* @
|
|
4067
|
-
* @param
|
|
4068
|
-
* @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).
|
|
4130
|
+
* @param config - Optional custom wildcard render function.
|
|
4131
|
+
* @param deps - Optional dependencies to refresh registration.
|
|
4069
4132
|
*
|
|
4070
4133
|
* @example
|
|
4071
4134
|
* ```tsx
|
|
4072
|
-
*
|
|
4073
|
-
* useComponent({
|
|
4074
|
-
* name: "showGreeting",
|
|
4075
|
-
* render: ({ message }: { message: string }) => <div>{message}</div>,
|
|
4076
|
-
* });
|
|
4135
|
+
* useDefaultRenderTool();
|
|
4077
4136
|
* ```
|
|
4078
4137
|
*
|
|
4079
4138
|
* @example
|
|
4080
4139
|
* ```tsx
|
|
4081
|
-
*
|
|
4082
|
-
*
|
|
4083
|
-
* name: "showWeatherCard",
|
|
4084
|
-
* parameters: z.object({ city: z.string() }),
|
|
4085
|
-
* render: ({ city }) => <div>{city}</div>,
|
|
4140
|
+
* useDefaultRenderTool({
|
|
4141
|
+
* render: ({ name, status }) => <div>{name}: {status}</div>,
|
|
4086
4142
|
* });
|
|
4087
4143
|
* ```
|
|
4088
4144
|
*
|
|
4089
4145
|
* @example
|
|
4090
4146
|
* ```tsx
|
|
4091
|
-
*
|
|
4147
|
+
* useDefaultRenderTool(
|
|
4092
4148
|
* {
|
|
4093
|
-
*
|
|
4094
|
-
*
|
|
4095
|
-
*
|
|
4096
|
-
* agentId: "support-agent",
|
|
4149
|
+
* render: ({ name, result }) => (
|
|
4150
|
+
* <ToolEventRow title={name} payload={result} compact={compactMode} />
|
|
4151
|
+
* ),
|
|
4097
4152
|
* },
|
|
4098
|
-
* [
|
|
4153
|
+
* [compactMode],
|
|
4099
4154
|
* );
|
|
4100
4155
|
* ```
|
|
4101
4156
|
*/
|
|
4102
|
-
function
|
|
4103
|
-
const
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
description: fullDescription,
|
|
4108
|
-
parameters: config.parameters,
|
|
4109
|
-
render: ({ args }) => {
|
|
4110
|
-
const Component = config.render;
|
|
4111
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...args });
|
|
4112
|
-
},
|
|
4113
|
-
agentId: config.agentId,
|
|
4114
|
-
followUp: config.followUp
|
|
4157
|
+
function useDefaultRenderTool(config, deps) {
|
|
4158
|
+
const userRender = config?.render;
|
|
4159
|
+
useRenderTool({
|
|
4160
|
+
name: "*",
|
|
4161
|
+
render: userRender ? (raw) => userRender(adaptRendererProps(raw)) : (raw) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(raw) })
|
|
4115
4162
|
}, deps);
|
|
4116
4163
|
}
|
|
4164
|
+
/**
|
|
4165
|
+
* Guarded JSON.stringify used inside the expanded `<pre>` blocks. A circular
|
|
4166
|
+
* reference would otherwise crash the entire React tree on render.
|
|
4167
|
+
*/
|
|
4168
|
+
function safeStringifyForPre(value) {
|
|
4169
|
+
try {
|
|
4170
|
+
return JSON.stringify(value, null, 2);
|
|
4171
|
+
} catch (err) {
|
|
4172
|
+
console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for default renderer; falling back to String():", err);
|
|
4173
|
+
try {
|
|
4174
|
+
return String(value);
|
|
4175
|
+
} catch (innerErr) {
|
|
4176
|
+
console.warn("[CopilotKit] safeStringifyForPre: value could not be stringified:", innerErr);
|
|
4177
|
+
return "[unserializable]";
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
function DefaultToolCallRenderer({ name, toolCallId, parameters, status, result }) {
|
|
4182
|
+
const [isExpanded, setIsExpanded] = (0, react.useState)(false);
|
|
4183
|
+
const isActive = status === "inProgress" || status === "executing";
|
|
4184
|
+
const isComplete = status === "complete";
|
|
4185
|
+
const statusLabel = isActive ? "Running" : isComplete ? "Done" : status;
|
|
4186
|
+
const dotClassName = isActive ? "cpk:bg-amber-500" : isComplete ? "cpk:bg-emerald-500" : "cpk:bg-zinc-400";
|
|
4187
|
+
const badgeClassName = isActive ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : isComplete ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300";
|
|
4188
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4189
|
+
"data-testid": "copilot-tool-render",
|
|
4190
|
+
"data-tool-name": name,
|
|
4191
|
+
"data-tool-call-id": toolCallId,
|
|
4192
|
+
"data-status": status,
|
|
4193
|
+
"data-args": safeStringifyForAttr(parameters),
|
|
4194
|
+
"data-result": safeStringifyForAttr(result),
|
|
4195
|
+
className: "cpk:mt-2 cpk:pb-2",
|
|
4196
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4197
|
+
className: "cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:bg-white/70 cpk:p-4 cpk:shadow-sm cpk:backdrop-blur cpk:dark:border-zinc-800/60 cpk:dark:bg-zinc-900/50",
|
|
4198
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4199
|
+
type: "button",
|
|
4200
|
+
"aria-expanded": isExpanded,
|
|
4201
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
4202
|
+
className: "cpk:flex cpk:w-full cpk:cursor-pointer cpk:select-none cpk:items-center cpk:justify-between cpk:gap-2.5 cpk:border-none cpk:bg-transparent cpk:p-0 cpk:m-0 cpk:text-left cpk:text-inherit",
|
|
4203
|
+
style: { font: "inherit" },
|
|
4204
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4205
|
+
className: "cpk:flex cpk:min-w-0 cpk:items-center cpk:gap-2",
|
|
4206
|
+
children: [
|
|
4207
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
4208
|
+
className: `cpk:h-3.5 cpk:w-3.5 cpk:flex-shrink-0 cpk:text-zinc-500 cpk:transition-transform cpk:dark:text-zinc-400 ${isExpanded ? "cpk:rotate-90" : ""}`,
|
|
4209
|
+
fill: "none",
|
|
4210
|
+
viewBox: "0 0 24 24",
|
|
4211
|
+
strokeWidth: 2,
|
|
4212
|
+
stroke: "currentColor",
|
|
4213
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
4214
|
+
strokeLinecap: "round",
|
|
4215
|
+
strokeLinejoin: "round",
|
|
4216
|
+
d: "M8.25 4.5l7.5 7.5-7.5 7.5"
|
|
4217
|
+
})
|
|
4218
|
+
}),
|
|
4219
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `cpk:inline-block cpk:h-2 cpk:w-2 cpk:flex-shrink-0 cpk:rounded-full ${dotClassName}` }),
|
|
4220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4221
|
+
"data-testid": "copilot-tool-render-name",
|
|
4222
|
+
className: "cpk:truncate cpk:text-[13px] cpk:font-semibold cpk:text-zinc-900 cpk:dark:text-zinc-100",
|
|
4223
|
+
children: name
|
|
4224
|
+
})
|
|
4225
|
+
]
|
|
4226
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4227
|
+
"data-testid": "copilot-tool-render-status",
|
|
4228
|
+
className: `cpk:inline-flex cpk:flex-shrink-0 cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-0.5 cpk:text-[11px] cpk:font-medium ${badgeClassName}`,
|
|
4229
|
+
children: statusLabel
|
|
4230
|
+
})]
|
|
4231
|
+
}), isExpanded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4232
|
+
className: "cpk:mt-3 cpk:grid cpk:gap-3",
|
|
4233
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4234
|
+
className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
4235
|
+
children: "Arguments"
|
|
4236
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
4237
|
+
className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
|
|
4238
|
+
children: safeStringifyForPre(parameters ?? {})
|
|
4239
|
+
})] }), result !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4240
|
+
className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
4241
|
+
children: "Result"
|
|
4242
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
4243
|
+
className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
|
|
4244
|
+
children: typeof result === "string" ? result : safeStringifyForPre(result)
|
|
4245
|
+
})] })]
|
|
4246
|
+
})]
|
|
4247
|
+
})
|
|
4248
|
+
});
|
|
4249
|
+
}
|
|
4250
|
+
function safeStringifyForAttr(value) {
|
|
4251
|
+
if (value === void 0 || value === null) return "";
|
|
4252
|
+
if (typeof value === "string") return value;
|
|
4253
|
+
try {
|
|
4254
|
+
return JSON.stringify(value);
|
|
4255
|
+
} catch (err) {
|
|
4256
|
+
console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for data-* attribute; falling back to String():", err);
|
|
4257
|
+
try {
|
|
4258
|
+
return String(value);
|
|
4259
|
+
} catch (innerErr) {
|
|
4260
|
+
console.warn("[CopilotKit] safeStringifyForAttr: value could not be stringified:", innerErr);
|
|
4261
|
+
return "";
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4117
4265
|
|
|
4118
4266
|
//#endregion
|
|
4119
4267
|
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
@@ -4851,7 +4999,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4851
4999
|
return (0, react.useSyncExternalStore)((0, react.useCallback)((onStoreChange) => {
|
|
4852
5000
|
const subscription = store.select(selector).subscribe(onStoreChange);
|
|
4853
5001
|
return () => subscription.unsubscribe();
|
|
4854
|
-
}, [store, selector]), () => selector(store.getState()));
|
|
5002
|
+
}, [store, selector]), () => selector(store.getState()), () => selector(store.getServerState()));
|
|
4855
5003
|
}
|
|
4856
5004
|
/**
|
|
4857
5005
|
* React hook for listing and managing Intelligence platform threads.
|
|
@@ -4894,7 +5042,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4894
5042
|
* }
|
|
4895
5043
|
* ```
|
|
4896
5044
|
*/
|
|
4897
|
-
function useThreads({ agentId, includeArchived, limit }) {
|
|
5045
|
+
function useThreads({ agentId, includeArchived, limit, enabled = true }) {
|
|
4898
5046
|
const { copilotkit } = useCopilotKit();
|
|
4899
5047
|
const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
|
|
4900
5048
|
const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
|
|
@@ -4911,6 +5059,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4911
5059
|
const storeError = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsError);
|
|
4912
5060
|
const hasMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectHasNextPage);
|
|
4913
5061
|
const isFetchingMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsFetchingNextPage);
|
|
5062
|
+
const isMutating = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsMutating);
|
|
4914
5063
|
const headersKey = (0, react.useMemo)(() => {
|
|
4915
5064
|
return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
|
|
4916
5065
|
}, [copilotkit.headers]);
|
|
@@ -4931,9 +5080,16 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4931
5080
|
return /* @__PURE__ */ new Error("Thread mutations are not available on this CopilotKit runtime");
|
|
4932
5081
|
}, [threadMutationsSupported]);
|
|
4933
5082
|
const [hasDispatchedContext, setHasDispatchedContext] = (0, react.useState)(false);
|
|
4934
|
-
const preConnectLoading = !!copilotkit.runtimeUrl && !threadEndpointsUnavailable && !hasDispatchedContext;
|
|
4935
|
-
const
|
|
4936
|
-
|
|
5083
|
+
const preConnectLoading = enabled && !!copilotkit.runtimeUrl && !threadEndpointsUnavailable && !hasDispatchedContext;
|
|
5084
|
+
const [configErrorDismissed, setConfigErrorDismissed] = (0, react.useState)(false);
|
|
5085
|
+
(0, react.useEffect)(() => {
|
|
5086
|
+
setConfigErrorDismissed(false);
|
|
5087
|
+
}, [runtimeError, threadEndpointsError]);
|
|
5088
|
+
const activeRuntimeError = configErrorDismissed ? null : runtimeError;
|
|
5089
|
+
const activeThreadEndpointsError = configErrorDismissed ? null : threadEndpointsError;
|
|
5090
|
+
const isLoading = activeRuntimeError || activeThreadEndpointsError ? false : preConnectLoading || storeIsLoading;
|
|
5091
|
+
const error = activeRuntimeError ?? activeThreadEndpointsError ?? storeError;
|
|
5092
|
+
const listError = storeError;
|
|
4937
5093
|
(0, react.useEffect)(() => {
|
|
4938
5094
|
store.start();
|
|
4939
5095
|
return () => {
|
|
@@ -4941,6 +5097,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4941
5097
|
};
|
|
4942
5098
|
}, [store]);
|
|
4943
5099
|
(0, react.useEffect)(() => {
|
|
5100
|
+
if (!enabled) return;
|
|
4944
5101
|
copilotkit.registerThreadStore(agentId, store);
|
|
4945
5102
|
return () => {
|
|
4946
5103
|
copilotkit.unregisterThreadStore(agentId);
|
|
@@ -4948,9 +5105,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4948
5105
|
}, [
|
|
4949
5106
|
copilotkit,
|
|
4950
5107
|
agentId,
|
|
4951
|
-
store
|
|
5108
|
+
store,
|
|
5109
|
+
enabled
|
|
4952
5110
|
]);
|
|
4953
5111
|
(0, react.useEffect)(() => {
|
|
5112
|
+
if (!enabled) {
|
|
5113
|
+
store.setContext(null);
|
|
5114
|
+
setHasDispatchedContext(false);
|
|
5115
|
+
return;
|
|
5116
|
+
}
|
|
4954
5117
|
if (!copilotkit.runtimeUrl) {
|
|
4955
5118
|
store.setContext(null);
|
|
4956
5119
|
setHasDispatchedContext(false);
|
|
@@ -4974,6 +5137,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4974
5137
|
setHasDispatchedContext(true);
|
|
4975
5138
|
}, [
|
|
4976
5139
|
store,
|
|
5140
|
+
enabled,
|
|
4977
5141
|
copilotkit.runtimeUrl,
|
|
4978
5142
|
runtimeStatus,
|
|
4979
5143
|
headersKey,
|
|
@@ -4997,9 +5161,16 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4997
5161
|
threads,
|
|
4998
5162
|
isLoading,
|
|
4999
5163
|
error,
|
|
5164
|
+
listError,
|
|
5000
5165
|
hasMoreThreads,
|
|
5001
5166
|
isFetchingMoreThreads,
|
|
5167
|
+
isMutating,
|
|
5002
5168
|
fetchMoreThreads: (0, react.useCallback)(() => store.fetchNextPage(), [store]),
|
|
5169
|
+
refetchThreads: (0, react.useCallback)(() => store.refetchThreads(), [store]),
|
|
5170
|
+
startNewThread: (0, react.useCallback)(() => {
|
|
5171
|
+
setConfigErrorDismissed(true);
|
|
5172
|
+
store.startNewThread();
|
|
5173
|
+
}, [store]),
|
|
5003
5174
|
renameThread,
|
|
5004
5175
|
archiveThread,
|
|
5005
5176
|
unarchiveThread,
|
|
@@ -6186,7 +6357,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6186
6357
|
ref,
|
|
6187
6358
|
"data-copilotkit": true,
|
|
6188
6359
|
"data-testid": "copilot-suggestions",
|
|
6189
|
-
className: cn("cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:
|
|
6360
|
+
className: cn("cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:@3xl:px-0 cpk:pointer-events-none", className),
|
|
6190
6361
|
...props
|
|
6191
6362
|
});
|
|
6192
6363
|
});
|
|
@@ -7291,7 +7462,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7291
7462
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7292
7463
|
className: "cpk:max-w-3xl cpk:mx-auto",
|
|
7293
7464
|
children: [BoundMessageView, hasSuggestions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7294
|
-
className: "cpk:pl-0 cpk:pr-4 cpk:
|
|
7465
|
+
className: "cpk:pl-0 cpk:pr-4 cpk:@3xl:px-0 cpk:mt-4",
|
|
7295
7466
|
children: BoundSuggestionView
|
|
7296
7467
|
}) : null]
|
|
7297
7468
|
})
|
|
@@ -7334,7 +7505,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7334
7505
|
onDragOver,
|
|
7335
7506
|
onDragLeave,
|
|
7336
7507
|
onDrop,
|
|
7337
|
-
className: cn("copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
7508
|
+
className: cn("copilotKitChat cpk:@container cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
7338
7509
|
...props,
|
|
7339
7510
|
children: [dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}), BoundWelcomeScreen]
|
|
7340
7511
|
});
|
|
@@ -7356,7 +7527,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7356
7527
|
onDragOver,
|
|
7357
7528
|
onDragLeave,
|
|
7358
7529
|
onDrop,
|
|
7359
|
-
className: cn("copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
7530
|
+
className: cn("copilotKitChat cpk:@container cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
7360
7531
|
...props,
|
|
7361
7532
|
children: [
|
|
7362
7533
|
dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}),
|
|
@@ -7395,7 +7566,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7395
7566
|
minHeight: 0
|
|
7396
7567
|
},
|
|
7397
7568
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7398
|
-
className: "cpk:px-4 cpk:
|
|
7569
|
+
className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
7399
7570
|
children
|
|
7400
7571
|
})
|
|
7401
7572
|
}),
|
|
@@ -7428,7 +7599,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7428
7599
|
...props,
|
|
7429
7600
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7430
7601
|
ref: contentRef,
|
|
7431
|
-
className: "cpk:px-4 cpk:
|
|
7602
|
+
className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
7432
7603
|
children
|
|
7433
7604
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7434
7605
|
ref: spacerRef,
|
|
@@ -7490,7 +7661,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7490
7661
|
if (!hasMounted) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7491
7662
|
className: "cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
|
|
7492
7663
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7493
|
-
className: "cpk:px-4 cpk:
|
|
7664
|
+
className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
7494
7665
|
children
|
|
7495
7666
|
})
|
|
7496
7667
|
});
|
|
@@ -7505,7 +7676,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7505
7676
|
children: [
|
|
7506
7677
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7507
7678
|
ref: contentRef,
|
|
7508
|
-
className: "cpk:px-4 cpk:
|
|
7679
|
+
className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
7509
7680
|
children
|
|
7510
7681
|
}),
|
|
7511
7682
|
BoundFeather,
|
|
@@ -7769,9 +7940,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7769
7940
|
const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
|
|
7770
7941
|
const [lastConnectedThreadId, setLastConnectedThreadId] = (0, react.useState)(null);
|
|
7771
7942
|
const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
|
|
7943
|
+
const previousThreadIdRef = (0, react.useRef)(null);
|
|
7944
|
+
const hasExplicitThreadIdRef = (0, react.useRef)(hasExplicitThreadId);
|
|
7945
|
+
hasExplicitThreadIdRef.current = hasExplicitThreadId;
|
|
7772
7946
|
(0, react.useEffect)(() => {
|
|
7947
|
+
const threadChanged = previousThreadIdRef.current !== resolvedThreadId;
|
|
7948
|
+
previousThreadIdRef.current = resolvedThreadId;
|
|
7773
7949
|
agent.threadId = resolvedThreadId;
|
|
7774
|
-
if (!hasExplicitThreadId)
|
|
7950
|
+
if (!hasExplicitThreadId) {
|
|
7951
|
+
if (threadChanged && agent.messages.length > 0) agent.setMessages([]);
|
|
7952
|
+
return;
|
|
7953
|
+
}
|
|
7775
7954
|
let detached = false;
|
|
7776
7955
|
const connectAbortController = new AbortController();
|
|
7777
7956
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
|
|
@@ -7785,6 +7964,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7785
7964
|
if (!detached) (typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 16))(() => {
|
|
7786
7965
|
if (!detached) setLastConnectedThreadId(resolvedThreadId);
|
|
7787
7966
|
});
|
|
7967
|
+
else if (!hasExplicitThreadIdRef.current) agentToConnect.setMessages([]);
|
|
7788
7968
|
}
|
|
7789
7969
|
};
|
|
7790
7970
|
connect(agent);
|
|
@@ -8135,18 +8315,46 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8135
8315
|
|
|
8136
8316
|
//#endregion
|
|
8137
8317
|
//#region src/v2/components/chat/CopilotModalHeader.tsx
|
|
8138
|
-
|
|
8318
|
+
/**
|
|
8319
|
+
* Reactively tracks whether the viewport is in the mobile range (≤767px) — the
|
|
8320
|
+
* same breakpoint the drawer + chat coordination use. SSR-safe: starts `false`
|
|
8321
|
+
* (desktop) so the server render and first client render agree, then syncs on
|
|
8322
|
+
* mount and on resize.
|
|
8323
|
+
*/
|
|
8324
|
+
function useIsMobileViewport() {
|
|
8325
|
+
const [isMobile, setIsMobile] = (0, react.useState)(false);
|
|
8326
|
+
(0, react.useEffect)(() => {
|
|
8327
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
8328
|
+
const mql = window.matchMedia("(max-width: 767px)");
|
|
8329
|
+
const update = () => setIsMobile(mql.matches);
|
|
8330
|
+
update();
|
|
8331
|
+
mql.addEventListener("change", update);
|
|
8332
|
+
return () => mql.removeEventListener("change", update);
|
|
8333
|
+
}, []);
|
|
8334
|
+
return isMobile;
|
|
8335
|
+
}
|
|
8336
|
+
function CopilotModalHeader({ title, titleContent, closeButton, drawerLauncher, children, className, ...rest }) {
|
|
8139
8337
|
const configuration = useCopilotChatConfiguration();
|
|
8140
8338
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
8141
8339
|
const resolvedTitle = title ?? fallbackTitle;
|
|
8340
|
+
const isMobile = useIsMobileViewport();
|
|
8341
|
+
const drawerRegistered = (configuration?.drawerRegistered ?? false) && isMobile;
|
|
8142
8342
|
const handleClose = (0, react.useCallback)(() => {
|
|
8143
8343
|
configuration?.setModalOpen?.(false);
|
|
8144
8344
|
}, [configuration]);
|
|
8345
|
+
const handleToggleDrawer = (0, react.useCallback)(() => {
|
|
8346
|
+
configuration?.setDrawerOpen?.(!configuration.drawerOpen);
|
|
8347
|
+
}, [configuration]);
|
|
8145
8348
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, { children: resolvedTitle });
|
|
8146
8349
|
const BoundCloseButton = renderSlot(closeButton, CopilotModalHeader.CloseButton, { onClick: handleClose });
|
|
8350
|
+
const BoundDrawerLauncher = drawerRegistered ? renderSlot(drawerLauncher, CopilotModalHeader.DrawerLauncher, {
|
|
8351
|
+
onClick: handleToggleDrawer,
|
|
8352
|
+
"aria-expanded": configuration?.drawerOpen ?? false
|
|
8353
|
+
}) : null;
|
|
8147
8354
|
if (children) return children({
|
|
8148
8355
|
titleContent: BoundTitle,
|
|
8149
8356
|
closeButton: BoundCloseButton,
|
|
8357
|
+
drawerLauncher: BoundDrawerLauncher,
|
|
8150
8358
|
title: resolvedTitle,
|
|
8151
8359
|
...rest
|
|
8152
8360
|
});
|
|
@@ -8159,8 +8367,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8159
8367
|
className: "cpk:flex cpk:w-full cpk:items-center cpk:gap-2",
|
|
8160
8368
|
children: [
|
|
8161
8369
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8162
|
-
className: "cpk:flex-1",
|
|
8163
|
-
"aria-hidden": "true"
|
|
8370
|
+
className: "cpk:flex cpk:flex-1 cpk:justify-start",
|
|
8371
|
+
children: BoundDrawerLauncher ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { "aria-hidden": "true" })
|
|
8164
8372
|
}),
|
|
8165
8373
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8166
8374
|
className: "cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center",
|
|
@@ -8193,9 +8401,21 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8193
8401
|
"aria-hidden": "true"
|
|
8194
8402
|
})
|
|
8195
8403
|
});
|
|
8404
|
+
_CopilotModalHeader.DrawerLauncher = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8405
|
+
type: "button",
|
|
8406
|
+
"data-testid": "copilot-threads-drawer-launcher",
|
|
8407
|
+
className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
|
|
8408
|
+
"aria-label": "Open threads",
|
|
8409
|
+
...props,
|
|
8410
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PanelLeftOpen, {
|
|
8411
|
+
className: "cpk:h-4 cpk:w-4",
|
|
8412
|
+
"aria-hidden": "true"
|
|
8413
|
+
})
|
|
8414
|
+
});
|
|
8196
8415
|
})(CopilotModalHeader || (CopilotModalHeader = {}));
|
|
8197
8416
|
CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
|
|
8198
8417
|
CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
|
|
8418
|
+
CopilotModalHeader.DrawerLauncher.displayName = "CopilotModalHeader.DrawerLauncher";
|
|
8199
8419
|
|
|
8200
8420
|
//#endregion
|
|
8201
8421
|
//#region src/v2/components/chat/CopilotSidebarView.tsx
|
|
@@ -8553,6 +8773,322 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8553
8773
|
}
|
|
8554
8774
|
CopilotPopup.displayName = "CopilotPopup";
|
|
8555
8775
|
|
|
8776
|
+
//#endregion
|
|
8777
|
+
//#region src/v2/components/chat/CopilotThreadsDrawer.tsx
|
|
8778
|
+
/**
|
|
8779
|
+
* Maps a {@link Thread} from {@link useThreads} to the element's
|
|
8780
|
+
* {@link DrawerThread} view shape. The shapes are structurally compatible; this
|
|
8781
|
+
* narrows to exactly the fields the element renders so the element never sees
|
|
8782
|
+
* platform-internal fields.
|
|
8783
|
+
*/
|
|
8784
|
+
function toDrawerThread(thread) {
|
|
8785
|
+
return {
|
|
8786
|
+
id: thread.id,
|
|
8787
|
+
name: thread.name,
|
|
8788
|
+
archived: thread.archived,
|
|
8789
|
+
createdAt: thread.createdAt,
|
|
8790
|
+
updatedAt: thread.updatedAt,
|
|
8791
|
+
...thread.lastRunAt !== void 0 ? { lastRunAt: thread.lastRunAt } : {}
|
|
8792
|
+
};
|
|
8793
|
+
}
|
|
8794
|
+
/** The chat input textarea's documented `data-testid`. */
|
|
8795
|
+
const CHAT_INPUT_TESTID = "copilot-chat-textarea";
|
|
8796
|
+
/** The chat view container's documented `data-testid`. */
|
|
8797
|
+
const CHAT_CONTAINER_TESTID = "copilot-chat";
|
|
8798
|
+
/**
|
|
8799
|
+
* Returns the chat input element for focus-return after a thread is selected.
|
|
8800
|
+
*
|
|
8801
|
+
* Best-effort and SCOPED: walks up from the drawer element looking for an
|
|
8802
|
+
* ancestor that contains a chat-view container (`data-testid="copilot-chat"`),
|
|
8803
|
+
* then returns the chat input within that subtree. This avoids focusing the
|
|
8804
|
+
* wrong composer on a page hosting more than one chat (multi-chat dashboards),
|
|
8805
|
+
* where a document-global lookup would grab whichever input appears first in
|
|
8806
|
+
* DOM order rather than the one this drawer drives.
|
|
8807
|
+
*
|
|
8808
|
+
* Falls back to a document-global lookup when no scoping ancestor is found
|
|
8809
|
+
* (e.g. the drawer and chat share no common container, or headless usage),
|
|
8810
|
+
* and returns `null` when there is no chat input at all.
|
|
8811
|
+
*
|
|
8812
|
+
* @param origin - The drawer element to scope the search from.
|
|
8813
|
+
*/
|
|
8814
|
+
function findChatInput(origin) {
|
|
8815
|
+
if (typeof document === "undefined") return null;
|
|
8816
|
+
const container = origin?.closest?.(`[data-testid="${CHAT_CONTAINER_TESTID}"]`);
|
|
8817
|
+
if (container) {
|
|
8818
|
+
const scoped = container.querySelector(`[data-testid="${CHAT_INPUT_TESTID}"]`);
|
|
8819
|
+
if (scoped) return scoped;
|
|
8820
|
+
}
|
|
8821
|
+
return document.querySelector(`[data-testid="${CHAT_INPUT_TESTID}"]`);
|
|
8822
|
+
}
|
|
8823
|
+
/**
|
|
8824
|
+
* React wrapper for the shadow-DOM `<copilotkit-threads-drawer>` threads drawer.
|
|
8825
|
+
*
|
|
8826
|
+
* Responsibilities:
|
|
8827
|
+
* - Registers the custom element on the client (SSR-safe; nothing renders
|
|
8828
|
+
* during prerender to avoid hydration mismatch).
|
|
8829
|
+
* - Feeds the element domain data: `threads`, `loading`, `error`,
|
|
8830
|
+
* `activeThreadId`, `licensed`, fetch-more state.
|
|
8831
|
+
* - Routes the element's nine outbound events to core thread operations
|
|
8832
|
+
* ({@link useThreads}) and chat-configuration changes.
|
|
8833
|
+
* - Registers with the surrounding chat configuration so the header
|
|
8834
|
+
* thread-list launcher appears, and binds the element `open` state to the
|
|
8835
|
+
* configuration's `drawerOpen`.
|
|
8836
|
+
*
|
|
8837
|
+
* License gating is two-pronged: the locked view shows when no license is configured
|
|
8838
|
+
* (the runtime reported no license status) OR the `threads` feature is
|
|
8839
|
+
* explicitly unlicensed. While unlicensed, the thread fetch is skipped entirely
|
|
8840
|
+
* so an unlicensed drawer issues no network requests.
|
|
8841
|
+
*
|
|
8842
|
+
* Thread switching needs no host wiring: when `onThreadSelect`/`onNewThread`
|
|
8843
|
+
* are omitted, the wrapper drives the surrounding chat configuration directly
|
|
8844
|
+
* ({@link CopilotChatConfigurationValue.setActiveThreadId} /
|
|
8845
|
+
* {@link CopilotChatConfigurationValue.startNewThread}), so a bare drawer
|
|
8846
|
+
* connects to the picked thread and shows the welcome screen on "+ New". Pass
|
|
8847
|
+
* the callbacks only to take control yourself.
|
|
8848
|
+
*
|
|
8849
|
+
* @example
|
|
8850
|
+
* ```tsx
|
|
8851
|
+
* // Callback-free: the drawer drives the chat configuration itself.
|
|
8852
|
+
* <CopilotKitProvider runtimeUrl="/api/copilotkit" publicLicenseKey="ck_pub_...">
|
|
8853
|
+
* <CopilotChat />
|
|
8854
|
+
* <CopilotThreadsDrawer />
|
|
8855
|
+
* </CopilotKitProvider>
|
|
8856
|
+
* ```
|
|
8857
|
+
*/
|
|
8858
|
+
function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
|
|
8859
|
+
const configuration = useCopilotChatConfiguration();
|
|
8860
|
+
const { status, checkFeature } = useLicenseContext();
|
|
8861
|
+
const licensePresent = status === "valid" || status === "expiring";
|
|
8862
|
+
const featureLicensed = checkFeature("threads");
|
|
8863
|
+
const licensed = licensePresent && featureLicensed;
|
|
8864
|
+
const licensePending = status === null;
|
|
8865
|
+
const resolvedAgentId = agentId ?? configuration?.agentId ?? "default";
|
|
8866
|
+
const activeThreadId = configuration?.threadId ?? null;
|
|
8867
|
+
const { threads, isLoading, listError, hasMoreThreads, isFetchingMoreThreads, archiveThread, unarchiveThread, deleteThread, fetchMoreThreads, refetchThreads, startNewThread } = useThreads({
|
|
8868
|
+
agentId: resolvedAgentId,
|
|
8869
|
+
includeArchived: true,
|
|
8870
|
+
enabled: licensed,
|
|
8871
|
+
...limit !== void 0 ? { limit } : {}
|
|
8872
|
+
});
|
|
8873
|
+
const drawerThreads = (0, react.useMemo)(() => threads.map(toDrawerThread), [threads]);
|
|
8874
|
+
const elementRef = (0, react.useRef)(null);
|
|
8875
|
+
const [mounted, setMounted] = (0, react.useState)(false);
|
|
8876
|
+
(0, react.useEffect)(() => {
|
|
8877
|
+
(0, _copilotkit_web_components_threads_drawer.defineCopilotKitThreadsDrawer)();
|
|
8878
|
+
setMounted(true);
|
|
8879
|
+
}, []);
|
|
8880
|
+
const registerDrawer = configuration?.registerDrawer;
|
|
8881
|
+
(0, react.useEffect)(() => {
|
|
8882
|
+
if (!registerDrawer) return;
|
|
8883
|
+
return registerDrawer();
|
|
8884
|
+
}, [registerDrawer]);
|
|
8885
|
+
const [localDrawerOpen, setLocalDrawerOpen] = (0, react.useState)(false);
|
|
8886
|
+
const drawerOpen = configuration ? configuration.drawerOpen : localDrawerOpen;
|
|
8887
|
+
const setDrawerOpen = configuration ? configuration.setDrawerOpen : setLocalDrawerOpen;
|
|
8888
|
+
const setActiveThreadId = configuration?.setActiveThreadId;
|
|
8889
|
+
const startNewThreadConfig = configuration?.startNewThread;
|
|
8890
|
+
const handleThreadSelected = (0, react.useCallback)((threadId) => {
|
|
8891
|
+
if (onThreadSelect) onThreadSelect(threadId);
|
|
8892
|
+
else setActiveThreadId?.(threadId, { explicit: true });
|
|
8893
|
+
findChatInput(elementRef.current)?.focus();
|
|
8894
|
+
}, [onThreadSelect, setActiveThreadId]);
|
|
8895
|
+
const handleNewThread = (0, react.useCallback)(() => {
|
|
8896
|
+
startNewThread();
|
|
8897
|
+
if (onNewThread) onNewThread();
|
|
8898
|
+
else startNewThreadConfig?.();
|
|
8899
|
+
}, [
|
|
8900
|
+
startNewThread,
|
|
8901
|
+
onNewThread,
|
|
8902
|
+
startNewThreadConfig
|
|
8903
|
+
]);
|
|
8904
|
+
const handleArchive = (0, react.useCallback)((threadId) => {
|
|
8905
|
+
archiveThread(threadId).catch((err) => {
|
|
8906
|
+
console.error("CopilotThreadsDrawer: archiveThread failed", err);
|
|
8907
|
+
});
|
|
8908
|
+
}, [archiveThread]);
|
|
8909
|
+
const handleUnarchive = (0, react.useCallback)((threadId) => {
|
|
8910
|
+
unarchiveThread(threadId).catch((err) => {
|
|
8911
|
+
console.error("CopilotThreadsDrawer: unarchiveThread failed", err);
|
|
8912
|
+
});
|
|
8913
|
+
}, [unarchiveThread]);
|
|
8914
|
+
const handleDelete = (0, react.useCallback)((threadId) => {
|
|
8915
|
+
const isActive = threadId === activeThreadId;
|
|
8916
|
+
deleteThread(threadId).then(() => {
|
|
8917
|
+
if (isActive) {
|
|
8918
|
+
startNewThread();
|
|
8919
|
+
if (onNewThread) onNewThread();
|
|
8920
|
+
else startNewThreadConfig?.();
|
|
8921
|
+
}
|
|
8922
|
+
}).catch((err) => {
|
|
8923
|
+
console.error("CopilotThreadsDrawer: deleteThread failed", err);
|
|
8924
|
+
});
|
|
8925
|
+
}, [
|
|
8926
|
+
deleteThread,
|
|
8927
|
+
activeThreadId,
|
|
8928
|
+
startNewThread,
|
|
8929
|
+
onNewThread,
|
|
8930
|
+
startNewThreadConfig
|
|
8931
|
+
]);
|
|
8932
|
+
const handleFilterChange = (0, react.useCallback)(() => {
|
|
8933
|
+
refetchThreads();
|
|
8934
|
+
}, [refetchThreads]);
|
|
8935
|
+
const handleRetry = (0, react.useCallback)((scope) => {
|
|
8936
|
+
if (scope === "fetch-more") fetchMoreThreads();
|
|
8937
|
+
else refetchThreads();
|
|
8938
|
+
}, [fetchMoreThreads, refetchThreads]);
|
|
8939
|
+
const handleOpenChange = (0, react.useCallback)((open) => {
|
|
8940
|
+
setDrawerOpen(open);
|
|
8941
|
+
}, [setDrawerOpen]);
|
|
8942
|
+
const handleLicensed = (0, react.useCallback)(() => {
|
|
8943
|
+
onLicensed?.();
|
|
8944
|
+
}, [onLicensed]);
|
|
8945
|
+
const handleLoadMore = (0, react.useCallback)(() => {
|
|
8946
|
+
fetchMoreThreads();
|
|
8947
|
+
}, [fetchMoreThreads]);
|
|
8948
|
+
const handlersRef = (0, react.useRef)({
|
|
8949
|
+
handleThreadSelected,
|
|
8950
|
+
handleNewThread,
|
|
8951
|
+
handleArchive,
|
|
8952
|
+
handleUnarchive,
|
|
8953
|
+
handleDelete,
|
|
8954
|
+
handleFilterChange,
|
|
8955
|
+
handleRetry,
|
|
8956
|
+
handleOpenChange,
|
|
8957
|
+
handleLicensed,
|
|
8958
|
+
handleLoadMore
|
|
8959
|
+
});
|
|
8960
|
+
handlersRef.current = {
|
|
8961
|
+
handleThreadSelected,
|
|
8962
|
+
handleNewThread,
|
|
8963
|
+
handleArchive,
|
|
8964
|
+
handleUnarchive,
|
|
8965
|
+
handleDelete,
|
|
8966
|
+
handleFilterChange,
|
|
8967
|
+
handleRetry,
|
|
8968
|
+
handleOpenChange,
|
|
8969
|
+
handleLicensed,
|
|
8970
|
+
handleLoadMore
|
|
8971
|
+
};
|
|
8972
|
+
(0, react.useEffect)(() => {
|
|
8973
|
+
const el = elementRef.current;
|
|
8974
|
+
if (!el) return;
|
|
8975
|
+
const onThreadSelected = (event) => {
|
|
8976
|
+
const detail = event.detail;
|
|
8977
|
+
handlersRef.current.handleThreadSelected(detail.threadId);
|
|
8978
|
+
};
|
|
8979
|
+
const onNewThreadEvent = () => handlersRef.current.handleNewThread();
|
|
8980
|
+
const onArchive = (event) => {
|
|
8981
|
+
const detail = event.detail;
|
|
8982
|
+
handlersRef.current.handleArchive(detail.threadId);
|
|
8983
|
+
};
|
|
8984
|
+
const onUnarchive = (event) => {
|
|
8985
|
+
const detail = event.detail;
|
|
8986
|
+
handlersRef.current.handleUnarchive(detail.threadId);
|
|
8987
|
+
};
|
|
8988
|
+
const onDelete = (event) => {
|
|
8989
|
+
const detail = event.detail;
|
|
8990
|
+
handlersRef.current.handleDelete(detail.threadId);
|
|
8991
|
+
};
|
|
8992
|
+
const onFilterChange = (_event) => {
|
|
8993
|
+
handlersRef.current.handleFilterChange();
|
|
8994
|
+
};
|
|
8995
|
+
const onOpenChangeEvent = (event) => {
|
|
8996
|
+
const detail = event.detail;
|
|
8997
|
+
handlersRef.current.handleOpenChange(detail.open);
|
|
8998
|
+
};
|
|
8999
|
+
const onRetry = (event) => {
|
|
9000
|
+
const detail = event.detail;
|
|
9001
|
+
handlersRef.current.handleRetry(detail.scope);
|
|
9002
|
+
};
|
|
9003
|
+
const onLicensedEvent = () => handlersRef.current.handleLicensed();
|
|
9004
|
+
const onLoadMore = () => handlersRef.current.handleLoadMore();
|
|
9005
|
+
el.addEventListener("thread-selected", onThreadSelected);
|
|
9006
|
+
el.addEventListener("new-thread", onNewThreadEvent);
|
|
9007
|
+
el.addEventListener("archive", onArchive);
|
|
9008
|
+
el.addEventListener("unarchive", onUnarchive);
|
|
9009
|
+
el.addEventListener("delete", onDelete);
|
|
9010
|
+
el.addEventListener("filter-change", onFilterChange);
|
|
9011
|
+
el.addEventListener("open-change", onOpenChangeEvent);
|
|
9012
|
+
el.addEventListener("retry", onRetry);
|
|
9013
|
+
el.addEventListener("licensed", onLicensedEvent);
|
|
9014
|
+
el.addEventListener("load-more", onLoadMore);
|
|
9015
|
+
return () => {
|
|
9016
|
+
el.removeEventListener("thread-selected", onThreadSelected);
|
|
9017
|
+
el.removeEventListener("new-thread", onNewThreadEvent);
|
|
9018
|
+
el.removeEventListener("archive", onArchive);
|
|
9019
|
+
el.removeEventListener("unarchive", onUnarchive);
|
|
9020
|
+
el.removeEventListener("delete", onDelete);
|
|
9021
|
+
el.removeEventListener("filter-change", onFilterChange);
|
|
9022
|
+
el.removeEventListener("open-change", onOpenChangeEvent);
|
|
9023
|
+
el.removeEventListener("retry", onRetry);
|
|
9024
|
+
el.removeEventListener("licensed", onLicensedEvent);
|
|
9025
|
+
el.removeEventListener("load-more", onLoadMore);
|
|
9026
|
+
};
|
|
9027
|
+
}, [mounted]);
|
|
9028
|
+
(0, react.useEffect)(() => {
|
|
9029
|
+
const el = elementRef.current;
|
|
9030
|
+
if (!el) return;
|
|
9031
|
+
el.threads = drawerThreads;
|
|
9032
|
+
}, [drawerThreads, mounted]);
|
|
9033
|
+
(0, react.useEffect)(() => {
|
|
9034
|
+
const el = elementRef.current;
|
|
9035
|
+
if (!el) return;
|
|
9036
|
+
el.loading = isLoading || licensePending;
|
|
9037
|
+
el.error = listError ? listError.message : null;
|
|
9038
|
+
el.activeThreadId = activeThreadId;
|
|
9039
|
+
el.licensed = licensed || licensePending;
|
|
9040
|
+
el.hasMore = hasMoreThreads;
|
|
9041
|
+
el.fetchingMore = isFetchingMoreThreads;
|
|
9042
|
+
}, [
|
|
9043
|
+
isLoading,
|
|
9044
|
+
listError,
|
|
9045
|
+
activeThreadId,
|
|
9046
|
+
licensed,
|
|
9047
|
+
licensePending,
|
|
9048
|
+
hasMoreThreads,
|
|
9049
|
+
isFetchingMoreThreads,
|
|
9050
|
+
mounted
|
|
9051
|
+
]);
|
|
9052
|
+
(0, react.useEffect)(() => {
|
|
9053
|
+
const el = elementRef.current;
|
|
9054
|
+
if (!el) return;
|
|
9055
|
+
el.open = drawerOpen;
|
|
9056
|
+
}, [drawerOpen, mounted]);
|
|
9057
|
+
(0, react.useEffect)(() => {
|
|
9058
|
+
const el = elementRef.current;
|
|
9059
|
+
if (!el) return;
|
|
9060
|
+
if (label !== void 0) el.label = label;
|
|
9061
|
+
}, [label, mounted]);
|
|
9062
|
+
(0, react.useEffect)(() => {
|
|
9063
|
+
const el = elementRef.current;
|
|
9064
|
+
if (!el) return;
|
|
9065
|
+
if (licenseUrl !== void 0) el.licenseUrl = licenseUrl;
|
|
9066
|
+
}, [licenseUrl, mounted]);
|
|
9067
|
+
const rowChildren = (0, react.useMemo)(() => {
|
|
9068
|
+
if (!renderRow) return null;
|
|
9069
|
+
return drawerThreads.map((drawerThread) => {
|
|
9070
|
+
const fullThread = threads.find((t) => t.id === drawerThread.id);
|
|
9071
|
+
if (!fullThread) return null;
|
|
9072
|
+
const content = renderRow(fullThread);
|
|
9073
|
+
if (content === null || content === void 0) return null;
|
|
9074
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9075
|
+
slot: `row:${drawerThread.id}`,
|
|
9076
|
+
children: content
|
|
9077
|
+
}, drawerThread.id);
|
|
9078
|
+
});
|
|
9079
|
+
}, [
|
|
9080
|
+
renderRow,
|
|
9081
|
+
drawerThreads,
|
|
9082
|
+
threads
|
|
9083
|
+
]);
|
|
9084
|
+
if (!mounted) return null;
|
|
9085
|
+
return react.default.createElement(_copilotkit_web_components_threads_drawer.COPILOTKIT_THREADS_DRAWER_TAG, {
|
|
9086
|
+
ref: elementRef,
|
|
9087
|
+
"data-testid": dataTestId
|
|
9088
|
+
}, rowChildren);
|
|
9089
|
+
}
|
|
9090
|
+
CopilotThreadsDrawer.displayName = "CopilotThreadsDrawer";
|
|
9091
|
+
|
|
8556
9092
|
//#endregion
|
|
8557
9093
|
//#region src/v2/components/WildcardToolCallRender.tsx
|
|
8558
9094
|
const WildcardToolCallRender = defineToolCallRenderer({
|
|
@@ -10668,6 +11204,7 @@ Object.defineProperty(exports, 'CopilotSidebarView', {
|
|
|
10668
11204
|
return CopilotSidebarView;
|
|
10669
11205
|
}
|
|
10670
11206
|
});
|
|
11207
|
+
exports.CopilotThreadsDrawer = CopilotThreadsDrawer;
|
|
10671
11208
|
exports.INTELLIGENCE_TURN_HEAD = INTELLIGENCE_TURN_HEAD;
|
|
10672
11209
|
exports.IntelligenceIndicator = IntelligenceIndicator;
|
|
10673
11210
|
exports.IntelligenceIndicatorView = IntelligenceIndicatorView;
|