@copilotkit/react-core 1.55.0-next.8 → 1.55.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/CHANGELOG.md +48 -5
- package/dist/{copilotkit-DNYSFuz5.mjs → copilotkit-BY5S1-0P.mjs} +2772 -858
- package/dist/copilotkit-BY5S1-0P.mjs.map +1 -0
- package/dist/{copilotkit-Dy5w3qEV.d.mts → copilotkit-BuhSUZHb.d.mts} +230 -17
- package/dist/copilotkit-BuhSUZHb.d.mts.map +1 -0
- package/dist/{copilotkit-B3Mb1yVE.cjs → copilotkit-Bz5-ImDl.cjs} +2776 -832
- package/dist/copilotkit-Bz5-ImDl.cjs.map +1 -0
- package/dist/{copilotkit-DBzgOMby.d.cts → copilotkit-dwDWYpya.d.cts} +230 -17
- package/dist/copilotkit-dwDWYpya.d.cts.map +1 -0
- package/dist/index.cjs +9 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +9 -4
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1624 -396
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +13 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +3 -3
- package/dist/v2/index.d.mts +3 -3
- package/dist/v2/index.mjs +3 -2
- package/dist/v2/index.umd.js +2746 -790
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +62 -54
- package/scripts/scope-preflight.mjs +1 -2
- package/src/components/CopilotListeners.tsx +41 -8
- package/src/components/copilot-provider/__tests__/copilot-messages-key.test.tsx +92 -0
- package/src/components/copilot-provider/copilotkit-props.tsx +4 -2
- package/src/components/copilot-provider/copilotkit.tsx +3 -3
- package/src/components/toast/toast-provider.tsx +269 -194
- package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +27 -16
- package/src/hooks/use-copilot-chat_internal.ts +15 -4
- package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +86 -22
- package/src/v2/__tests__/utils/test-helpers.tsx +107 -7
- package/src/v2/a2ui/A2UICatalogContext.tsx +79 -0
- package/src/v2/a2ui/A2UIMessageRenderer.tsx +125 -37
- package/src/v2/a2ui/A2UIToolCallRenderer.tsx +290 -0
- package/src/v2/components/CopilotKitInspector.tsx +2 -0
- package/src/v2/components/OpenGenerativeUIRenderer.tsx +598 -0
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.tsx +665 -0
- package/src/v2/components/chat/CopilotChat.tsx +197 -52
- package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +17 -2
- package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +481 -0
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +139 -0
- package/src/v2/components/chat/CopilotChatInput.tsx +146 -77
- package/src/v2/components/chat/CopilotChatMessageView.tsx +260 -151
- package/src/v2/components/chat/CopilotChatSuggestionView.tsx +1 -0
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +54 -0
- package/src/v2/components/chat/CopilotChatView.tsx +179 -66
- package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.tsx +168 -0
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +63 -2
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +544 -1
- package/src/v2/components/chat/__tests__/CopilotChatPerf.e2e.test.tsx +268 -0
- package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.tsx +249 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +5 -2
- package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +5 -2
- package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +60 -3
- package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +138 -0
- package/src/v2/components/chat/index.ts +9 -0
- package/src/v2/components/chat/scroll-element-context.ts +13 -0
- package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +8 -0
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +327 -0
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +1003 -0
- package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +13 -2
- package/src/v2/hooks/__tests__/use-attachments.test.tsx +169 -0
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +23 -4
- package/src/v2/hooks/__tests__/use-threads.test.tsx +54 -0
- package/src/v2/hooks/index.ts +5 -0
- package/src/v2/hooks/use-agent.tsx +220 -15
- package/src/v2/hooks/use-attachments.tsx +269 -0
- package/src/v2/hooks/use-frontend-tool.tsx +5 -2
- package/src/v2/hooks/use-render-activity-message.tsx +9 -2
- package/src/v2/hooks/use-render-custom-messages.tsx +6 -1
- package/src/v2/hooks/use-threads.tsx +35 -15
- package/src/v2/index.ts +5 -1
- package/src/v2/lib/__tests__/processPartialHtml.test.ts +112 -0
- package/src/v2/lib/__tests__/slots.test.ts +56 -0
- package/src/v2/lib/processPartialHtml.ts +45 -0
- package/src/v2/lib/slots.tsx +42 -1
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +9 -3
- package/src/v2/providers/CopilotKitProvider.tsx +268 -32
- package/src/v2/providers/SandboxFunctionsContext.ts +10 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.tsx +198 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +71 -0
- package/src/v2/providers/index.ts +7 -0
- package/src/v2/styles/globals.css +2 -1
- package/src/v2/types/index.ts +1 -0
- package/src/v2/types/sandbox-function.ts +11 -0
- package/dist/copilotkit-B3Mb1yVE.cjs.map +0 -1
- package/dist/copilotkit-DBzgOMby.d.cts.map +0 -1
- package/dist/copilotkit-DNYSFuz5.mjs.map +0 -1
- package/dist/copilotkit-Dy5w3qEV.d.mts.map +0 -1
- package/src/v2/components/__tests__/license-warning-banner.test.tsx +0 -46
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('
|
|
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', '
|
|
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.
|
|
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,
|
|
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('@tanstack/react-virtual'), require('react-dom'), 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', '@tanstack/react-virtual', 'react-dom', '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._tanstack_react_virtual,global.ReactDOM,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, _tanstack_react_virtual, react_dom, use_stick_to_bottom) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -37,13 +37,113 @@ react = __toESM(react);
|
|
|
37
37
|
_radix_ui_react_tooltip = __toESM(_radix_ui_react_tooltip);
|
|
38
38
|
_radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
39
39
|
|
|
40
|
+
//#region src/v2/lib/slots.tsx
|
|
41
|
+
/**
|
|
42
|
+
* Shallow equality comparison for objects.
|
|
43
|
+
*/
|
|
44
|
+
function shallowEqual(obj1, obj2) {
|
|
45
|
+
const keys1 = Object.keys(obj1);
|
|
46
|
+
const keys2 = Object.keys(obj2);
|
|
47
|
+
if (keys1.length !== keys2.length) return false;
|
|
48
|
+
for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
|
|
53
|
+
* class instances, and other exotic objects that happen to have typeof "object".
|
|
54
|
+
*/
|
|
55
|
+
function isPlainObject(obj) {
|
|
56
|
+
return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns the same reference as long as the value is shallowly equal to the
|
|
60
|
+
* previous render's value.
|
|
61
|
+
*
|
|
62
|
+
* - Identical references bail out immediately (O(1)).
|
|
63
|
+
* - Plain objects ({}) are shallow-compared key-by-key.
|
|
64
|
+
* - Arrays, Dates, class instances, functions, and primitives are compared by
|
|
65
|
+
* reference only — shallowEqual is never called on non-plain objects, which
|
|
66
|
+
* avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
|
|
67
|
+
*
|
|
68
|
+
* Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
|
|
69
|
+
* equality check isn't defeated by a new object reference on every render.
|
|
70
|
+
*/
|
|
71
|
+
function useShallowStableRef(value) {
|
|
72
|
+
const ref = (0, react.useRef)(value);
|
|
73
|
+
if (ref.current === value) return ref.current;
|
|
74
|
+
if (isPlainObject(ref.current) && isPlainObject(value)) {
|
|
75
|
+
if (shallowEqual(ref.current, value)) return ref.current;
|
|
76
|
+
}
|
|
77
|
+
ref.current = value;
|
|
78
|
+
return ref.current;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if a value is a React component type (function, class, forwardRef, memo, etc.)
|
|
82
|
+
*/
|
|
83
|
+
function isReactComponentType(value) {
|
|
84
|
+
if (typeof value === "function") return true;
|
|
85
|
+
if (value && typeof value === "object" && "$$typeof" in value && !react.default.isValidElement(value)) return true;
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Internal function to render a slot value as a React element (non-memoized).
|
|
90
|
+
*/
|
|
91
|
+
function renderSlotElement(slot, DefaultComponent, props) {
|
|
92
|
+
if (typeof slot === "string") {
|
|
93
|
+
const existingClassName = props.className;
|
|
94
|
+
return react.default.createElement(DefaultComponent, {
|
|
95
|
+
...props,
|
|
96
|
+
className: (0, tailwind_merge.twMerge)(existingClassName, slot)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (isReactComponentType(slot)) return react.default.createElement(slot, props);
|
|
100
|
+
if (slot && typeof slot === "object" && !react.default.isValidElement(slot)) return react.default.createElement(DefaultComponent, {
|
|
101
|
+
...props,
|
|
102
|
+
...slot
|
|
103
|
+
});
|
|
104
|
+
return react.default.createElement(DefaultComponent, props);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Internal memoized wrapper component for renderSlot.
|
|
108
|
+
* Uses forwardRef to support ref forwarding.
|
|
109
|
+
*/
|
|
110
|
+
const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function MemoizedSlotWrapper(props, ref) {
|
|
111
|
+
const { $slot, $component, ...rest } = props;
|
|
112
|
+
return renderSlotElement($slot, $component, ref !== null ? {
|
|
113
|
+
...rest,
|
|
114
|
+
ref
|
|
115
|
+
} : rest);
|
|
116
|
+
}), (prev, next) => {
|
|
117
|
+
if (prev.$slot !== next.$slot) return false;
|
|
118
|
+
if (prev.$component !== next.$component) return false;
|
|
119
|
+
const { $slot: _ps, $component: _pc, ...prevRest } = prev;
|
|
120
|
+
const { $slot: _ns, $component: _nc, ...nextRest } = next;
|
|
121
|
+
return shallowEqual(prevRest, nextRest);
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* Renders a slot value as a memoized React element.
|
|
125
|
+
* Automatically prevents unnecessary re-renders using shallow prop comparison.
|
|
126
|
+
* Supports ref forwarding.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })
|
|
130
|
+
*/
|
|
131
|
+
function renderSlot(slot, DefaultComponent, props) {
|
|
132
|
+
return react.default.createElement(MemoizedSlotWrapper, {
|
|
133
|
+
...props,
|
|
134
|
+
$slot: slot,
|
|
135
|
+
$component: DefaultComponent
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
40
140
|
//#region src/v2/providers/CopilotChatConfigurationProvider.tsx
|
|
41
141
|
const CopilotChatDefaultLabels = {
|
|
42
142
|
chatInputPlaceholder: "Type a message...",
|
|
43
143
|
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
|
44
144
|
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
|
45
145
|
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
46
|
-
chatInputToolbarAddButtonLabel: "Add
|
|
146
|
+
chatInputToolbarAddButtonLabel: "Add attachments",
|
|
47
147
|
chatInputToolbarToolsButtonLabel: "Tools",
|
|
48
148
|
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
49
149
|
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
@@ -64,14 +164,15 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
64
164
|
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
|
|
65
165
|
var _ref, _parentConfig$isModal, _parentConfig$setModa;
|
|
66
166
|
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
167
|
+
const stableLabels = useShallowStableRef(labels);
|
|
67
168
|
const mergedLabels = (0, react.useMemo)(() => {
|
|
68
169
|
var _parentConfig$labels;
|
|
69
170
|
return {
|
|
70
171
|
...CopilotChatDefaultLabels,
|
|
71
172
|
...(_parentConfig$labels = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels) !== null && _parentConfig$labels !== void 0 ? _parentConfig$labels : {},
|
|
72
|
-
...
|
|
173
|
+
...stableLabels !== null && stableLabels !== void 0 ? stableLabels : {}
|
|
73
174
|
};
|
|
74
|
-
}, [
|
|
175
|
+
}, [stableLabels, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels]);
|
|
75
176
|
const resolvedAgentId = (_ref = agentId !== null && agentId !== void 0 ? agentId : parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.agentId) !== null && _ref !== void 0 ? _ref : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
76
177
|
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
77
178
|
if (threadId) return threadId;
|
|
@@ -120,9 +221,9 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
120
221
|
|
|
121
222
|
//#endregion
|
|
122
223
|
//#region src/v2/lib/utils.ts
|
|
123
|
-
const twMerge$
|
|
224
|
+
const twMerge$7 = (0, tailwind_merge.extendTailwindMerge)({ prefix: "cpk" });
|
|
124
225
|
function cn(...inputs) {
|
|
125
|
-
return twMerge$
|
|
226
|
+
return twMerge$7((0, clsx.clsx)(inputs));
|
|
126
227
|
}
|
|
127
228
|
|
|
128
229
|
//#endregion
|
|
@@ -496,82 +597,11 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
496
597
|
});
|
|
497
598
|
CopilotChatAudioRecorder.displayName = "CopilotChatAudioRecorder";
|
|
498
599
|
|
|
499
|
-
//#endregion
|
|
500
|
-
//#region src/v2/lib/slots.tsx
|
|
501
|
-
/**
|
|
502
|
-
* Shallow equality comparison for objects.
|
|
503
|
-
*/
|
|
504
|
-
function shallowEqual(obj1, obj2) {
|
|
505
|
-
const keys1 = Object.keys(obj1);
|
|
506
|
-
const keys2 = Object.keys(obj2);
|
|
507
|
-
if (keys1.length !== keys2.length) return false;
|
|
508
|
-
for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Check if a value is a React component type (function, class, forwardRef, memo, etc.)
|
|
513
|
-
*/
|
|
514
|
-
function isReactComponentType(value) {
|
|
515
|
-
if (typeof value === "function") return true;
|
|
516
|
-
if (value && typeof value === "object" && "$$typeof" in value && !react.default.isValidElement(value)) return true;
|
|
517
|
-
return false;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* Internal function to render a slot value as a React element (non-memoized).
|
|
521
|
-
*/
|
|
522
|
-
function renderSlotElement(slot, DefaultComponent, props) {
|
|
523
|
-
if (typeof slot === "string") {
|
|
524
|
-
const existingClassName = props.className;
|
|
525
|
-
return react.default.createElement(DefaultComponent, {
|
|
526
|
-
...props,
|
|
527
|
-
className: (0, tailwind_merge.twMerge)(existingClassName, slot)
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
if (isReactComponentType(slot)) return react.default.createElement(slot, props);
|
|
531
|
-
if (slot && typeof slot === "object" && !react.default.isValidElement(slot)) return react.default.createElement(DefaultComponent, {
|
|
532
|
-
...props,
|
|
533
|
-
...slot
|
|
534
|
-
});
|
|
535
|
-
return react.default.createElement(DefaultComponent, props);
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Internal memoized wrapper component for renderSlot.
|
|
539
|
-
* Uses forwardRef to support ref forwarding.
|
|
540
|
-
*/
|
|
541
|
-
const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function MemoizedSlotWrapper(props, ref) {
|
|
542
|
-
const { $slot, $component, ...rest } = props;
|
|
543
|
-
return renderSlotElement($slot, $component, ref !== null ? {
|
|
544
|
-
...rest,
|
|
545
|
-
ref
|
|
546
|
-
} : rest);
|
|
547
|
-
}), (prev, next) => {
|
|
548
|
-
if (prev.$slot !== next.$slot) return false;
|
|
549
|
-
if (prev.$component !== next.$component) return false;
|
|
550
|
-
const { $slot: _ps, $component: _pc, ...prevRest } = prev;
|
|
551
|
-
const { $slot: _ns, $component: _nc, ...nextRest } = next;
|
|
552
|
-
return shallowEqual(prevRest, nextRest);
|
|
553
|
-
});
|
|
554
|
-
/**
|
|
555
|
-
* Renders a slot value as a memoized React element.
|
|
556
|
-
* Automatically prevents unnecessary re-renders using shallow prop comparison.
|
|
557
|
-
* Supports ref forwarding.
|
|
558
|
-
*
|
|
559
|
-
* @example
|
|
560
|
-
* renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })
|
|
561
|
-
*/
|
|
562
|
-
function renderSlot(slot, DefaultComponent, props) {
|
|
563
|
-
return react.default.createElement(MemoizedSlotWrapper, {
|
|
564
|
-
...props,
|
|
565
|
-
$slot: slot,
|
|
566
|
-
$component: DefaultComponent
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
|
|
570
600
|
//#endregion
|
|
571
601
|
//#region src/v2/components/chat/CopilotChatInput.tsx
|
|
572
602
|
const SLASH_MENU_MAX_VISIBLE_ITEMS = 5;
|
|
573
603
|
const SLASH_MENU_ITEM_HEIGHT_PX = 40;
|
|
574
|
-
function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning = false, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, onAddFile, onChange, value, toolsMenu, autoFocus =
|
|
604
|
+
function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning = false, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, onAddFile, onChange, value, toolsMenu, autoFocus = false, positioning = "static", keyboardHeight = 0, containerRef, showDisclaimer, textArea, sendButton, startTranscribeButton, cancelTranscribeButton, finishTranscribeButton, addMenuButton, audioRecorder, disclaimer, children, className, ...props }) {
|
|
575
605
|
var _config$labels;
|
|
576
606
|
const isControlled = value !== void 0;
|
|
577
607
|
const [internalValue, setInternalValue] = (0, react.useState)(() => value !== null && value !== void 0 ? value : "");
|
|
@@ -601,6 +631,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
601
631
|
paddingLeft: 0,
|
|
602
632
|
paddingRight: 0
|
|
603
633
|
});
|
|
634
|
+
const containerCacheRef = (0, react.useRef)(null);
|
|
604
635
|
const commandItems = (0, react.useMemo)(() => {
|
|
605
636
|
const entries = [];
|
|
606
637
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -647,7 +678,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
647
678
|
}
|
|
648
679
|
if ((config === null || config === void 0 ? void 0 : config.isModalOpen) && !previousModalStateRef.current) {
|
|
649
680
|
var _inputRef$current;
|
|
650
|
-
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
|
|
681
|
+
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus({ preventScroll: true });
|
|
651
682
|
}
|
|
652
683
|
previousModalStateRef.current = config === null || config === void 0 ? void 0 : config.isModalOpen;
|
|
653
684
|
}, [config === null || config === void 0 ? void 0 : config.isModalOpen, autoFocus]);
|
|
@@ -894,6 +925,25 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
894
925
|
return nextLayout;
|
|
895
926
|
});
|
|
896
927
|
}, []);
|
|
928
|
+
const updateContainerCache = (0, react.useCallback)(() => {
|
|
929
|
+
const grid = gridRef.current;
|
|
930
|
+
const addContainer = addButtonContainerRef.current;
|
|
931
|
+
const actionsContainer = actionsContainerRef.current;
|
|
932
|
+
if (!grid || !addContainer || !actionsContainer) return null;
|
|
933
|
+
const gridStyles = window.getComputedStyle(grid);
|
|
934
|
+
const paddingLeft = parseFloat(gridStyles.paddingLeft) || 0;
|
|
935
|
+
const paddingRight = parseFloat(gridStyles.paddingRight) || 0;
|
|
936
|
+
const columnGap = parseFloat(gridStyles.columnGap) || 0;
|
|
937
|
+
const gridAvailableWidth = grid.clientWidth - paddingLeft - paddingRight;
|
|
938
|
+
if (gridAvailableWidth <= 0) return null;
|
|
939
|
+
const addWidth = addContainer.getBoundingClientRect().width;
|
|
940
|
+
const actionsWidth = actionsContainer.getBoundingClientRect().width;
|
|
941
|
+
const compactWidth = Math.max(gridAvailableWidth - addWidth - actionsWidth - columnGap * 2, 0);
|
|
942
|
+
if (compactWidth <= 0) return null;
|
|
943
|
+
const result = { compactWidth };
|
|
944
|
+
containerCacheRef.current = result;
|
|
945
|
+
return result;
|
|
946
|
+
}, []);
|
|
897
947
|
const evaluateLayout = (0, react.useCallback)(() => {
|
|
898
948
|
if (mode !== "input") {
|
|
899
949
|
updateLayout("compact");
|
|
@@ -919,32 +969,33 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
919
969
|
const renderedMultiline = baseline > 0 ? scrollHeight > baseline + 1 : false;
|
|
920
970
|
let shouldExpand = hasExplicitBreak || renderedMultiline;
|
|
921
971
|
if (!shouldExpand) {
|
|
922
|
-
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
if (gridAvailableWidth > 0) {
|
|
928
|
-
var _measurementCanvasRef;
|
|
929
|
-
const addWidth = addContainer.getBoundingClientRect().width;
|
|
930
|
-
const actionsWidth = actionsContainer.getBoundingClientRect().width;
|
|
931
|
-
const compactWidth = Math.max(gridAvailableWidth - addWidth - actionsWidth - columnGap * 2, 0);
|
|
932
|
-
const canvas = (_measurementCanvasRef = measurementCanvasRef.current) !== null && _measurementCanvasRef !== void 0 ? _measurementCanvasRef : document.createElement("canvas");
|
|
933
|
-
if (!measurementCanvasRef.current) measurementCanvasRef.current = canvas;
|
|
934
|
-
const context = canvas.getContext("2d");
|
|
935
|
-
if (context) {
|
|
972
|
+
var _containerCacheRef$cu;
|
|
973
|
+
const cache = (_containerCacheRef$cu = containerCacheRef.current) !== null && _containerCacheRef$cu !== void 0 ? _containerCacheRef$cu : updateContainerCache();
|
|
974
|
+
if (cache && cache.compactWidth > 0) {
|
|
975
|
+
const compactInnerWidth = Math.max(cache.compactWidth - (measurementsRef.current.paddingLeft || 0) - (measurementsRef.current.paddingRight || 0), 0);
|
|
976
|
+
if (compactInnerWidth > 0) {
|
|
936
977
|
const textareaStyles = window.getComputedStyle(textarea);
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
let longestWidth = 0;
|
|
942
|
-
for (const line of lines) {
|
|
943
|
-
const metrics = context.measureText(line || " ");
|
|
944
|
-
if (metrics.width > longestWidth) longestWidth = metrics.width;
|
|
945
|
-
}
|
|
946
|
-
if (longestWidth > compactInnerWidth) shouldExpand = true;
|
|
978
|
+
let font = textareaStyles.font;
|
|
979
|
+
if (!font) {
|
|
980
|
+
const { fontStyle, fontVariant, fontWeight, fontSize, lineHeight, fontFamily } = textareaStyles;
|
|
981
|
+
if (fontSize && fontFamily) font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`;
|
|
947
982
|
}
|
|
983
|
+
if (font === null || font === void 0 ? void 0 : font.trim()) {
|
|
984
|
+
var _measurementCanvasRef;
|
|
985
|
+
const canvas = (_measurementCanvasRef = measurementCanvasRef.current) !== null && _measurementCanvasRef !== void 0 ? _measurementCanvasRef : document.createElement("canvas");
|
|
986
|
+
if (!measurementCanvasRef.current) measurementCanvasRef.current = canvas;
|
|
987
|
+
const context = canvas.getContext("2d");
|
|
988
|
+
if (context) {
|
|
989
|
+
context.font = font;
|
|
990
|
+
const lines = resolvedValue.length > 0 ? resolvedValue.split("\n") : [""];
|
|
991
|
+
let longestWidth = 0;
|
|
992
|
+
for (const line of lines) {
|
|
993
|
+
const metrics = context.measureText(line || " ");
|
|
994
|
+
if (metrics.width > longestWidth) longestWidth = metrics.width;
|
|
995
|
+
}
|
|
996
|
+
if (longestWidth > compactInnerWidth) shouldExpand = true;
|
|
997
|
+
} else if (process.env.NODE_ENV !== "production") console.warn("[CopilotChatInput] canvas.getContext('2d') returned null. Text-width-based expansion will be unavailable.");
|
|
998
|
+
} else if (process.env.NODE_ENV !== "production") console.warn("[CopilotChatInput] Could not resolve textarea font for layout measurement. Text-width-based expansion will be skipped until the next evaluation.");
|
|
948
999
|
}
|
|
949
1000
|
}
|
|
950
1001
|
}
|
|
@@ -954,6 +1005,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
954
1005
|
ensureMeasurements,
|
|
955
1006
|
mode,
|
|
956
1007
|
resolvedValue,
|
|
1008
|
+
updateContainerCache,
|
|
957
1009
|
updateLayout
|
|
958
1010
|
]);
|
|
959
1011
|
(0, react.useLayoutEffect)(() => {
|
|
@@ -966,11 +1018,17 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
966
1018
|
const addContainer = addButtonContainerRef.current;
|
|
967
1019
|
const actionsContainer = actionsContainerRef.current;
|
|
968
1020
|
if (!textarea || !grid || !addContainer || !actionsContainer) return;
|
|
969
|
-
const
|
|
1021
|
+
const containerTargets = new Set([
|
|
1022
|
+
grid,
|
|
1023
|
+
addContainer,
|
|
1024
|
+
actionsContainer
|
|
1025
|
+
]);
|
|
1026
|
+
const scheduleEvaluation = (invalidateCache) => {
|
|
970
1027
|
if (ignoreResizeRef.current) {
|
|
971
1028
|
ignoreResizeRef.current = false;
|
|
972
1029
|
return;
|
|
973
1030
|
}
|
|
1031
|
+
if (invalidateCache) containerCacheRef.current = null;
|
|
974
1032
|
if (typeof window === "undefined") {
|
|
975
1033
|
evaluateLayout();
|
|
976
1034
|
return;
|
|
@@ -981,8 +1039,13 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
981
1039
|
evaluateLayout();
|
|
982
1040
|
});
|
|
983
1041
|
};
|
|
984
|
-
const observer = new ResizeObserver(() => {
|
|
985
|
-
|
|
1042
|
+
const observer = new ResizeObserver((entries) => {
|
|
1043
|
+
let shouldInvalidate = false;
|
|
1044
|
+
for (const entry of entries) if (containerTargets.has(entry.target)) {
|
|
1045
|
+
shouldInvalidate = true;
|
|
1046
|
+
break;
|
|
1047
|
+
}
|
|
1048
|
+
scheduleEvaluation(shouldInvalidate);
|
|
986
1049
|
});
|
|
987
1050
|
observer.observe(grid);
|
|
988
1051
|
observer.observe(addContainer);
|
|
@@ -1133,6 +1196,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1133
1196
|
var _config$labels3;
|
|
1134
1197
|
const config = useCopilotChatConfiguration();
|
|
1135
1198
|
const labels = (_config$labels3 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels3 !== void 0 ? _config$labels3 : CopilotChatDefaultLabels;
|
|
1199
|
+
const [mounted, setMounted] = (0, react.useState)(false);
|
|
1200
|
+
(0, react.useEffect)(() => setMounted(true), []);
|
|
1136
1201
|
const menuItems = (0, react.useMemo)(() => {
|
|
1137
1202
|
const items = [];
|
|
1138
1203
|
if (onAddFile) items.push({
|
|
@@ -1163,26 +1228,28 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1163
1228
|
}), []);
|
|
1164
1229
|
const hasMenuItems = menuItems.length > 0;
|
|
1165
1230
|
const isDisabled = disabled || !hasMenuItems;
|
|
1231
|
+
const button = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
1232
|
+
type: "button",
|
|
1233
|
+
"data-testid": "copilot-add-menu-button",
|
|
1234
|
+
variant: "chatInputToolbarSecondary",
|
|
1235
|
+
size: "chatInputToolbarIcon",
|
|
1236
|
+
className: (0, tailwind_merge.twMerge)("cpk:ml-1", className),
|
|
1237
|
+
disabled: isDisabled,
|
|
1238
|
+
...props,
|
|
1239
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "cpk:size-[20px]" })
|
|
1240
|
+
});
|
|
1241
|
+
if (!mounted) return button;
|
|
1166
1242
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, {
|
|
1167
1243
|
asChild: true,
|
|
1168
1244
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuTrigger, {
|
|
1169
1245
|
asChild: true,
|
|
1170
|
-
children:
|
|
1171
|
-
type: "button",
|
|
1172
|
-
"data-testid": "copilot-add-menu-button",
|
|
1173
|
-
variant: "chatInputToolbarSecondary",
|
|
1174
|
-
size: "chatInputToolbarIcon",
|
|
1175
|
-
className: (0, tailwind_merge.twMerge)("cpk:ml-1", className),
|
|
1176
|
-
disabled: isDisabled,
|
|
1177
|
-
...props,
|
|
1178
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "cpk:size-[20px]" })
|
|
1179
|
-
})
|
|
1246
|
+
children: button
|
|
1180
1247
|
})
|
|
1181
1248
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipContent, {
|
|
1182
1249
|
side: "bottom",
|
|
1183
1250
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1184
1251
|
className: "cpk:flex cpk:items-center cpk:gap-1 cpk:text-xs cpk:font-medium",
|
|
1185
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Add
|
|
1252
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Add attachments" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
1186
1253
|
className: "cpk:rounded cpk:bg-[#4a4a4a] cpk:px-1 cpk:py-[1px] cpk:font-mono cpk:text-[11px] cpk:text-white cpk:dark:bg-[#e0e0e0] cpk:dark:text-black",
|
|
1187
1254
|
children: "/"
|
|
1188
1255
|
})]
|
|
@@ -1199,24 +1266,10 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1199
1266
|
const config = useCopilotChatConfiguration();
|
|
1200
1267
|
const labels = (_config$labels4 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels4 !== void 0 ? _config$labels4 : CopilotChatDefaultLabels;
|
|
1201
1268
|
(0, react.useImperativeHandle)(ref, () => internalTextareaRef.current);
|
|
1202
|
-
(0, react.useEffect)(() => {
|
|
1203
|
-
const textarea = internalTextareaRef.current;
|
|
1204
|
-
if (!textarea) return;
|
|
1205
|
-
const handleFocus = () => {
|
|
1206
|
-
setTimeout(() => {
|
|
1207
|
-
textarea.scrollIntoView({
|
|
1208
|
-
behavior: "smooth",
|
|
1209
|
-
block: "nearest"
|
|
1210
|
-
});
|
|
1211
|
-
}, 300);
|
|
1212
|
-
};
|
|
1213
|
-
textarea.addEventListener("focus", handleFocus);
|
|
1214
|
-
return () => textarea.removeEventListener("focus", handleFocus);
|
|
1215
|
-
}, []);
|
|
1216
1269
|
(0, react.useEffect)(() => {
|
|
1217
1270
|
if (autoFocus) {
|
|
1218
1271
|
var _internalTextareaRef$;
|
|
1219
|
-
(_internalTextareaRef$ = internalTextareaRef.current) === null || _internalTextareaRef$ === void 0 || _internalTextareaRef$.focus();
|
|
1272
|
+
(_internalTextareaRef$ = internalTextareaRef.current) === null || _internalTextareaRef$ === void 0 || _internalTextareaRef$.focus({ preventScroll: true });
|
|
1220
1273
|
}
|
|
1221
1274
|
}, [autoFocus]);
|
|
1222
1275
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
@@ -1936,128 +1989,991 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1936
1989
|
};
|
|
1937
1990
|
|
|
1938
1991
|
//#endregion
|
|
1939
|
-
//#region src/v2/
|
|
1940
|
-
|
|
1941
|
-
function
|
|
1942
|
-
|
|
1943
|
-
(0, _copilotkit_a2ui_renderer.initializeDefaultCatalog)();
|
|
1944
|
-
(0, _copilotkit_a2ui_renderer.injectStyles)();
|
|
1945
|
-
initialized = true;
|
|
1946
|
-
}
|
|
1992
|
+
//#region src/v2/providers/SandboxFunctionsContext.ts
|
|
1993
|
+
const SandboxFunctionsContext = (0, react.createContext)([]);
|
|
1994
|
+
function useSandboxFunctions() {
|
|
1995
|
+
return (0, react.useContext)(SandboxFunctionsContext);
|
|
1947
1996
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
(0, react.useEffect)(() => {
|
|
1959
|
-
if (!content || !Array.isArray(content.operations)) {
|
|
1960
|
-
lastSignatureRef.current = null;
|
|
1961
|
-
setOperations([]);
|
|
1962
|
-
return;
|
|
1963
|
-
}
|
|
1964
|
-
const incoming = content.operations;
|
|
1965
|
-
const signature = stringifyOperations(incoming);
|
|
1966
|
-
if (signature && signature === lastSignatureRef.current) return;
|
|
1967
|
-
lastSignatureRef.current = signature;
|
|
1968
|
-
setOperations(incoming);
|
|
1969
|
-
}, [content]);
|
|
1970
|
-
const groupedOperations = (0, react.useMemo)(() => {
|
|
1971
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1972
|
-
for (const operation of operations) {
|
|
1973
|
-
var _getOperationSurfaceI;
|
|
1974
|
-
const surfaceId = (_getOperationSurfaceI = getOperationSurfaceId(operation)) !== null && _getOperationSurfaceI !== void 0 ? _getOperationSurfaceI : _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
|
|
1975
|
-
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
|
|
1976
|
-
groups.get(surfaceId).push(operation);
|
|
1977
|
-
}
|
|
1978
|
-
return groups;
|
|
1979
|
-
}, [operations]);
|
|
1980
|
-
if (!groupedOperations.size) return null;
|
|
1981
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1982
|
-
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
1983
|
-
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
1984
|
-
surfaceId,
|
|
1985
|
-
operations: ops,
|
|
1986
|
-
theme,
|
|
1987
|
-
agent,
|
|
1988
|
-
copilotkit
|
|
1989
|
-
}, surfaceId))
|
|
1990
|
-
});
|
|
1991
|
-
}
|
|
1992
|
-
};
|
|
1997
|
+
|
|
1998
|
+
//#endregion
|
|
1999
|
+
//#region src/v2/lib/processPartialHtml.ts
|
|
2000
|
+
/**
|
|
2001
|
+
* Extracts all complete `<style>` blocks from the raw HTML.
|
|
2002
|
+
* Returns the concatenated style tags, suitable for injection into `<head>`.
|
|
2003
|
+
*/
|
|
2004
|
+
function extractCompleteStyles(html) {
|
|
2005
|
+
const matches = html.match(/<style\b[^>]*>[\s\S]*?<\/style>/gi);
|
|
2006
|
+
return matches ? matches.join("") : "";
|
|
1993
2007
|
}
|
|
1994
2008
|
/**
|
|
1995
|
-
*
|
|
1996
|
-
*
|
|
2009
|
+
* Processes raw accumulated HTML for safe preview via innerHTML injection.
|
|
2010
|
+
* Pure function, no DOM dependencies.
|
|
2011
|
+
*
|
|
2012
|
+
* Pipeline (order matters):
|
|
2013
|
+
* 1. Strip incomplete tag at end
|
|
2014
|
+
* 2. Strip complete <style>, <script>, and <head> blocks
|
|
2015
|
+
* 3. Strip incomplete <style>/<script>/<head> blocks
|
|
2016
|
+
* 4. Strip incomplete HTML entities
|
|
2017
|
+
* 5. Extract body content (or use full string if no <body>)
|
|
1997
2018
|
*/
|
|
1998
|
-
function
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
});
|
|
2011
|
-
await copilotkit.runAgent({ agent });
|
|
2012
|
-
} finally {
|
|
2013
|
-
if (copilotkit.properties) {
|
|
2014
|
-
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
2015
|
-
copilotkit.setProperties(rest);
|
|
2016
|
-
}
|
|
2017
|
-
}
|
|
2018
|
-
}, [agent, copilotkit]),
|
|
2019
|
-
theme,
|
|
2020
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
2021
|
-
surfaceId,
|
|
2022
|
-
operations
|
|
2023
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_a2ui_renderer.A2UIRenderer, {
|
|
2024
|
-
surfaceId,
|
|
2025
|
-
className: "cpk:flex cpk:flex-1"
|
|
2026
|
-
})]
|
|
2027
|
-
})
|
|
2028
|
-
});
|
|
2019
|
+
function processPartialHtml(html) {
|
|
2020
|
+
let result = html;
|
|
2021
|
+
result = result.replace(/<[^>]*$/, "");
|
|
2022
|
+
result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*?<\/\1>/gi, "");
|
|
2023
|
+
result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*$/gi, "");
|
|
2024
|
+
result = result.replace(/&[a-zA-Z0-9#]*$/, "");
|
|
2025
|
+
const bodyMatch = result.match(/<body[^>]*>([\s\S]*)/i);
|
|
2026
|
+
if (bodyMatch) {
|
|
2027
|
+
result = bodyMatch[1];
|
|
2028
|
+
result = result.replace(/<\/body>[\s\S]*/i, "");
|
|
2029
|
+
}
|
|
2030
|
+
return result;
|
|
2029
2031
|
}
|
|
2032
|
+
|
|
2033
|
+
//#endregion
|
|
2034
|
+
//#region src/v2/components/OpenGenerativeUIRenderer.tsx
|
|
2035
|
+
const OpenGenerativeUIActivityType = "open-generative-ui";
|
|
2036
|
+
const OpenGenerativeUIContentSchema = zod.z.object({
|
|
2037
|
+
initialHeight: zod.z.number().optional(),
|
|
2038
|
+
generating: zod.z.boolean().optional(),
|
|
2039
|
+
css: zod.z.string().optional(),
|
|
2040
|
+
cssComplete: zod.z.boolean().optional(),
|
|
2041
|
+
html: zod.z.array(zod.z.string()).optional(),
|
|
2042
|
+
htmlComplete: zod.z.boolean().optional(),
|
|
2043
|
+
jsFunctions: zod.z.string().optional(),
|
|
2044
|
+
jsFunctionsComplete: zod.z.boolean().optional(),
|
|
2045
|
+
jsExpressions: zod.z.array(zod.z.string()).optional(),
|
|
2046
|
+
jsExpressionsComplete: zod.z.boolean().optional()
|
|
2047
|
+
});
|
|
2030
2048
|
/**
|
|
2031
|
-
*
|
|
2032
|
-
*
|
|
2049
|
+
* Schema for the generateSandboxedUi tool call arguments.
|
|
2050
|
+
* Used by the frontend tool renderer to display placeholder messages.
|
|
2033
2051
|
*/
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2052
|
+
const GenerateSandboxedUiArgsSchema = zod.z.object({
|
|
2053
|
+
initialHeight: zod.z.number().optional(),
|
|
2054
|
+
placeholderMessages: zod.z.array(zod.z.string()).optional(),
|
|
2055
|
+
css: zod.z.string().optional(),
|
|
2056
|
+
html: zod.z.string().optional(),
|
|
2057
|
+
jsFunctions: zod.z.string().optional(),
|
|
2058
|
+
jsExpressions: zod.z.array(zod.z.string()).optional()
|
|
2059
|
+
});
|
|
2060
|
+
const THROTTLE_MS = 1e3;
|
|
2061
|
+
/**
|
|
2062
|
+
* Returns true when the inner component should re-render immediately
|
|
2063
|
+
* (no throttle delay).
|
|
2064
|
+
*/
|
|
2065
|
+
function shouldFlushImmediately(prev, next) {
|
|
2066
|
+
var _next$jsExpressions$l, _next$jsExpressions, _prev$jsExpressions$l, _prev$jsExpressions, _next$html, _prev$html;
|
|
2067
|
+
if (next.cssComplete && (!prev || !prev.cssComplete)) return true;
|
|
2068
|
+
if (next.htmlComplete) return true;
|
|
2069
|
+
if (next.generating === false) return true;
|
|
2070
|
+
if (next.jsFunctions && (!prev || !prev.jsFunctions)) return true;
|
|
2071
|
+
if (((_next$jsExpressions$l = (_next$jsExpressions = next.jsExpressions) === null || _next$jsExpressions === void 0 ? void 0 : _next$jsExpressions.length) !== null && _next$jsExpressions$l !== void 0 ? _next$jsExpressions$l : 0) > ((_prev$jsExpressions$l = prev === null || prev === void 0 || (_prev$jsExpressions = prev.jsExpressions) === null || _prev$jsExpressions === void 0 ? void 0 : _prev$jsExpressions.length) !== null && _prev$jsExpressions$l !== void 0 ? _prev$jsExpressions$l : 0)) return true;
|
|
2072
|
+
if (((_next$html = next.html) === null || _next$html === void 0 ? void 0 : _next$html.length) && (!prev || !((_prev$html = prev.html) === null || _prev$html === void 0 ? void 0 : _prev$html.length))) return true;
|
|
2073
|
+
return false;
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Outer wrapper — absorbs every parent re-render but only forwards
|
|
2077
|
+
* throttled content snapshots to the memoized inner component.
|
|
2078
|
+
*/
|
|
2079
|
+
const OpenGenerativeUIActivityRenderer = function OpenGenerativeUIActivityRenderer({ content }) {
|
|
2080
|
+
const latestContentRef = (0, react.useRef)(content);
|
|
2081
|
+
latestContentRef.current = content;
|
|
2082
|
+
const [throttledContent, setThrottledContent] = (0, react.useState)(content);
|
|
2083
|
+
const throttledContentRef = (0, react.useRef)(throttledContent);
|
|
2084
|
+
const timerRef = (0, react.useRef)(null);
|
|
2085
|
+
if (throttledContentRef.current !== content) {
|
|
2086
|
+
if (shouldFlushImmediately(throttledContentRef.current, content)) {
|
|
2087
|
+
if (timerRef.current !== null) {
|
|
2088
|
+
clearTimeout(timerRef.current);
|
|
2089
|
+
timerRef.current = null;
|
|
2090
|
+
}
|
|
2091
|
+
throttledContentRef.current = content;
|
|
2092
|
+
setThrottledContent(content);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
const flush = (0, react.useCallback)(() => {
|
|
2096
|
+
timerRef.current = null;
|
|
2097
|
+
const latest = latestContentRef.current;
|
|
2098
|
+
throttledContentRef.current = latest;
|
|
2099
|
+
setThrottledContent(latest);
|
|
2100
|
+
}, []);
|
|
2101
|
+
(0, react.useEffect)(() => {
|
|
2102
|
+
if (throttledContentRef.current === content) return;
|
|
2103
|
+
if (timerRef.current === null) timerRef.current = setTimeout(flush, THROTTLE_MS);
|
|
2104
|
+
}, [content, flush]);
|
|
2105
|
+
(0, react.useEffect)(() => {
|
|
2106
|
+
return () => {
|
|
2107
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
2108
|
+
};
|
|
2109
|
+
}, []);
|
|
2110
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenGenerativeUIActivityRendererInner, { content: throttledContent });
|
|
2111
|
+
};
|
|
2112
|
+
function ensureHead(html) {
|
|
2113
|
+
if (/<head[\s>]/i.test(html)) return html;
|
|
2114
|
+
return `<head></head>${html}`;
|
|
2115
|
+
}
|
|
2116
|
+
function injectCssIntoHtml(html, css) {
|
|
2117
|
+
const headCloseIdx = html.indexOf("</head>");
|
|
2118
|
+
if (headCloseIdx !== -1) return html.slice(0, headCloseIdx) + `<style>${css}</style>` + html.slice(headCloseIdx);
|
|
2119
|
+
return `<head><style>${css}</style></head>${html}`;
|
|
2120
|
+
}
|
|
2121
|
+
const OpenGenerativeUIActivityRendererInner = react.default.memo(function OpenGenerativeUIActivityRendererInner({ content }) {
|
|
2122
|
+
var _content$initialHeigh, _content$html, _content$html2, _content$jsExpression;
|
|
2123
|
+
const initialHeight = (_content$initialHeigh = content.initialHeight) !== null && _content$initialHeigh !== void 0 ? _content$initialHeigh : 200;
|
|
2124
|
+
const [autoHeight, setAutoHeight] = (0, react.useState)(null);
|
|
2125
|
+
const sandboxFunctions = useSandboxFunctions();
|
|
2126
|
+
const localApi = (0, react.useMemo)(() => {
|
|
2127
|
+
const api = {};
|
|
2128
|
+
for (const fn of sandboxFunctions) api[fn.name] = fn.handler;
|
|
2129
|
+
return api;
|
|
2130
|
+
}, [sandboxFunctions]);
|
|
2131
|
+
const fullHtml = content.htmlComplete && ((_content$html = content.html) === null || _content$html === void 0 ? void 0 : _content$html.length) ? content.html.join("") : void 0;
|
|
2132
|
+
const css = content.cssComplete ? content.css : void 0;
|
|
2133
|
+
const cssReady = !!content.cssComplete;
|
|
2134
|
+
const partialHtml = !content.htmlComplete && ((_content$html2 = content.html) === null || _content$html2 === void 0 ? void 0 : _content$html2.length) ? content.html.join("") : void 0;
|
|
2135
|
+
const previewBody = partialHtml ? processPartialHtml(partialHtml) : void 0;
|
|
2136
|
+
const previewStyles = partialHtml ? extractCompleteStyles(partialHtml) : "";
|
|
2137
|
+
const hasPreview = cssReady && !!(previewBody === null || previewBody === void 0 ? void 0 : previewBody.trim());
|
|
2138
|
+
const hasVisibleSandbox = !!fullHtml || hasPreview;
|
|
2139
|
+
const containerRef = (0, react.useRef)(null);
|
|
2140
|
+
const sandboxRef = (0, react.useRef)(null);
|
|
2141
|
+
const previewSandboxRef = (0, react.useRef)(null);
|
|
2142
|
+
const previewReadyRef = (0, react.useRef)(false);
|
|
2143
|
+
const sandboxReadyRef = (0, react.useRef)(false);
|
|
2144
|
+
const executedIndexRef = (0, react.useRef)(0);
|
|
2145
|
+
const pendingQueueRef = (0, react.useRef)([]);
|
|
2146
|
+
const jsFunctionsInjectedRef = (0, react.useRef)(false);
|
|
2147
|
+
(0, react.useEffect)(() => {
|
|
2148
|
+
const container = containerRef.current;
|
|
2149
|
+
if (!container || fullHtml || !hasPreview || previewSandboxRef.current) return;
|
|
2150
|
+
let cancelled = false;
|
|
2151
|
+
import("@jetbrains/websandbox").then((mod) => {
|
|
2152
|
+
var _mod$default$default, _mod$default;
|
|
2153
|
+
if (cancelled) return;
|
|
2154
|
+
const sandbox = ((_mod$default$default = (_mod$default = mod.default) === null || _mod$default === void 0 ? void 0 : _mod$default.default) !== null && _mod$default$default !== void 0 ? _mod$default$default : mod.default).create({}, {
|
|
2155
|
+
frameContainer: container,
|
|
2156
|
+
frameContent: "<head></head><body></body>",
|
|
2157
|
+
allowAdditionalAttributes: ""
|
|
2158
|
+
});
|
|
2159
|
+
previewSandboxRef.current = sandbox;
|
|
2160
|
+
sandbox.iframe.style.width = "100%";
|
|
2161
|
+
sandbox.iframe.style.height = "100%";
|
|
2162
|
+
sandbox.iframe.style.border = "none";
|
|
2163
|
+
sandbox.iframe.style.backgroundColor = "transparent";
|
|
2164
|
+
sandbox.promise.then(() => {
|
|
2165
|
+
if (cancelled) return;
|
|
2166
|
+
previewReadyRef.current = true;
|
|
2167
|
+
sandbox.run(`
|
|
2168
|
+
var s = document.createElement('style');
|
|
2169
|
+
s.textContent = 'html, body { overflow: hidden !important; }';
|
|
2170
|
+
document.head.appendChild(s);
|
|
2171
|
+
`);
|
|
2172
|
+
const headParts = [];
|
|
2173
|
+
if (css) headParts.push(`<style>${css}</style>`);
|
|
2174
|
+
if (previewStyles) headParts.push(previewStyles);
|
|
2175
|
+
if (headParts.length) sandbox.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
|
|
2176
|
+
if (previewBody) sandbox.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
|
|
2177
|
+
});
|
|
2178
|
+
}).catch((err) => {
|
|
2179
|
+
console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
|
|
2180
|
+
});
|
|
2181
|
+
return () => {
|
|
2182
|
+
cancelled = true;
|
|
2183
|
+
};
|
|
2184
|
+
}, [hasPreview, fullHtml]);
|
|
2185
|
+
(0, react.useEffect)(() => {
|
|
2186
|
+
if (!previewSandboxRef.current || !previewReadyRef.current) return;
|
|
2187
|
+
const headParts = [];
|
|
2188
|
+
if (css) headParts.push(`<style>${css}</style>`);
|
|
2189
|
+
if (previewStyles) headParts.push(previewStyles);
|
|
2190
|
+
if (headParts.length) previewSandboxRef.current.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
|
|
2191
|
+
if (!previewBody) return;
|
|
2192
|
+
previewSandboxRef.current.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
|
|
2193
|
+
}, [
|
|
2194
|
+
previewBody,
|
|
2195
|
+
previewStyles,
|
|
2196
|
+
css
|
|
2197
|
+
]);
|
|
2198
|
+
(0, react.useEffect)(() => {
|
|
2199
|
+
const container = containerRef.current;
|
|
2200
|
+
if (!container || !fullHtml) return;
|
|
2201
|
+
if (previewSandboxRef.current) {
|
|
2202
|
+
previewSandboxRef.current.destroy();
|
|
2203
|
+
previewSandboxRef.current = null;
|
|
2204
|
+
previewReadyRef.current = false;
|
|
2205
|
+
}
|
|
2206
|
+
let cancelled = false;
|
|
2207
|
+
executedIndexRef.current = 0;
|
|
2208
|
+
jsFunctionsInjectedRef.current = false;
|
|
2209
|
+
sandboxReadyRef.current = false;
|
|
2210
|
+
pendingQueueRef.current = [];
|
|
2211
|
+
const htmlContent = css ? injectCssIntoHtml(fullHtml, css) : fullHtml;
|
|
2212
|
+
import("@jetbrains/websandbox").then((mod) => {
|
|
2213
|
+
var _mod$default$default2, _mod$default2;
|
|
2214
|
+
if (cancelled) return;
|
|
2215
|
+
const sandbox = ((_mod$default$default2 = (_mod$default2 = mod.default) === null || _mod$default2 === void 0 ? void 0 : _mod$default2.default) !== null && _mod$default$default2 !== void 0 ? _mod$default$default2 : mod.default).create(localApi, {
|
|
2216
|
+
frameContainer: container,
|
|
2217
|
+
frameContent: ensureHead(htmlContent),
|
|
2218
|
+
allowAdditionalAttributes: ""
|
|
2219
|
+
});
|
|
2220
|
+
sandboxRef.current = sandbox;
|
|
2221
|
+
sandbox.iframe.style.width = "100%";
|
|
2222
|
+
sandbox.iframe.style.height = "100%";
|
|
2223
|
+
sandbox.iframe.style.border = "none";
|
|
2224
|
+
sandbox.iframe.style.backgroundColor = "transparent";
|
|
2225
|
+
sandbox.promise.then(() => {
|
|
2226
|
+
if (cancelled) return;
|
|
2227
|
+
sandboxReadyRef.current = true;
|
|
2228
|
+
sandbox.run(`
|
|
2229
|
+
var s = document.createElement('style');
|
|
2230
|
+
s.textContent = 'html, body { overflow: hidden !important; }';
|
|
2231
|
+
document.head.appendChild(s);
|
|
2232
|
+
`);
|
|
2233
|
+
const queue = pendingQueueRef.current;
|
|
2234
|
+
pendingQueueRef.current = [];
|
|
2235
|
+
for (const code of queue) sandbox.run(code);
|
|
2236
|
+
});
|
|
2237
|
+
}).catch((err) => {
|
|
2238
|
+
console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
|
|
2239
|
+
});
|
|
2240
|
+
return () => {
|
|
2241
|
+
cancelled = true;
|
|
2242
|
+
if (previewSandboxRef.current) {
|
|
2243
|
+
previewSandboxRef.current.destroy();
|
|
2244
|
+
previewSandboxRef.current = null;
|
|
2245
|
+
previewReadyRef.current = false;
|
|
2246
|
+
}
|
|
2247
|
+
if (sandboxRef.current) {
|
|
2248
|
+
sandboxRef.current.destroy();
|
|
2249
|
+
sandboxRef.current = null;
|
|
2250
|
+
}
|
|
2251
|
+
sandboxReadyRef.current = false;
|
|
2252
|
+
setAutoHeight(null);
|
|
2253
|
+
};
|
|
2254
|
+
}, [
|
|
2255
|
+
fullHtml,
|
|
2256
|
+
css,
|
|
2257
|
+
localApi
|
|
2258
|
+
]);
|
|
2259
|
+
(0, react.useEffect)(() => {
|
|
2260
|
+
if (!content.jsFunctions || jsFunctionsInjectedRef.current) return;
|
|
2261
|
+
jsFunctionsInjectedRef.current = true;
|
|
2262
|
+
const sandbox = sandboxRef.current;
|
|
2263
|
+
if (sandboxReadyRef.current && sandbox) sandbox.run(content.jsFunctions);
|
|
2264
|
+
else pendingQueueRef.current.push(content.jsFunctions);
|
|
2265
|
+
}, [content.jsFunctions]);
|
|
2266
|
+
(0, react.useEffect)(() => {
|
|
2267
|
+
const expressions = content.jsExpressions;
|
|
2268
|
+
if (!expressions || expressions.length === 0) return;
|
|
2269
|
+
const startIndex = executedIndexRef.current;
|
|
2270
|
+
if (startIndex >= expressions.length) return;
|
|
2271
|
+
const newExprs = expressions.slice(startIndex);
|
|
2272
|
+
executedIndexRef.current = expressions.length;
|
|
2273
|
+
const sandbox = sandboxRef.current;
|
|
2274
|
+
if (sandboxReadyRef.current && sandbox) (async () => {
|
|
2275
|
+
for (const expr of newExprs) await sandbox.run(expr);
|
|
2276
|
+
})();
|
|
2277
|
+
else pendingQueueRef.current.push(...newExprs);
|
|
2278
|
+
}, [(_content$jsExpression = content.jsExpressions) === null || _content$jsExpression === void 0 ? void 0 : _content$jsExpression.length]);
|
|
2279
|
+
const generationDone = content.generating === false;
|
|
2280
|
+
(0, react.useEffect)(() => {
|
|
2281
|
+
const sandbox = sandboxRef.current;
|
|
2282
|
+
if (!generationDone || !sandbox) return;
|
|
2283
|
+
let handled = false;
|
|
2284
|
+
const onMessage = (e) => {
|
|
2285
|
+
var _e$data;
|
|
2286
|
+
if (handled) return;
|
|
2287
|
+
if (e.source === sandbox.iframe.contentWindow && ((_e$data = e.data) === null || _e$data === void 0 ? void 0 : _e$data.type) === "__ck_resize") {
|
|
2288
|
+
handled = true;
|
|
2289
|
+
setAutoHeight(e.data.height);
|
|
2290
|
+
window.removeEventListener("message", onMessage);
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
window.addEventListener("message", onMessage);
|
|
2294
|
+
const measureOnce = `
|
|
2295
|
+
(function() {
|
|
2296
|
+
var s = document.createElement('style');
|
|
2297
|
+
s.textContent = 'body { height: auto !important; min-height: 0 !important; }';
|
|
2298
|
+
document.head.appendChild(s);
|
|
2299
|
+
var h = document.body.scrollHeight;
|
|
2300
|
+
var cs = getComputedStyle(document.body);
|
|
2301
|
+
h += parseFloat(cs.marginTop) || 0;
|
|
2302
|
+
h += parseFloat(cs.marginBottom) || 0;
|
|
2303
|
+
s.remove();
|
|
2304
|
+
parent.postMessage({ type: "__ck_resize", height: Math.ceil(h) }, "*");
|
|
2305
|
+
})();
|
|
2306
|
+
`;
|
|
2307
|
+
if (sandboxReadyRef.current) sandbox.run(measureOnce);
|
|
2308
|
+
else pendingQueueRef.current.push(measureOnce);
|
|
2309
|
+
return () => {
|
|
2310
|
+
window.removeEventListener("message", onMessage);
|
|
2311
|
+
};
|
|
2312
|
+
}, [generationDone]);
|
|
2313
|
+
const height = autoHeight !== null && autoHeight !== void 0 ? autoHeight : initialHeight;
|
|
2314
|
+
const isGenerating = content.generating !== false;
|
|
2315
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2316
|
+
ref: containerRef,
|
|
2317
|
+
style: {
|
|
2318
|
+
position: "relative",
|
|
2319
|
+
width: "100%",
|
|
2320
|
+
height: `${height}px`,
|
|
2321
|
+
borderRadius: "8px",
|
|
2322
|
+
backgroundColor: hasVisibleSandbox ? "transparent" : "#f5f5f5",
|
|
2323
|
+
border: hasVisibleSandbox ? "none" : "1px solid #e0e0e0",
|
|
2324
|
+
display: hasVisibleSandbox ? "block" : "flex",
|
|
2325
|
+
alignItems: hasVisibleSandbox ? void 0 : "center",
|
|
2326
|
+
justifyContent: hasVisibleSandbox ? void 0 : "center",
|
|
2327
|
+
overflow: "hidden"
|
|
2328
|
+
},
|
|
2329
|
+
children: isGenerating && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2330
|
+
style: {
|
|
2331
|
+
position: "absolute",
|
|
2332
|
+
inset: 0,
|
|
2333
|
+
zIndex: 10,
|
|
2334
|
+
pointerEvents: "all",
|
|
2335
|
+
backgroundColor: "rgba(255, 255, 255, 0.5)",
|
|
2336
|
+
display: "flex",
|
|
2337
|
+
alignItems: "center",
|
|
2338
|
+
justifyContent: "center"
|
|
2339
|
+
},
|
|
2340
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
2341
|
+
width: "48",
|
|
2342
|
+
height: "48",
|
|
2343
|
+
viewBox: "0 0 24 24",
|
|
2344
|
+
fill: "none",
|
|
2345
|
+
style: { animation: "ck-spin 1s linear infinite" },
|
|
2346
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
2347
|
+
cx: "12",
|
|
2348
|
+
cy: "12",
|
|
2349
|
+
r: "10",
|
|
2350
|
+
stroke: "#e0e0e0",
|
|
2351
|
+
strokeWidth: "3"
|
|
2352
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2353
|
+
d: "M12 2a10 10 0 0 1 10 10",
|
|
2354
|
+
stroke: "#999",
|
|
2355
|
+
strokeWidth: "3",
|
|
2356
|
+
strokeLinecap: "round"
|
|
2357
|
+
})]
|
|
2358
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `@keyframes ck-spin { to { transform: rotate(360deg) } }` })]
|
|
2359
|
+
})
|
|
2360
|
+
});
|
|
2361
|
+
}, (prev, next) => prev.content === next.content);
|
|
2362
|
+
/**
|
|
2363
|
+
* Frontend tool renderer for generateSandboxedUi.
|
|
2364
|
+
* Displays placeholder messages while the UI is being generated.
|
|
2365
|
+
*/
|
|
2366
|
+
const OpenGenerativeUIToolRenderer = function OpenGenerativeUIToolRenderer(props) {
|
|
2367
|
+
var _messages$visibleMess;
|
|
2368
|
+
const [visibleMessageIndex, setVisibleMessageIndex] = (0, react.useState)(0);
|
|
2369
|
+
const prevMessageCountRef = (0, react.useRef)(0);
|
|
2370
|
+
const messages = props.args.placeholderMessages;
|
|
2371
|
+
(0, react.useEffect)(() => {
|
|
2372
|
+
if (!messages || messages.length === 0) return;
|
|
2373
|
+
if (messages.length !== prevMessageCountRef.current) {
|
|
2374
|
+
prevMessageCountRef.current = messages.length;
|
|
2375
|
+
setVisibleMessageIndex(messages.length - 1);
|
|
2376
|
+
}
|
|
2377
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Complete) return;
|
|
2378
|
+
const timer = setInterval(() => {
|
|
2379
|
+
setVisibleMessageIndex((i) => (i + 1) % messages.length);
|
|
2380
|
+
}, 5e3);
|
|
2381
|
+
return () => clearInterval(timer);
|
|
2382
|
+
}, [messages === null || messages === void 0 ? void 0 : messages.length, props.status]);
|
|
2383
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Complete) return null;
|
|
2384
|
+
if (!messages || messages.length === 0) return null;
|
|
2385
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2386
|
+
style: {
|
|
2387
|
+
padding: "8px 12px",
|
|
2388
|
+
color: "#999",
|
|
2389
|
+
fontSize: "14px"
|
|
2390
|
+
},
|
|
2391
|
+
children: (_messages$visibleMess = messages[visibleMessageIndex]) !== null && _messages$visibleMess !== void 0 ? _messages$visibleMess : messages[0]
|
|
2392
|
+
});
|
|
2393
|
+
};
|
|
2394
|
+
|
|
2395
|
+
//#endregion
|
|
2396
|
+
//#region src/v2/a2ui/A2UIMessageRenderer.tsx
|
|
2397
|
+
/**
|
|
2398
|
+
* The container key used to wrap A2UI operations for explicit detection.
|
|
2399
|
+
* Must match A2UI_OPERATIONS_KEY in @ag-ui/a2ui-middleware and copilotkit.a2ui (Python).
|
|
2400
|
+
*/
|
|
2401
|
+
const A2UI_OPERATIONS_KEY = "a2ui_operations";
|
|
2402
|
+
let initialized = false;
|
|
2403
|
+
function ensureInitialized() {
|
|
2404
|
+
if (!initialized) {
|
|
2405
|
+
(0, _copilotkit_a2ui_renderer.initializeDefaultCatalog)();
|
|
2406
|
+
(0, _copilotkit_a2ui_renderer.injectStyles)();
|
|
2407
|
+
initialized = true;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
function createA2UIMessageRenderer(options) {
|
|
2411
|
+
const { theme, catalog, loadingComponent } = options;
|
|
2412
|
+
return {
|
|
2413
|
+
activityType: "a2ui-surface",
|
|
2414
|
+
content: zod.z.any(),
|
|
2415
|
+
render: ({ content, agent }) => {
|
|
2416
|
+
ensureInitialized();
|
|
2417
|
+
const [operations, setOperations] = (0, react.useState)([]);
|
|
2418
|
+
const { copilotkit } = useCopilotKit();
|
|
2419
|
+
const lastContentRef = (0, react.useRef)(null);
|
|
2420
|
+
(0, react.useEffect)(() => {
|
|
2421
|
+
if (content === lastContentRef.current) return;
|
|
2422
|
+
lastContentRef.current = content;
|
|
2423
|
+
const incoming = content === null || content === void 0 ? void 0 : content[A2UI_OPERATIONS_KEY];
|
|
2424
|
+
if (!content || !Array.isArray(incoming)) {
|
|
2425
|
+
setOperations([]);
|
|
2426
|
+
return;
|
|
2427
|
+
}
|
|
2428
|
+
setOperations(incoming);
|
|
2429
|
+
}, [content]);
|
|
2430
|
+
const groupedOperations = (0, react.useMemo)(() => {
|
|
2431
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2432
|
+
for (const operation of operations) {
|
|
2433
|
+
var _getOperationSurfaceI;
|
|
2434
|
+
const surfaceId = (_getOperationSurfaceI = getOperationSurfaceId(operation)) !== null && _getOperationSurfaceI !== void 0 ? _getOperationSurfaceI : _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
|
|
2435
|
+
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
|
|
2436
|
+
groups.get(surfaceId).push(operation);
|
|
2437
|
+
}
|
|
2438
|
+
return groups;
|
|
2439
|
+
}, [operations]);
|
|
2440
|
+
if (!groupedOperations.size) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(loadingComponent !== null && loadingComponent !== void 0 ? loadingComponent : DefaultA2UILoading, {});
|
|
2441
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2442
|
+
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
2443
|
+
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
2444
|
+
surfaceId,
|
|
2445
|
+
operations: ops,
|
|
2446
|
+
theme,
|
|
2447
|
+
agent,
|
|
2448
|
+
copilotkit,
|
|
2449
|
+
catalog
|
|
2450
|
+
}, surfaceId))
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
};
|
|
2454
|
+
}
|
|
2455
|
+
/**
|
|
2456
|
+
* Renders a single A2UI surface using the React renderer.
|
|
2457
|
+
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
|
|
2458
|
+
*/
|
|
2459
|
+
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog }) {
|
|
2460
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2461
|
+
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
2462
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
2463
|
+
onAction: (0, react.useCallback)(async (message) => {
|
|
2464
|
+
if (!agent) return;
|
|
2465
|
+
message.userAction;
|
|
2466
|
+
try {
|
|
2467
|
+
var _copilotkit$propertie;
|
|
2468
|
+
copilotkit.setProperties({
|
|
2469
|
+
...(_copilotkit$propertie = copilotkit.properties) !== null && _copilotkit$propertie !== void 0 ? _copilotkit$propertie : {},
|
|
2470
|
+
a2uiAction: message
|
|
2471
|
+
});
|
|
2472
|
+
await copilotkit.runAgent({ agent });
|
|
2473
|
+
} finally {
|
|
2474
|
+
if (copilotkit.properties) {
|
|
2475
|
+
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
2476
|
+
copilotkit.setProperties(rest);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}, [agent, copilotkit]),
|
|
2480
|
+
theme,
|
|
2481
|
+
catalog,
|
|
2482
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
2483
|
+
surfaceId,
|
|
2484
|
+
operations
|
|
2485
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UISurfaceOrError, { surfaceId })]
|
|
2486
|
+
})
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* Renders the A2UI surface, or an error message if processing failed.
|
|
2491
|
+
* Must be a child of A2UIProvider to access the error state.
|
|
2492
|
+
*/
|
|
2493
|
+
function A2UISurfaceOrError({ surfaceId }) {
|
|
2494
|
+
const error = (0, _copilotkit_a2ui_renderer.useA2UIError)();
|
|
2495
|
+
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2496
|
+
className: "cpk:rounded-lg cpk:border cpk:border-red-200 cpk:bg-red-50 cpk:p-3 cpk:text-sm cpk:text-red-700",
|
|
2497
|
+
children: ["A2UI render error: ", error]
|
|
2498
|
+
});
|
|
2499
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_a2ui_renderer.A2UIRenderer, {
|
|
2500
|
+
surfaceId,
|
|
2501
|
+
className: "cpk:flex cpk:flex-1"
|
|
2502
|
+
});
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* Processes A2UI operations into the provider's message processor.
|
|
2506
|
+
* Must be a child of A2UIProvider to access the actions context.
|
|
2507
|
+
*/
|
|
2508
|
+
function SurfaceMessageProcessor({ surfaceId, operations }) {
|
|
2509
|
+
const { processMessages, getSurface } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
2510
|
+
const lastHashRef = (0, react.useRef)("");
|
|
2511
|
+
(0, react.useEffect)(() => {
|
|
2512
|
+
const hash = JSON.stringify(operations);
|
|
2513
|
+
if (hash === lastHashRef.current) return;
|
|
2514
|
+
lastHashRef.current = hash;
|
|
2515
|
+
processMessages(getSurface(surfaceId) ? operations.filter((op) => !(op === null || op === void 0 ? void 0 : op.createSurface)) : operations);
|
|
2042
2516
|
}, [
|
|
2043
2517
|
processMessages,
|
|
2518
|
+
getSurface,
|
|
2044
2519
|
surfaceId,
|
|
2045
2520
|
operations
|
|
2046
2521
|
]);
|
|
2047
2522
|
return null;
|
|
2048
2523
|
}
|
|
2524
|
+
/**
|
|
2525
|
+
* Default loading component shown while an A2UI surface is generating.
|
|
2526
|
+
* Displays an animated shimmer skeleton.
|
|
2527
|
+
*/
|
|
2528
|
+
function DefaultA2UILoading() {
|
|
2529
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2530
|
+
className: "cpk:flex cpk:flex-col cpk:gap-3 cpk:rounded-xl cpk:border cpk:border-gray-100 cpk:bg-gray-50/50 cpk:p-5",
|
|
2531
|
+
style: { minHeight: 120 },
|
|
2532
|
+
children: [
|
|
2533
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2534
|
+
className: "cpk:flex cpk:items-center cpk:gap-2",
|
|
2535
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2536
|
+
className: "cpk:h-3 cpk:w-3 cpk:rounded-full cpk:bg-gray-200",
|
|
2537
|
+
style: { animation: "cpk-a2ui-pulse 1.5s ease-in-out infinite" }
|
|
2538
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2539
|
+
className: "cpk:text-xs cpk:font-medium cpk:text-gray-400",
|
|
2540
|
+
children: "Generating UI..."
|
|
2541
|
+
})]
|
|
2542
|
+
}),
|
|
2543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2544
|
+
className: "cpk:flex cpk:flex-col cpk:gap-2",
|
|
2545
|
+
children: [
|
|
2546
|
+
.8,
|
|
2547
|
+
.6,
|
|
2548
|
+
.4
|
|
2549
|
+
].map((width, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2550
|
+
className: "cpk:h-3 cpk:rounded cpk:bg-gray-200/70",
|
|
2551
|
+
style: {
|
|
2552
|
+
width: `${width * 100}%`,
|
|
2553
|
+
animation: `cpk-a2ui-pulse 1.5s ease-in-out ${i * .15}s infinite`
|
|
2554
|
+
}
|
|
2555
|
+
}, i))
|
|
2556
|
+
}),
|
|
2557
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
|
|
2558
|
+
@keyframes cpk-a2ui-pulse {
|
|
2559
|
+
0%, 100% { opacity: 0.4; }
|
|
2560
|
+
50% { opacity: 1; }
|
|
2561
|
+
}
|
|
2562
|
+
` })
|
|
2563
|
+
]
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2049
2566
|
function getOperationSurfaceId(operation) {
|
|
2050
|
-
var _ref, _ref2, _ref3, _operation$
|
|
2567
|
+
var _ref, _ref2, _ref3, _operation$createSurf, _operation$createSurf2, _operation$updateComp, _operation$updateData, _operation$deleteSurf;
|
|
2051
2568
|
if (!operation || typeof operation !== "object") return null;
|
|
2052
2569
|
if (typeof operation.surfaceId === "string") return operation.surfaceId;
|
|
2053
|
-
return (_ref = (_ref2 = (_ref3 = (_operation$
|
|
2570
|
+
return (_ref = (_ref2 = (_ref3 = (_operation$createSurf = operation === null || operation === void 0 || (_operation$createSurf2 = operation.createSurface) === null || _operation$createSurf2 === void 0 ? void 0 : _operation$createSurf2.surfaceId) !== null && _operation$createSurf !== void 0 ? _operation$createSurf : operation === null || operation === void 0 || (_operation$updateComp = operation.updateComponents) === null || _operation$updateComp === void 0 ? void 0 : _operation$updateComp.surfaceId) !== null && _ref3 !== void 0 ? _ref3 : operation === null || operation === void 0 || (_operation$updateData = operation.updateDataModel) === null || _operation$updateData === void 0 ? void 0 : _operation$updateData.surfaceId) !== null && _ref2 !== void 0 ? _ref2 : operation === null || operation === void 0 || (_operation$deleteSurf = operation.deleteSurface) === null || _operation$deleteSurf === void 0 ? void 0 : _operation$deleteSurf.surfaceId) !== null && _ref !== void 0 ? _ref : null;
|
|
2054
2571
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2572
|
+
|
|
2573
|
+
//#endregion
|
|
2574
|
+
//#region src/v2/types/defineToolCallRenderer.ts
|
|
2575
|
+
function defineToolCallRenderer(def) {
|
|
2576
|
+
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
2577
|
+
return {
|
|
2578
|
+
name: def.name,
|
|
2579
|
+
args: argsSchema,
|
|
2580
|
+
render: def.render,
|
|
2581
|
+
...def.agentId ? { agentId: def.agentId } : {}
|
|
2582
|
+
};
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
//#endregion
|
|
2586
|
+
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
2587
|
+
/**
|
|
2588
|
+
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
2589
|
+
* This renderer is auto-registered when A2UI is enabled.
|
|
2590
|
+
*/
|
|
2591
|
+
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
2592
|
+
/**
|
|
2593
|
+
* Built-in progress indicator for dynamic A2UI generation.
|
|
2594
|
+
* Shows a skeleton wireframe that progressively reveals as tokens stream in.
|
|
2595
|
+
*
|
|
2596
|
+
* Registered automatically when A2UI is enabled. Users can override by
|
|
2597
|
+
* providing their own `useRenderTool({ name: "render_a2ui", ... })`.
|
|
2598
|
+
*/
|
|
2599
|
+
function A2UIProgressIndicator({ parameters }) {
|
|
2600
|
+
const lastRef = (0, react.useRef)({
|
|
2601
|
+
time: 0,
|
|
2602
|
+
tokens: 0
|
|
2603
|
+
});
|
|
2604
|
+
const now = Date.now();
|
|
2605
|
+
let { tokens } = lastRef.current;
|
|
2606
|
+
if (now - lastRef.current.time > 200) {
|
|
2607
|
+
const chars = JSON.stringify(parameters !== null && parameters !== void 0 ? parameters : {}).length;
|
|
2608
|
+
tokens = Math.round(chars / 4);
|
|
2609
|
+
lastRef.current = {
|
|
2610
|
+
time: now,
|
|
2611
|
+
tokens
|
|
2612
|
+
};
|
|
2060
2613
|
}
|
|
2614
|
+
const phase = tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;
|
|
2615
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2616
|
+
style: {
|
|
2617
|
+
margin: "12px 0",
|
|
2618
|
+
maxWidth: 320
|
|
2619
|
+
},
|
|
2620
|
+
children: [
|
|
2621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2622
|
+
style: {
|
|
2623
|
+
position: "relative",
|
|
2624
|
+
overflow: "hidden",
|
|
2625
|
+
borderRadius: 12,
|
|
2626
|
+
border: "1px solid rgba(228,228,231,0.8)",
|
|
2627
|
+
backgroundColor: "#fff",
|
|
2628
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
|
|
2629
|
+
padding: "16px 18px 14px"
|
|
2630
|
+
},
|
|
2631
|
+
children: [
|
|
2632
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2633
|
+
style: {
|
|
2634
|
+
display: "flex",
|
|
2635
|
+
alignItems: "center",
|
|
2636
|
+
gap: 8,
|
|
2637
|
+
marginBottom: 12
|
|
2638
|
+
},
|
|
2639
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2640
|
+
style: {
|
|
2641
|
+
display: "flex",
|
|
2642
|
+
gap: 4
|
|
2643
|
+
},
|
|
2644
|
+
children: [
|
|
2645
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2646
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2647
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {})
|
|
2648
|
+
]
|
|
2649
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2650
|
+
w: 64,
|
|
2651
|
+
h: 6,
|
|
2652
|
+
bg: "#e4e4e7",
|
|
2653
|
+
opacity: phase >= 1 ? 1 : .4,
|
|
2654
|
+
transition: "opacity 0.5s"
|
|
2655
|
+
})]
|
|
2656
|
+
}),
|
|
2657
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2658
|
+
style: {
|
|
2659
|
+
display: "grid",
|
|
2660
|
+
gap: 7
|
|
2661
|
+
},
|
|
2662
|
+
children: [
|
|
2663
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2664
|
+
show: phase >= 0,
|
|
2665
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2666
|
+
w: 36,
|
|
2667
|
+
h: 7,
|
|
2668
|
+
bg: "rgba(147,197,253,0.7)",
|
|
2669
|
+
anim: 0
|
|
2670
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2671
|
+
w: 80,
|
|
2672
|
+
h: 7,
|
|
2673
|
+
bg: "rgba(219,234,254,0.8)",
|
|
2674
|
+
anim: .2
|
|
2675
|
+
})]
|
|
2676
|
+
}),
|
|
2677
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2678
|
+
show: phase >= 0,
|
|
2679
|
+
delay: .1,
|
|
2680
|
+
children: [
|
|
2681
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
2682
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2683
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2684
|
+
w: 100,
|
|
2685
|
+
h: 7,
|
|
2686
|
+
bg: "rgba(24,24,27,0.2)",
|
|
2687
|
+
anim: .3
|
|
2688
|
+
})
|
|
2689
|
+
]
|
|
2690
|
+
}),
|
|
2691
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2692
|
+
show: phase >= 1,
|
|
2693
|
+
delay: .15,
|
|
2694
|
+
children: [
|
|
2695
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
2696
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2697
|
+
w: 48,
|
|
2698
|
+
h: 7,
|
|
2699
|
+
bg: "rgba(24,24,27,0.15)",
|
|
2700
|
+
anim: .1
|
|
2701
|
+
}),
|
|
2702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2703
|
+
w: 40,
|
|
2704
|
+
h: 7,
|
|
2705
|
+
bg: "rgba(153,246,228,0.6)",
|
|
2706
|
+
anim: .5
|
|
2707
|
+
}),
|
|
2708
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2709
|
+
w: 56,
|
|
2710
|
+
h: 7,
|
|
2711
|
+
bg: "rgba(147,197,253,0.6)",
|
|
2712
|
+
anim: .3
|
|
2713
|
+
})
|
|
2714
|
+
]
|
|
2715
|
+
}),
|
|
2716
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2717
|
+
show: phase >= 1,
|
|
2718
|
+
delay: .2,
|
|
2719
|
+
children: [
|
|
2720
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
2721
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2722
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2723
|
+
w: 60,
|
|
2724
|
+
h: 7,
|
|
2725
|
+
bg: "rgba(24,24,27,0.15)",
|
|
2726
|
+
anim: .4
|
|
2727
|
+
})
|
|
2728
|
+
]
|
|
2729
|
+
}),
|
|
2730
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2731
|
+
show: phase >= 2,
|
|
2732
|
+
delay: .25,
|
|
2733
|
+
children: [
|
|
2734
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2735
|
+
w: 40,
|
|
2736
|
+
h: 7,
|
|
2737
|
+
bg: "rgba(153,246,228,0.5)",
|
|
2738
|
+
anim: .2
|
|
2739
|
+
}),
|
|
2740
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2741
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2742
|
+
w: 48,
|
|
2743
|
+
h: 7,
|
|
2744
|
+
bg: "rgba(24,24,27,0.15)",
|
|
2745
|
+
anim: .6
|
|
2746
|
+
}),
|
|
2747
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2748
|
+
w: 64,
|
|
2749
|
+
h: 7,
|
|
2750
|
+
bg: "rgba(147,197,253,0.5)",
|
|
2751
|
+
anim: .1
|
|
2752
|
+
})
|
|
2753
|
+
]
|
|
2754
|
+
}),
|
|
2755
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2756
|
+
show: phase >= 2,
|
|
2757
|
+
delay: .3,
|
|
2758
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2759
|
+
w: 36,
|
|
2760
|
+
h: 7,
|
|
2761
|
+
bg: "rgba(147,197,253,0.6)",
|
|
2762
|
+
anim: .5
|
|
2763
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2764
|
+
w: 36,
|
|
2765
|
+
h: 7,
|
|
2766
|
+
bg: "rgba(24,24,27,0.12)",
|
|
2767
|
+
anim: .7
|
|
2768
|
+
})]
|
|
2769
|
+
}),
|
|
2770
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
2771
|
+
show: phase >= 3,
|
|
2772
|
+
delay: .35,
|
|
2773
|
+
children: [
|
|
2774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2775
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2776
|
+
w: 44,
|
|
2777
|
+
h: 7,
|
|
2778
|
+
bg: "rgba(24,24,27,0.18)",
|
|
2779
|
+
anim: .3
|
|
2780
|
+
}),
|
|
2781
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
2782
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2783
|
+
w: 56,
|
|
2784
|
+
h: 7,
|
|
2785
|
+
bg: "rgba(153,246,228,0.5)",
|
|
2786
|
+
anim: .8
|
|
2787
|
+
}),
|
|
2788
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
2789
|
+
w: 48,
|
|
2790
|
+
h: 7,
|
|
2791
|
+
bg: "rgba(147,197,253,0.5)",
|
|
2792
|
+
anim: .4
|
|
2793
|
+
})
|
|
2794
|
+
]
|
|
2795
|
+
})
|
|
2796
|
+
]
|
|
2797
|
+
}),
|
|
2798
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
2799
|
+
pointerEvents: "none",
|
|
2800
|
+
position: "absolute",
|
|
2801
|
+
inset: 0,
|
|
2802
|
+
background: "linear-gradient(105deg, transparent 0%, transparent 40%, rgba(255,255,255,0.6) 50%, transparent 60%, transparent 100%)",
|
|
2803
|
+
backgroundSize: "250% 100%",
|
|
2804
|
+
animation: "cpk-a2ui-sweep 3s ease-in-out infinite"
|
|
2805
|
+
} })
|
|
2806
|
+
]
|
|
2807
|
+
}),
|
|
2808
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2809
|
+
style: {
|
|
2810
|
+
display: "flex",
|
|
2811
|
+
alignItems: "center",
|
|
2812
|
+
justifyContent: "center",
|
|
2813
|
+
gap: 8,
|
|
2814
|
+
marginTop: 8
|
|
2815
|
+
},
|
|
2816
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2817
|
+
style: {
|
|
2818
|
+
fontSize: 12,
|
|
2819
|
+
color: "#a1a1aa",
|
|
2820
|
+
letterSpacing: "0.025em"
|
|
2821
|
+
},
|
|
2822
|
+
children: "Building interface"
|
|
2823
|
+
}), tokens > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2824
|
+
style: {
|
|
2825
|
+
fontSize: 11,
|
|
2826
|
+
color: "#d4d4d8",
|
|
2827
|
+
fontVariantNumeric: "tabular-nums"
|
|
2828
|
+
},
|
|
2829
|
+
children: [
|
|
2830
|
+
"~",
|
|
2831
|
+
tokens.toLocaleString(),
|
|
2832
|
+
" tokens"
|
|
2833
|
+
]
|
|
2834
|
+
})]
|
|
2835
|
+
}),
|
|
2836
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
|
|
2837
|
+
@keyframes cpk-a2ui-fade {
|
|
2838
|
+
0%, 100% { opacity: 1; }
|
|
2839
|
+
50% { opacity: 0.5; }
|
|
2840
|
+
}
|
|
2841
|
+
@keyframes cpk-a2ui-sweep {
|
|
2842
|
+
0% { background-position: 250% 0; }
|
|
2843
|
+
100% { background-position: -250% 0; }
|
|
2844
|
+
}
|
|
2845
|
+
` })
|
|
2846
|
+
]
|
|
2847
|
+
});
|
|
2848
|
+
}
|
|
2849
|
+
function Dot() {
|
|
2850
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
2851
|
+
width: 7,
|
|
2852
|
+
height: 7,
|
|
2853
|
+
borderRadius: "50%",
|
|
2854
|
+
backgroundColor: "#d4d4d8",
|
|
2855
|
+
flexShrink: 0
|
|
2856
|
+
} });
|
|
2857
|
+
}
|
|
2858
|
+
function Spacer() {
|
|
2859
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: { width: 12 } });
|
|
2860
|
+
}
|
|
2861
|
+
function Bar({ w, h, bg, anim, opacity, transition }) {
|
|
2862
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
2863
|
+
width: w,
|
|
2864
|
+
height: h,
|
|
2865
|
+
borderRadius: 9999,
|
|
2866
|
+
backgroundColor: bg,
|
|
2867
|
+
...anim !== void 0 ? { animation: `cpk-a2ui-fade 2.4s ease-in-out ${anim}s infinite` } : {},
|
|
2868
|
+
...opacity !== void 0 ? { opacity } : {},
|
|
2869
|
+
...transition ? { transition } : {}
|
|
2870
|
+
} });
|
|
2871
|
+
}
|
|
2872
|
+
function Row({ children, show, delay = 0 }) {
|
|
2873
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2874
|
+
style: {
|
|
2875
|
+
display: "flex",
|
|
2876
|
+
alignItems: "center",
|
|
2877
|
+
gap: 6,
|
|
2878
|
+
opacity: show ? 1 : 0,
|
|
2879
|
+
transition: `opacity 0.4s ${delay}s`
|
|
2880
|
+
},
|
|
2881
|
+
children
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
/**
|
|
2885
|
+
* Registers the built-in `render_a2ui` tool call renderer via the props-based
|
|
2886
|
+
* `setRenderToolCalls` mechanism (not `useRenderTool`).
|
|
2887
|
+
*
|
|
2888
|
+
* This ensures user-registered `useRenderTool({ name: "render_a2ui", ... })`
|
|
2889
|
+
* hooks automatically override the built-in, since the merge logic in
|
|
2890
|
+
* react-core.ts gives hook-based entries priority over prop-based entries.
|
|
2891
|
+
*/
|
|
2892
|
+
function A2UIBuiltInToolCallRenderer() {
|
|
2893
|
+
const { copilotkit } = useCopilotKit();
|
|
2894
|
+
(0, react.useEffect)(() => {
|
|
2895
|
+
var _renderToolCalls;
|
|
2896
|
+
const renderer = defineToolCallRenderer({
|
|
2897
|
+
name: RENDER_A2UI_TOOL_NAME,
|
|
2898
|
+
args: zod.z.any(),
|
|
2899
|
+
render: ({ status, args: parameters }) => {
|
|
2900
|
+
if (status === "complete") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2901
|
+
const params = parameters;
|
|
2902
|
+
const items = params === null || params === void 0 ? void 0 : params.items;
|
|
2903
|
+
if (Array.isArray(items) && items.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2904
|
+
const components = params === null || params === void 0 ? void 0 : params.components;
|
|
2905
|
+
if (Array.isArray(components) && components.length > 2) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2906
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIProgressIndicator, { parameters });
|
|
2907
|
+
}
|
|
2908
|
+
});
|
|
2909
|
+
const existing = (_renderToolCalls = copilotkit._renderToolCalls) !== null && _renderToolCalls !== void 0 ? _renderToolCalls : [];
|
|
2910
|
+
copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
|
|
2911
|
+
}, [copilotkit]);
|
|
2912
|
+
return null;
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
//#endregion
|
|
2916
|
+
//#region src/v2/hooks/use-agent-context.tsx
|
|
2917
|
+
function useAgentContext(context) {
|
|
2918
|
+
const { description, value } = context;
|
|
2919
|
+
const { copilotkit } = useCopilotKit();
|
|
2920
|
+
const stringValue = (0, react.useMemo)(() => {
|
|
2921
|
+
if (typeof value === "string") return value;
|
|
2922
|
+
return JSON.stringify(value);
|
|
2923
|
+
}, [value]);
|
|
2924
|
+
(0, react.useLayoutEffect)(() => {
|
|
2925
|
+
if (!copilotkit) return;
|
|
2926
|
+
const id = copilotkit.addContext({
|
|
2927
|
+
description,
|
|
2928
|
+
value: stringValue
|
|
2929
|
+
});
|
|
2930
|
+
return () => {
|
|
2931
|
+
copilotkit.removeContext(id);
|
|
2932
|
+
};
|
|
2933
|
+
}, [
|
|
2934
|
+
description,
|
|
2935
|
+
stringValue,
|
|
2936
|
+
copilotkit
|
|
2937
|
+
]);
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
//#endregion
|
|
2941
|
+
//#region src/v2/a2ui/A2UICatalogContext.tsx
|
|
2942
|
+
/**
|
|
2943
|
+
* Renders agent context describing the available A2UI catalog and custom components.
|
|
2944
|
+
* Only mount this component when A2UI is enabled.
|
|
2945
|
+
*
|
|
2946
|
+
* When `includeSchema` is true, the full component schemas (JSON Schema) are also
|
|
2947
|
+
* sent as context using the same description key as the A2UI middleware, so the
|
|
2948
|
+
* middleware can optionally overwrite it with a server-side schema.
|
|
2949
|
+
*/
|
|
2950
|
+
function A2UICatalogContext({ catalog, includeSchema }) {
|
|
2951
|
+
useAgentContext({
|
|
2952
|
+
description: "A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.",
|
|
2953
|
+
value: (0, _copilotkit_a2ui_renderer.buildCatalogContextValue)(catalog)
|
|
2954
|
+
});
|
|
2955
|
+
const { copilotkit } = useCopilotKit();
|
|
2956
|
+
const schemaValue = (0, react.useMemo)(() => includeSchema !== false ? JSON.stringify((0, _copilotkit_a2ui_renderer.extractCatalogComponentSchemas)(catalog)) : null, [catalog, includeSchema]);
|
|
2957
|
+
(0, react.useLayoutEffect)(() => {
|
|
2958
|
+
if (!copilotkit || !schemaValue) return;
|
|
2959
|
+
const ids = [];
|
|
2960
|
+
ids.push(copilotkit.addContext({
|
|
2961
|
+
description: _copilotkit_a2ui_renderer.A2UI_SCHEMA_CONTEXT_DESCRIPTION,
|
|
2962
|
+
value: schemaValue
|
|
2963
|
+
}));
|
|
2964
|
+
ids.push(copilotkit.addContext({
|
|
2965
|
+
description: "A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.",
|
|
2966
|
+
value: _copilotkit_shared.A2UI_DEFAULT_GENERATION_GUIDELINES
|
|
2967
|
+
}));
|
|
2968
|
+
ids.push(copilotkit.addContext({
|
|
2969
|
+
description: "A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.",
|
|
2970
|
+
value: _copilotkit_shared.A2UI_DEFAULT_DESIGN_GUIDELINES
|
|
2971
|
+
}));
|
|
2972
|
+
return () => {
|
|
2973
|
+
for (const id of ids) copilotkit.removeContext(id);
|
|
2974
|
+
};
|
|
2975
|
+
}, [copilotkit, schemaValue]);
|
|
2976
|
+
return null;
|
|
2061
2977
|
}
|
|
2062
2978
|
|
|
2063
2979
|
//#endregion
|
|
@@ -2167,6 +3083,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2167
3083
|
//#region src/v2/providers/CopilotKitProvider.tsx
|
|
2168
3084
|
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
2169
3085
|
const COPILOT_CLOUD_CHAT_URL$1 = "https://api.cloud.copilotkit.ai/copilotkit/v1";
|
|
3086
|
+
const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follow these design principles inspired by shadcn/ui:
|
|
3087
|
+
|
|
3088
|
+
- Use a minimal, flat aesthetic. Avoid drop shadows and gradients — rely on subtle borders (1px solid, light gray like #e5e7eb) to define surfaces.
|
|
3089
|
+
- Neutral base palette: white backgrounds, zinc/slate gray text (#09090b for headings, #71717a for secondary text). One accent color for interactive elements.
|
|
3090
|
+
- Use system font stacks (system-ui, -apple-system, sans-serif) at readable sizes (14px body, 600 weight for headings). Tight line-heights.
|
|
3091
|
+
- Small, consistent border-radius (6–8px). Cards and containers use border, not shadow, for separation.
|
|
3092
|
+
- Buttons: solid fill for primary (dark bg, white text), outline for secondary (border + transparent bg). Subtle hover state (slight opacity or background shift).
|
|
3093
|
+
- Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
|
|
3094
|
+
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
|
|
3095
|
+
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
|
|
3096
|
+
const GENERATE_SANDBOXED_UI_DESCRIPTION = "Generate sandboxed UI. IMPORTANT: The generated code runs in a sandboxed iframe WITHOUT same-origin access. Do NOT use localStorage, sessionStorage, document.cookie, IndexedDB, or fetch/XMLHttpRequest to same-origin URLs. To communicate with the host application, use Websandbox.connection.remote.<functionName>(args) which returns a Promise.\n\nYou CAN use external libraries from CDNs by including <script> or <link> tags in the HTML <head> (e.g., Chart.js, D3, Three.js, x-data-spreadsheet, etc.). CDN resources load normally inside the sandbox.\n\nPARAMETER ORDER IS CRITICAL — generate parameters in exactly this order:\n1. initialHeight + placeholderMessages (shown to user while generating)\n2. css (all styles FIRST — the user sees a placeholder until CSS is complete)\n3. html (streams in live — the user watches the UI build as HTML is generated)\n4. jsFunctions (reusable helper functions)\n5. jsExpressions (applied one-by-one — the user sees each expression take effect)";
|
|
2170
3097
|
const CopilotKitContext = (0, react.createContext)({
|
|
2171
3098
|
copilotkit: null,
|
|
2172
3099
|
executingToolCallIds: /* @__PURE__ */ new Set()
|
|
@@ -2182,9 +3109,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2182
3109
|
}, [value, warningMessage]);
|
|
2183
3110
|
return value;
|
|
2184
3111
|
}
|
|
2185
|
-
const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, showDevConsole = false, useSingleEndpoint
|
|
3112
|
+
const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor }) => {
|
|
3113
|
+
var _openGenerativeUI$des;
|
|
2186
3114
|
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
|
|
2187
3115
|
const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
|
|
3116
|
+
const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = (0, react.useState)(false);
|
|
3117
|
+
const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;
|
|
2188
3118
|
const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
|
|
2189
3119
|
(0, react.useEffect)(() => {
|
|
2190
3120
|
if (typeof window === "undefined") return;
|
|
@@ -2213,12 +3143,25 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2213
3143
|
content: MCPAppsActivityContentSchema,
|
|
2214
3144
|
render: MCPAppsActivityRenderer
|
|
2215
3145
|
}];
|
|
3146
|
+
if (openGenUIActive) renderers.push({
|
|
3147
|
+
activityType: OpenGenerativeUIActivityType,
|
|
3148
|
+
content: OpenGenerativeUIContentSchema,
|
|
3149
|
+
render: OpenGenerativeUIActivityRenderer
|
|
3150
|
+
});
|
|
2216
3151
|
if (runtimeA2UIEnabled) {
|
|
2217
3152
|
var _a2ui$theme;
|
|
2218
|
-
renderers.unshift(createA2UIMessageRenderer({
|
|
3153
|
+
renderers.unshift(createA2UIMessageRenderer({
|
|
3154
|
+
theme: (_a2ui$theme = a2ui === null || a2ui === void 0 ? void 0 : a2ui.theme) !== null && _a2ui$theme !== void 0 ? _a2ui$theme : _copilotkit_a2ui_renderer.viewerTheme,
|
|
3155
|
+
catalog: a2ui === null || a2ui === void 0 ? void 0 : a2ui.catalog,
|
|
3156
|
+
loadingComponent: a2ui === null || a2ui === void 0 ? void 0 : a2ui.loadingComponent
|
|
3157
|
+
}));
|
|
2219
3158
|
}
|
|
2220
3159
|
return renderers;
|
|
2221
|
-
}, [
|
|
3160
|
+
}, [
|
|
3161
|
+
runtimeA2UIEnabled,
|
|
3162
|
+
openGenUIActive,
|
|
3163
|
+
a2ui
|
|
3164
|
+
]);
|
|
2222
3165
|
const allActivityRenderers = (0, react.useMemo)(() => {
|
|
2223
3166
|
return [...renderActivityMessagesList, ...builtInActivityRenderers];
|
|
2224
3167
|
}, [renderActivityMessagesList, builtInActivityRenderers]);
|
|
@@ -2244,6 +3187,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2244
3187
|
const chatApiEndpoint = runtimeUrl !== null && runtimeUrl !== void 0 ? runtimeUrl : resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL$1 : void 0;
|
|
2245
3188
|
const frontendToolsList = useStableArrayProp(frontendTools, "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.");
|
|
2246
3189
|
const humanInTheLoopList = useStableArrayProp(humanInTheLoop, "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.");
|
|
3190
|
+
const sandboxFunctionsList = useStableArrayProp(openGenerativeUI === null || openGenerativeUI === void 0 ? void 0 : openGenerativeUI.sandboxFunctions, "openGenerativeUI.sandboxFunctions must be a stable array.");
|
|
2247
3191
|
const processedHumanInTheLoopTools = (0, react.useMemo)(() => {
|
|
2248
3192
|
const processedTools = [];
|
|
2249
3193
|
const processedRenderToolCalls = [];
|
|
@@ -2274,15 +3218,31 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2274
3218
|
renderToolCalls: processedRenderToolCalls
|
|
2275
3219
|
};
|
|
2276
3220
|
}, [humanInTheLoopList]);
|
|
3221
|
+
const builtInFrontendTools = (0, react.useMemo)(() => {
|
|
3222
|
+
if (!openGenUIActive) return [];
|
|
3223
|
+
return [{
|
|
3224
|
+
name: "generateSandboxedUi",
|
|
3225
|
+
description: GENERATE_SANDBOXED_UI_DESCRIPTION,
|
|
3226
|
+
parameters: GenerateSandboxedUiArgsSchema,
|
|
3227
|
+
handler: async () => "UI generated",
|
|
3228
|
+
followUp: true,
|
|
3229
|
+
render: OpenGenerativeUIToolRenderer
|
|
3230
|
+
}];
|
|
3231
|
+
}, [openGenUIActive]);
|
|
2277
3232
|
const allTools = (0, react.useMemo)(() => {
|
|
2278
3233
|
const tools = [];
|
|
2279
3234
|
tools.push(...frontendToolsList);
|
|
3235
|
+
tools.push(...builtInFrontendTools);
|
|
2280
3236
|
tools.push(...processedHumanInTheLoopTools.tools);
|
|
2281
3237
|
return tools;
|
|
2282
|
-
}, [
|
|
3238
|
+
}, [
|
|
3239
|
+
frontendToolsList,
|
|
3240
|
+
builtInFrontendTools,
|
|
3241
|
+
processedHumanInTheLoopTools
|
|
3242
|
+
]);
|
|
2283
3243
|
const allRenderToolCalls = (0, react.useMemo)(() => {
|
|
2284
3244
|
const combined = [...renderToolCallsList];
|
|
2285
|
-
frontendToolsList.forEach((tool) => {
|
|
3245
|
+
[...frontendToolsList, ...builtInFrontendTools].forEach((tool) => {
|
|
2286
3246
|
if (tool.render) {
|
|
2287
3247
|
const args = tool.parameters || (tool.name === "*" ? zod.z.any() : void 0);
|
|
2288
3248
|
if (args) combined.push({
|
|
@@ -2297,25 +3257,31 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2297
3257
|
}, [
|
|
2298
3258
|
renderToolCallsList,
|
|
2299
3259
|
frontendToolsList,
|
|
3260
|
+
builtInFrontendTools,
|
|
2300
3261
|
processedHumanInTheLoopTools
|
|
2301
3262
|
]);
|
|
2302
3263
|
const copilotkitRef = (0, react.useRef)(null);
|
|
2303
|
-
if (copilotkitRef.current === null)
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
3264
|
+
if (copilotkitRef.current === null) {
|
|
3265
|
+
copilotkitRef.current = new CopilotKitCoreReact({
|
|
3266
|
+
runtimeUrl: chatApiEndpoint,
|
|
3267
|
+
runtimeTransport: useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto",
|
|
3268
|
+
headers: mergedHeaders,
|
|
3269
|
+
credentials,
|
|
3270
|
+
properties,
|
|
3271
|
+
agents__unsafe_dev_only: mergedAgents,
|
|
3272
|
+
tools: allTools,
|
|
3273
|
+
renderToolCalls: allRenderToolCalls,
|
|
3274
|
+
renderActivityMessages: allActivityRenderers,
|
|
3275
|
+
renderCustomMessages: renderCustomMessagesList
|
|
3276
|
+
});
|
|
3277
|
+
if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
|
|
3278
|
+
}
|
|
2315
3279
|
const copilotkit = copilotkitRef.current;
|
|
2316
3280
|
(0, react.useEffect)(() => {
|
|
3281
|
+
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
2317
3282
|
const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
2318
3283
|
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
3284
|
+
setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
|
|
2319
3285
|
setRuntimeLicenseStatus(copilotkit.licenseStatus);
|
|
2320
3286
|
} });
|
|
2321
3287
|
return () => {
|
|
@@ -2375,7 +3341,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2375
3341
|
}, [copilotkit]);
|
|
2376
3342
|
(0, react.useEffect)(() => {
|
|
2377
3343
|
copilotkit.setRuntimeUrl(chatApiEndpoint);
|
|
2378
|
-
copilotkit.setRuntimeTransport(useSingleEndpoint ? "single" : "rest");
|
|
3344
|
+
copilotkit.setRuntimeTransport(useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto");
|
|
2379
3345
|
copilotkit.setHeaders(mergedHeaders);
|
|
2380
3346
|
copilotkit.setCredentials(credentials);
|
|
2381
3347
|
copilotkit.setProperties(properties);
|
|
@@ -2409,23 +3375,75 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2409
3375
|
(0, react.useEffect)(() => {
|
|
2410
3376
|
didMountRef.current = true;
|
|
2411
3377
|
}, []);
|
|
3378
|
+
(0, react.useEffect)(() => {
|
|
3379
|
+
if (defaultThrottleMs !== void 0 && (!Number.isFinite(defaultThrottleMs) || defaultThrottleMs < 0)) console.error(`CopilotKitProvider: defaultThrottleMs must be a non-negative finite number, got ${defaultThrottleMs}. useAgent hooks without an explicit throttleMs will fall back to unthrottled.`);
|
|
3380
|
+
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3381
|
+
}, [copilotkit, defaultThrottleMs]);
|
|
3382
|
+
const designSkill = (_openGenerativeUI$des = openGenerativeUI === null || openGenerativeUI === void 0 ? void 0 : openGenerativeUI.designSkill) !== null && _openGenerativeUI$des !== void 0 ? _openGenerativeUI$des : DEFAULT_DESIGN_SKILL;
|
|
3383
|
+
(0, react.useLayoutEffect)(() => {
|
|
3384
|
+
if (!copilotkit || !openGenUIActive) return;
|
|
3385
|
+
const id = copilotkit.addContext({
|
|
3386
|
+
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
3387
|
+
value: designSkill
|
|
3388
|
+
});
|
|
3389
|
+
return () => {
|
|
3390
|
+
copilotkit.removeContext(id);
|
|
3391
|
+
};
|
|
3392
|
+
}, [
|
|
3393
|
+
copilotkit,
|
|
3394
|
+
designSkill,
|
|
3395
|
+
openGenUIActive
|
|
3396
|
+
]);
|
|
3397
|
+
const sandboxFunctionsDescriptors = (0, react.useMemo)(() => {
|
|
3398
|
+
if (sandboxFunctionsList.length === 0) return null;
|
|
3399
|
+
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
3400
|
+
name: fn.name,
|
|
3401
|
+
description: fn.description,
|
|
3402
|
+
parameters: (0, _copilotkit_shared.schemaToJsonSchema)(fn.parameters, { zodToJsonSchema: zod_to_json_schema.zodToJsonSchema })
|
|
3403
|
+
})));
|
|
3404
|
+
}, [sandboxFunctionsList]);
|
|
3405
|
+
(0, react.useLayoutEffect)(() => {
|
|
3406
|
+
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
3407
|
+
const id = copilotkit.addContext({
|
|
3408
|
+
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
3409
|
+
value: sandboxFunctionsDescriptors
|
|
3410
|
+
});
|
|
3411
|
+
return () => {
|
|
3412
|
+
copilotkit.removeContext(id);
|
|
3413
|
+
};
|
|
3414
|
+
}, [
|
|
3415
|
+
copilotkit,
|
|
3416
|
+
sandboxFunctionsDescriptors,
|
|
3417
|
+
openGenUIActive
|
|
3418
|
+
]);
|
|
2412
3419
|
const contextValue = (0, react.useMemo)(() => ({
|
|
2413
3420
|
copilotkit,
|
|
2414
3421
|
executingToolCallIds
|
|
2415
3422
|
}), [copilotkit, executingToolCallIds]);
|
|
2416
3423
|
const licenseContextValue = (0, react.useMemo)(() => (0, _copilotkit_shared.createLicenseContextValue)(null), []);
|
|
2417
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2418
|
-
value:
|
|
2419
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2420
|
-
value:
|
|
2421
|
-
children:
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
3424
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
|
|
3425
|
+
value: sandboxFunctionsList,
|
|
3426
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
|
|
3427
|
+
value: contextValue,
|
|
3428
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LicenseContext.Provider, {
|
|
3429
|
+
value: licenseContextValue,
|
|
3430
|
+
children: [
|
|
3431
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuiltInToolCallRenderer, {}),
|
|
3432
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UICatalogContext, {
|
|
3433
|
+
catalog: a2ui === null || a2ui === void 0 ? void 0 : a2ui.catalog,
|
|
3434
|
+
includeSchema: a2ui === null || a2ui === void 0 ? void 0 : a2ui.includeSchema
|
|
3435
|
+
}),
|
|
3436
|
+
children,
|
|
3437
|
+
shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, {
|
|
3438
|
+
core: copilotkit,
|
|
3439
|
+
defaultAnchor: inspectorDefaultAnchor
|
|
3440
|
+
}) : null,
|
|
3441
|
+
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
|
|
3442
|
+
runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
|
|
3443
|
+
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
|
|
3444
|
+
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
|
|
3445
|
+
]
|
|
3446
|
+
})
|
|
2429
3447
|
})
|
|
2430
3448
|
});
|
|
2431
3449
|
};
|
|
@@ -2508,10 +3526,197 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2508
3526
|
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
2509
3527
|
}, toolCall.id);
|
|
2510
3528
|
}, [
|
|
2511
|
-
renderToolCalls,
|
|
2512
|
-
executingToolCallIds,
|
|
2513
|
-
agentId
|
|
3529
|
+
renderToolCalls,
|
|
3530
|
+
executingToolCallIds,
|
|
3531
|
+
agentId
|
|
3532
|
+
]);
|
|
3533
|
+
}
|
|
3534
|
+
|
|
3535
|
+
//#endregion
|
|
3536
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
3537
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3538
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
3539
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
3540
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
3541
|
+
return UseAgentUpdate;
|
|
3542
|
+
}({});
|
|
3543
|
+
const ALL_UPDATES = [
|
|
3544
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
3545
|
+
UseAgentUpdate.OnStateChanged,
|
|
3546
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
3547
|
+
];
|
|
3548
|
+
/**
|
|
3549
|
+
* Clone a registry agent for per-thread isolation.
|
|
3550
|
+
* Copies agent configuration (transport, headers, etc.) but resets conversation
|
|
3551
|
+
* state (messages, threadId, state) so each thread starts fresh.
|
|
3552
|
+
*/
|
|
3553
|
+
function cloneForThread(source, threadId, headers) {
|
|
3554
|
+
const clone = source.clone();
|
|
3555
|
+
if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
|
|
3556
|
+
clone.threadId = threadId;
|
|
3557
|
+
clone.setMessages([]);
|
|
3558
|
+
clone.setState({});
|
|
3559
|
+
if (clone instanceof _ag_ui_client.HttpAgent) clone.headers = { ...headers };
|
|
3560
|
+
return clone;
|
|
3561
|
+
}
|
|
3562
|
+
/**
|
|
3563
|
+
* Module-level WeakMap: registryAgent → (threadId → clone).
|
|
3564
|
+
* Shared across all useAgent() calls so that every component using the same
|
|
3565
|
+
* (agentId, threadId) pair receives the same agent instance. Using WeakMap
|
|
3566
|
+
* ensures the clone map is garbage-collected when the registry agent is
|
|
3567
|
+
* replaced (e.g. after reconnect or hot-reload).
|
|
3568
|
+
*/
|
|
3569
|
+
const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
|
|
3570
|
+
/**
|
|
3571
|
+
* Look up an existing per-thread clone without creating one.
|
|
3572
|
+
* Returns undefined when no clone has been created yet for this pair.
|
|
3573
|
+
*/
|
|
3574
|
+
function getThreadClone(registryAgent, threadId) {
|
|
3575
|
+
var _globalThreadCloneMap;
|
|
3576
|
+
if (!registryAgent || !threadId) return void 0;
|
|
3577
|
+
return (_globalThreadCloneMap = globalThreadCloneMap.get(registryAgent)) === null || _globalThreadCloneMap === void 0 ? void 0 : _globalThreadCloneMap.get(threadId);
|
|
3578
|
+
}
|
|
3579
|
+
function getOrCreateThreadClone(existing, threadId, headers) {
|
|
3580
|
+
let byThread = globalThreadCloneMap.get(existing);
|
|
3581
|
+
if (!byThread) {
|
|
3582
|
+
byThread = /* @__PURE__ */ new Map();
|
|
3583
|
+
globalThreadCloneMap.set(existing, byThread);
|
|
3584
|
+
}
|
|
3585
|
+
const cached = byThread.get(threadId);
|
|
3586
|
+
if (cached) return cached;
|
|
3587
|
+
const clone = cloneForThread(existing, threadId, headers);
|
|
3588
|
+
byThread.set(threadId, clone);
|
|
3589
|
+
return clone;
|
|
3590
|
+
}
|
|
3591
|
+
function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
3592
|
+
var _agentId, _threadId;
|
|
3593
|
+
(_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
|
|
3594
|
+
const { copilotkit } = useCopilotKit();
|
|
3595
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
3596
|
+
const chatConfig = useCopilotChatConfiguration();
|
|
3597
|
+
(_threadId = threadId) !== null && _threadId !== void 0 || (threadId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.threadId);
|
|
3598
|
+
const effectiveThrottleMs = (0, react.useMemo)(() => {
|
|
3599
|
+
var _ref;
|
|
3600
|
+
const resolved = (_ref = throttleMs !== null && throttleMs !== void 0 ? throttleMs : providerThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
|
|
3601
|
+
if (!Number.isFinite(resolved) || resolved < 0) {
|
|
3602
|
+
const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
|
|
3603
|
+
console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
|
|
3604
|
+
return 0;
|
|
3605
|
+
}
|
|
3606
|
+
return resolved;
|
|
3607
|
+
}, [throttleMs, providerThrottleMs]);
|
|
3608
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
3609
|
+
const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3610
|
+
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
3611
|
+
const agent = (0, react.useMemo)(() => {
|
|
3612
|
+
var _copilotkit$agents;
|
|
3613
|
+
const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
|
|
3614
|
+
const existing = copilotkit.getAgent(agentId);
|
|
3615
|
+
if (existing) {
|
|
3616
|
+
provisionalAgentCache.current.delete(cacheKey);
|
|
3617
|
+
provisionalAgentCache.current.delete(agentId);
|
|
3618
|
+
if (!threadId) return existing;
|
|
3619
|
+
return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
|
|
3620
|
+
}
|
|
3621
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
3622
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
3623
|
+
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
3624
|
+
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3625
|
+
if (cached) {
|
|
3626
|
+
cached.headers = { ...copilotkit.headers };
|
|
3627
|
+
return cached;
|
|
3628
|
+
}
|
|
3629
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3630
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
3631
|
+
agentId,
|
|
3632
|
+
transport: copilotkit.runtimeTransport,
|
|
3633
|
+
runtimeMode: "pending"
|
|
3634
|
+
});
|
|
3635
|
+
provisional.headers = { ...copilotkit.headers };
|
|
3636
|
+
if (threadId) provisional.threadId = threadId;
|
|
3637
|
+
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3638
|
+
return provisional;
|
|
3639
|
+
}
|
|
3640
|
+
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
3641
|
+
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3642
|
+
if (cached) {
|
|
3643
|
+
cached.headers = { ...copilotkit.headers };
|
|
3644
|
+
return cached;
|
|
3645
|
+
}
|
|
3646
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3647
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
3648
|
+
agentId,
|
|
3649
|
+
transport: copilotkit.runtimeTransport,
|
|
3650
|
+
runtimeMode: "pending"
|
|
3651
|
+
});
|
|
3652
|
+
provisional.headers = { ...copilotkit.headers };
|
|
3653
|
+
if (threadId) provisional.threadId = threadId;
|
|
3654
|
+
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3655
|
+
return provisional;
|
|
3656
|
+
}
|
|
3657
|
+
const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
|
|
3658
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
3659
|
+
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
3660
|
+
}, [
|
|
3661
|
+
agentId,
|
|
3662
|
+
threadId,
|
|
3663
|
+
copilotkit.agents,
|
|
3664
|
+
copilotkit.runtimeConnectionStatus,
|
|
3665
|
+
copilotkit.runtimeUrl,
|
|
3666
|
+
copilotkit.runtimeTransport,
|
|
3667
|
+
JSON.stringify(copilotkit.headers)
|
|
3668
|
+
]);
|
|
3669
|
+
(0, react.useEffect)(() => {
|
|
3670
|
+
if (updateFlags.length === 0) return;
|
|
3671
|
+
const handlers = {};
|
|
3672
|
+
let timerId = null;
|
|
3673
|
+
let active = true;
|
|
3674
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
|
|
3675
|
+
const ms = effectiveThrottleMs;
|
|
3676
|
+
if (ms > 0) {
|
|
3677
|
+
let throttleActive = false;
|
|
3678
|
+
let pending = false;
|
|
3679
|
+
const throttledNotify = () => {
|
|
3680
|
+
if (!active) return;
|
|
3681
|
+
if (!throttleActive) {
|
|
3682
|
+
throttleActive = true;
|
|
3683
|
+
pending = false;
|
|
3684
|
+
forceUpdate();
|
|
3685
|
+
timerId = setTimeout(function trailingEdge() {
|
|
3686
|
+
timerId = null;
|
|
3687
|
+
if (active && pending) {
|
|
3688
|
+
pending = false;
|
|
3689
|
+
forceUpdate();
|
|
3690
|
+
timerId = setTimeout(trailingEdge, ms);
|
|
3691
|
+
} else throttleActive = false;
|
|
3692
|
+
}, ms);
|
|
3693
|
+
} else pending = true;
|
|
3694
|
+
};
|
|
3695
|
+
handlers.onMessagesChanged = throttledNotify;
|
|
3696
|
+
} else handlers.onMessagesChanged = forceUpdate;
|
|
3697
|
+
}
|
|
3698
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
|
|
3699
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3700
|
+
handlers.onRunInitialized = forceUpdate;
|
|
3701
|
+
handlers.onRunFinalized = forceUpdate;
|
|
3702
|
+
handlers.onRunFailed = forceUpdate;
|
|
3703
|
+
}
|
|
3704
|
+
const subscription = agent.subscribe(handlers);
|
|
3705
|
+
return () => {
|
|
3706
|
+
active = false;
|
|
3707
|
+
if (timerId !== null) clearTimeout(timerId);
|
|
3708
|
+
subscription.unsubscribe();
|
|
3709
|
+
};
|
|
3710
|
+
}, [
|
|
3711
|
+
agent,
|
|
3712
|
+
forceUpdate,
|
|
3713
|
+
effectiveThrottleMs,
|
|
3714
|
+
updateFlags
|
|
2514
3715
|
]);
|
|
3716
|
+
(0, react.useEffect)(() => {
|
|
3717
|
+
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
3718
|
+
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
3719
|
+
return { agent };
|
|
2515
3720
|
}
|
|
2516
3721
|
|
|
2517
3722
|
//#endregion
|
|
@@ -2527,12 +3732,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2527
3732
|
return aHasAgent ? -1 : 1;
|
|
2528
3733
|
});
|
|
2529
3734
|
return function(params) {
|
|
2530
|
-
var _copilotkit$getRunIdF;
|
|
3735
|
+
var _copilotkit$getRunIdF, _getThreadClone;
|
|
2531
3736
|
if (!customMessageRenderers.length) return null;
|
|
2532
3737
|
const { message, position } = params;
|
|
2533
3738
|
const resolvedRunId = (_copilotkit$getRunIdF = copilotkit.getRunIdForMessage(agentId, threadId, message.id)) !== null && _copilotkit$getRunIdF !== void 0 ? _copilotkit$getRunIdF : copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
2534
3739
|
const runId = resolvedRunId !== null && resolvedRunId !== void 0 ? resolvedRunId : `missing-run-id:${message.id}`;
|
|
2535
|
-
const
|
|
3740
|
+
const registryAgent = copilotkit.getAgent(agentId);
|
|
3741
|
+
const agent = (_getThreadClone = getThreadClone(registryAgent, threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
|
|
2536
3742
|
if (!agent) throw new Error("Agent not found");
|
|
2537
3743
|
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
2538
3744
|
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
@@ -2575,6 +3781,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2575
3781
|
return (_ref = (_ref2 = (_matches$find = matches.find((candidate) => candidate.agentId === agentId)) !== null && _matches$find !== void 0 ? _matches$find : matches.find((candidate) => candidate.agentId === void 0)) !== null && _ref2 !== void 0 ? _ref2 : renderers.find((candidate) => candidate.activityType === "*")) !== null && _ref !== void 0 ? _ref : null;
|
|
2576
3782
|
}, [agentId, renderers]);
|
|
2577
3783
|
const renderActivityMessage = (0, react.useCallback)((message) => {
|
|
3784
|
+
var _getThreadClone;
|
|
2578
3785
|
const renderer = findRenderer(message.activityType);
|
|
2579
3786
|
if (!renderer) return null;
|
|
2580
3787
|
const parseResult = renderer.content.safeParse(message.content);
|
|
@@ -2583,7 +3790,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2583
3790
|
return null;
|
|
2584
3791
|
}
|
|
2585
3792
|
const Component = renderer.render;
|
|
2586
|
-
const
|
|
3793
|
+
const registryAgent = copilotkit.getAgent(agentId);
|
|
3794
|
+
const agent = (_getThreadClone = getThreadClone(registryAgent, config === null || config === void 0 ? void 0 : config.threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
|
|
2587
3795
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
2588
3796
|
activityType: message.activityType,
|
|
2589
3797
|
content: parseResult.data,
|
|
@@ -2592,6 +3800,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2592
3800
|
}, message.id);
|
|
2593
3801
|
}, [
|
|
2594
3802
|
agentId,
|
|
3803
|
+
config === null || config === void 0 ? void 0 : config.threadId,
|
|
2595
3804
|
copilotkit,
|
|
2596
3805
|
findRenderer
|
|
2597
3806
|
]);
|
|
@@ -2617,7 +3826,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2617
3826
|
copilotkit.removeTool(name, tool.agentId);
|
|
2618
3827
|
}
|
|
2619
3828
|
copilotkit.addTool(tool);
|
|
2620
|
-
if (tool.render
|
|
3829
|
+
if (tool.render) copilotkit.addHookRenderToolCall({
|
|
2621
3830
|
name,
|
|
2622
3831
|
args: tool.parameters,
|
|
2623
3832
|
agentId: tool.agentId,
|
|
@@ -2702,18 +3911,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2702
3911
|
}, deps);
|
|
2703
3912
|
}
|
|
2704
3913
|
|
|
2705
|
-
//#endregion
|
|
2706
|
-
//#region src/v2/types/defineToolCallRenderer.ts
|
|
2707
|
-
function defineToolCallRenderer(def) {
|
|
2708
|
-
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
2709
|
-
return {
|
|
2710
|
-
name: def.name,
|
|
2711
|
-
args: argsSchema,
|
|
2712
|
-
render: def.render,
|
|
2713
|
-
...def.agentId ? { agentId: def.agentId } : {}
|
|
2714
|
-
};
|
|
2715
|
-
}
|
|
2716
|
-
|
|
2717
3914
|
//#endregion
|
|
2718
3915
|
//#region src/v2/hooks/use-render-tool.tsx
|
|
2719
3916
|
const EMPTY_DEPS = [];
|
|
@@ -2953,207 +4150,94 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2953
4150
|
style: {
|
|
2954
4151
|
fontSize: "10px",
|
|
2955
4152
|
textTransform: "uppercase",
|
|
2956
|
-
letterSpacing: "0.05em",
|
|
2957
|
-
color: "#71717a"
|
|
2958
|
-
},
|
|
2959
|
-
children: "Result"
|
|
2960
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
2961
|
-
style: {
|
|
2962
|
-
marginTop: "6px",
|
|
2963
|
-
maxHeight: "200px",
|
|
2964
|
-
overflow: "auto",
|
|
2965
|
-
borderRadius: "6px",
|
|
2966
|
-
backgroundColor: "#f4f4f5",
|
|
2967
|
-
padding: "10px",
|
|
2968
|
-
fontSize: "11px",
|
|
2969
|
-
lineHeight: 1.6,
|
|
2970
|
-
color: "#27272a",
|
|
2971
|
-
whiteSpace: "pre-wrap",
|
|
2972
|
-
wordBreak: "break-word"
|
|
2973
|
-
},
|
|
2974
|
-
children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
2975
|
-
})] })]
|
|
2976
|
-
})]
|
|
2977
|
-
})
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
|
|
2981
|
-
//#endregion
|
|
2982
|
-
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
2983
|
-
function useHumanInTheLoop(tool, deps) {
|
|
2984
|
-
const { copilotkit } = useCopilotKit();
|
|
2985
|
-
const resolvePromiseRef = (0, react.useRef)(null);
|
|
2986
|
-
const respond = (0, react.useCallback)(async (result) => {
|
|
2987
|
-
if (resolvePromiseRef.current) {
|
|
2988
|
-
resolvePromiseRef.current(result);
|
|
2989
|
-
resolvePromiseRef.current = null;
|
|
2990
|
-
}
|
|
2991
|
-
}, []);
|
|
2992
|
-
const handler = (0, react.useCallback)(async () => {
|
|
2993
|
-
return new Promise((resolve) => {
|
|
2994
|
-
resolvePromiseRef.current = resolve;
|
|
2995
|
-
});
|
|
2996
|
-
}, []);
|
|
2997
|
-
const RenderComponent = (0, react.useCallback)((props) => {
|
|
2998
|
-
const ToolComponent = tool.render;
|
|
2999
|
-
if (props.status === "inProgress") {
|
|
3000
|
-
const enhancedProps = {
|
|
3001
|
-
...props,
|
|
3002
|
-
name: tool.name,
|
|
3003
|
-
description: tool.description || "",
|
|
3004
|
-
respond: void 0
|
|
3005
|
-
};
|
|
3006
|
-
return react.default.createElement(ToolComponent, enhancedProps);
|
|
3007
|
-
} else if (props.status === "executing") {
|
|
3008
|
-
const enhancedProps = {
|
|
3009
|
-
...props,
|
|
3010
|
-
name: tool.name,
|
|
3011
|
-
description: tool.description || "",
|
|
3012
|
-
respond
|
|
3013
|
-
};
|
|
3014
|
-
return react.default.createElement(ToolComponent, enhancedProps);
|
|
3015
|
-
} else if (props.status === "complete") {
|
|
3016
|
-
const enhancedProps = {
|
|
3017
|
-
...props,
|
|
3018
|
-
name: tool.name,
|
|
3019
|
-
description: tool.description || "",
|
|
3020
|
-
respond: void 0
|
|
3021
|
-
};
|
|
3022
|
-
return react.default.createElement(ToolComponent, enhancedProps);
|
|
3023
|
-
}
|
|
3024
|
-
return react.default.createElement(ToolComponent, props);
|
|
3025
|
-
}, [
|
|
3026
|
-
tool.render,
|
|
3027
|
-
tool.name,
|
|
3028
|
-
tool.description,
|
|
3029
|
-
respond
|
|
3030
|
-
]);
|
|
3031
|
-
useFrontendTool({
|
|
3032
|
-
...tool,
|
|
3033
|
-
handler,
|
|
3034
|
-
render: RenderComponent
|
|
3035
|
-
}, deps);
|
|
3036
|
-
(0, react.useEffect)(() => {
|
|
3037
|
-
return () => {
|
|
3038
|
-
copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
|
|
3039
|
-
};
|
|
3040
|
-
}, [
|
|
3041
|
-
copilotkit,
|
|
3042
|
-
tool.name,
|
|
3043
|
-
tool.agentId
|
|
3044
|
-
]);
|
|
3045
|
-
}
|
|
3046
|
-
|
|
3047
|
-
//#endregion
|
|
3048
|
-
//#region src/v2/hooks/use-agent.tsx
|
|
3049
|
-
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3050
|
-
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
3051
|
-
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
3052
|
-
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
3053
|
-
return UseAgentUpdate;
|
|
3054
|
-
}({});
|
|
3055
|
-
const ALL_UPDATES = [
|
|
3056
|
-
UseAgentUpdate.OnMessagesChanged,
|
|
3057
|
-
UseAgentUpdate.OnStateChanged,
|
|
3058
|
-
UseAgentUpdate.OnRunStatusChanged
|
|
3059
|
-
];
|
|
3060
|
-
function useAgent({ agentId, updates } = {}) {
|
|
3061
|
-
var _agentId;
|
|
3062
|
-
(_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
|
|
3063
|
-
const { copilotkit } = useCopilotKit();
|
|
3064
|
-
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
3065
|
-
const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3066
|
-
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
3067
|
-
const agent = (0, react.useMemo)(() => {
|
|
3068
|
-
var _copilotkit$agents;
|
|
3069
|
-
const existing = copilotkit.getAgent(agentId);
|
|
3070
|
-
if (existing) {
|
|
3071
|
-
provisionalAgentCache.current.delete(agentId);
|
|
3072
|
-
return existing;
|
|
3073
|
-
}
|
|
3074
|
-
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
3075
|
-
const status = copilotkit.runtimeConnectionStatus;
|
|
3076
|
-
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
3077
|
-
const cached = provisionalAgentCache.current.get(agentId);
|
|
3078
|
-
if (cached) {
|
|
3079
|
-
cached.headers = { ...copilotkit.headers };
|
|
3080
|
-
return cached;
|
|
3081
|
-
}
|
|
3082
|
-
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3083
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3084
|
-
agentId,
|
|
3085
|
-
transport: copilotkit.runtimeTransport,
|
|
3086
|
-
runtimeMode: "pending"
|
|
3087
|
-
});
|
|
3088
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3089
|
-
provisionalAgentCache.current.set(agentId, provisional);
|
|
3090
|
-
return provisional;
|
|
3091
|
-
}
|
|
3092
|
-
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
3093
|
-
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3094
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3095
|
-
agentId,
|
|
3096
|
-
transport: copilotkit.runtimeTransport,
|
|
3097
|
-
runtimeMode: "pending"
|
|
3098
|
-
});
|
|
3099
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3100
|
-
return provisional;
|
|
3101
|
-
}
|
|
3102
|
-
const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
|
|
3103
|
-
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
3104
|
-
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
3105
|
-
}, [
|
|
3106
|
-
agentId,
|
|
3107
|
-
copilotkit.agents,
|
|
3108
|
-
copilotkit.runtimeConnectionStatus,
|
|
3109
|
-
copilotkit.runtimeUrl,
|
|
3110
|
-
copilotkit.runtimeTransport,
|
|
3111
|
-
JSON.stringify(copilotkit.headers)
|
|
3112
|
-
]);
|
|
3113
|
-
(0, react.useEffect)(() => {
|
|
3114
|
-
if (updateFlags.length === 0) return;
|
|
3115
|
-
const handlers = {};
|
|
3116
|
-
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = () => {
|
|
3117
|
-
forceUpdate();
|
|
3118
|
-
};
|
|
3119
|
-
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
|
|
3120
|
-
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3121
|
-
handlers.onRunInitialized = forceUpdate;
|
|
3122
|
-
handlers.onRunFinalized = forceUpdate;
|
|
3123
|
-
handlers.onRunFailed = forceUpdate;
|
|
3124
|
-
}
|
|
3125
|
-
const subscription = agent.subscribe(handlers);
|
|
3126
|
-
return () => subscription.unsubscribe();
|
|
3127
|
-
}, [
|
|
3128
|
-
agent,
|
|
3129
|
-
forceUpdate,
|
|
3130
|
-
JSON.stringify(updateFlags)
|
|
3131
|
-
]);
|
|
3132
|
-
return { agent };
|
|
4153
|
+
letterSpacing: "0.05em",
|
|
4154
|
+
color: "#71717a"
|
|
4155
|
+
},
|
|
4156
|
+
children: "Result"
|
|
4157
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
4158
|
+
style: {
|
|
4159
|
+
marginTop: "6px",
|
|
4160
|
+
maxHeight: "200px",
|
|
4161
|
+
overflow: "auto",
|
|
4162
|
+
borderRadius: "6px",
|
|
4163
|
+
backgroundColor: "#f4f4f5",
|
|
4164
|
+
padding: "10px",
|
|
4165
|
+
fontSize: "11px",
|
|
4166
|
+
lineHeight: 1.6,
|
|
4167
|
+
color: "#27272a",
|
|
4168
|
+
whiteSpace: "pre-wrap",
|
|
4169
|
+
wordBreak: "break-word"
|
|
4170
|
+
},
|
|
4171
|
+
children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
4172
|
+
})] })]
|
|
4173
|
+
})]
|
|
4174
|
+
})
|
|
4175
|
+
});
|
|
3133
4176
|
}
|
|
3134
4177
|
|
|
3135
4178
|
//#endregion
|
|
3136
|
-
//#region src/v2/hooks/use-
|
|
3137
|
-
function
|
|
3138
|
-
const { description, value } = context;
|
|
4179
|
+
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
4180
|
+
function useHumanInTheLoop(tool, deps) {
|
|
3139
4181
|
const { copilotkit } = useCopilotKit();
|
|
3140
|
-
const
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
4182
|
+
const resolvePromiseRef = (0, react.useRef)(null);
|
|
4183
|
+
const respond = (0, react.useCallback)(async (result) => {
|
|
4184
|
+
if (resolvePromiseRef.current) {
|
|
4185
|
+
resolvePromiseRef.current(result);
|
|
4186
|
+
resolvePromiseRef.current = null;
|
|
4187
|
+
}
|
|
4188
|
+
}, []);
|
|
4189
|
+
const handler = (0, react.useCallback)(async () => {
|
|
4190
|
+
return new Promise((resolve) => {
|
|
4191
|
+
resolvePromiseRef.current = resolve;
|
|
3149
4192
|
});
|
|
4193
|
+
}, []);
|
|
4194
|
+
const RenderComponent = (0, react.useCallback)((props) => {
|
|
4195
|
+
const ToolComponent = tool.render;
|
|
4196
|
+
if (props.status === "inProgress") {
|
|
4197
|
+
const enhancedProps = {
|
|
4198
|
+
...props,
|
|
4199
|
+
name: tool.name,
|
|
4200
|
+
description: tool.description || "",
|
|
4201
|
+
respond: void 0
|
|
4202
|
+
};
|
|
4203
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
4204
|
+
} else if (props.status === "executing") {
|
|
4205
|
+
const enhancedProps = {
|
|
4206
|
+
...props,
|
|
4207
|
+
name: tool.name,
|
|
4208
|
+
description: tool.description || "",
|
|
4209
|
+
respond
|
|
4210
|
+
};
|
|
4211
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
4212
|
+
} else if (props.status === "complete") {
|
|
4213
|
+
const enhancedProps = {
|
|
4214
|
+
...props,
|
|
4215
|
+
name: tool.name,
|
|
4216
|
+
description: tool.description || "",
|
|
4217
|
+
respond: void 0
|
|
4218
|
+
};
|
|
4219
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
4220
|
+
}
|
|
4221
|
+
return react.default.createElement(ToolComponent, props);
|
|
4222
|
+
}, [
|
|
4223
|
+
tool.render,
|
|
4224
|
+
tool.name,
|
|
4225
|
+
tool.description,
|
|
4226
|
+
respond
|
|
4227
|
+
]);
|
|
4228
|
+
useFrontendTool({
|
|
4229
|
+
...tool,
|
|
4230
|
+
handler,
|
|
4231
|
+
render: RenderComponent
|
|
4232
|
+
}, deps);
|
|
4233
|
+
(0, react.useEffect)(() => {
|
|
3150
4234
|
return () => {
|
|
3151
|
-
copilotkit.
|
|
4235
|
+
copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
|
|
3152
4236
|
};
|
|
3153
4237
|
}, [
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
4238
|
+
copilotkit,
|
|
4239
|
+
tool.name,
|
|
4240
|
+
tool.agentId
|
|
3157
4241
|
]);
|
|
3158
4242
|
}
|
|
3159
4243
|
|
|
@@ -3578,11 +4662,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3578
4662
|
var _copilotkit$intellige2;
|
|
3579
4663
|
const { copilotkit } = useCopilotKit();
|
|
3580
4664
|
const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
|
|
3581
|
-
const
|
|
4665
|
+
const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
|
|
4666
|
+
const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt }) => ({
|
|
4667
|
+
id,
|
|
4668
|
+
agentId,
|
|
4669
|
+
name,
|
|
4670
|
+
archived,
|
|
4671
|
+
createdAt,
|
|
4672
|
+
updatedAt
|
|
4673
|
+
})), [coreThreads]);
|
|
3582
4674
|
const storeIsLoading = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsIsLoading);
|
|
3583
4675
|
const storeError = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsError);
|
|
3584
|
-
const
|
|
3585
|
-
const
|
|
4676
|
+
const hasMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectHasNextPage);
|
|
4677
|
+
const isFetchingMoreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectIsFetchingNextPage);
|
|
3586
4678
|
const headersKey = (0, react.useMemo)(() => {
|
|
3587
4679
|
var _copilotkit$headers;
|
|
3588
4680
|
return JSON.stringify(Object.entries((_copilotkit$headers = copilotkit.headers) !== null && _copilotkit$headers !== void 0 ? _copilotkit$headers : {}).sort(([left], [right]) => left.localeCompare(right)));
|
|
@@ -3627,15 +4719,184 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3627
4719
|
threads,
|
|
3628
4720
|
isLoading,
|
|
3629
4721
|
error,
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
4722
|
+
hasMoreThreads,
|
|
4723
|
+
isFetchingMoreThreads,
|
|
4724
|
+
fetchMoreThreads: (0, react.useCallback)(() => store.fetchNextPage(), [store]),
|
|
3633
4725
|
renameThread,
|
|
3634
4726
|
archiveThread,
|
|
3635
4727
|
deleteThread
|
|
3636
4728
|
};
|
|
3637
4729
|
}
|
|
3638
4730
|
|
|
4731
|
+
//#endregion
|
|
4732
|
+
//#region src/v2/hooks/use-attachments.tsx
|
|
4733
|
+
/**
|
|
4734
|
+
* Hook that manages file attachment state — uploads, drag-and-drop, paste,
|
|
4735
|
+
* and lifecycle. All returned callbacks are referentially stable across
|
|
4736
|
+
* renders (via useCallback) to avoid destabilizing downstream memoization.
|
|
4737
|
+
*/
|
|
4738
|
+
function useAttachments({ config }) {
|
|
4739
|
+
var _config$enabled;
|
|
4740
|
+
const enabled = (_config$enabled = config === null || config === void 0 ? void 0 : config.enabled) !== null && _config$enabled !== void 0 ? _config$enabled : false;
|
|
4741
|
+
const [attachments, setAttachments] = (0, react.useState)([]);
|
|
4742
|
+
const [dragOver, setDragOver] = (0, react.useState)(false);
|
|
4743
|
+
const fileInputRef = (0, react.useRef)(null);
|
|
4744
|
+
const containerRef = (0, react.useRef)(null);
|
|
4745
|
+
const configRef = (0, react.useRef)(config);
|
|
4746
|
+
configRef.current = config;
|
|
4747
|
+
const attachmentsRef = (0, react.useRef)([]);
|
|
4748
|
+
attachmentsRef.current = attachments;
|
|
4749
|
+
const processFiles = (0, react.useCallback)(async (files) => {
|
|
4750
|
+
var _cfg$accept, _cfg$maxSize;
|
|
4751
|
+
const cfg = configRef.current;
|
|
4752
|
+
const accept = (_cfg$accept = cfg === null || cfg === void 0 ? void 0 : cfg.accept) !== null && _cfg$accept !== void 0 ? _cfg$accept : "*/*";
|
|
4753
|
+
const maxSize = (_cfg$maxSize = cfg === null || cfg === void 0 ? void 0 : cfg.maxSize) !== null && _cfg$maxSize !== void 0 ? _cfg$maxSize : 20 * 1024 * 1024;
|
|
4754
|
+
const rejectedFiles = files.filter((file) => !(0, _copilotkit_shared.matchesAcceptFilter)(file, accept));
|
|
4755
|
+
for (const file of rejectedFiles) {
|
|
4756
|
+
var _cfg$onUploadFailed;
|
|
4757
|
+
cfg === null || cfg === void 0 || (_cfg$onUploadFailed = cfg.onUploadFailed) === null || _cfg$onUploadFailed === void 0 || _cfg$onUploadFailed.call(cfg, {
|
|
4758
|
+
reason: "invalid-type",
|
|
4759
|
+
file,
|
|
4760
|
+
message: `File "${file.name}" is not accepted. Supported types: ${accept}`
|
|
4761
|
+
});
|
|
4762
|
+
}
|
|
4763
|
+
const validFiles = files.filter((file) => (0, _copilotkit_shared.matchesAcceptFilter)(file, accept));
|
|
4764
|
+
for (const file of validFiles) {
|
|
4765
|
+
if ((0, _copilotkit_shared.exceedsMaxSize)(file, maxSize)) {
|
|
4766
|
+
var _cfg$onUploadFailed2;
|
|
4767
|
+
cfg === null || cfg === void 0 || (_cfg$onUploadFailed2 = cfg.onUploadFailed) === null || _cfg$onUploadFailed2 === void 0 || _cfg$onUploadFailed2.call(cfg, {
|
|
4768
|
+
reason: "file-too-large",
|
|
4769
|
+
file,
|
|
4770
|
+
message: `File "${file.name}" exceeds the maximum size of ${(0, _copilotkit_shared.formatFileSize)(maxSize)}`
|
|
4771
|
+
});
|
|
4772
|
+
continue;
|
|
4773
|
+
}
|
|
4774
|
+
const modality = (0, _copilotkit_shared.getModalityFromMimeType)(file.type);
|
|
4775
|
+
const placeholderId = (0, _copilotkit_shared.randomUUID)();
|
|
4776
|
+
const placeholder = {
|
|
4777
|
+
id: placeholderId,
|
|
4778
|
+
type: modality,
|
|
4779
|
+
source: {
|
|
4780
|
+
type: "data",
|
|
4781
|
+
value: "",
|
|
4782
|
+
mimeType: file.type
|
|
4783
|
+
},
|
|
4784
|
+
filename: file.name,
|
|
4785
|
+
size: file.size,
|
|
4786
|
+
status: "uploading"
|
|
4787
|
+
};
|
|
4788
|
+
setAttachments((prev) => [...prev, placeholder]);
|
|
4789
|
+
try {
|
|
4790
|
+
let source;
|
|
4791
|
+
let uploadMetadata;
|
|
4792
|
+
if (cfg === null || cfg === void 0 ? void 0 : cfg.onUpload) {
|
|
4793
|
+
const { metadata: meta, ...uploadSource } = await cfg.onUpload(file);
|
|
4794
|
+
source = uploadSource;
|
|
4795
|
+
uploadMetadata = meta;
|
|
4796
|
+
} else source = {
|
|
4797
|
+
type: "data",
|
|
4798
|
+
value: await (0, _copilotkit_shared.readFileAsBase64)(file),
|
|
4799
|
+
mimeType: file.type
|
|
4800
|
+
};
|
|
4801
|
+
let thumbnail;
|
|
4802
|
+
if (modality === "video") thumbnail = await (0, _copilotkit_shared.generateVideoThumbnail)(file);
|
|
4803
|
+
setAttachments((prev) => prev.map((att) => att.id === placeholderId ? {
|
|
4804
|
+
...att,
|
|
4805
|
+
source,
|
|
4806
|
+
status: "ready",
|
|
4807
|
+
thumbnail,
|
|
4808
|
+
metadata: uploadMetadata
|
|
4809
|
+
} : att));
|
|
4810
|
+
} catch (error) {
|
|
4811
|
+
var _cfg$onUploadFailed3;
|
|
4812
|
+
setAttachments((prev) => prev.filter((att) => att.id !== placeholderId));
|
|
4813
|
+
console.error(`[CopilotKit] Failed to upload "${file.name}":`, error);
|
|
4814
|
+
cfg === null || cfg === void 0 || (_cfg$onUploadFailed3 = cfg.onUploadFailed) === null || _cfg$onUploadFailed3 === void 0 || _cfg$onUploadFailed3.call(cfg, {
|
|
4815
|
+
reason: "upload-failed",
|
|
4816
|
+
file,
|
|
4817
|
+
message: error instanceof Error ? error.message : `Failed to upload "${file.name}"`
|
|
4818
|
+
});
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
}, []);
|
|
4822
|
+
const handleFileUpload = (0, react.useCallback)(async (e) => {
|
|
4823
|
+
var _e$target$files;
|
|
4824
|
+
if (!((_e$target$files = e.target.files) === null || _e$target$files === void 0 ? void 0 : _e$target$files.length)) return;
|
|
4825
|
+
try {
|
|
4826
|
+
await processFiles(Array.from(e.target.files));
|
|
4827
|
+
} catch (error) {
|
|
4828
|
+
console.error("[CopilotKit] Upload error:", error);
|
|
4829
|
+
}
|
|
4830
|
+
}, [processFiles]);
|
|
4831
|
+
const handleDragOver = (0, react.useCallback)((e) => {
|
|
4832
|
+
var _configRef$current;
|
|
4833
|
+
if (!((_configRef$current = configRef.current) === null || _configRef$current === void 0 ? void 0 : _configRef$current.enabled)) return;
|
|
4834
|
+
e.preventDefault();
|
|
4835
|
+
e.stopPropagation();
|
|
4836
|
+
setDragOver(true);
|
|
4837
|
+
}, []);
|
|
4838
|
+
const handleDragLeave = (0, react.useCallback)((e) => {
|
|
4839
|
+
e.preventDefault();
|
|
4840
|
+
e.stopPropagation();
|
|
4841
|
+
setDragOver(false);
|
|
4842
|
+
}, []);
|
|
4843
|
+
const handleDrop = (0, react.useCallback)(async (e) => {
|
|
4844
|
+
var _configRef$current2;
|
|
4845
|
+
e.preventDefault();
|
|
4846
|
+
e.stopPropagation();
|
|
4847
|
+
setDragOver(false);
|
|
4848
|
+
if (!((_configRef$current2 = configRef.current) === null || _configRef$current2 === void 0 ? void 0 : _configRef$current2.enabled)) return;
|
|
4849
|
+
const files = Array.from(e.dataTransfer.files);
|
|
4850
|
+
if (files.length > 0) try {
|
|
4851
|
+
await processFiles(files);
|
|
4852
|
+
} catch (error) {
|
|
4853
|
+
console.error("[CopilotKit] Drop error:", error);
|
|
4854
|
+
}
|
|
4855
|
+
}, [processFiles]);
|
|
4856
|
+
(0, react.useEffect)(() => {
|
|
4857
|
+
if (!enabled) return;
|
|
4858
|
+
const handlePaste = async (e) => {
|
|
4859
|
+
var _containerRef$current, _configRef$current$ac, _configRef$current3, _e$clipboardData;
|
|
4860
|
+
const target = e.target;
|
|
4861
|
+
if (!target || !((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.contains(target))) return;
|
|
4862
|
+
const accept = (_configRef$current$ac = (_configRef$current3 = configRef.current) === null || _configRef$current3 === void 0 ? void 0 : _configRef$current3.accept) !== null && _configRef$current$ac !== void 0 ? _configRef$current$ac : "*/*";
|
|
4863
|
+
const fileItems = Array.from(((_e$clipboardData = e.clipboardData) === null || _e$clipboardData === void 0 ? void 0 : _e$clipboardData.items) || []).filter((item) => item.kind === "file" && item.getAsFile() !== null && (0, _copilotkit_shared.matchesAcceptFilter)(item.getAsFile(), accept));
|
|
4864
|
+
if (fileItems.length === 0) return;
|
|
4865
|
+
e.preventDefault();
|
|
4866
|
+
const files = fileItems.map((item) => item.getAsFile()).filter((f) => f !== null);
|
|
4867
|
+
try {
|
|
4868
|
+
await processFiles(files);
|
|
4869
|
+
} catch (error) {
|
|
4870
|
+
console.error("[CopilotKit] Paste error:", error);
|
|
4871
|
+
}
|
|
4872
|
+
};
|
|
4873
|
+
document.addEventListener("paste", handlePaste);
|
|
4874
|
+
return () => document.removeEventListener("paste", handlePaste);
|
|
4875
|
+
}, [enabled, processFiles]);
|
|
4876
|
+
return {
|
|
4877
|
+
attachments,
|
|
4878
|
+
enabled,
|
|
4879
|
+
dragOver,
|
|
4880
|
+
fileInputRef,
|
|
4881
|
+
containerRef,
|
|
4882
|
+
processFiles,
|
|
4883
|
+
handleFileUpload,
|
|
4884
|
+
handleDragOver,
|
|
4885
|
+
handleDragLeave,
|
|
4886
|
+
handleDrop,
|
|
4887
|
+
removeAttachment: (0, react.useCallback)((id) => {
|
|
4888
|
+
setAttachments((prev) => prev.filter((a) => a.id !== id));
|
|
4889
|
+
}, []),
|
|
4890
|
+
consumeAttachments: (0, react.useCallback)(() => {
|
|
4891
|
+
const ready = attachmentsRef.current.filter((a) => a.status === "ready");
|
|
4892
|
+
if (ready.length === 0) return ready;
|
|
4893
|
+
setAttachments((prev) => prev.filter((a) => a.status !== "ready"));
|
|
4894
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
4895
|
+
return ready;
|
|
4896
|
+
}, [])
|
|
4897
|
+
};
|
|
4898
|
+
}
|
|
4899
|
+
|
|
3639
4900
|
//#endregion
|
|
3640
4901
|
//#region src/v2/components/chat/CopilotChatToolCallsView.tsx
|
|
3641
4902
|
function CopilotChatToolCallsView({ message, messages = [] }) {
|
|
@@ -3755,9 +5016,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3755
5016
|
const config = useCopilotChatConfiguration();
|
|
3756
5017
|
const labels = (_config$labels = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels !== void 0 ? _config$labels : CopilotChatDefaultLabels;
|
|
3757
5018
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
5019
|
+
const timerRef = (0, react.useRef)(null);
|
|
5020
|
+
(0, react.useEffect)(() => {
|
|
5021
|
+
return () => {
|
|
5022
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
5023
|
+
};
|
|
5024
|
+
}, []);
|
|
3758
5025
|
const handleClick = (event) => {
|
|
3759
5026
|
setCopied(true);
|
|
3760
|
-
|
|
5027
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
5028
|
+
timerRef.current = setTimeout(() => {
|
|
5029
|
+
timerRef.current = null;
|
|
5030
|
+
setCopied(false);
|
|
5031
|
+
}, 2e3);
|
|
3761
5032
|
if (onClick) onClick(event);
|
|
3762
5033
|
};
|
|
3763
5034
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
@@ -3823,6 +5094,80 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3823
5094
|
CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
|
|
3824
5095
|
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
|
|
3825
5096
|
|
|
5097
|
+
//#endregion
|
|
5098
|
+
//#region src/v2/components/chat/CopilotChatAttachmentRenderer.tsx
|
|
5099
|
+
const ImageAttachment = (0, react.memo)(function ImageAttachment({ src, className }) {
|
|
5100
|
+
const [error, setError] = (0, react.useState)(false);
|
|
5101
|
+
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5102
|
+
className: cn("cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:rounded-lg cpk:bg-muted cpk:p-4 cpk:text-sm cpk:text-muted-foreground", className),
|
|
5103
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Failed to load image" })
|
|
5104
|
+
});
|
|
5105
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
5106
|
+
src,
|
|
5107
|
+
alt: "Image attachment",
|
|
5108
|
+
className: cn("cpk:max-w-full cpk:h-auto cpk:rounded-lg", className),
|
|
5109
|
+
onError: () => setError(true)
|
|
5110
|
+
});
|
|
5111
|
+
});
|
|
5112
|
+
const AudioAttachment = (0, react.memo)(function AudioAttachment({ src, filename, className }) {
|
|
5113
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5114
|
+
className: cn("cpk:flex cpk:flex-col cpk:gap-1", className),
|
|
5115
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
|
|
5116
|
+
src,
|
|
5117
|
+
controls: true,
|
|
5118
|
+
preload: "metadata",
|
|
5119
|
+
className: "cpk:max-w-[300px] cpk:w-full cpk:h-10"
|
|
5120
|
+
}), filename && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5121
|
+
className: "cpk:text-xs cpk:text-muted-foreground cpk:truncate cpk:max-w-[300px]",
|
|
5122
|
+
children: filename
|
|
5123
|
+
})]
|
|
5124
|
+
});
|
|
5125
|
+
});
|
|
5126
|
+
const VideoAttachment = (0, react.memo)(function VideoAttachment({ src, className }) {
|
|
5127
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
|
|
5128
|
+
src,
|
|
5129
|
+
controls: true,
|
|
5130
|
+
preload: "metadata",
|
|
5131
|
+
className: cn("cpk:max-w-[400px] cpk:w-full cpk:rounded-lg", className)
|
|
5132
|
+
});
|
|
5133
|
+
});
|
|
5134
|
+
const DocumentAttachment = (0, react.memo)(function DocumentAttachment({ source, filename, className }) {
|
|
5135
|
+
var _source$mimeType;
|
|
5136
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5137
|
+
className: cn("cpk:inline-flex cpk:items-center cpk:gap-2 cpk:px-3 cpk:py-2 cpk:border cpk:border-border cpk:rounded-lg cpk:bg-muted", className),
|
|
5138
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5139
|
+
className: "cpk:text-xs cpk:font-bold cpk:uppercase",
|
|
5140
|
+
children: (0, _copilotkit_shared.getDocumentIcon)((_source$mimeType = source.mimeType) !== null && _source$mimeType !== void 0 ? _source$mimeType : "")
|
|
5141
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5142
|
+
className: "cpk:text-sm cpk:text-muted-foreground cpk:truncate",
|
|
5143
|
+
children: filename || source.mimeType || "Unknown type"
|
|
5144
|
+
})]
|
|
5145
|
+
});
|
|
5146
|
+
});
|
|
5147
|
+
const CopilotChatAttachmentRenderer = ({ type, source, filename, className }) => {
|
|
5148
|
+
const src = (0, _copilotkit_shared.getSourceUrl)(source);
|
|
5149
|
+
switch (type) {
|
|
5150
|
+
case "image": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageAttachment, {
|
|
5151
|
+
src,
|
|
5152
|
+
className
|
|
5153
|
+
});
|
|
5154
|
+
case "audio": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioAttachment, {
|
|
5155
|
+
src,
|
|
5156
|
+
filename,
|
|
5157
|
+
className
|
|
5158
|
+
});
|
|
5159
|
+
case "video": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VideoAttachment, {
|
|
5160
|
+
src,
|
|
5161
|
+
className
|
|
5162
|
+
});
|
|
5163
|
+
case "document": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocumentAttachment, {
|
|
5164
|
+
source,
|
|
5165
|
+
filename,
|
|
5166
|
+
className
|
|
5167
|
+
});
|
|
5168
|
+
}
|
|
5169
|
+
};
|
|
5170
|
+
|
|
3826
5171
|
//#endregion
|
|
3827
5172
|
//#region src/v2/components/chat/CopilotChatUserMessage.tsx
|
|
3828
5173
|
function flattenUserMessageContent(content) {
|
|
@@ -3833,8 +5178,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3833
5178
|
return "";
|
|
3834
5179
|
}).filter((text) => text.length > 0).join("\n");
|
|
3835
5180
|
}
|
|
5181
|
+
function getMediaParts(content) {
|
|
5182
|
+
if (!content || typeof content === "string") return [];
|
|
5183
|
+
return content.filter((part) => part.type === "image" || part.type === "audio" || part.type === "video" || part.type === "document");
|
|
5184
|
+
}
|
|
5185
|
+
function getFilename(part) {
|
|
5186
|
+
const meta = part.metadata;
|
|
5187
|
+
if (meta != null && typeof meta === "object" && "filename" in meta && typeof meta.filename === "string") return meta.filename;
|
|
5188
|
+
}
|
|
3836
5189
|
function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfBranches, onSwitchToBranch, additionalToolbarItems, messageRenderer, toolbar, copyButton, editButton, branchNavigation, children, className, ...props }) {
|
|
3837
5190
|
const flattenedContent = (0, react.useMemo)(() => flattenUserMessageContent(message.content), [message.content]);
|
|
5191
|
+
const mediaParts = (0, react.useMemo)(() => getMediaParts(message.content), [message.content]);
|
|
3838
5192
|
const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
|
|
3839
5193
|
const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
|
|
3840
5194
|
if (flattenedContent) try {
|
|
@@ -3881,7 +5235,18 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3881
5235
|
className: (0, tailwind_merge.twMerge)("copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10", className),
|
|
3882
5236
|
"data-message-id": message.id,
|
|
3883
5237
|
...props,
|
|
3884
|
-
children: [
|
|
5238
|
+
children: [
|
|
5239
|
+
BoundMessageRenderer,
|
|
5240
|
+
mediaParts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5241
|
+
className: "cpk:flex cpk:flex-col cpk:items-end cpk:gap-2 cpk:mt-2",
|
|
5242
|
+
children: mediaParts.map((part, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentRenderer, {
|
|
5243
|
+
type: part.type,
|
|
5244
|
+
source: part.source,
|
|
5245
|
+
filename: getFilename(part)
|
|
5246
|
+
}, index))
|
|
5247
|
+
}),
|
|
5248
|
+
BoundToolbar
|
|
5249
|
+
]
|
|
3885
5250
|
});
|
|
3886
5251
|
}
|
|
3887
5252
|
(function(_CopilotChatUserMessage) {
|
|
@@ -4184,6 +5549,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4184
5549
|
const isLoading = loadingSet.has(index) || suggestion.isLoading === true;
|
|
4185
5550
|
const pill = renderSlot(suggestionSlot, CopilotChatSuggestionPill, {
|
|
4186
5551
|
children: suggestion.title,
|
|
5552
|
+
className: suggestion.className,
|
|
4187
5553
|
isLoading,
|
|
4188
5554
|
type: "button",
|
|
4189
5555
|
onClick: () => onSelectSuggestion === null || onSelectSuggestion === void 0 ? void 0 : onSelectSuggestion(suggestion, index)
|
|
@@ -4221,9 +5587,43 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4221
5587
|
});
|
|
4222
5588
|
CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
4223
5589
|
|
|
5590
|
+
//#endregion
|
|
5591
|
+
//#region src/v2/components/chat/scroll-element-context.ts
|
|
5592
|
+
/**
|
|
5593
|
+
* Provides the scroll container element to child components that need it for
|
|
5594
|
+
* virtualization. Set by CopilotChatView.ScrollView; consumed by
|
|
5595
|
+
* CopilotChatMessageView to feed useVirtualizer's getScrollElement.
|
|
5596
|
+
*
|
|
5597
|
+
* Carries the element itself (not a ref) so that context consumers re-render
|
|
5598
|
+
* reactively when the scroll container is first mounted.
|
|
5599
|
+
*/
|
|
5600
|
+
const ScrollElementContext = react.default.createContext(null);
|
|
5601
|
+
|
|
4224
5602
|
//#endregion
|
|
4225
5603
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
4226
5604
|
/**
|
|
5605
|
+
* Resolves a slot value into a { Component, slotProps } pair, handling the three
|
|
5606
|
+
* slot forms: a component type, a className string, or a partial-props object.
|
|
5607
|
+
*/
|
|
5608
|
+
function resolveSlotComponent(slot, DefaultComponent) {
|
|
5609
|
+
if (isReactComponentType(slot)) return {
|
|
5610
|
+
Component: slot,
|
|
5611
|
+
slotProps: void 0
|
|
5612
|
+
};
|
|
5613
|
+
if (typeof slot === "string") return {
|
|
5614
|
+
Component: DefaultComponent,
|
|
5615
|
+
slotProps: { className: slot }
|
|
5616
|
+
};
|
|
5617
|
+
if (slot && typeof slot === "object") return {
|
|
5618
|
+
Component: DefaultComponent,
|
|
5619
|
+
slotProps: slot
|
|
5620
|
+
};
|
|
5621
|
+
return {
|
|
5622
|
+
Component: DefaultComponent,
|
|
5623
|
+
slotProps: void 0
|
|
5624
|
+
};
|
|
5625
|
+
}
|
|
5626
|
+
/**
|
|
4227
5627
|
* Memoized wrapper for assistant messages to prevent re-renders when other messages change.
|
|
4228
5628
|
*/
|
|
4229
5629
|
const MemoizedAssistantMessage = react.default.memo(function MemoizedAssistantMessage({ message, messages, isRunning, AssistantMessageComponent, slotProps }) {
|
|
@@ -4243,7 +5643,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4243
5643
|
if (prevToolCalls && nextToolCalls) for (let i = 0; i < prevToolCalls.length; i++) {
|
|
4244
5644
|
const prevTc = prevToolCalls[i];
|
|
4245
5645
|
const nextTc = nextToolCalls[i];
|
|
4246
|
-
if (!prevTc || !nextTc) return false;
|
|
4247
5646
|
if (prevTc.id !== nextTc.id) return false;
|
|
4248
5647
|
if (prevTc.function.arguments !== nextTc.function.arguments) return false;
|
|
4249
5648
|
}
|
|
@@ -4323,20 +5722,25 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4323
5722
|
if (JSON.stringify(prevProps.stateSnapshot) !== JSON.stringify(nextProps.stateSnapshot)) return false;
|
|
4324
5723
|
return true;
|
|
4325
5724
|
});
|
|
5725
|
+
const VIRTUALIZE_THRESHOLD = 50;
|
|
4326
5726
|
function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, isRunning = false, children, className, ...props }) {
|
|
5727
|
+
var _deduplicatedMessages;
|
|
4327
5728
|
const renderCustomMessage = useRenderCustomMessages();
|
|
4328
5729
|
const { renderActivityMessage } = useRenderActivityMessage();
|
|
4329
5730
|
const { copilotkit } = useCopilotKit();
|
|
4330
5731
|
const config = useCopilotChatConfiguration();
|
|
4331
5732
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
4332
5733
|
(0, react.useEffect)(() => {
|
|
5734
|
+
var _getThreadClone;
|
|
4333
5735
|
if (!(config === null || config === void 0 ? void 0 : config.agentId)) return;
|
|
4334
|
-
const
|
|
5736
|
+
const registryAgent = copilotkit.getAgent(config.agentId);
|
|
5737
|
+
const agent = (_getThreadClone = getThreadClone(registryAgent, config.threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
|
|
4335
5738
|
if (!agent) return;
|
|
4336
5739
|
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
|
|
4337
5740
|
return () => subscription.unsubscribe();
|
|
4338
5741
|
}, [
|
|
4339
5742
|
config === null || config === void 0 ? void 0 : config.agentId,
|
|
5743
|
+
config === null || config === void 0 ? void 0 : config.threadId,
|
|
4340
5744
|
copilotkit,
|
|
4341
5745
|
forceUpdate
|
|
4342
5746
|
]);
|
|
@@ -4355,9 +5759,36 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4355
5759
|
if (!resolvedRunId) return void 0;
|
|
4356
5760
|
return copilotkit.getStateByRun(config.agentId, config.threadId, resolvedRunId);
|
|
4357
5761
|
};
|
|
4358
|
-
const deduplicatedMessages = [...new Map(messages.map((m) => [m.id, m])).values()];
|
|
5762
|
+
const deduplicatedMessages = (0, react.useMemo)(() => [...new Map(messages.map((m) => [m.id, m])).values()], [messages]);
|
|
4359
5763
|
if (process.env.NODE_ENV === "development" && deduplicatedMessages.length < messages.length) console.warn(`CopilotChatMessageView: Deduplicated ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`);
|
|
4360
|
-
const
|
|
5764
|
+
const { Component: AssistantComponent, slotProps: assistantSlotProps } = (0, react.useMemo)(() => resolveSlotComponent(assistantMessage, CopilotChatAssistantMessage_default), [assistantMessage]);
|
|
5765
|
+
const { Component: UserComponent, slotProps: userSlotProps } = (0, react.useMemo)(() => resolveSlotComponent(userMessage, CopilotChatUserMessage_default), [userMessage]);
|
|
5766
|
+
const { Component: ReasoningComponent, slotProps: reasoningSlotProps } = (0, react.useMemo)(() => resolveSlotComponent(reasoningMessage, CopilotChatReasoningMessage_default), [reasoningMessage]);
|
|
5767
|
+
const scrollElementFromCtx = (0, react.useContext)(ScrollElementContext);
|
|
5768
|
+
const scrollElement = scrollElementFromCtx && scrollElementFromCtx.clientHeight > 0 ? scrollElementFromCtx : null;
|
|
5769
|
+
(0, react.useEffect)(() => {
|
|
5770
|
+
if (process.env.NODE_ENV !== "production" && scrollElementFromCtx && scrollElementFromCtx.clientHeight === 0) console.warn("[CopilotKit] Chat scroll container has clientHeight=0 — virtualization disabled. Ensure the chat is rendered in a visible container with a non-zero height.");
|
|
5771
|
+
}, [scrollElementFromCtx]);
|
|
5772
|
+
const shouldVirtualize = !!scrollElement && !children && deduplicatedMessages.length > VIRTUALIZE_THRESHOLD;
|
|
5773
|
+
const virtualizer = (0, _tanstack_react_virtual.useVirtualizer)({
|
|
5774
|
+
count: shouldVirtualize ? deduplicatedMessages.length : 0,
|
|
5775
|
+
getScrollElement: () => scrollElement,
|
|
5776
|
+
estimateSize: () => 100,
|
|
5777
|
+
overscan: 5,
|
|
5778
|
+
measureElement: (el) => {
|
|
5779
|
+
var _el$getBoundingClient;
|
|
5780
|
+
return (_el$getBoundingClient = el === null || el === void 0 ? void 0 : el.getBoundingClientRect().height) !== null && _el$getBoundingClient !== void 0 ? _el$getBoundingClient : 0;
|
|
5781
|
+
},
|
|
5782
|
+
initialRect: {
|
|
5783
|
+
width: 0,
|
|
5784
|
+
height: 600
|
|
5785
|
+
}
|
|
5786
|
+
});
|
|
5787
|
+
(0, react.useLayoutEffect)(() => {
|
|
5788
|
+
if (!shouldVirtualize || !deduplicatedMessages.length) return;
|
|
5789
|
+
virtualizer.scrollToIndex(deduplicatedMessages.length - 1, { align: "end" });
|
|
5790
|
+
}, [shouldVirtualize, (_deduplicatedMessages = deduplicatedMessages[0]) === null || _deduplicatedMessages === void 0 ? void 0 : _deduplicatedMessages.id]);
|
|
5791
|
+
const renderMessageBlock = (message) => {
|
|
4361
5792
|
const elements = [];
|
|
4362
5793
|
const stateSnapshot = getStateSnapshotForMessage(message.id);
|
|
4363
5794
|
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
|
|
@@ -4366,58 +5797,38 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4366
5797
|
renderCustomMessage,
|
|
4367
5798
|
stateSnapshot
|
|
4368
5799
|
}, `${message.id}-custom-before`));
|
|
4369
|
-
if (message.role === "assistant") {
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
}, message.id));
|
|
4393
|
-
} else if (message.role === "activity") {
|
|
4394
|
-
const activityMsg = message;
|
|
4395
|
-
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedActivityMessage, {
|
|
4396
|
-
message: activityMsg,
|
|
4397
|
-
renderActivityMessage
|
|
4398
|
-
}, message.id));
|
|
4399
|
-
} else if (message.role === "reasoning") {
|
|
4400
|
-
let ReasoningComponent = CopilotChatReasoningMessage_default;
|
|
4401
|
-
let reasoningSlotProps;
|
|
4402
|
-
if (isReactComponentType(reasoningMessage)) ReasoningComponent = reasoningMessage;
|
|
4403
|
-
else if (typeof reasoningMessage === "string") reasoningSlotProps = { className: reasoningMessage };
|
|
4404
|
-
else if (reasoningMessage && typeof reasoningMessage === "object") reasoningSlotProps = reasoningMessage;
|
|
4405
|
-
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedReasoningMessage, {
|
|
4406
|
-
message,
|
|
4407
|
-
messages,
|
|
4408
|
-
isRunning,
|
|
4409
|
-
ReasoningMessageComponent: ReasoningComponent,
|
|
4410
|
-
slotProps: reasoningSlotProps
|
|
4411
|
-
}, message.id));
|
|
4412
|
-
}
|
|
5800
|
+
if (message.role === "assistant") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedAssistantMessage, {
|
|
5801
|
+
message,
|
|
5802
|
+
messages,
|
|
5803
|
+
isRunning,
|
|
5804
|
+
AssistantMessageComponent: AssistantComponent,
|
|
5805
|
+
slotProps: assistantSlotProps
|
|
5806
|
+
}, message.id));
|
|
5807
|
+
else if (message.role === "user") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedUserMessage, {
|
|
5808
|
+
message,
|
|
5809
|
+
UserMessageComponent: UserComponent,
|
|
5810
|
+
slotProps: userSlotProps
|
|
5811
|
+
}, message.id));
|
|
5812
|
+
else if (message.role === "activity") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedActivityMessage, {
|
|
5813
|
+
message,
|
|
5814
|
+
renderActivityMessage
|
|
5815
|
+
}, message.id));
|
|
5816
|
+
else if (message.role === "reasoning") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedReasoningMessage, {
|
|
5817
|
+
message,
|
|
5818
|
+
messages,
|
|
5819
|
+
isRunning,
|
|
5820
|
+
ReasoningMessageComponent: ReasoningComponent,
|
|
5821
|
+
slotProps: reasoningSlotProps
|
|
5822
|
+
}, message.id));
|
|
4413
5823
|
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
|
|
4414
5824
|
message,
|
|
4415
5825
|
position: "after",
|
|
4416
5826
|
renderCustomMessage,
|
|
4417
5827
|
stateSnapshot
|
|
4418
5828
|
}, `${message.id}-custom-after`));
|
|
4419
|
-
return elements;
|
|
4420
|
-
}
|
|
5829
|
+
return elements.filter(Boolean);
|
|
5830
|
+
};
|
|
5831
|
+
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
4421
5832
|
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4422
5833
|
"data-copilotkit": true,
|
|
4423
5834
|
style: { display: "contents" },
|
|
@@ -4428,30 +5839,356 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4428
5839
|
interruptElement
|
|
4429
5840
|
})
|
|
4430
5841
|
});
|
|
4431
|
-
const lastMessage = messages[messages.length - 1];
|
|
4432
|
-
const showCursor = isRunning && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) !== "reasoning";
|
|
5842
|
+
const lastMessage = messages[messages.length - 1];
|
|
5843
|
+
const showCursor = isRunning && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) !== "reasoning";
|
|
5844
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5845
|
+
"data-copilotkit": true,
|
|
5846
|
+
"data-testid": "copilot-message-list",
|
|
5847
|
+
className: (0, tailwind_merge.twMerge)("copilotKitMessages cpk:flex cpk:flex-col", className),
|
|
5848
|
+
...props,
|
|
5849
|
+
children: [
|
|
5850
|
+
shouldVirtualize ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5851
|
+
style: {
|
|
5852
|
+
height: virtualizer.getTotalSize(),
|
|
5853
|
+
position: "relative"
|
|
5854
|
+
},
|
|
5855
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
5856
|
+
const message = deduplicatedMessages[virtualItem.index];
|
|
5857
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5858
|
+
"data-index": virtualItem.index,
|
|
5859
|
+
ref: virtualizer.measureElement,
|
|
5860
|
+
style: {
|
|
5861
|
+
position: "absolute",
|
|
5862
|
+
top: 0,
|
|
5863
|
+
left: 0,
|
|
5864
|
+
width: "100%",
|
|
5865
|
+
transform: `translateY(${virtualItem.start}px)`
|
|
5866
|
+
},
|
|
5867
|
+
children: renderMessageBlock(message)
|
|
5868
|
+
}, message.id);
|
|
5869
|
+
})
|
|
5870
|
+
}) : messageElements,
|
|
5871
|
+
interruptElement,
|
|
5872
|
+
showCursor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5873
|
+
className: "cpk:mt-2",
|
|
5874
|
+
children: renderSlot(cursor, CopilotChatMessageView.Cursor, {})
|
|
5875
|
+
})
|
|
5876
|
+
]
|
|
5877
|
+
});
|
|
5878
|
+
}
|
|
5879
|
+
CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
5880
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5881
|
+
"data-testid": "copilot-loading-cursor",
|
|
5882
|
+
className: (0, tailwind_merge.twMerge)("cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1", className),
|
|
5883
|
+
...props
|
|
5884
|
+
});
|
|
5885
|
+
};
|
|
5886
|
+
|
|
5887
|
+
//#endregion
|
|
5888
|
+
//#region src/v2/components/chat/CopilotChatAttachmentQueue.tsx
|
|
5889
|
+
const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className }) => {
|
|
5890
|
+
if (attachments.length === 0) return null;
|
|
5891
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5892
|
+
className: cn("cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2", className),
|
|
5893
|
+
children: attachments.map((attachment) => {
|
|
5894
|
+
const isMedia = attachment.type === "image" || attachment.type === "video";
|
|
5895
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5896
|
+
className: cn("cpk:relative cpk:inline-flex cpk:rounded-lg cpk:overflow-hidden cpk:border cpk:border-border", isMedia ? "cpk:w-[72px] cpk:h-[72px]" : attachment.type === "audio" ? "cpk:min-w-[200px] cpk:max-w-[280px] cpk:flex-col cpk:p-1 cpk:pr-8" : "cpk:p-2 cpk:px-3 cpk:pr-8 cpk:max-w-[240px]"),
|
|
5897
|
+
children: [
|
|
5898
|
+
attachment.status === "uploading" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UploadingOverlay, {}),
|
|
5899
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AttachmentPreview, { attachment }),
|
|
5900
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5901
|
+
onClick: () => onRemoveAttachment(attachment.id),
|
|
5902
|
+
className: cn("cpk:absolute cpk:bg-black/60 cpk:text-white cpk:border-none cpk:rounded-full cpk:w-5 cpk:h-5 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:text-[10px] cpk:z-20", isMedia ? "cpk:top-1 cpk:right-1" : "cpk:top-1.5 cpk:right-1.5"),
|
|
5903
|
+
"aria-label": "Remove attachment",
|
|
5904
|
+
children: "✕"
|
|
5905
|
+
})
|
|
5906
|
+
]
|
|
5907
|
+
}, attachment.id);
|
|
5908
|
+
})
|
|
5909
|
+
});
|
|
5910
|
+
};
|
|
5911
|
+
function UploadingOverlay() {
|
|
5912
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5913
|
+
className: "cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/40 cpk:z-10",
|
|
5914
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:w-5 cpk:h-5 cpk:border-2 cpk:border-white cpk:border-t-transparent cpk:rounded-full cpk:animate-spin" })
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5917
|
+
function AttachmentPreview({ attachment }) {
|
|
5918
|
+
if (attachment.status === "uploading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:w-full cpk:h-full" });
|
|
5919
|
+
switch (attachment.type) {
|
|
5920
|
+
case "image": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImagePreview, { attachment });
|
|
5921
|
+
case "audio": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioPreview, { attachment });
|
|
5922
|
+
case "video": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VideoPreview, { attachment });
|
|
5923
|
+
case "document": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocumentPreview, { attachment });
|
|
5924
|
+
}
|
|
5925
|
+
}
|
|
5926
|
+
function Lightbox({ onClose, children }) {
|
|
5927
|
+
(0, react.useEffect)(() => {
|
|
5928
|
+
const handleKey = (e) => {
|
|
5929
|
+
if (e.key === "Escape") onClose();
|
|
5930
|
+
};
|
|
5931
|
+
document.addEventListener("keydown", handleKey);
|
|
5932
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
5933
|
+
}, [onClose]);
|
|
5934
|
+
if (typeof document === "undefined") return null;
|
|
5935
|
+
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5936
|
+
className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
|
|
5937
|
+
onClick: onClose,
|
|
5938
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5939
|
+
onClick: onClose,
|
|
5940
|
+
className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
|
|
5941
|
+
"aria-label": "Close preview",
|
|
5942
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:w-5 cpk:h-5" })
|
|
5943
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5944
|
+
onClick: (e) => e.stopPropagation(),
|
|
5945
|
+
children
|
|
5946
|
+
})]
|
|
5947
|
+
}), document.body);
|
|
5948
|
+
}
|
|
5949
|
+
/**
|
|
5950
|
+
* Hook that manages lightbox open/close and uses the View Transition API to
|
|
5951
|
+
* morph the thumbnail into fullscreen content.
|
|
5952
|
+
*
|
|
5953
|
+
* The trick: `view-transition-name` must live on exactly ONE element at a time.
|
|
5954
|
+
* - Old state (thumbnail visible): name is on the thumbnail.
|
|
5955
|
+
* - New state (lightbox visible): name moves to the lightbox content.
|
|
5956
|
+
* `flushSync` ensures React commits the DOM change synchronously inside the
|
|
5957
|
+
* `startViewTransition` callback so the API can snapshot old → new correctly.
|
|
5958
|
+
*/
|
|
5959
|
+
function useLightbox() {
|
|
5960
|
+
const thumbnailRef = (0, react.useRef)(null);
|
|
5961
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
5962
|
+
const vtName = (0, react.useId)();
|
|
5963
|
+
return {
|
|
5964
|
+
thumbnailRef,
|
|
5965
|
+
vtName,
|
|
5966
|
+
open,
|
|
5967
|
+
openLightbox: (0, react.useCallback)(() => {
|
|
5968
|
+
const thumb = thumbnailRef.current;
|
|
5969
|
+
const doc = document;
|
|
5970
|
+
if (doc.startViewTransition && thumb) {
|
|
5971
|
+
thumb.style.viewTransitionName = vtName;
|
|
5972
|
+
doc.startViewTransition(() => {
|
|
5973
|
+
thumb.style.viewTransitionName = "";
|
|
5974
|
+
(0, react_dom.flushSync)(() => setOpen(true));
|
|
5975
|
+
});
|
|
5976
|
+
} else setOpen(true);
|
|
5977
|
+
}, []),
|
|
5978
|
+
closeLightbox: (0, react.useCallback)(() => {
|
|
5979
|
+
const thumb = thumbnailRef.current;
|
|
5980
|
+
const doc = document;
|
|
5981
|
+
if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
|
|
5982
|
+
(0, react_dom.flushSync)(() => setOpen(false));
|
|
5983
|
+
thumb.style.viewTransitionName = vtName;
|
|
5984
|
+
}).finished.then(() => {
|
|
5985
|
+
thumb.style.viewTransitionName = "";
|
|
5986
|
+
}).catch(() => {
|
|
5987
|
+
thumb.style.viewTransitionName = "";
|
|
5988
|
+
});
|
|
5989
|
+
else setOpen(false);
|
|
5990
|
+
}, [])
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5993
|
+
function ImagePreview({ attachment }) {
|
|
5994
|
+
const src = (0, _copilotkit_shared.getSourceUrl)(attachment.source);
|
|
5995
|
+
const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
|
|
5996
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
5997
|
+
ref: thumbnailRef,
|
|
5998
|
+
src,
|
|
5999
|
+
alt: attachment.filename || "Image attachment",
|
|
6000
|
+
className: "cpk:w-full cpk:h-full cpk:object-cover cpk:cursor-pointer",
|
|
6001
|
+
onClick: openLightbox
|
|
6002
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Lightbox, {
|
|
6003
|
+
onClose: closeLightbox,
|
|
6004
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
6005
|
+
style: { viewTransitionName: vtName },
|
|
6006
|
+
src,
|
|
6007
|
+
alt: attachment.filename || "Image attachment",
|
|
6008
|
+
className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg"
|
|
6009
|
+
})
|
|
6010
|
+
})] });
|
|
6011
|
+
}
|
|
6012
|
+
function AudioPreview({ attachment }) {
|
|
6013
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6014
|
+
className: "cpk:flex cpk:flex-col cpk:gap-1 cpk:w-full",
|
|
6015
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
|
|
6016
|
+
src: (0, _copilotkit_shared.getSourceUrl)(attachment.source),
|
|
6017
|
+
controls: true,
|
|
6018
|
+
preload: "metadata",
|
|
6019
|
+
className: "cpk:w-full cpk:h-8"
|
|
6020
|
+
}), attachment.filename && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6021
|
+
className: "cpk:text-xs cpk:font-medium cpk:overflow-hidden cpk:text-ellipsis cpk:whitespace-nowrap",
|
|
6022
|
+
children: attachment.filename
|
|
6023
|
+
})]
|
|
6024
|
+
});
|
|
6025
|
+
}
|
|
6026
|
+
function VideoPreview({ attachment }) {
|
|
6027
|
+
const src = (0, _copilotkit_shared.getSourceUrl)(attachment.source);
|
|
6028
|
+
const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
|
|
6029
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
6030
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6031
|
+
ref: thumbnailRef,
|
|
6032
|
+
className: "cpk:w-full cpk:h-full",
|
|
6033
|
+
children: attachment.thumbnail ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
6034
|
+
src: attachment.thumbnail,
|
|
6035
|
+
alt: attachment.filename || "Video thumbnail",
|
|
6036
|
+
className: "cpk:w-full cpk:h-full cpk:object-cover"
|
|
6037
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
|
|
6038
|
+
src,
|
|
6039
|
+
preload: "metadata",
|
|
6040
|
+
muted: true,
|
|
6041
|
+
className: "cpk:w-full cpk:h-full cpk:object-cover"
|
|
6042
|
+
})
|
|
6043
|
+
}),
|
|
6044
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6045
|
+
onClick: openLightbox,
|
|
6046
|
+
className: "cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:z-10 cpk:cursor-pointer cpk:bg-black/20 cpk:border-none cpk:p-0",
|
|
6047
|
+
"aria-label": "Play video",
|
|
6048
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6049
|
+
className: "cpk:w-8 cpk:h-8 cpk:rounded-full cpk:bg-black/60 cpk:flex cpk:items-center cpk:justify-center",
|
|
6050
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Play, { className: "cpk:w-4 cpk:h-4 cpk:text-white cpk:ml-0.5" })
|
|
6051
|
+
})
|
|
6052
|
+
}),
|
|
6053
|
+
open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Lightbox, {
|
|
6054
|
+
onClose: closeLightbox,
|
|
6055
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
|
|
6056
|
+
style: { viewTransitionName: vtName },
|
|
6057
|
+
src,
|
|
6058
|
+
controls: true,
|
|
6059
|
+
autoPlay: true,
|
|
6060
|
+
className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:rounded-lg"
|
|
6061
|
+
})
|
|
6062
|
+
})
|
|
6063
|
+
] });
|
|
6064
|
+
}
|
|
6065
|
+
function isPdf(mimeType) {
|
|
6066
|
+
return !!mimeType && mimeType.includes("pdf");
|
|
6067
|
+
}
|
|
6068
|
+
function isText(mimeType) {
|
|
6069
|
+
return !!mimeType && mimeType.startsWith("text/");
|
|
6070
|
+
}
|
|
6071
|
+
function canPreviewInBrowser(mimeType) {
|
|
6072
|
+
return isPdf(mimeType) || isText(mimeType);
|
|
6073
|
+
}
|
|
6074
|
+
/**
|
|
6075
|
+
* Convert a base64-encoded data source to a blob: URL that browsers will
|
|
6076
|
+
* render inside an iframe (data: URLs are blocked for PDFs in most browsers).
|
|
6077
|
+
*/
|
|
6078
|
+
function useBlobUrl(attachment) {
|
|
6079
|
+
const [url, setUrl] = (0, react.useState)(null);
|
|
6080
|
+
(0, react.useEffect)(() => {
|
|
6081
|
+
if (attachment.source.type !== "data") return;
|
|
6082
|
+
try {
|
|
6083
|
+
const binary = atob(attachment.source.value);
|
|
6084
|
+
const bytes = new Uint8Array(binary.length);
|
|
6085
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
6086
|
+
const blob = new Blob([bytes], { type: attachment.source.mimeType || "application/octet-stream" });
|
|
6087
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
6088
|
+
setUrl(blobUrl);
|
|
6089
|
+
return () => URL.revokeObjectURL(blobUrl);
|
|
6090
|
+
} catch (error) {
|
|
6091
|
+
console.error("[CopilotKit] Failed to decode attachment data:", error);
|
|
6092
|
+
setUrl(null);
|
|
6093
|
+
}
|
|
6094
|
+
}, [
|
|
6095
|
+
attachment.source.type,
|
|
6096
|
+
attachment.source.value,
|
|
6097
|
+
attachment.source.mimeType
|
|
6098
|
+
]);
|
|
6099
|
+
if (attachment.source.type === "url") return attachment.source.value;
|
|
6100
|
+
return url;
|
|
6101
|
+
}
|
|
6102
|
+
function DocumentLightboxContent({ attachment, vtName }) {
|
|
6103
|
+
const mimeType = attachment.source.mimeType;
|
|
6104
|
+
const blobUrl = useBlobUrl(attachment);
|
|
6105
|
+
if (isPdf(mimeType)) {
|
|
6106
|
+
if (!blobUrl) return null;
|
|
6107
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
6108
|
+
style: { viewTransitionName: vtName },
|
|
6109
|
+
src: blobUrl,
|
|
6110
|
+
title: attachment.filename || "PDF preview",
|
|
6111
|
+
className: "cpk:w-[90vw] cpk:h-[90vh] cpk:max-w-[1000px] cpk:rounded-lg cpk:bg-white"
|
|
6112
|
+
});
|
|
6113
|
+
}
|
|
6114
|
+
if (isText(mimeType)) {
|
|
6115
|
+
const textContent = attachment.source.type === "data" ? (() => {
|
|
6116
|
+
try {
|
|
6117
|
+
return atob(attachment.source.value);
|
|
6118
|
+
} catch (_unused) {
|
|
6119
|
+
return attachment.source.value;
|
|
6120
|
+
}
|
|
6121
|
+
})() : null;
|
|
6122
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6123
|
+
style: { viewTransitionName: vtName },
|
|
6124
|
+
className: "cpk:w-[90vw] cpk:max-w-[800px] cpk:max-h-[90vh] cpk:overflow-auto cpk:rounded-lg cpk:bg-white cpk:dark:bg-gray-900 cpk:p-6",
|
|
6125
|
+
children: [attachment.filename && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6126
|
+
className: "cpk:text-sm cpk:font-medium cpk:text-gray-500 cpk:dark:text-gray-400 cpk:mb-4 cpk:pb-2 cpk:border-b cpk:border-gray-200 cpk:dark:border-gray-700",
|
|
6127
|
+
children: attachment.filename
|
|
6128
|
+
}), textContent ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
6129
|
+
className: "cpk:text-sm cpk:whitespace-pre-wrap cpk:break-words cpk:text-gray-800 cpk:dark:text-gray-200 cpk:font-mono cpk:m-0",
|
|
6130
|
+
children: textContent
|
|
6131
|
+
}) : blobUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
6132
|
+
src: blobUrl,
|
|
6133
|
+
title: attachment.filename || "Text preview",
|
|
6134
|
+
className: "cpk:w-full cpk:h-[80vh] cpk:border-none"
|
|
6135
|
+
}) : null]
|
|
6136
|
+
});
|
|
6137
|
+
}
|
|
4433
6138
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4434
|
-
|
|
4435
|
-
"
|
|
4436
|
-
className: (0, tailwind_merge.twMerge)("copilotKitMessages cpk:flex cpk:flex-col", className),
|
|
4437
|
-
...props,
|
|
6139
|
+
style: { viewTransitionName: vtName },
|
|
6140
|
+
className: "cpk:flex cpk:flex-col cpk:items-center cpk:gap-4 cpk:p-8 cpk:rounded-lg cpk:bg-white cpk:dark:bg-gray-900",
|
|
4438
6141
|
children: [
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
6142
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6143
|
+
className: "cpk:w-16 cpk:h-16 cpk:rounded-xl cpk:bg-primary cpk:text-primary-foreground cpk:flex cpk:items-center cpk:justify-center cpk:text-xl cpk:font-bold",
|
|
6144
|
+
children: (0, _copilotkit_shared.getDocumentIcon)(mimeType !== null && mimeType !== void 0 ? mimeType : "")
|
|
6145
|
+
}),
|
|
6146
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6147
|
+
className: "cpk:text-center",
|
|
6148
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6149
|
+
className: "cpk:text-base cpk:font-medium cpk:text-gray-800 cpk:dark:text-gray-200",
|
|
6150
|
+
children: attachment.filename || "Document"
|
|
6151
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6152
|
+
className: "cpk:text-sm cpk:text-gray-500 cpk:dark:text-gray-400 cpk:mt-1",
|
|
6153
|
+
children: [mimeType || "Unknown type", attachment.size != null && ` · ${(0, _copilotkit_shared.formatFileSize)(attachment.size)}`]
|
|
6154
|
+
})]
|
|
6155
|
+
}),
|
|
6156
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6157
|
+
className: "cpk:text-xs cpk:text-gray-400 cpk:dark:text-gray-500",
|
|
6158
|
+
children: "No preview available for this file type"
|
|
4444
6159
|
})
|
|
4445
6160
|
]
|
|
4446
6161
|
});
|
|
4447
6162
|
}
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
6163
|
+
function DocumentPreview({ attachment }) {
|
|
6164
|
+
const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
|
|
6165
|
+
const mimeType = attachment.source.mimeType;
|
|
6166
|
+
const previewable = canPreviewInBrowser(mimeType);
|
|
6167
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6168
|
+
ref: thumbnailRef,
|
|
6169
|
+
className: cn("cpk:flex cpk:items-center cpk:gap-2", previewable && "cpk:cursor-pointer"),
|
|
6170
|
+
onClick: previewable ? openLightbox : void 0,
|
|
6171
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6172
|
+
className: "cpk:w-8 cpk:h-8 cpk:rounded-md cpk:bg-primary cpk:text-primary-foreground cpk:flex cpk:items-center cpk:justify-center cpk:text-[10px] cpk:font-semibold cpk:shrink-0",
|
|
6173
|
+
children: (0, _copilotkit_shared.getDocumentIcon)(mimeType !== null && mimeType !== void 0 ? mimeType : "")
|
|
6174
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6175
|
+
className: "cpk:flex cpk:flex-col cpk:min-w-0",
|
|
6176
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6177
|
+
className: "cpk:text-xs cpk:font-medium cpk:break-all cpk:leading-tight",
|
|
6178
|
+
children: attachment.filename || "Document"
|
|
6179
|
+
}), attachment.size != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6180
|
+
className: "cpk:text-[11px] cpk:text-muted-foreground",
|
|
6181
|
+
children: (0, _copilotkit_shared.formatFileSize)(attachment.size)
|
|
6182
|
+
})]
|
|
6183
|
+
})]
|
|
6184
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Lightbox, {
|
|
6185
|
+
onClose: closeLightbox,
|
|
6186
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocumentLightboxContent, {
|
|
6187
|
+
attachment,
|
|
6188
|
+
vtName
|
|
6189
|
+
})
|
|
6190
|
+
})] });
|
|
6191
|
+
}
|
|
4455
6192
|
|
|
4456
6193
|
//#endregion
|
|
4457
6194
|
//#region src/v2/hooks/use-keyboard-height.tsx
|
|
@@ -4497,7 +6234,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4497
6234
|
//#endregion
|
|
4498
6235
|
//#region src/v2/components/chat/CopilotChatView.tsx
|
|
4499
6236
|
const FEATHER_HEIGHT = 96;
|
|
4500
|
-
function
|
|
6237
|
+
function DropOverlay() {
|
|
6238
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6239
|
+
className: cn("cpk:absolute cpk:inset-0 cpk:z-50 cpk:pointer-events-none", "cpk:flex cpk:items-center cpk:justify-center", "cpk:bg-primary/5 cpk:backdrop-blur-[2px]", "cpk:border-2 cpk:border-dashed cpk:border-primary/40 cpk:rounded-lg cpk:m-2"),
|
|
6240
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6241
|
+
className: "cpk:flex cpk:flex-col cpk:items-center cpk:gap-2 cpk:text-primary/70",
|
|
6242
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "cpk:w-8 cpk:h-8" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6243
|
+
className: "cpk:text-sm cpk:font-medium",
|
|
6244
|
+
children: "Drop files here"
|
|
6245
|
+
})]
|
|
6246
|
+
})
|
|
6247
|
+
});
|
|
6248
|
+
}
|
|
6249
|
+
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, disclaimer, children, className, ...props }) {
|
|
4501
6250
|
const inputContainerRef = (0, react.useRef)(null);
|
|
4502
6251
|
const [inputContainerHeight, setInputContainerHeight] = (0, react.useState)(0);
|
|
4503
6252
|
const [isResizing, setIsResizing] = (0, react.useState)(false);
|
|
@@ -4544,6 +6293,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4544
6293
|
onCancelTranscribe,
|
|
4545
6294
|
onFinishTranscribe,
|
|
4546
6295
|
onFinishTranscribeWithAudio,
|
|
6296
|
+
onAddFile,
|
|
4547
6297
|
positioning: "static",
|
|
4548
6298
|
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
4549
6299
|
containerRef: inputContainerRef,
|
|
@@ -4584,21 +6334,34 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4584
6334
|
onCancelTranscribe,
|
|
4585
6335
|
onFinishTranscribe,
|
|
4586
6336
|
onFinishTranscribeWithAudio,
|
|
6337
|
+
onAddFile,
|
|
4587
6338
|
positioning: "static",
|
|
4588
6339
|
showDisclaimer: true,
|
|
4589
6340
|
...disclaimer !== void 0 ? { disclaimer } : {}
|
|
4590
6341
|
});
|
|
4591
|
-
const
|
|
4592
|
-
|
|
6342
|
+
const welcomeScreenSlot = welcomeScreen === true ? void 0 : welcomeScreen;
|
|
6343
|
+
const inputWithAttachments = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6344
|
+
className: "cpk:w-full",
|
|
6345
|
+
children: [attachments && attachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentQueue, {
|
|
6346
|
+
attachments,
|
|
6347
|
+
onRemoveAttachment: (id) => onRemoveAttachment === null || onRemoveAttachment === void 0 ? void 0 : onRemoveAttachment(id),
|
|
6348
|
+
className: "cpk:mb-2"
|
|
6349
|
+
}), BoundInputForWelcome]
|
|
6350
|
+
});
|
|
6351
|
+
const BoundWelcomeScreen = renderSlot(welcomeScreenSlot, CopilotChatView.WelcomeScreen, {
|
|
6352
|
+
input: inputWithAttachments,
|
|
4593
6353
|
suggestionView: BoundSuggestionView !== null && BoundSuggestionView !== void 0 ? BoundSuggestionView : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {})
|
|
4594
6354
|
});
|
|
4595
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6355
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4596
6356
|
"data-copilotkit": true,
|
|
4597
6357
|
"data-testid": "copilot-chat",
|
|
4598
6358
|
"data-copilot-running": isRunning ? "true" : "false",
|
|
4599
|
-
|
|
6359
|
+
onDragOver,
|
|
6360
|
+
onDragLeave,
|
|
6361
|
+
onDrop,
|
|
6362
|
+
className: cn("copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
4600
6363
|
...props,
|
|
4601
|
-
children: BoundWelcomeScreen
|
|
6364
|
+
children: [dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}), BoundWelcomeScreen]
|
|
4602
6365
|
});
|
|
4603
6366
|
}
|
|
4604
6367
|
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -4615,39 +6378,67 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4615
6378
|
"data-copilotkit": true,
|
|
4616
6379
|
"data-testid": "copilot-chat",
|
|
4617
6380
|
"data-copilot-running": isRunning ? "true" : "false",
|
|
4618
|
-
|
|
6381
|
+
onDragOver,
|
|
6382
|
+
onDragLeave,
|
|
6383
|
+
onDrop,
|
|
6384
|
+
className: cn("copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
4619
6385
|
...props,
|
|
4620
|
-
children: [
|
|
6386
|
+
children: [
|
|
6387
|
+
dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}),
|
|
6388
|
+
BoundScrollView,
|
|
6389
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6390
|
+
className: "cpk:max-w-3xl cpk:mx-auto cpk:w-full",
|
|
6391
|
+
children: attachments && attachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentQueue, {
|
|
6392
|
+
attachments,
|
|
6393
|
+
onRemoveAttachment: (id) => onRemoveAttachment === null || onRemoveAttachment === void 0 ? void 0 : onRemoveAttachment(id),
|
|
6394
|
+
className: "cpk:px-4"
|
|
6395
|
+
})
|
|
6396
|
+
}),
|
|
6397
|
+
BoundInput
|
|
6398
|
+
]
|
|
4621
6399
|
});
|
|
4622
6400
|
}
|
|
4623
6401
|
(function(_CopilotChatView) {
|
|
4624
6402
|
const ScrollContent = ({ children, scrollToBottomButton, feather, inputContainerHeight, isResizing }) => {
|
|
4625
|
-
const { isAtBottom, scrollToBottom } = (0, use_stick_to_bottom.useStickToBottomContext)();
|
|
6403
|
+
const { isAtBottom, scrollToBottom, scrollRef } = (0, use_stick_to_bottom.useStickToBottomContext)();
|
|
6404
|
+
const [scrollEl, setScrollEl] = (0, react.useState)(null);
|
|
6405
|
+
(0, react.useLayoutEffect)(() => {
|
|
6406
|
+
var _scrollRef$current;
|
|
6407
|
+
setScrollEl((_scrollRef$current = scrollRef.current) !== null && _scrollRef$current !== void 0 ? _scrollRef$current : null);
|
|
6408
|
+
}, []);
|
|
4626
6409
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
4627
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
children
|
|
6410
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6411
|
+
value: scrollEl,
|
|
6412
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
6413
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(use_stick_to_bottom.StickToBottom.Content, {
|
|
6414
|
+
className: "cpk:overflow-y-auto cpk:overflow-x-hidden",
|
|
6415
|
+
style: {
|
|
6416
|
+
flex: "1 1 0%",
|
|
6417
|
+
minHeight: 0
|
|
6418
|
+
},
|
|
6419
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6420
|
+
className: "cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
6421
|
+
children
|
|
6422
|
+
})
|
|
6423
|
+
}),
|
|
6424
|
+
BoundFeather,
|
|
6425
|
+
!isAtBottom && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6426
|
+
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6427
|
+
style: { bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px` },
|
|
6428
|
+
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
4637
6429
|
})
|
|
4638
|
-
})
|
|
4639
|
-
|
|
4640
|
-
!isAtBottom && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4641
|
-
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
4642
|
-
style: { bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px` },
|
|
4643
|
-
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
4644
|
-
})
|
|
4645
|
-
] });
|
|
6430
|
+
] })
|
|
6431
|
+
});
|
|
4646
6432
|
};
|
|
4647
6433
|
_CopilotChatView.ScrollView = ({ children, autoScroll = true, scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
|
|
4648
6434
|
const [hasMounted, setHasMounted] = (0, react.useState)(false);
|
|
4649
6435
|
const { scrollRef, contentRef, scrollToBottom } = (0, use_stick_to_bottom.useStickToBottom)();
|
|
4650
6436
|
const [showScrollButton, setShowScrollButton] = (0, react.useState)(false);
|
|
6437
|
+
const [nonAutoScrollEl, setNonAutoScrollEl] = (0, react.useState)(null);
|
|
6438
|
+
const nonAutoScrollRefCallback = (0, react.useCallback)((el) => {
|
|
6439
|
+
scrollRef.current = el;
|
|
6440
|
+
setNonAutoScrollEl(el);
|
|
6441
|
+
}, []);
|
|
4651
6442
|
(0, react.useEffect)(() => {
|
|
4652
6443
|
setHasMounted(true);
|
|
4653
6444
|
}, []);
|
|
@@ -4676,23 +6467,26 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4676
6467
|
});
|
|
4677
6468
|
if (!autoScroll) {
|
|
4678
6469
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
4679
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
6470
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6471
|
+
value: nonAutoScrollEl,
|
|
6472
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6473
|
+
ref: nonAutoScrollRefCallback,
|
|
6474
|
+
className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden cpk:relative", className),
|
|
6475
|
+
...props,
|
|
6476
|
+
children: [
|
|
6477
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6478
|
+
ref: contentRef,
|
|
6479
|
+
className: "cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
6480
|
+
children
|
|
6481
|
+
}),
|
|
6482
|
+
BoundFeather,
|
|
6483
|
+
showScrollButton && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6484
|
+
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6485
|
+
style: { bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px` },
|
|
6486
|
+
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6487
|
+
})
|
|
6488
|
+
]
|
|
6489
|
+
})
|
|
4696
6490
|
});
|
|
4697
6491
|
}
|
|
4698
6492
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(use_stick_to_bottom.StickToBottom, {
|
|
@@ -4887,15 +6681,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4887
6681
|
|
|
4888
6682
|
//#endregion
|
|
4889
6683
|
//#region src/v2/components/chat/CopilotChat.tsx
|
|
4890
|
-
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, onError, ...props }) {
|
|
4891
|
-
var _ref;
|
|
6684
|
+
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, attachments: attachmentsConfig, onError, throttleMs, ...props }) {
|
|
6685
|
+
var _ref, _attachmentsConfig$ac;
|
|
4892
6686
|
const existingConfig = useCopilotChatConfiguration();
|
|
4893
6687
|
const resolvedAgentId = (_ref = agentId !== null && agentId !== void 0 ? agentId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _ref !== void 0 ? _ref : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
4894
6688
|
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
4895
6689
|
var _ref2;
|
|
4896
6690
|
return (_ref2 = threadId !== null && threadId !== void 0 ? threadId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId) !== null && _ref2 !== void 0 ? _ref2 : (0, _copilotkit_shared.randomUUID)();
|
|
4897
6691
|
}, [threadId, existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId]);
|
|
4898
|
-
const { agent } = useAgent({
|
|
6692
|
+
const { agent } = useAgent({
|
|
6693
|
+
agentId: resolvedAgentId,
|
|
6694
|
+
threadId: resolvedThreadId,
|
|
6695
|
+
throttleMs
|
|
6696
|
+
});
|
|
4899
6697
|
const { copilotkit } = useCopilotKit();
|
|
4900
6698
|
const { suggestions: autoSuggestions } = useSuggestions({ agentId: resolvedAgentId });
|
|
4901
6699
|
const { checkFeature } = useLicenseContext();
|
|
@@ -4928,6 +6726,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4928
6726
|
const [inputValue, setInputValue] = (0, react.useState)("");
|
|
4929
6727
|
const [transcriptionError, setTranscriptionError] = (0, react.useState)(null);
|
|
4930
6728
|
const [isTranscribing, setIsTranscribing] = (0, react.useState)(false);
|
|
6729
|
+
const { attachments: selectedAttachments, enabled: attachmentsEnabled, dragOver, fileInputRef, containerRef: chatContainerRef, handleFileUpload, handleDragOver, handleDragLeave, handleDrop, removeAttachment, consumeAttachments } = useAttachments({ config: attachmentsConfig });
|
|
4931
6730
|
const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;
|
|
4932
6731
|
const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
|
|
4933
6732
|
const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
|
|
@@ -4943,7 +6742,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4943
6742
|
console.error("CopilotChat: connectAgent failed", error);
|
|
4944
6743
|
}
|
|
4945
6744
|
};
|
|
4946
|
-
agent.threadId = resolvedThreadId;
|
|
4947
6745
|
connect(agent);
|
|
4948
6746
|
return () => {
|
|
4949
6747
|
detached = true;
|
|
@@ -4956,7 +6754,31 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4956
6754
|
resolvedAgentId
|
|
4957
6755
|
]);
|
|
4958
6756
|
const onSubmitInput = (0, react.useCallback)(async (value) => {
|
|
4959
|
-
|
|
6757
|
+
if (selectedAttachments.some((a) => a.status === "uploading")) {
|
|
6758
|
+
console.error("[CopilotKit] Cannot send while attachments are uploading");
|
|
6759
|
+
return;
|
|
6760
|
+
}
|
|
6761
|
+
const readyAttachments = consumeAttachments();
|
|
6762
|
+
if (readyAttachments.length > 0) {
|
|
6763
|
+
const contentParts = [];
|
|
6764
|
+
if (value.trim()) contentParts.push({
|
|
6765
|
+
type: "text",
|
|
6766
|
+
text: value
|
|
6767
|
+
});
|
|
6768
|
+
for (const att of readyAttachments) contentParts.push({
|
|
6769
|
+
type: att.type,
|
|
6770
|
+
source: att.source,
|
|
6771
|
+
metadata: {
|
|
6772
|
+
...att.filename ? { filename: att.filename } : {},
|
|
6773
|
+
...att.metadata
|
|
6774
|
+
}
|
|
6775
|
+
});
|
|
6776
|
+
agent.addMessage({
|
|
6777
|
+
id: (0, _copilotkit_shared.randomUUID)(),
|
|
6778
|
+
role: "user",
|
|
6779
|
+
content: contentParts
|
|
6780
|
+
});
|
|
6781
|
+
} else agent.addMessage({
|
|
4960
6782
|
id: (0, _copilotkit_shared.randomUUID)(),
|
|
4961
6783
|
role: "user",
|
|
4962
6784
|
content: value
|
|
@@ -4967,7 +6789,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4967
6789
|
} catch (error) {
|
|
4968
6790
|
console.error("CopilotChat: runAgent failed", error);
|
|
4969
6791
|
}
|
|
4970
|
-
}, [
|
|
6792
|
+
}, [
|
|
6793
|
+
agent,
|
|
6794
|
+
selectedAttachments,
|
|
6795
|
+
consumeAttachments
|
|
6796
|
+
]);
|
|
4971
6797
|
const handleSelectSuggestion = (0, react.useCallback)(async (suggestion) => {
|
|
4972
6798
|
agent.addMessage({
|
|
4973
6799
|
id: (0, _copilotkit_shared.randomUUID)(),
|
|
@@ -5054,21 +6880,37 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5054
6880
|
return () => clearTimeout(timer);
|
|
5055
6881
|
}
|
|
5056
6882
|
}, [transcriptionError]);
|
|
5057
|
-
const
|
|
6883
|
+
const stableMessageView = useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
|
|
6884
|
+
const stableSuggestionView = useShallowStableRef(providedSuggestionView);
|
|
6885
|
+
const handleAddFile = (0, react.useCallback)(() => {
|
|
6886
|
+
setTimeout(() => {
|
|
6887
|
+
var _fileInputRef$current;
|
|
6888
|
+
(_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 || _fileInputRef$current.click();
|
|
6889
|
+
}, 100);
|
|
6890
|
+
}, []);
|
|
6891
|
+
const mergedProps = {
|
|
5058
6892
|
isRunning: agent.isRunning,
|
|
5059
6893
|
suggestions: autoSuggestions,
|
|
5060
6894
|
onSelectSuggestion: handleSelectSuggestion,
|
|
5061
|
-
suggestionView:
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
});
|
|
6895
|
+
suggestionView: stableSuggestionView,
|
|
6896
|
+
...restProps
|
|
6897
|
+
};
|
|
6898
|
+
if (stableMessageView !== void 0) mergedProps.messageView = stableMessageView;
|
|
5066
6899
|
const hasMessages = agent.messages.length > 0;
|
|
5067
6900
|
const effectiveStopHandler = agent.isRunning && hasMessages ? providedStopHandler !== null && providedStopHandler !== void 0 ? providedStopHandler : stopCurrentRun : providedStopHandler;
|
|
5068
6901
|
const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;
|
|
5069
6902
|
const effectiveMode = isTranscribing ? "processing" : transcribeMode;
|
|
5070
|
-
const
|
|
5071
|
-
|
|
6903
|
+
const messages = (0, react.useMemo)(() => [...agent.messages], [agent.messages.map((m) => {
|
|
6904
|
+
const contentKey = typeof m.content === "string" ? m.content.length : Array.isArray(m.content) ? m.content.length : 0;
|
|
6905
|
+
const toolCallsKey = "toolCalls" in m && Array.isArray(m.toolCalls) ? m.toolCalls.map((tc) => {
|
|
6906
|
+
var _tc$function$argument, _tc$function;
|
|
6907
|
+
return `${tc.id}:${(_tc$function$argument = (_tc$function = tc.function) === null || _tc$function === void 0 || (_tc$function = _tc$function.arguments) === null || _tc$function === void 0 ? void 0 : _tc$function.length) !== null && _tc$function$argument !== void 0 ? _tc$function$argument : 0}`;
|
|
6908
|
+
}).join(";") : "";
|
|
6909
|
+
return `${m.id}:${m.role}:${contentKey}:${toolCallsKey}`;
|
|
6910
|
+
}).join(",")]);
|
|
6911
|
+
const RenderedChatView = renderSlot(chatView, CopilotChatView, {
|
|
6912
|
+
...mergedProps,
|
|
6913
|
+
messages,
|
|
5072
6914
|
onSubmitMessage: onSubmitInput,
|
|
5073
6915
|
onStop: effectiveStopHandler,
|
|
5074
6916
|
inputMode: effectiveMode,
|
|
@@ -5077,32 +6919,51 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5077
6919
|
onStartTranscribe: showTranscription ? handleStartTranscribe : void 0,
|
|
5078
6920
|
onCancelTranscribe: showTranscription ? handleCancelTranscribe : void 0,
|
|
5079
6921
|
onFinishTranscribe: showTranscription ? handleFinishTranscribe : void 0,
|
|
5080
|
-
onFinishTranscribeWithAudio: showTranscription ? handleFinishTranscribeWithAudio : void 0
|
|
5081
|
-
|
|
5082
|
-
|
|
6922
|
+
onFinishTranscribeWithAudio: showTranscription ? handleFinishTranscribeWithAudio : void 0,
|
|
6923
|
+
attachments: selectedAttachments,
|
|
6924
|
+
onRemoveAttachment: removeAttachment,
|
|
6925
|
+
onAddFile: attachmentsEnabled ? handleAddFile : void 0,
|
|
6926
|
+
dragOver,
|
|
6927
|
+
onDragOver: handleDragOver,
|
|
6928
|
+
onDragLeave: handleDragLeave,
|
|
6929
|
+
onDrop: handleDrop
|
|
6930
|
+
});
|
|
6931
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
5083
6932
|
agentId: resolvedAgentId,
|
|
5084
6933
|
threadId: resolvedThreadId,
|
|
5085
6934
|
labels,
|
|
5086
6935
|
isModalDefaultOpen,
|
|
5087
|
-
children:
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
6936
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6937
|
+
ref: chatContainerRef,
|
|
6938
|
+
style: { display: "contents" },
|
|
6939
|
+
children: [
|
|
6940
|
+
attachmentsEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6941
|
+
type: "file",
|
|
6942
|
+
multiple: true,
|
|
6943
|
+
ref: fileInputRef,
|
|
6944
|
+
onChange: handleFileUpload,
|
|
6945
|
+
accept: (_attachmentsConfig$ac = attachmentsConfig === null || attachmentsConfig === void 0 ? void 0 : attachmentsConfig.accept) !== null && _attachmentsConfig$ac !== void 0 ? _attachmentsConfig$ac : "*/*",
|
|
6946
|
+
style: { display: "none" }
|
|
6947
|
+
}),
|
|
6948
|
+
!isChatLicensed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InlineFeatureWarning, { featureName: "Chat" }),
|
|
6949
|
+
transcriptionError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6950
|
+
style: {
|
|
6951
|
+
position: "absolute",
|
|
6952
|
+
bottom: "100px",
|
|
6953
|
+
left: "50%",
|
|
6954
|
+
transform: "translateX(-50%)",
|
|
6955
|
+
backgroundColor: "#ef4444",
|
|
6956
|
+
color: "white",
|
|
6957
|
+
padding: "8px 16px",
|
|
6958
|
+
borderRadius: "8px",
|
|
6959
|
+
fontSize: "14px",
|
|
6960
|
+
zIndex: 50
|
|
6961
|
+
},
|
|
6962
|
+
children: transcriptionError
|
|
6963
|
+
}),
|
|
6964
|
+
RenderedChatView
|
|
6965
|
+
]
|
|
6966
|
+
})
|
|
5106
6967
|
});
|
|
5107
6968
|
}
|
|
5108
6969
|
(function(_CopilotChat) {
|
|
@@ -5969,6 +7830,227 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5969
7830
|
if (!context) throw new Error("useToast must be used within a ToastProvider");
|
|
5970
7831
|
return context;
|
|
5971
7832
|
}
|
|
7833
|
+
function formatBannerMessage(message) {
|
|
7834
|
+
const jsonMatch = message.match(/'message':\s*'([^']+)'/);
|
|
7835
|
+
if (jsonMatch) return jsonMatch[1];
|
|
7836
|
+
let cleaned = message.split(" - ")[0];
|
|
7837
|
+
cleaned = cleaned.split(": Error code")[0];
|
|
7838
|
+
cleaned = cleaned.replace(/:\s*\d{3}$/, "");
|
|
7839
|
+
cleaned = cleaned.replace(/See more:.*$/g, "");
|
|
7840
|
+
cleaned = cleaned.trim();
|
|
7841
|
+
return cleaned || "An error occurred.";
|
|
7842
|
+
}
|
|
7843
|
+
function extractUrl(message) {
|
|
7844
|
+
const markdownMatch = /\[([^\]]+)\]\(([^)]+)\)/.exec(message);
|
|
7845
|
+
if (markdownMatch) return {
|
|
7846
|
+
url: markdownMatch[2],
|
|
7847
|
+
text: "See More"
|
|
7848
|
+
};
|
|
7849
|
+
const plainMatch = /(https?:\/\/[^\s)]+)/.exec(message);
|
|
7850
|
+
if (plainMatch) return {
|
|
7851
|
+
url: plainMatch[0].replace(/[.,;:'"]*$/, ""),
|
|
7852
|
+
text: "See More"
|
|
7853
|
+
};
|
|
7854
|
+
return null;
|
|
7855
|
+
}
|
|
7856
|
+
function BannerErrorDisplay({ bannerError, onDismiss }) {
|
|
7857
|
+
const [detailsExpanded, setDetailsExpanded] = (0, react.useState)(false);
|
|
7858
|
+
const colors = getErrorColors(getErrorSeverity(bannerError));
|
|
7859
|
+
const details = bannerError.details;
|
|
7860
|
+
const link = extractUrl(bannerError.message);
|
|
7861
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7862
|
+
style: {
|
|
7863
|
+
position: "fixed",
|
|
7864
|
+
bottom: "20px",
|
|
7865
|
+
left: "50%",
|
|
7866
|
+
transform: "translateX(-50%)",
|
|
7867
|
+
zIndex: 9999,
|
|
7868
|
+
backgroundColor: colors.background,
|
|
7869
|
+
border: `1px solid ${colors.border}`,
|
|
7870
|
+
borderLeft: `4px solid ${colors.border}`,
|
|
7871
|
+
borderRadius: "8px",
|
|
7872
|
+
padding: "12px 16px",
|
|
7873
|
+
fontSize: "13px",
|
|
7874
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
7875
|
+
backdropFilter: "blur(8px)",
|
|
7876
|
+
maxWidth: "min(90vw, 700px)",
|
|
7877
|
+
width: "100%",
|
|
7878
|
+
boxSizing: "border-box",
|
|
7879
|
+
overflow: "hidden"
|
|
7880
|
+
},
|
|
7881
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7882
|
+
style: {
|
|
7883
|
+
display: "flex",
|
|
7884
|
+
justifyContent: "space-between",
|
|
7885
|
+
alignItems: "center",
|
|
7886
|
+
gap: "10px"
|
|
7887
|
+
},
|
|
7888
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7889
|
+
style: {
|
|
7890
|
+
display: "flex",
|
|
7891
|
+
alignItems: "center",
|
|
7892
|
+
gap: "8px",
|
|
7893
|
+
flex: 1,
|
|
7894
|
+
minWidth: 0
|
|
7895
|
+
},
|
|
7896
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
7897
|
+
width: "12px",
|
|
7898
|
+
height: "12px",
|
|
7899
|
+
borderRadius: "50%",
|
|
7900
|
+
backgroundColor: colors.border,
|
|
7901
|
+
flexShrink: 0
|
|
7902
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7903
|
+
style: {
|
|
7904
|
+
display: "flex",
|
|
7905
|
+
alignItems: "center",
|
|
7906
|
+
gap: "10px",
|
|
7907
|
+
flex: 1,
|
|
7908
|
+
minWidth: 0
|
|
7909
|
+
},
|
|
7910
|
+
children: [
|
|
7911
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7912
|
+
style: {
|
|
7913
|
+
color: colors.text,
|
|
7914
|
+
lineHeight: "1.4",
|
|
7915
|
+
fontWeight: "400",
|
|
7916
|
+
fontSize: "13px",
|
|
7917
|
+
flex: 1,
|
|
7918
|
+
wordBreak: "break-all",
|
|
7919
|
+
overflowWrap: "break-word",
|
|
7920
|
+
maxWidth: "550px",
|
|
7921
|
+
overflow: "hidden",
|
|
7922
|
+
display: "-webkit-box",
|
|
7923
|
+
WebkitLineClamp: 10,
|
|
7924
|
+
WebkitBoxOrient: "vertical"
|
|
7925
|
+
},
|
|
7926
|
+
children: formatBannerMessage(bannerError.message)
|
|
7927
|
+
}),
|
|
7928
|
+
link && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7929
|
+
onClick: () => window.open(link.url, "_blank", "noopener,noreferrer"),
|
|
7930
|
+
style: {
|
|
7931
|
+
background: colors.border,
|
|
7932
|
+
color: "white",
|
|
7933
|
+
border: "none",
|
|
7934
|
+
borderRadius: "5px",
|
|
7935
|
+
padding: "4px 10px",
|
|
7936
|
+
fontSize: "11px",
|
|
7937
|
+
fontWeight: "500",
|
|
7938
|
+
cursor: "pointer",
|
|
7939
|
+
transition: "all 0.2s ease",
|
|
7940
|
+
flexShrink: 0
|
|
7941
|
+
},
|
|
7942
|
+
onMouseEnter: (e) => {
|
|
7943
|
+
e.currentTarget.style.opacity = "0.9";
|
|
7944
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
7945
|
+
},
|
|
7946
|
+
onMouseLeave: (e) => {
|
|
7947
|
+
e.currentTarget.style.opacity = "1";
|
|
7948
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
7949
|
+
},
|
|
7950
|
+
children: link.text
|
|
7951
|
+
}),
|
|
7952
|
+
details && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7953
|
+
onClick: () => setDetailsExpanded(!detailsExpanded),
|
|
7954
|
+
style: {
|
|
7955
|
+
background: "transparent",
|
|
7956
|
+
border: `1px solid ${colors.border}`,
|
|
7957
|
+
borderRadius: "5px",
|
|
7958
|
+
padding: "4px 10px",
|
|
7959
|
+
fontSize: "11px",
|
|
7960
|
+
fontWeight: "500",
|
|
7961
|
+
cursor: "pointer",
|
|
7962
|
+
color: colors.text,
|
|
7963
|
+
flexShrink: 0,
|
|
7964
|
+
transition: "all 0.2s ease"
|
|
7965
|
+
},
|
|
7966
|
+
onMouseEnter: (e) => {
|
|
7967
|
+
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
7968
|
+
},
|
|
7969
|
+
onMouseLeave: (e) => {
|
|
7970
|
+
e.currentTarget.style.background = "transparent";
|
|
7971
|
+
},
|
|
7972
|
+
children: detailsExpanded ? "Hide Details" : "Show Details"
|
|
7973
|
+
})
|
|
7974
|
+
]
|
|
7975
|
+
})]
|
|
7976
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7977
|
+
onClick: onDismiss,
|
|
7978
|
+
style: {
|
|
7979
|
+
background: "transparent",
|
|
7980
|
+
border: "none",
|
|
7981
|
+
color: colors.text,
|
|
7982
|
+
cursor: "pointer",
|
|
7983
|
+
padding: "2px",
|
|
7984
|
+
borderRadius: "3px",
|
|
7985
|
+
fontSize: "14px",
|
|
7986
|
+
lineHeight: "1",
|
|
7987
|
+
opacity: .6,
|
|
7988
|
+
transition: "all 0.2s ease",
|
|
7989
|
+
flexShrink: 0
|
|
7990
|
+
},
|
|
7991
|
+
title: "Dismiss",
|
|
7992
|
+
onMouseEnter: (e) => {
|
|
7993
|
+
e.currentTarget.style.opacity = "1";
|
|
7994
|
+
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
7995
|
+
},
|
|
7996
|
+
onMouseLeave: (e) => {
|
|
7997
|
+
e.currentTarget.style.opacity = "0.6";
|
|
7998
|
+
e.currentTarget.style.background = "transparent";
|
|
7999
|
+
},
|
|
8000
|
+
children: "x"
|
|
8001
|
+
})]
|
|
8002
|
+
}), detailsExpanded && details && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8003
|
+
style: {
|
|
8004
|
+
marginTop: "10px",
|
|
8005
|
+
padding: "10px",
|
|
8006
|
+
background: "rgba(0, 0, 0, 0.04)",
|
|
8007
|
+
borderRadius: "6px",
|
|
8008
|
+
fontSize: "11px",
|
|
8009
|
+
fontFamily: "monospace",
|
|
8010
|
+
color: colors.text,
|
|
8011
|
+
lineHeight: "1.5",
|
|
8012
|
+
maxHeight: "200px",
|
|
8013
|
+
overflowY: "auto",
|
|
8014
|
+
whiteSpace: "pre-wrap",
|
|
8015
|
+
wordBreak: "break-all"
|
|
8016
|
+
},
|
|
8017
|
+
children: [
|
|
8018
|
+
details.code && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
8019
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Code:" }),
|
|
8020
|
+
" ",
|
|
8021
|
+
details.code
|
|
8022
|
+
] }),
|
|
8023
|
+
details.originalMessage && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8024
|
+
style: { marginTop: "4px" },
|
|
8025
|
+
children: [
|
|
8026
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Message:" }),
|
|
8027
|
+
" ",
|
|
8028
|
+
details.originalMessage
|
|
8029
|
+
]
|
|
8030
|
+
}),
|
|
8031
|
+
details.context && Object.keys(details.context).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8032
|
+
style: { marginTop: "4px" },
|
|
8033
|
+
children: [
|
|
8034
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Context:" }),
|
|
8035
|
+
" ",
|
|
8036
|
+
JSON.stringify(details.context, null, 2)
|
|
8037
|
+
]
|
|
8038
|
+
}),
|
|
8039
|
+
details.stack && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8040
|
+
style: {
|
|
8041
|
+
marginTop: "4px",
|
|
8042
|
+
opacity: .7
|
|
8043
|
+
},
|
|
8044
|
+
children: [
|
|
8045
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Stack:" }),
|
|
8046
|
+
"\n",
|
|
8047
|
+
details.stack
|
|
8048
|
+
]
|
|
8049
|
+
})
|
|
8050
|
+
]
|
|
8051
|
+
})]
|
|
8052
|
+
});
|
|
8053
|
+
}
|
|
5972
8054
|
function ToastProvider({ enabled, children }) {
|
|
5973
8055
|
const [toasts, setToasts] = (0, react.useState)([]);
|
|
5974
8056
|
const [bannerError, setBannerErrorState] = (0, react.useState)(null);
|
|
@@ -6007,156 +8089,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6007
8089
|
};
|
|
6008
8090
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ToastContext.Provider, {
|
|
6009
8091
|
value,
|
|
6010
|
-
children: [bannerError && ((
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
position: "fixed",
|
|
6015
|
-
bottom: "20px",
|
|
6016
|
-
left: "50%",
|
|
6017
|
-
transform: "translateX(-50%)",
|
|
6018
|
-
zIndex: 9999,
|
|
6019
|
-
backgroundColor: colors.background,
|
|
6020
|
-
border: `1px solid ${colors.border}`,
|
|
6021
|
-
borderLeft: `4px solid ${colors.border}`,
|
|
6022
|
-
borderRadius: "8px",
|
|
6023
|
-
padding: "12px 16px",
|
|
6024
|
-
fontSize: "13px",
|
|
6025
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
6026
|
-
backdropFilter: "blur(8px)",
|
|
6027
|
-
maxWidth: "min(90vw, 700px)",
|
|
6028
|
-
width: "100%",
|
|
6029
|
-
boxSizing: "border-box",
|
|
6030
|
-
overflow: "hidden"
|
|
6031
|
-
},
|
|
6032
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6033
|
-
style: {
|
|
6034
|
-
display: "flex",
|
|
6035
|
-
justifyContent: "space-between",
|
|
6036
|
-
alignItems: "center",
|
|
6037
|
-
gap: "10px"
|
|
6038
|
-
},
|
|
6039
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6040
|
-
style: {
|
|
6041
|
-
display: "flex",
|
|
6042
|
-
alignItems: "center",
|
|
6043
|
-
gap: "8px",
|
|
6044
|
-
flex: 1,
|
|
6045
|
-
minWidth: 0
|
|
6046
|
-
},
|
|
6047
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
6048
|
-
width: "12px",
|
|
6049
|
-
height: "12px",
|
|
6050
|
-
borderRadius: "50%",
|
|
6051
|
-
backgroundColor: colors.border,
|
|
6052
|
-
flexShrink: 0
|
|
6053
|
-
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6054
|
-
style: {
|
|
6055
|
-
display: "flex",
|
|
6056
|
-
alignItems: "center",
|
|
6057
|
-
gap: "10px",
|
|
6058
|
-
flex: 1,
|
|
6059
|
-
minWidth: 0
|
|
6060
|
-
},
|
|
6061
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6062
|
-
style: {
|
|
6063
|
-
color: colors.text,
|
|
6064
|
-
lineHeight: "1.4",
|
|
6065
|
-
fontWeight: "400",
|
|
6066
|
-
fontSize: "13px",
|
|
6067
|
-
flex: 1,
|
|
6068
|
-
wordBreak: "break-all",
|
|
6069
|
-
overflowWrap: "break-word",
|
|
6070
|
-
maxWidth: "550px",
|
|
6071
|
-
overflow: "hidden",
|
|
6072
|
-
display: "-webkit-box",
|
|
6073
|
-
WebkitLineClamp: 10,
|
|
6074
|
-
WebkitBoxOrient: "vertical"
|
|
6075
|
-
},
|
|
6076
|
-
children: (() => {
|
|
6077
|
-
let message = bannerError.message;
|
|
6078
|
-
const jsonMatch = message.match(/'message':\s*'([^']+)'/);
|
|
6079
|
-
if (jsonMatch) return jsonMatch[1];
|
|
6080
|
-
message = message.split(" - ")[0];
|
|
6081
|
-
message = message.split(": Error code")[0];
|
|
6082
|
-
message = message.replace(/:\s*\d{3}$/, "");
|
|
6083
|
-
message = message.replace(/See more:.*$/g, "");
|
|
6084
|
-
message = message.trim();
|
|
6085
|
-
return message || "Configuration error occurred.";
|
|
6086
|
-
})()
|
|
6087
|
-
}), (() => {
|
|
6088
|
-
const message = bannerError.message;
|
|
6089
|
-
const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
6090
|
-
const plainUrlRegex = /(https?:\/\/[^\s)]+)/g;
|
|
6091
|
-
let url = null;
|
|
6092
|
-
let buttonText = "See More";
|
|
6093
|
-
const markdownMatch = markdownLinkRegex.exec(message);
|
|
6094
|
-
if (markdownMatch) {
|
|
6095
|
-
url = markdownMatch[2];
|
|
6096
|
-
buttonText = "See More";
|
|
6097
|
-
} else {
|
|
6098
|
-
const urlMatch = plainUrlRegex.exec(message);
|
|
6099
|
-
if (urlMatch) {
|
|
6100
|
-
url = urlMatch[0].replace(/[.,;:'"]*$/, "");
|
|
6101
|
-
buttonText = "See More";
|
|
6102
|
-
}
|
|
6103
|
-
}
|
|
6104
|
-
if (!url) return null;
|
|
6105
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6106
|
-
onClick: () => window.open(url, "_blank", "noopener,noreferrer"),
|
|
6107
|
-
style: {
|
|
6108
|
-
background: colors.border,
|
|
6109
|
-
color: "white",
|
|
6110
|
-
border: "none",
|
|
6111
|
-
borderRadius: "5px",
|
|
6112
|
-
padding: "4px 10px",
|
|
6113
|
-
fontSize: "11px",
|
|
6114
|
-
fontWeight: "500",
|
|
6115
|
-
cursor: "pointer",
|
|
6116
|
-
transition: "all 0.2s ease",
|
|
6117
|
-
flexShrink: 0
|
|
6118
|
-
},
|
|
6119
|
-
onMouseEnter: (e) => {
|
|
6120
|
-
e.currentTarget.style.opacity = "0.9";
|
|
6121
|
-
e.currentTarget.style.transform = "translateY(-1px)";
|
|
6122
|
-
},
|
|
6123
|
-
onMouseLeave: (e) => {
|
|
6124
|
-
e.currentTarget.style.opacity = "1";
|
|
6125
|
-
e.currentTarget.style.transform = "translateY(0)";
|
|
6126
|
-
},
|
|
6127
|
-
children: buttonText
|
|
6128
|
-
});
|
|
6129
|
-
})()]
|
|
6130
|
-
})]
|
|
6131
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6132
|
-
onClick: () => setBannerError(null),
|
|
6133
|
-
style: {
|
|
6134
|
-
background: "transparent",
|
|
6135
|
-
border: "none",
|
|
6136
|
-
color: colors.text,
|
|
6137
|
-
cursor: "pointer",
|
|
6138
|
-
padding: "2px",
|
|
6139
|
-
borderRadius: "3px",
|
|
6140
|
-
fontSize: "14px",
|
|
6141
|
-
lineHeight: "1",
|
|
6142
|
-
opacity: .6,
|
|
6143
|
-
transition: "all 0.2s ease",
|
|
6144
|
-
flexShrink: 0
|
|
6145
|
-
},
|
|
6146
|
-
title: "Dismiss",
|
|
6147
|
-
onMouseEnter: (e) => {
|
|
6148
|
-
e.currentTarget.style.opacity = "1";
|
|
6149
|
-
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
6150
|
-
},
|
|
6151
|
-
onMouseLeave: (e) => {
|
|
6152
|
-
e.currentTarget.style.opacity = "0.6";
|
|
6153
|
-
e.currentTarget.style.background = "transparent";
|
|
6154
|
-
},
|
|
6155
|
-
children: "×"
|
|
6156
|
-
})]
|
|
6157
|
-
})
|
|
6158
|
-
});
|
|
6159
|
-
})(), children]
|
|
8092
|
+
children: [bannerError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerErrorDisplay, {
|
|
8093
|
+
bannerError,
|
|
8094
|
+
onDismiss: () => setBannerError(null)
|
|
8095
|
+
}), children]
|
|
6160
8096
|
});
|
|
6161
8097
|
}
|
|
6162
8098
|
|
|
@@ -7075,12 +9011,21 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7075
9011
|
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
7076
9012
|
usePredictStateSubscription(agent);
|
|
7077
9013
|
(0, react.useEffect)(() => {
|
|
7078
|
-
const subscription = copilotkit.subscribe({ onError: ({ error }) => {
|
|
7079
|
-
|
|
9014
|
+
const subscription = copilotkit.subscribe({ onError: ({ error, code, context }) => {
|
|
9015
|
+
if (error.name === "AbortError" || error.message === "Fetch is aborted" || error.message === "signal is aborted without reason" || error.message === "component unmounted" || !error.message) return;
|
|
9016
|
+
if (process.env.NODE_ENV === "development") console.error("[CopilotKit] Agent error:", error.message, "\n Code:", code, "\n Context:", context, "\n Stack:", error.stack);
|
|
9017
|
+
const ckError = new _copilotkit_shared.CopilotKitLowLevelError({
|
|
7080
9018
|
error,
|
|
7081
9019
|
message: error.message,
|
|
7082
9020
|
url: typeof window !== "undefined" ? window.location.href : ""
|
|
7083
|
-
})
|
|
9021
|
+
});
|
|
9022
|
+
ckError.details = {
|
|
9023
|
+
code,
|
|
9024
|
+
context,
|
|
9025
|
+
stack: error.stack,
|
|
9026
|
+
originalMessage: error.message
|
|
9027
|
+
};
|
|
9028
|
+
setBannerError(ckError);
|
|
7084
9029
|
} });
|
|
7085
9030
|
return () => {
|
|
7086
9031
|
subscription.unsubscribe();
|
|
@@ -7566,7 +9511,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7566
9511
|
children: [
|
|
7567
9512
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotListeners, {}),
|
|
7568
9513
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitErrorBridge, {}),
|
|
7569
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CoAgentStateRendersProvider, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessagesTapProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotMessages, { children: [memoizedChildren, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RegisteredActionsRenderer, {})] }) }), bannerError && showDevConsole && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageBanner, {
|
|
9514
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CoAgentStateRendersProvider, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessagesTapProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotMessages, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: memoizedChildren }, "children"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RegisteredActionsRenderer, {}, "actions")] }) }), bannerError && showDevConsole && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageBanner, {
|
|
7570
9515
|
severity: bannerError.severity,
|
|
7571
9516
|
message: bannerError.message,
|
|
7572
9517
|
onClose: () => setBannerError(null),
|
|
@@ -7619,6 +9564,8 @@ Object.defineProperty(exports, 'CopilotChat', {
|
|
|
7619
9564
|
}
|
|
7620
9565
|
});
|
|
7621
9566
|
exports.CopilotChatAssistantMessage = CopilotChatAssistantMessage_default;
|
|
9567
|
+
exports.CopilotChatAttachmentQueue = CopilotChatAttachmentQueue;
|
|
9568
|
+
exports.CopilotChatAttachmentRenderer = CopilotChatAttachmentRenderer;
|
|
7622
9569
|
exports.CopilotChatAudioRecorder = CopilotChatAudioRecorder;
|
|
7623
9570
|
exports.CopilotChatConfigurationProvider = CopilotChatConfigurationProvider;
|
|
7624
9571
|
exports.CopilotChatInput = CopilotChatInput_default;
|
|
@@ -7659,12 +9606,20 @@ Object.defineProperty(exports, 'CopilotSidebarView', {
|
|
|
7659
9606
|
exports.MCPAppsActivityContentSchema = MCPAppsActivityContentSchema;
|
|
7660
9607
|
exports.MCPAppsActivityRenderer = MCPAppsActivityRenderer;
|
|
7661
9608
|
exports.MCPAppsActivityType = MCPAppsActivityType;
|
|
9609
|
+
exports.SandboxFunctionsContext = SandboxFunctionsContext;
|
|
7662
9610
|
exports.UseAgentUpdate = UseAgentUpdate;
|
|
7663
9611
|
exports.WildcardToolCallRender = WildcardToolCallRender;
|
|
9612
|
+
Object.defineProperty(exports, 'a2uiDefaultTheme', {
|
|
9613
|
+
enumerable: true,
|
|
9614
|
+
get: function () {
|
|
9615
|
+
return _copilotkit_a2ui_renderer.defaultTheme;
|
|
9616
|
+
}
|
|
9617
|
+
});
|
|
7664
9618
|
exports.createA2UIMessageRenderer = createA2UIMessageRenderer;
|
|
7665
9619
|
exports.defineToolCallRenderer = defineToolCallRenderer;
|
|
7666
9620
|
exports.useAgent = useAgent;
|
|
7667
9621
|
exports.useAgentContext = useAgentContext;
|
|
9622
|
+
exports.useAttachments = useAttachments;
|
|
7668
9623
|
exports.useComponent = useComponent;
|
|
7669
9624
|
exports.useConfigureSuggestions = useConfigureSuggestions;
|
|
7670
9625
|
exports.useCopilotChatConfiguration = useCopilotChatConfiguration;
|
|
@@ -7677,6 +9632,7 @@ exports.useRenderActivityMessage = useRenderActivityMessage;
|
|
|
7677
9632
|
exports.useRenderCustomMessages = useRenderCustomMessages;
|
|
7678
9633
|
exports.useRenderTool = useRenderTool;
|
|
7679
9634
|
exports.useRenderToolCall = useRenderToolCall;
|
|
9635
|
+
exports.useSandboxFunctions = useSandboxFunctions;
|
|
7680
9636
|
exports.useSuggestions = useSuggestions;
|
|
7681
9637
|
exports.useThreads = useThreads;
|
|
7682
9638
|
Object.keys(_copilotkit_core).forEach(function (k) {
|