@copilotkit/react-core 1.55.0-next.9 → 1.55.1-next.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 +46 -6
- package/dist/{copilotkit-DeOzjPsb.mjs → copilotkit-BY5S1-0P.mjs} +2402 -552
- package/dist/copilotkit-BY5S1-0P.mjs.map +1 -0
- package/dist/{copilotkit-BqcyhQjT.d.mts → copilotkit-BuhSUZHb.d.mts} +228 -17
- package/dist/copilotkit-BuhSUZHb.d.mts.map +1 -0
- package/dist/{copilotkit-BDNjFNmk.cjs → copilotkit-Bz5-ImDl.cjs} +2421 -541
- package/dist/copilotkit-Bz5-ImDl.cjs.map +1 -0
- package/dist/{copilotkit-l-IBF4Xp.d.cts → copilotkit-dwDWYpya.d.cts} +228 -17
- package/dist/copilotkit-dwDWYpya.d.cts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +1400 -238
- 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 +2442 -552
- 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/copilotkit-props.tsx +4 -2
- package/src/components/toast/toast-provider.tsx +269 -194
- package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +86 -22
- package/src/v2/__tests__/utils/test-helpers.tsx +67 -0
- 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 +193 -50
- 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 +253 -149
- 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__/MCPAppsActivityRenderer.e2e.test.tsx +43 -2
- 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-throttle.test.tsx +1003 -0
- package/src/v2/hooks/__tests__/use-attachments.test.tsx +169 -0
- 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 +95 -10
- 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-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-BDNjFNmk.cjs.map +0 -1
- package/dist/copilotkit-BqcyhQjT.d.mts.map +0 -1
- package/dist/copilotkit-DeOzjPsb.mjs.map +0 -1
- package/dist/copilotkit-l-IBF4Xp.d.cts.map +0 -1
- package/src/v2/components/__tests__/license-warning-banner.test.tsx +0 -46
package/dist/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('react'), require('@copilotkit/core'), require('@ag-ui/client'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('react-dom'), require('react-markdown'), require('@copilotkit/runtime-client-gql')) :
|
|
5
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@copilotkit/core', '@ag-ui/client', '@copilotkit/shared', 'react/jsx-runtime', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'react-dom', 'react-markdown', '@copilotkit/runtime-client-gql'], factory) :
|
|
6
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCore = {}), global.React,global.CopilotKitCore,global.AgUIClient,global.CopilotKitShared,global.ReactJsxRuntime,global.Zod,global._lit_labs_react,global.CopilotKitA2UIRenderer,global.ReactDOM,global.ReactMarkdown,global.CopilotKitRuntimeClientGQL));
|
|
7
|
-
})(this, function(exports, react, _copilotkit_core, _ag_ui_client, _copilotkit_shared, react_jsx_runtime, zod, _lit_labs_react, _copilotkit_a2ui_renderer, react_dom, react_markdown, _copilotkit_runtime_client_gql) {
|
|
4
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@copilotkit/core'), require('@ag-ui/client'), require('tailwind-merge'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('react-markdown'), require('@copilotkit/runtime-client-gql')) :
|
|
5
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', '@copilotkit/core', '@ag-ui/client', 'tailwind-merge', '@copilotkit/shared', 'react/jsx-runtime', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', 'react-markdown', '@copilotkit/runtime-client-gql'], factory) :
|
|
6
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCore = {}), global.React,global.CopilotKitCore,global.AgUIClient,global.tailwind_merge,global.CopilotKitShared,global.ReactJsxRuntime,global.Zod,global._lit_labs_react,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global.ReactMarkdown,global.CopilotKitRuntimeClientGQL));
|
|
7
|
+
})(this, function(exports, react, _copilotkit_core, _ag_ui_client, tailwind_merge, _copilotkit_shared, react_jsx_runtime, zod, _lit_labs_react, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, react_markdown, _copilotkit_runtime_client_gql) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -36,13 +36,98 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
36
36
|
react = __toESM(react);
|
|
37
37
|
react_markdown = __toESM(react_markdown);
|
|
38
38
|
|
|
39
|
+
//#region src/v2/lib/slots.tsx
|
|
40
|
+
/**
|
|
41
|
+
* Shallow equality comparison for objects.
|
|
42
|
+
*/
|
|
43
|
+
function shallowEqual(obj1, obj2) {
|
|
44
|
+
const keys1 = Object.keys(obj1);
|
|
45
|
+
const keys2 = Object.keys(obj2);
|
|
46
|
+
if (keys1.length !== keys2.length) return false;
|
|
47
|
+
for (const key of keys1) if (obj1[key] !== obj2[key]) return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
|
|
52
|
+
* class instances, and other exotic objects that happen to have typeof "object".
|
|
53
|
+
*/
|
|
54
|
+
function isPlainObject(obj) {
|
|
55
|
+
return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the same reference as long as the value is shallowly equal to the
|
|
59
|
+
* previous render's value.
|
|
60
|
+
*
|
|
61
|
+
* - Identical references bail out immediately (O(1)).
|
|
62
|
+
* - Plain objects ({}) are shallow-compared key-by-key.
|
|
63
|
+
* - Arrays, Dates, class instances, functions, and primitives are compared by
|
|
64
|
+
* reference only — shallowEqual is never called on non-plain objects, which
|
|
65
|
+
* avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
|
|
66
|
+
*
|
|
67
|
+
* Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
|
|
68
|
+
* equality check isn't defeated by a new object reference on every render.
|
|
69
|
+
*/
|
|
70
|
+
function useShallowStableRef(value) {
|
|
71
|
+
const ref = (0, react.useRef)(value);
|
|
72
|
+
if (ref.current === value) return ref.current;
|
|
73
|
+
if (isPlainObject(ref.current) && isPlainObject(value)) {
|
|
74
|
+
if (shallowEqual(ref.current, value)) return ref.current;
|
|
75
|
+
}
|
|
76
|
+
ref.current = value;
|
|
77
|
+
return ref.current;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a value is a React component type (function, class, forwardRef, memo, etc.)
|
|
81
|
+
*/
|
|
82
|
+
function isReactComponentType(value) {
|
|
83
|
+
if (typeof value === "function") return true;
|
|
84
|
+
if (value && typeof value === "object" && "$$typeof" in value && !react.default.isValidElement(value)) return true;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Internal function to render a slot value as a React element (non-memoized).
|
|
89
|
+
*/
|
|
90
|
+
function renderSlotElement(slot, DefaultComponent, props) {
|
|
91
|
+
if (typeof slot === "string") {
|
|
92
|
+
const existingClassName = props.className;
|
|
93
|
+
return react.default.createElement(DefaultComponent, {
|
|
94
|
+
...props,
|
|
95
|
+
className: (0, tailwind_merge.twMerge)(existingClassName, slot)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (isReactComponentType(slot)) return react.default.createElement(slot, props);
|
|
99
|
+
if (slot && typeof slot === "object" && !react.default.isValidElement(slot)) return react.default.createElement(DefaultComponent, {
|
|
100
|
+
...props,
|
|
101
|
+
...slot
|
|
102
|
+
});
|
|
103
|
+
return react.default.createElement(DefaultComponent, props);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Internal memoized wrapper component for renderSlot.
|
|
107
|
+
* Uses forwardRef to support ref forwarding.
|
|
108
|
+
*/
|
|
109
|
+
const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function MemoizedSlotWrapper(props, ref) {
|
|
110
|
+
const { $slot, $component, ...rest } = props;
|
|
111
|
+
return renderSlotElement($slot, $component, ref !== null ? {
|
|
112
|
+
...rest,
|
|
113
|
+
ref
|
|
114
|
+
} : rest);
|
|
115
|
+
}), (prev, next) => {
|
|
116
|
+
if (prev.$slot !== next.$slot) return false;
|
|
117
|
+
if (prev.$component !== next.$component) return false;
|
|
118
|
+
const { $slot: _ps, $component: _pc, ...prevRest } = prev;
|
|
119
|
+
const { $slot: _ns, $component: _nc, ...nextRest } = next;
|
|
120
|
+
return shallowEqual(prevRest, nextRest);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
//#endregion
|
|
39
124
|
//#region src/v2/providers/CopilotChatConfigurationProvider.tsx
|
|
40
125
|
const CopilotChatDefaultLabels = {
|
|
41
126
|
chatInputPlaceholder: "Type a message...",
|
|
42
127
|
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
|
43
128
|
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
|
44
129
|
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
45
|
-
chatInputToolbarAddButtonLabel: "Add
|
|
130
|
+
chatInputToolbarAddButtonLabel: "Add attachments",
|
|
46
131
|
chatInputToolbarToolsButtonLabel: "Tools",
|
|
47
132
|
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
48
133
|
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
@@ -63,14 +148,15 @@ react_markdown = __toESM(react_markdown);
|
|
|
63
148
|
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
|
|
64
149
|
var _ref, _parentConfig$isModal, _parentConfig$setModa;
|
|
65
150
|
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
151
|
+
const stableLabels = useShallowStableRef(labels);
|
|
66
152
|
const mergedLabels = (0, react.useMemo)(() => {
|
|
67
153
|
var _parentConfig$labels;
|
|
68
154
|
return {
|
|
69
155
|
...CopilotChatDefaultLabels,
|
|
70
156
|
...(_parentConfig$labels = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels) !== null && _parentConfig$labels !== void 0 ? _parentConfig$labels : {},
|
|
71
|
-
...
|
|
157
|
+
...stableLabels !== null && stableLabels !== void 0 ? stableLabels : {}
|
|
72
158
|
};
|
|
73
|
-
}, [
|
|
159
|
+
}, [stableLabels, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels]);
|
|
74
160
|
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;
|
|
75
161
|
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
76
162
|
if (threadId) return threadId;
|
|
@@ -749,8 +835,417 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
749
835
|
});
|
|
750
836
|
};
|
|
751
837
|
|
|
838
|
+
//#endregion
|
|
839
|
+
//#region src/v2/providers/SandboxFunctionsContext.ts
|
|
840
|
+
const SandboxFunctionsContext = (0, react.createContext)([]);
|
|
841
|
+
function useSandboxFunctions() {
|
|
842
|
+
return (0, react.useContext)(SandboxFunctionsContext);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
//#endregion
|
|
846
|
+
//#region src/v2/lib/processPartialHtml.ts
|
|
847
|
+
/**
|
|
848
|
+
* Extracts all complete `<style>` blocks from the raw HTML.
|
|
849
|
+
* Returns the concatenated style tags, suitable for injection into `<head>`.
|
|
850
|
+
*/
|
|
851
|
+
function extractCompleteStyles(html) {
|
|
852
|
+
const matches = html.match(/<style\b[^>]*>[\s\S]*?<\/style>/gi);
|
|
853
|
+
return matches ? matches.join("") : "";
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Processes raw accumulated HTML for safe preview via innerHTML injection.
|
|
857
|
+
* Pure function, no DOM dependencies.
|
|
858
|
+
*
|
|
859
|
+
* Pipeline (order matters):
|
|
860
|
+
* 1. Strip incomplete tag at end
|
|
861
|
+
* 2. Strip complete <style>, <script>, and <head> blocks
|
|
862
|
+
* 3. Strip incomplete <style>/<script>/<head> blocks
|
|
863
|
+
* 4. Strip incomplete HTML entities
|
|
864
|
+
* 5. Extract body content (or use full string if no <body>)
|
|
865
|
+
*/
|
|
866
|
+
function processPartialHtml(html) {
|
|
867
|
+
let result = html;
|
|
868
|
+
result = result.replace(/<[^>]*$/, "");
|
|
869
|
+
result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*?<\/\1>/gi, "");
|
|
870
|
+
result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*$/gi, "");
|
|
871
|
+
result = result.replace(/&[a-zA-Z0-9#]*$/, "");
|
|
872
|
+
const bodyMatch = result.match(/<body[^>]*>([\s\S]*)/i);
|
|
873
|
+
if (bodyMatch) {
|
|
874
|
+
result = bodyMatch[1];
|
|
875
|
+
result = result.replace(/<\/body>[\s\S]*/i, "");
|
|
876
|
+
}
|
|
877
|
+
return result;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/v2/components/OpenGenerativeUIRenderer.tsx
|
|
882
|
+
const OpenGenerativeUIActivityType = "open-generative-ui";
|
|
883
|
+
const OpenGenerativeUIContentSchema = zod.z.object({
|
|
884
|
+
initialHeight: zod.z.number().optional(),
|
|
885
|
+
generating: zod.z.boolean().optional(),
|
|
886
|
+
css: zod.z.string().optional(),
|
|
887
|
+
cssComplete: zod.z.boolean().optional(),
|
|
888
|
+
html: zod.z.array(zod.z.string()).optional(),
|
|
889
|
+
htmlComplete: zod.z.boolean().optional(),
|
|
890
|
+
jsFunctions: zod.z.string().optional(),
|
|
891
|
+
jsFunctionsComplete: zod.z.boolean().optional(),
|
|
892
|
+
jsExpressions: zod.z.array(zod.z.string()).optional(),
|
|
893
|
+
jsExpressionsComplete: zod.z.boolean().optional()
|
|
894
|
+
});
|
|
895
|
+
/**
|
|
896
|
+
* Schema for the generateSandboxedUi tool call arguments.
|
|
897
|
+
* Used by the frontend tool renderer to display placeholder messages.
|
|
898
|
+
*/
|
|
899
|
+
const GenerateSandboxedUiArgsSchema = zod.z.object({
|
|
900
|
+
initialHeight: zod.z.number().optional(),
|
|
901
|
+
placeholderMessages: zod.z.array(zod.z.string()).optional(),
|
|
902
|
+
css: zod.z.string().optional(),
|
|
903
|
+
html: zod.z.string().optional(),
|
|
904
|
+
jsFunctions: zod.z.string().optional(),
|
|
905
|
+
jsExpressions: zod.z.array(zod.z.string()).optional()
|
|
906
|
+
});
|
|
907
|
+
const THROTTLE_MS = 1e3;
|
|
908
|
+
/**
|
|
909
|
+
* Returns true when the inner component should re-render immediately
|
|
910
|
+
* (no throttle delay).
|
|
911
|
+
*/
|
|
912
|
+
function shouldFlushImmediately(prev, next) {
|
|
913
|
+
var _next$jsExpressions$l, _next$jsExpressions, _prev$jsExpressions$l, _prev$jsExpressions, _next$html, _prev$html;
|
|
914
|
+
if (next.cssComplete && (!prev || !prev.cssComplete)) return true;
|
|
915
|
+
if (next.htmlComplete) return true;
|
|
916
|
+
if (next.generating === false) return true;
|
|
917
|
+
if (next.jsFunctions && (!prev || !prev.jsFunctions)) return true;
|
|
918
|
+
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;
|
|
919
|
+
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;
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Outer wrapper — absorbs every parent re-render but only forwards
|
|
924
|
+
* throttled content snapshots to the memoized inner component.
|
|
925
|
+
*/
|
|
926
|
+
const OpenGenerativeUIActivityRenderer = function OpenGenerativeUIActivityRenderer({ content }) {
|
|
927
|
+
const latestContentRef = (0, react.useRef)(content);
|
|
928
|
+
latestContentRef.current = content;
|
|
929
|
+
const [throttledContent, setThrottledContent] = (0, react.useState)(content);
|
|
930
|
+
const throttledContentRef = (0, react.useRef)(throttledContent);
|
|
931
|
+
const timerRef = (0, react.useRef)(null);
|
|
932
|
+
if (throttledContentRef.current !== content) {
|
|
933
|
+
if (shouldFlushImmediately(throttledContentRef.current, content)) {
|
|
934
|
+
if (timerRef.current !== null) {
|
|
935
|
+
clearTimeout(timerRef.current);
|
|
936
|
+
timerRef.current = null;
|
|
937
|
+
}
|
|
938
|
+
throttledContentRef.current = content;
|
|
939
|
+
setThrottledContent(content);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
const flush = (0, react.useCallback)(() => {
|
|
943
|
+
timerRef.current = null;
|
|
944
|
+
const latest = latestContentRef.current;
|
|
945
|
+
throttledContentRef.current = latest;
|
|
946
|
+
setThrottledContent(latest);
|
|
947
|
+
}, []);
|
|
948
|
+
(0, react.useEffect)(() => {
|
|
949
|
+
if (throttledContentRef.current === content) return;
|
|
950
|
+
if (timerRef.current === null) timerRef.current = setTimeout(flush, THROTTLE_MS);
|
|
951
|
+
}, [content, flush]);
|
|
952
|
+
(0, react.useEffect)(() => {
|
|
953
|
+
return () => {
|
|
954
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
955
|
+
};
|
|
956
|
+
}, []);
|
|
957
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenGenerativeUIActivityRendererInner, { content: throttledContent });
|
|
958
|
+
};
|
|
959
|
+
function ensureHead(html) {
|
|
960
|
+
if (/<head[\s>]/i.test(html)) return html;
|
|
961
|
+
return `<head></head>${html}`;
|
|
962
|
+
}
|
|
963
|
+
function injectCssIntoHtml(html, css) {
|
|
964
|
+
const headCloseIdx = html.indexOf("</head>");
|
|
965
|
+
if (headCloseIdx !== -1) return html.slice(0, headCloseIdx) + `<style>${css}</style>` + html.slice(headCloseIdx);
|
|
966
|
+
return `<head><style>${css}</style></head>${html}`;
|
|
967
|
+
}
|
|
968
|
+
const OpenGenerativeUIActivityRendererInner = react.default.memo(function OpenGenerativeUIActivityRendererInner({ content }) {
|
|
969
|
+
var _content$initialHeigh, _content$html, _content$html2, _content$jsExpression;
|
|
970
|
+
const initialHeight = (_content$initialHeigh = content.initialHeight) !== null && _content$initialHeigh !== void 0 ? _content$initialHeigh : 200;
|
|
971
|
+
const [autoHeight, setAutoHeight] = (0, react.useState)(null);
|
|
972
|
+
const sandboxFunctions = useSandboxFunctions();
|
|
973
|
+
const localApi = (0, react.useMemo)(() => {
|
|
974
|
+
const api = {};
|
|
975
|
+
for (const fn of sandboxFunctions) api[fn.name] = fn.handler;
|
|
976
|
+
return api;
|
|
977
|
+
}, [sandboxFunctions]);
|
|
978
|
+
const fullHtml = content.htmlComplete && ((_content$html = content.html) === null || _content$html === void 0 ? void 0 : _content$html.length) ? content.html.join("") : void 0;
|
|
979
|
+
const css = content.cssComplete ? content.css : void 0;
|
|
980
|
+
const cssReady = !!content.cssComplete;
|
|
981
|
+
const partialHtml = !content.htmlComplete && ((_content$html2 = content.html) === null || _content$html2 === void 0 ? void 0 : _content$html2.length) ? content.html.join("") : void 0;
|
|
982
|
+
const previewBody = partialHtml ? processPartialHtml(partialHtml) : void 0;
|
|
983
|
+
const previewStyles = partialHtml ? extractCompleteStyles(partialHtml) : "";
|
|
984
|
+
const hasPreview = cssReady && !!(previewBody === null || previewBody === void 0 ? void 0 : previewBody.trim());
|
|
985
|
+
const hasVisibleSandbox = !!fullHtml || hasPreview;
|
|
986
|
+
const containerRef = (0, react.useRef)(null);
|
|
987
|
+
const sandboxRef = (0, react.useRef)(null);
|
|
988
|
+
const previewSandboxRef = (0, react.useRef)(null);
|
|
989
|
+
const previewReadyRef = (0, react.useRef)(false);
|
|
990
|
+
const sandboxReadyRef = (0, react.useRef)(false);
|
|
991
|
+
const executedIndexRef = (0, react.useRef)(0);
|
|
992
|
+
const pendingQueueRef = (0, react.useRef)([]);
|
|
993
|
+
const jsFunctionsInjectedRef = (0, react.useRef)(false);
|
|
994
|
+
(0, react.useEffect)(() => {
|
|
995
|
+
const container = containerRef.current;
|
|
996
|
+
if (!container || fullHtml || !hasPreview || previewSandboxRef.current) return;
|
|
997
|
+
let cancelled = false;
|
|
998
|
+
import("@jetbrains/websandbox").then((mod) => {
|
|
999
|
+
var _mod$default$default, _mod$default;
|
|
1000
|
+
if (cancelled) return;
|
|
1001
|
+
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({}, {
|
|
1002
|
+
frameContainer: container,
|
|
1003
|
+
frameContent: "<head></head><body></body>",
|
|
1004
|
+
allowAdditionalAttributes: ""
|
|
1005
|
+
});
|
|
1006
|
+
previewSandboxRef.current = sandbox;
|
|
1007
|
+
sandbox.iframe.style.width = "100%";
|
|
1008
|
+
sandbox.iframe.style.height = "100%";
|
|
1009
|
+
sandbox.iframe.style.border = "none";
|
|
1010
|
+
sandbox.iframe.style.backgroundColor = "transparent";
|
|
1011
|
+
sandbox.promise.then(() => {
|
|
1012
|
+
if (cancelled) return;
|
|
1013
|
+
previewReadyRef.current = true;
|
|
1014
|
+
sandbox.run(`
|
|
1015
|
+
var s = document.createElement('style');
|
|
1016
|
+
s.textContent = 'html, body { overflow: hidden !important; }';
|
|
1017
|
+
document.head.appendChild(s);
|
|
1018
|
+
`);
|
|
1019
|
+
const headParts = [];
|
|
1020
|
+
if (css) headParts.push(`<style>${css}</style>`);
|
|
1021
|
+
if (previewStyles) headParts.push(previewStyles);
|
|
1022
|
+
if (headParts.length) sandbox.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
|
|
1023
|
+
if (previewBody) sandbox.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
|
|
1024
|
+
});
|
|
1025
|
+
}).catch((err) => {
|
|
1026
|
+
console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
|
|
1027
|
+
});
|
|
1028
|
+
return () => {
|
|
1029
|
+
cancelled = true;
|
|
1030
|
+
};
|
|
1031
|
+
}, [hasPreview, fullHtml]);
|
|
1032
|
+
(0, react.useEffect)(() => {
|
|
1033
|
+
if (!previewSandboxRef.current || !previewReadyRef.current) return;
|
|
1034
|
+
const headParts = [];
|
|
1035
|
+
if (css) headParts.push(`<style>${css}</style>`);
|
|
1036
|
+
if (previewStyles) headParts.push(previewStyles);
|
|
1037
|
+
if (headParts.length) previewSandboxRef.current.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
|
|
1038
|
+
if (!previewBody) return;
|
|
1039
|
+
previewSandboxRef.current.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
|
|
1040
|
+
}, [
|
|
1041
|
+
previewBody,
|
|
1042
|
+
previewStyles,
|
|
1043
|
+
css
|
|
1044
|
+
]);
|
|
1045
|
+
(0, react.useEffect)(() => {
|
|
1046
|
+
const container = containerRef.current;
|
|
1047
|
+
if (!container || !fullHtml) return;
|
|
1048
|
+
if (previewSandboxRef.current) {
|
|
1049
|
+
previewSandboxRef.current.destroy();
|
|
1050
|
+
previewSandboxRef.current = null;
|
|
1051
|
+
previewReadyRef.current = false;
|
|
1052
|
+
}
|
|
1053
|
+
let cancelled = false;
|
|
1054
|
+
executedIndexRef.current = 0;
|
|
1055
|
+
jsFunctionsInjectedRef.current = false;
|
|
1056
|
+
sandboxReadyRef.current = false;
|
|
1057
|
+
pendingQueueRef.current = [];
|
|
1058
|
+
const htmlContent = css ? injectCssIntoHtml(fullHtml, css) : fullHtml;
|
|
1059
|
+
import("@jetbrains/websandbox").then((mod) => {
|
|
1060
|
+
var _mod$default$default2, _mod$default2;
|
|
1061
|
+
if (cancelled) return;
|
|
1062
|
+
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, {
|
|
1063
|
+
frameContainer: container,
|
|
1064
|
+
frameContent: ensureHead(htmlContent),
|
|
1065
|
+
allowAdditionalAttributes: ""
|
|
1066
|
+
});
|
|
1067
|
+
sandboxRef.current = sandbox;
|
|
1068
|
+
sandbox.iframe.style.width = "100%";
|
|
1069
|
+
sandbox.iframe.style.height = "100%";
|
|
1070
|
+
sandbox.iframe.style.border = "none";
|
|
1071
|
+
sandbox.iframe.style.backgroundColor = "transparent";
|
|
1072
|
+
sandbox.promise.then(() => {
|
|
1073
|
+
if (cancelled) return;
|
|
1074
|
+
sandboxReadyRef.current = true;
|
|
1075
|
+
sandbox.run(`
|
|
1076
|
+
var s = document.createElement('style');
|
|
1077
|
+
s.textContent = 'html, body { overflow: hidden !important; }';
|
|
1078
|
+
document.head.appendChild(s);
|
|
1079
|
+
`);
|
|
1080
|
+
const queue = pendingQueueRef.current;
|
|
1081
|
+
pendingQueueRef.current = [];
|
|
1082
|
+
for (const code of queue) sandbox.run(code);
|
|
1083
|
+
});
|
|
1084
|
+
}).catch((err) => {
|
|
1085
|
+
console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
|
|
1086
|
+
});
|
|
1087
|
+
return () => {
|
|
1088
|
+
cancelled = true;
|
|
1089
|
+
if (previewSandboxRef.current) {
|
|
1090
|
+
previewSandboxRef.current.destroy();
|
|
1091
|
+
previewSandboxRef.current = null;
|
|
1092
|
+
previewReadyRef.current = false;
|
|
1093
|
+
}
|
|
1094
|
+
if (sandboxRef.current) {
|
|
1095
|
+
sandboxRef.current.destroy();
|
|
1096
|
+
sandboxRef.current = null;
|
|
1097
|
+
}
|
|
1098
|
+
sandboxReadyRef.current = false;
|
|
1099
|
+
setAutoHeight(null);
|
|
1100
|
+
};
|
|
1101
|
+
}, [
|
|
1102
|
+
fullHtml,
|
|
1103
|
+
css,
|
|
1104
|
+
localApi
|
|
1105
|
+
]);
|
|
1106
|
+
(0, react.useEffect)(() => {
|
|
1107
|
+
if (!content.jsFunctions || jsFunctionsInjectedRef.current) return;
|
|
1108
|
+
jsFunctionsInjectedRef.current = true;
|
|
1109
|
+
const sandbox = sandboxRef.current;
|
|
1110
|
+
if (sandboxReadyRef.current && sandbox) sandbox.run(content.jsFunctions);
|
|
1111
|
+
else pendingQueueRef.current.push(content.jsFunctions);
|
|
1112
|
+
}, [content.jsFunctions]);
|
|
1113
|
+
(0, react.useEffect)(() => {
|
|
1114
|
+
const expressions = content.jsExpressions;
|
|
1115
|
+
if (!expressions || expressions.length === 0) return;
|
|
1116
|
+
const startIndex = executedIndexRef.current;
|
|
1117
|
+
if (startIndex >= expressions.length) return;
|
|
1118
|
+
const newExprs = expressions.slice(startIndex);
|
|
1119
|
+
executedIndexRef.current = expressions.length;
|
|
1120
|
+
const sandbox = sandboxRef.current;
|
|
1121
|
+
if (sandboxReadyRef.current && sandbox) (async () => {
|
|
1122
|
+
for (const expr of newExprs) await sandbox.run(expr);
|
|
1123
|
+
})();
|
|
1124
|
+
else pendingQueueRef.current.push(...newExprs);
|
|
1125
|
+
}, [(_content$jsExpression = content.jsExpressions) === null || _content$jsExpression === void 0 ? void 0 : _content$jsExpression.length]);
|
|
1126
|
+
const generationDone = content.generating === false;
|
|
1127
|
+
(0, react.useEffect)(() => {
|
|
1128
|
+
const sandbox = sandboxRef.current;
|
|
1129
|
+
if (!generationDone || !sandbox) return;
|
|
1130
|
+
let handled = false;
|
|
1131
|
+
const onMessage = (e) => {
|
|
1132
|
+
var _e$data;
|
|
1133
|
+
if (handled) return;
|
|
1134
|
+
if (e.source === sandbox.iframe.contentWindow && ((_e$data = e.data) === null || _e$data === void 0 ? void 0 : _e$data.type) === "__ck_resize") {
|
|
1135
|
+
handled = true;
|
|
1136
|
+
setAutoHeight(e.data.height);
|
|
1137
|
+
window.removeEventListener("message", onMessage);
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
window.addEventListener("message", onMessage);
|
|
1141
|
+
const measureOnce = `
|
|
1142
|
+
(function() {
|
|
1143
|
+
var s = document.createElement('style');
|
|
1144
|
+
s.textContent = 'body { height: auto !important; min-height: 0 !important; }';
|
|
1145
|
+
document.head.appendChild(s);
|
|
1146
|
+
var h = document.body.scrollHeight;
|
|
1147
|
+
var cs = getComputedStyle(document.body);
|
|
1148
|
+
h += parseFloat(cs.marginTop) || 0;
|
|
1149
|
+
h += parseFloat(cs.marginBottom) || 0;
|
|
1150
|
+
s.remove();
|
|
1151
|
+
parent.postMessage({ type: "__ck_resize", height: Math.ceil(h) }, "*");
|
|
1152
|
+
})();
|
|
1153
|
+
`;
|
|
1154
|
+
if (sandboxReadyRef.current) sandbox.run(measureOnce);
|
|
1155
|
+
else pendingQueueRef.current.push(measureOnce);
|
|
1156
|
+
return () => {
|
|
1157
|
+
window.removeEventListener("message", onMessage);
|
|
1158
|
+
};
|
|
1159
|
+
}, [generationDone]);
|
|
1160
|
+
const height = autoHeight !== null && autoHeight !== void 0 ? autoHeight : initialHeight;
|
|
1161
|
+
const isGenerating = content.generating !== false;
|
|
1162
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1163
|
+
ref: containerRef,
|
|
1164
|
+
style: {
|
|
1165
|
+
position: "relative",
|
|
1166
|
+
width: "100%",
|
|
1167
|
+
height: `${height}px`,
|
|
1168
|
+
borderRadius: "8px",
|
|
1169
|
+
backgroundColor: hasVisibleSandbox ? "transparent" : "#f5f5f5",
|
|
1170
|
+
border: hasVisibleSandbox ? "none" : "1px solid #e0e0e0",
|
|
1171
|
+
display: hasVisibleSandbox ? "block" : "flex",
|
|
1172
|
+
alignItems: hasVisibleSandbox ? void 0 : "center",
|
|
1173
|
+
justifyContent: hasVisibleSandbox ? void 0 : "center",
|
|
1174
|
+
overflow: "hidden"
|
|
1175
|
+
},
|
|
1176
|
+
children: isGenerating && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1177
|
+
style: {
|
|
1178
|
+
position: "absolute",
|
|
1179
|
+
inset: 0,
|
|
1180
|
+
zIndex: 10,
|
|
1181
|
+
pointerEvents: "all",
|
|
1182
|
+
backgroundColor: "rgba(255, 255, 255, 0.5)",
|
|
1183
|
+
display: "flex",
|
|
1184
|
+
alignItems: "center",
|
|
1185
|
+
justifyContent: "center"
|
|
1186
|
+
},
|
|
1187
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1188
|
+
width: "48",
|
|
1189
|
+
height: "48",
|
|
1190
|
+
viewBox: "0 0 24 24",
|
|
1191
|
+
fill: "none",
|
|
1192
|
+
style: { animation: "ck-spin 1s linear infinite" },
|
|
1193
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1194
|
+
cx: "12",
|
|
1195
|
+
cy: "12",
|
|
1196
|
+
r: "10",
|
|
1197
|
+
stroke: "#e0e0e0",
|
|
1198
|
+
strokeWidth: "3"
|
|
1199
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1200
|
+
d: "M12 2a10 10 0 0 1 10 10",
|
|
1201
|
+
stroke: "#999",
|
|
1202
|
+
strokeWidth: "3",
|
|
1203
|
+
strokeLinecap: "round"
|
|
1204
|
+
})]
|
|
1205
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `@keyframes ck-spin { to { transform: rotate(360deg) } }` })]
|
|
1206
|
+
})
|
|
1207
|
+
});
|
|
1208
|
+
}, (prev, next) => prev.content === next.content);
|
|
1209
|
+
/**
|
|
1210
|
+
* Frontend tool renderer for generateSandboxedUi.
|
|
1211
|
+
* Displays placeholder messages while the UI is being generated.
|
|
1212
|
+
*/
|
|
1213
|
+
const OpenGenerativeUIToolRenderer = function OpenGenerativeUIToolRenderer(props) {
|
|
1214
|
+
var _messages$visibleMess;
|
|
1215
|
+
const [visibleMessageIndex, setVisibleMessageIndex] = (0, react.useState)(0);
|
|
1216
|
+
const prevMessageCountRef = (0, react.useRef)(0);
|
|
1217
|
+
const messages = props.args.placeholderMessages;
|
|
1218
|
+
(0, react.useEffect)(() => {
|
|
1219
|
+
if (!messages || messages.length === 0) return;
|
|
1220
|
+
if (messages.length !== prevMessageCountRef.current) {
|
|
1221
|
+
prevMessageCountRef.current = messages.length;
|
|
1222
|
+
setVisibleMessageIndex(messages.length - 1);
|
|
1223
|
+
}
|
|
1224
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Complete) return;
|
|
1225
|
+
const timer = setInterval(() => {
|
|
1226
|
+
setVisibleMessageIndex((i) => (i + 1) % messages.length);
|
|
1227
|
+
}, 5e3);
|
|
1228
|
+
return () => clearInterval(timer);
|
|
1229
|
+
}, [messages === null || messages === void 0 ? void 0 : messages.length, props.status]);
|
|
1230
|
+
if (props.status === _copilotkit_core.ToolCallStatus.Complete) return null;
|
|
1231
|
+
if (!messages || messages.length === 0) return null;
|
|
1232
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1233
|
+
style: {
|
|
1234
|
+
padding: "8px 12px",
|
|
1235
|
+
color: "#999",
|
|
1236
|
+
fontSize: "14px"
|
|
1237
|
+
},
|
|
1238
|
+
children: (_messages$visibleMess = messages[visibleMessageIndex]) !== null && _messages$visibleMess !== void 0 ? _messages$visibleMess : messages[0]
|
|
1239
|
+
});
|
|
1240
|
+
};
|
|
1241
|
+
|
|
752
1242
|
//#endregion
|
|
753
1243
|
//#region src/v2/a2ui/A2UIMessageRenderer.tsx
|
|
1244
|
+
/**
|
|
1245
|
+
* The container key used to wrap A2UI operations for explicit detection.
|
|
1246
|
+
* Must match A2UI_OPERATIONS_KEY in @ag-ui/a2ui-middleware and copilotkit.a2ui (Python).
|
|
1247
|
+
*/
|
|
1248
|
+
const A2UI_OPERATIONS_KEY = "a2ui_operations";
|
|
754
1249
|
let initialized = false;
|
|
755
1250
|
function ensureInitialized() {
|
|
756
1251
|
if (!initialized) {
|
|
@@ -760,25 +1255,23 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
760
1255
|
}
|
|
761
1256
|
}
|
|
762
1257
|
function createA2UIMessageRenderer(options) {
|
|
763
|
-
const { theme } = options;
|
|
1258
|
+
const { theme, catalog, loadingComponent } = options;
|
|
764
1259
|
return {
|
|
765
1260
|
activityType: "a2ui-surface",
|
|
766
1261
|
content: zod.z.any(),
|
|
767
1262
|
render: ({ content, agent }) => {
|
|
768
1263
|
ensureInitialized();
|
|
769
1264
|
const [operations, setOperations] = (0, react.useState)([]);
|
|
770
|
-
const lastSignatureRef = (0, react.useRef)(null);
|
|
771
1265
|
const { copilotkit } = useCopilotKit();
|
|
1266
|
+
const lastContentRef = (0, react.useRef)(null);
|
|
772
1267
|
(0, react.useEffect)(() => {
|
|
773
|
-
if (
|
|
774
|
-
|
|
1268
|
+
if (content === lastContentRef.current) return;
|
|
1269
|
+
lastContentRef.current = content;
|
|
1270
|
+
const incoming = content === null || content === void 0 ? void 0 : content[A2UI_OPERATIONS_KEY];
|
|
1271
|
+
if (!content || !Array.isArray(incoming)) {
|
|
775
1272
|
setOperations([]);
|
|
776
1273
|
return;
|
|
777
1274
|
}
|
|
778
|
-
const incoming = content.operations;
|
|
779
|
-
const signature = stringifyOperations(incoming);
|
|
780
|
-
if (signature && signature === lastSignatureRef.current) return;
|
|
781
|
-
lastSignatureRef.current = signature;
|
|
782
1275
|
setOperations(incoming);
|
|
783
1276
|
}, [content]);
|
|
784
1277
|
const groupedOperations = (0, react.useMemo)(() => {
|
|
@@ -791,7 +1284,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
791
1284
|
}
|
|
792
1285
|
return groups;
|
|
793
1286
|
}, [operations]);
|
|
794
|
-
if (!groupedOperations.size) return null;
|
|
1287
|
+
if (!groupedOperations.size) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(loadingComponent !== null && loadingComponent !== void 0 ? loadingComponent : DefaultA2UILoading, {});
|
|
795
1288
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
796
1289
|
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
797
1290
|
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
@@ -799,7 +1292,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
799
1292
|
operations: ops,
|
|
800
1293
|
theme,
|
|
801
1294
|
agent,
|
|
802
|
-
copilotkit
|
|
1295
|
+
copilotkit,
|
|
1296
|
+
catalog
|
|
803
1297
|
}, surfaceId))
|
|
804
1298
|
});
|
|
805
1299
|
}
|
|
@@ -809,15 +1303,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
809
1303
|
* Renders a single A2UI surface using the React renderer.
|
|
810
1304
|
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
|
|
811
1305
|
*/
|
|
812
|
-
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit }) {
|
|
1306
|
+
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog }) {
|
|
813
1307
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
814
1308
|
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
815
1309
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
816
1310
|
onAction: (0, react.useCallback)(async (message) => {
|
|
817
1311
|
if (!agent) return;
|
|
1312
|
+
message.userAction;
|
|
818
1313
|
try {
|
|
819
1314
|
var _copilotkit$propertie;
|
|
820
|
-
console.info("[A2UI] Action dispatched", message.userAction);
|
|
821
1315
|
copilotkit.setProperties({
|
|
822
1316
|
...(_copilotkit$propertie = copilotkit.properties) !== null && _copilotkit$propertie !== void 0 ? _copilotkit$propertie : {},
|
|
823
1317
|
a2uiAction: message
|
|
@@ -831,47 +1325,502 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
831
1325
|
}
|
|
832
1326
|
}, [agent, copilotkit]),
|
|
833
1327
|
theme,
|
|
1328
|
+
catalog,
|
|
834
1329
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
835
1330
|
surfaceId,
|
|
836
1331
|
operations
|
|
837
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
838
|
-
surfaceId,
|
|
839
|
-
className: "cpk:flex cpk:flex-1"
|
|
840
|
-
})]
|
|
1332
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UISurfaceOrError, { surfaceId })]
|
|
841
1333
|
})
|
|
842
1334
|
});
|
|
843
1335
|
}
|
|
844
1336
|
/**
|
|
1337
|
+
* Renders the A2UI surface, or an error message if processing failed.
|
|
1338
|
+
* Must be a child of A2UIProvider to access the error state.
|
|
1339
|
+
*/
|
|
1340
|
+
function A2UISurfaceOrError({ surfaceId }) {
|
|
1341
|
+
const error = (0, _copilotkit_a2ui_renderer.useA2UIError)();
|
|
1342
|
+
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1343
|
+
className: "cpk:rounded-lg cpk:border cpk:border-red-200 cpk:bg-red-50 cpk:p-3 cpk:text-sm cpk:text-red-700",
|
|
1344
|
+
children: ["A2UI render error: ", error]
|
|
1345
|
+
});
|
|
1346
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_a2ui_renderer.A2UIRenderer, {
|
|
1347
|
+
surfaceId,
|
|
1348
|
+
className: "cpk:flex cpk:flex-1"
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
845
1352
|
* Processes A2UI operations into the provider's message processor.
|
|
846
1353
|
* Must be a child of A2UIProvider to access the actions context.
|
|
847
1354
|
*/
|
|
848
1355
|
function SurfaceMessageProcessor({ surfaceId, operations }) {
|
|
849
|
-
const { processMessages } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
850
|
-
const
|
|
1356
|
+
const { processMessages, getSurface } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
1357
|
+
const lastHashRef = (0, react.useRef)("");
|
|
851
1358
|
(0, react.useEffect)(() => {
|
|
852
|
-
const
|
|
853
|
-
if (
|
|
854
|
-
|
|
855
|
-
processMessages(operations);
|
|
1359
|
+
const hash = JSON.stringify(operations);
|
|
1360
|
+
if (hash === lastHashRef.current) return;
|
|
1361
|
+
lastHashRef.current = hash;
|
|
1362
|
+
processMessages(getSurface(surfaceId) ? operations.filter((op) => !(op === null || op === void 0 ? void 0 : op.createSurface)) : operations);
|
|
856
1363
|
}, [
|
|
857
1364
|
processMessages,
|
|
1365
|
+
getSurface,
|
|
858
1366
|
surfaceId,
|
|
859
1367
|
operations
|
|
860
1368
|
]);
|
|
861
1369
|
return null;
|
|
862
1370
|
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Default loading component shown while an A2UI surface is generating.
|
|
1373
|
+
* Displays an animated shimmer skeleton.
|
|
1374
|
+
*/
|
|
1375
|
+
function DefaultA2UILoading() {
|
|
1376
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1377
|
+
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",
|
|
1378
|
+
style: { minHeight: 120 },
|
|
1379
|
+
children: [
|
|
1380
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1381
|
+
className: "cpk:flex cpk:items-center cpk:gap-2",
|
|
1382
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1383
|
+
className: "cpk:h-3 cpk:w-3 cpk:rounded-full cpk:bg-gray-200",
|
|
1384
|
+
style: { animation: "cpk-a2ui-pulse 1.5s ease-in-out infinite" }
|
|
1385
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1386
|
+
className: "cpk:text-xs cpk:font-medium cpk:text-gray-400",
|
|
1387
|
+
children: "Generating UI..."
|
|
1388
|
+
})]
|
|
1389
|
+
}),
|
|
1390
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1391
|
+
className: "cpk:flex cpk:flex-col cpk:gap-2",
|
|
1392
|
+
children: [
|
|
1393
|
+
.8,
|
|
1394
|
+
.6,
|
|
1395
|
+
.4
|
|
1396
|
+
].map((width, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1397
|
+
className: "cpk:h-3 cpk:rounded cpk:bg-gray-200/70",
|
|
1398
|
+
style: {
|
|
1399
|
+
width: `${width * 100}%`,
|
|
1400
|
+
animation: `cpk-a2ui-pulse 1.5s ease-in-out ${i * .15}s infinite`
|
|
1401
|
+
}
|
|
1402
|
+
}, i))
|
|
1403
|
+
}),
|
|
1404
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
|
|
1405
|
+
@keyframes cpk-a2ui-pulse {
|
|
1406
|
+
0%, 100% { opacity: 0.4; }
|
|
1407
|
+
50% { opacity: 1; }
|
|
1408
|
+
}
|
|
1409
|
+
` })
|
|
1410
|
+
]
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
863
1413
|
function getOperationSurfaceId(operation) {
|
|
864
|
-
var _ref, _ref2, _ref3, _operation$
|
|
1414
|
+
var _ref, _ref2, _ref3, _operation$createSurf, _operation$createSurf2, _operation$updateComp, _operation$updateData, _operation$deleteSurf;
|
|
865
1415
|
if (!operation || typeof operation !== "object") return null;
|
|
866
1416
|
if (typeof operation.surfaceId === "string") return operation.surfaceId;
|
|
867
|
-
return (_ref = (_ref2 = (_ref3 = (_operation$
|
|
1417
|
+
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;
|
|
868
1418
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
1419
|
+
|
|
1420
|
+
//#endregion
|
|
1421
|
+
//#region src/v2/types/defineToolCallRenderer.ts
|
|
1422
|
+
function defineToolCallRenderer(def) {
|
|
1423
|
+
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
1424
|
+
return {
|
|
1425
|
+
name: def.name,
|
|
1426
|
+
args: argsSchema,
|
|
1427
|
+
render: def.render,
|
|
1428
|
+
...def.agentId ? { agentId: def.agentId } : {}
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
//#endregion
|
|
1433
|
+
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
1434
|
+
/**
|
|
1435
|
+
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
1436
|
+
* This renderer is auto-registered when A2UI is enabled.
|
|
1437
|
+
*/
|
|
1438
|
+
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
1439
|
+
/**
|
|
1440
|
+
* Built-in progress indicator for dynamic A2UI generation.
|
|
1441
|
+
* Shows a skeleton wireframe that progressively reveals as tokens stream in.
|
|
1442
|
+
*
|
|
1443
|
+
* Registered automatically when A2UI is enabled. Users can override by
|
|
1444
|
+
* providing their own `useRenderTool({ name: "render_a2ui", ... })`.
|
|
1445
|
+
*/
|
|
1446
|
+
function A2UIProgressIndicator({ parameters }) {
|
|
1447
|
+
const lastRef = (0, react.useRef)({
|
|
1448
|
+
time: 0,
|
|
1449
|
+
tokens: 0
|
|
1450
|
+
});
|
|
1451
|
+
const now = Date.now();
|
|
1452
|
+
let { tokens } = lastRef.current;
|
|
1453
|
+
if (now - lastRef.current.time > 200) {
|
|
1454
|
+
const chars = JSON.stringify(parameters !== null && parameters !== void 0 ? parameters : {}).length;
|
|
1455
|
+
tokens = Math.round(chars / 4);
|
|
1456
|
+
lastRef.current = {
|
|
1457
|
+
time: now,
|
|
1458
|
+
tokens
|
|
1459
|
+
};
|
|
874
1460
|
}
|
|
1461
|
+
const phase = tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;
|
|
1462
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1463
|
+
style: {
|
|
1464
|
+
margin: "12px 0",
|
|
1465
|
+
maxWidth: 320
|
|
1466
|
+
},
|
|
1467
|
+
children: [
|
|
1468
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1469
|
+
style: {
|
|
1470
|
+
position: "relative",
|
|
1471
|
+
overflow: "hidden",
|
|
1472
|
+
borderRadius: 12,
|
|
1473
|
+
border: "1px solid rgba(228,228,231,0.8)",
|
|
1474
|
+
backgroundColor: "#fff",
|
|
1475
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
|
|
1476
|
+
padding: "16px 18px 14px"
|
|
1477
|
+
},
|
|
1478
|
+
children: [
|
|
1479
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1480
|
+
style: {
|
|
1481
|
+
display: "flex",
|
|
1482
|
+
alignItems: "center",
|
|
1483
|
+
gap: 8,
|
|
1484
|
+
marginBottom: 12
|
|
1485
|
+
},
|
|
1486
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1487
|
+
style: {
|
|
1488
|
+
display: "flex",
|
|
1489
|
+
gap: 4
|
|
1490
|
+
},
|
|
1491
|
+
children: [
|
|
1492
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1493
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1494
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {})
|
|
1495
|
+
]
|
|
1496
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1497
|
+
w: 64,
|
|
1498
|
+
h: 6,
|
|
1499
|
+
bg: "#e4e4e7",
|
|
1500
|
+
opacity: phase >= 1 ? 1 : .4,
|
|
1501
|
+
transition: "opacity 0.5s"
|
|
1502
|
+
})]
|
|
1503
|
+
}),
|
|
1504
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1505
|
+
style: {
|
|
1506
|
+
display: "grid",
|
|
1507
|
+
gap: 7
|
|
1508
|
+
},
|
|
1509
|
+
children: [
|
|
1510
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1511
|
+
show: phase >= 0,
|
|
1512
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1513
|
+
w: 36,
|
|
1514
|
+
h: 7,
|
|
1515
|
+
bg: "rgba(147,197,253,0.7)",
|
|
1516
|
+
anim: 0
|
|
1517
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1518
|
+
w: 80,
|
|
1519
|
+
h: 7,
|
|
1520
|
+
bg: "rgba(219,234,254,0.8)",
|
|
1521
|
+
anim: .2
|
|
1522
|
+
})]
|
|
1523
|
+
}),
|
|
1524
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1525
|
+
show: phase >= 0,
|
|
1526
|
+
delay: .1,
|
|
1527
|
+
children: [
|
|
1528
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
1529
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1530
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1531
|
+
w: 100,
|
|
1532
|
+
h: 7,
|
|
1533
|
+
bg: "rgba(24,24,27,0.2)",
|
|
1534
|
+
anim: .3
|
|
1535
|
+
})
|
|
1536
|
+
]
|
|
1537
|
+
}),
|
|
1538
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1539
|
+
show: phase >= 1,
|
|
1540
|
+
delay: .15,
|
|
1541
|
+
children: [
|
|
1542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
1543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1544
|
+
w: 48,
|
|
1545
|
+
h: 7,
|
|
1546
|
+
bg: "rgba(24,24,27,0.15)",
|
|
1547
|
+
anim: .1
|
|
1548
|
+
}),
|
|
1549
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1550
|
+
w: 40,
|
|
1551
|
+
h: 7,
|
|
1552
|
+
bg: "rgba(153,246,228,0.6)",
|
|
1553
|
+
anim: .5
|
|
1554
|
+
}),
|
|
1555
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1556
|
+
w: 56,
|
|
1557
|
+
h: 7,
|
|
1558
|
+
bg: "rgba(147,197,253,0.6)",
|
|
1559
|
+
anim: .3
|
|
1560
|
+
})
|
|
1561
|
+
]
|
|
1562
|
+
}),
|
|
1563
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1564
|
+
show: phase >= 1,
|
|
1565
|
+
delay: .2,
|
|
1566
|
+
children: [
|
|
1567
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Spacer, {}),
|
|
1568
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1569
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1570
|
+
w: 60,
|
|
1571
|
+
h: 7,
|
|
1572
|
+
bg: "rgba(24,24,27,0.15)",
|
|
1573
|
+
anim: .4
|
|
1574
|
+
})
|
|
1575
|
+
]
|
|
1576
|
+
}),
|
|
1577
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1578
|
+
show: phase >= 2,
|
|
1579
|
+
delay: .25,
|
|
1580
|
+
children: [
|
|
1581
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1582
|
+
w: 40,
|
|
1583
|
+
h: 7,
|
|
1584
|
+
bg: "rgba(153,246,228,0.5)",
|
|
1585
|
+
anim: .2
|
|
1586
|
+
}),
|
|
1587
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1588
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1589
|
+
w: 48,
|
|
1590
|
+
h: 7,
|
|
1591
|
+
bg: "rgba(24,24,27,0.15)",
|
|
1592
|
+
anim: .6
|
|
1593
|
+
}),
|
|
1594
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1595
|
+
w: 64,
|
|
1596
|
+
h: 7,
|
|
1597
|
+
bg: "rgba(147,197,253,0.5)",
|
|
1598
|
+
anim: .1
|
|
1599
|
+
})
|
|
1600
|
+
]
|
|
1601
|
+
}),
|
|
1602
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1603
|
+
show: phase >= 2,
|
|
1604
|
+
delay: .3,
|
|
1605
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1606
|
+
w: 36,
|
|
1607
|
+
h: 7,
|
|
1608
|
+
bg: "rgba(147,197,253,0.6)",
|
|
1609
|
+
anim: .5
|
|
1610
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1611
|
+
w: 36,
|
|
1612
|
+
h: 7,
|
|
1613
|
+
bg: "rgba(24,24,27,0.12)",
|
|
1614
|
+
anim: .7
|
|
1615
|
+
})]
|
|
1616
|
+
}),
|
|
1617
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
|
|
1618
|
+
show: phase >= 3,
|
|
1619
|
+
delay: .35,
|
|
1620
|
+
children: [
|
|
1621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1622
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1623
|
+
w: 44,
|
|
1624
|
+
h: 7,
|
|
1625
|
+
bg: "rgba(24,24,27,0.18)",
|
|
1626
|
+
anim: .3
|
|
1627
|
+
}),
|
|
1628
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dot, {}),
|
|
1629
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1630
|
+
w: 56,
|
|
1631
|
+
h: 7,
|
|
1632
|
+
bg: "rgba(153,246,228,0.5)",
|
|
1633
|
+
anim: .8
|
|
1634
|
+
}),
|
|
1635
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
|
|
1636
|
+
w: 48,
|
|
1637
|
+
h: 7,
|
|
1638
|
+
bg: "rgba(147,197,253,0.5)",
|
|
1639
|
+
anim: .4
|
|
1640
|
+
})
|
|
1641
|
+
]
|
|
1642
|
+
})
|
|
1643
|
+
]
|
|
1644
|
+
}),
|
|
1645
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
1646
|
+
pointerEvents: "none",
|
|
1647
|
+
position: "absolute",
|
|
1648
|
+
inset: 0,
|
|
1649
|
+
background: "linear-gradient(105deg, transparent 0%, transparent 40%, rgba(255,255,255,0.6) 50%, transparent 60%, transparent 100%)",
|
|
1650
|
+
backgroundSize: "250% 100%",
|
|
1651
|
+
animation: "cpk-a2ui-sweep 3s ease-in-out infinite"
|
|
1652
|
+
} })
|
|
1653
|
+
]
|
|
1654
|
+
}),
|
|
1655
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1656
|
+
style: {
|
|
1657
|
+
display: "flex",
|
|
1658
|
+
alignItems: "center",
|
|
1659
|
+
justifyContent: "center",
|
|
1660
|
+
gap: 8,
|
|
1661
|
+
marginTop: 8
|
|
1662
|
+
},
|
|
1663
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1664
|
+
style: {
|
|
1665
|
+
fontSize: 12,
|
|
1666
|
+
color: "#a1a1aa",
|
|
1667
|
+
letterSpacing: "0.025em"
|
|
1668
|
+
},
|
|
1669
|
+
children: "Building interface"
|
|
1670
|
+
}), tokens > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1671
|
+
style: {
|
|
1672
|
+
fontSize: 11,
|
|
1673
|
+
color: "#d4d4d8",
|
|
1674
|
+
fontVariantNumeric: "tabular-nums"
|
|
1675
|
+
},
|
|
1676
|
+
children: [
|
|
1677
|
+
"~",
|
|
1678
|
+
tokens.toLocaleString(),
|
|
1679
|
+
" tokens"
|
|
1680
|
+
]
|
|
1681
|
+
})]
|
|
1682
|
+
}),
|
|
1683
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
|
|
1684
|
+
@keyframes cpk-a2ui-fade {
|
|
1685
|
+
0%, 100% { opacity: 1; }
|
|
1686
|
+
50% { opacity: 0.5; }
|
|
1687
|
+
}
|
|
1688
|
+
@keyframes cpk-a2ui-sweep {
|
|
1689
|
+
0% { background-position: 250% 0; }
|
|
1690
|
+
100% { background-position: -250% 0; }
|
|
1691
|
+
}
|
|
1692
|
+
` })
|
|
1693
|
+
]
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
function Dot() {
|
|
1697
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
1698
|
+
width: 7,
|
|
1699
|
+
height: 7,
|
|
1700
|
+
borderRadius: "50%",
|
|
1701
|
+
backgroundColor: "#d4d4d8",
|
|
1702
|
+
flexShrink: 0
|
|
1703
|
+
} });
|
|
1704
|
+
}
|
|
1705
|
+
function Spacer() {
|
|
1706
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: { width: 12 } });
|
|
1707
|
+
}
|
|
1708
|
+
function Bar({ w, h, bg, anim, opacity, transition }) {
|
|
1709
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
1710
|
+
width: w,
|
|
1711
|
+
height: h,
|
|
1712
|
+
borderRadius: 9999,
|
|
1713
|
+
backgroundColor: bg,
|
|
1714
|
+
...anim !== void 0 ? { animation: `cpk-a2ui-fade 2.4s ease-in-out ${anim}s infinite` } : {},
|
|
1715
|
+
...opacity !== void 0 ? { opacity } : {},
|
|
1716
|
+
...transition ? { transition } : {}
|
|
1717
|
+
} });
|
|
1718
|
+
}
|
|
1719
|
+
function Row({ children, show, delay = 0 }) {
|
|
1720
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1721
|
+
style: {
|
|
1722
|
+
display: "flex",
|
|
1723
|
+
alignItems: "center",
|
|
1724
|
+
gap: 6,
|
|
1725
|
+
opacity: show ? 1 : 0,
|
|
1726
|
+
transition: `opacity 0.4s ${delay}s`
|
|
1727
|
+
},
|
|
1728
|
+
children
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Registers the built-in `render_a2ui` tool call renderer via the props-based
|
|
1733
|
+
* `setRenderToolCalls` mechanism (not `useRenderTool`).
|
|
1734
|
+
*
|
|
1735
|
+
* This ensures user-registered `useRenderTool({ name: "render_a2ui", ... })`
|
|
1736
|
+
* hooks automatically override the built-in, since the merge logic in
|
|
1737
|
+
* react-core.ts gives hook-based entries priority over prop-based entries.
|
|
1738
|
+
*/
|
|
1739
|
+
function A2UIBuiltInToolCallRenderer() {
|
|
1740
|
+
const { copilotkit } = useCopilotKit();
|
|
1741
|
+
(0, react.useEffect)(() => {
|
|
1742
|
+
var _renderToolCalls;
|
|
1743
|
+
const renderer = defineToolCallRenderer({
|
|
1744
|
+
name: RENDER_A2UI_TOOL_NAME,
|
|
1745
|
+
args: zod.z.any(),
|
|
1746
|
+
render: ({ status, args: parameters }) => {
|
|
1747
|
+
if (status === "complete") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
1748
|
+
const params = parameters;
|
|
1749
|
+
const items = params === null || params === void 0 ? void 0 : params.items;
|
|
1750
|
+
if (Array.isArray(items) && items.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
1751
|
+
const components = params === null || params === void 0 ? void 0 : params.components;
|
|
1752
|
+
if (Array.isArray(components) && components.length > 2) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
1753
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIProgressIndicator, { parameters });
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
const existing = (_renderToolCalls = copilotkit._renderToolCalls) !== null && _renderToolCalls !== void 0 ? _renderToolCalls : [];
|
|
1757
|
+
copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
|
|
1758
|
+
}, [copilotkit]);
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
//#endregion
|
|
1763
|
+
//#region src/v2/hooks/use-agent-context.tsx
|
|
1764
|
+
function useAgentContext(context) {
|
|
1765
|
+
const { description, value } = context;
|
|
1766
|
+
const { copilotkit } = useCopilotKit();
|
|
1767
|
+
const stringValue = (0, react.useMemo)(() => {
|
|
1768
|
+
if (typeof value === "string") return value;
|
|
1769
|
+
return JSON.stringify(value);
|
|
1770
|
+
}, [value]);
|
|
1771
|
+
(0, react.useLayoutEffect)(() => {
|
|
1772
|
+
if (!copilotkit) return;
|
|
1773
|
+
const id = copilotkit.addContext({
|
|
1774
|
+
description,
|
|
1775
|
+
value: stringValue
|
|
1776
|
+
});
|
|
1777
|
+
return () => {
|
|
1778
|
+
copilotkit.removeContext(id);
|
|
1779
|
+
};
|
|
1780
|
+
}, [
|
|
1781
|
+
description,
|
|
1782
|
+
stringValue,
|
|
1783
|
+
copilotkit
|
|
1784
|
+
]);
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
//#endregion
|
|
1788
|
+
//#region src/v2/a2ui/A2UICatalogContext.tsx
|
|
1789
|
+
/**
|
|
1790
|
+
* Renders agent context describing the available A2UI catalog and custom components.
|
|
1791
|
+
* Only mount this component when A2UI is enabled.
|
|
1792
|
+
*
|
|
1793
|
+
* When `includeSchema` is true, the full component schemas (JSON Schema) are also
|
|
1794
|
+
* sent as context using the same description key as the A2UI middleware, so the
|
|
1795
|
+
* middleware can optionally overwrite it with a server-side schema.
|
|
1796
|
+
*/
|
|
1797
|
+
function A2UICatalogContext({ catalog, includeSchema }) {
|
|
1798
|
+
useAgentContext({
|
|
1799
|
+
description: "A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.",
|
|
1800
|
+
value: (0, _copilotkit_a2ui_renderer.buildCatalogContextValue)(catalog)
|
|
1801
|
+
});
|
|
1802
|
+
const { copilotkit } = useCopilotKit();
|
|
1803
|
+
const schemaValue = (0, react.useMemo)(() => includeSchema !== false ? JSON.stringify((0, _copilotkit_a2ui_renderer.extractCatalogComponentSchemas)(catalog)) : null, [catalog, includeSchema]);
|
|
1804
|
+
(0, react.useLayoutEffect)(() => {
|
|
1805
|
+
if (!copilotkit || !schemaValue) return;
|
|
1806
|
+
const ids = [];
|
|
1807
|
+
ids.push(copilotkit.addContext({
|
|
1808
|
+
description: _copilotkit_a2ui_renderer.A2UI_SCHEMA_CONTEXT_DESCRIPTION,
|
|
1809
|
+
value: schemaValue
|
|
1810
|
+
}));
|
|
1811
|
+
ids.push(copilotkit.addContext({
|
|
1812
|
+
description: "A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.",
|
|
1813
|
+
value: _copilotkit_shared.A2UI_DEFAULT_GENERATION_GUIDELINES
|
|
1814
|
+
}));
|
|
1815
|
+
ids.push(copilotkit.addContext({
|
|
1816
|
+
description: "A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.",
|
|
1817
|
+
value: _copilotkit_shared.A2UI_DEFAULT_DESIGN_GUIDELINES
|
|
1818
|
+
}));
|
|
1819
|
+
return () => {
|
|
1820
|
+
for (const id of ids) copilotkit.removeContext(id);
|
|
1821
|
+
};
|
|
1822
|
+
}, [copilotkit, schemaValue]);
|
|
1823
|
+
return null;
|
|
875
1824
|
}
|
|
876
1825
|
|
|
877
1826
|
//#endregion
|
|
@@ -981,6 +1930,17 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
981
1930
|
//#region src/v2/providers/CopilotKitProvider.tsx
|
|
982
1931
|
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
983
1932
|
const COPILOT_CLOUD_CHAT_URL$1 = "https://api.cloud.copilotkit.ai/copilotkit/v1";
|
|
1933
|
+
const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follow these design principles inspired by shadcn/ui:
|
|
1934
|
+
|
|
1935
|
+
- Use a minimal, flat aesthetic. Avoid drop shadows and gradients — rely on subtle borders (1px solid, light gray like #e5e7eb) to define surfaces.
|
|
1936
|
+
- Neutral base palette: white backgrounds, zinc/slate gray text (#09090b for headings, #71717a for secondary text). One accent color for interactive elements.
|
|
1937
|
+
- Use system font stacks (system-ui, -apple-system, sans-serif) at readable sizes (14px body, 600 weight for headings). Tight line-heights.
|
|
1938
|
+
- Small, consistent border-radius (6–8px). Cards and containers use border, not shadow, for separation.
|
|
1939
|
+
- Buttons: solid fill for primary (dark bg, white text), outline for secondary (border + transparent bg). Subtle hover state (slight opacity or background shift).
|
|
1940
|
+
- Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
|
|
1941
|
+
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
|
|
1942
|
+
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
|
|
1943
|
+
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)";
|
|
984
1944
|
const CopilotKitContext = (0, react.createContext)({
|
|
985
1945
|
copilotkit: null,
|
|
986
1946
|
executingToolCallIds: /* @__PURE__ */ new Set()
|
|
@@ -995,9 +1955,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
995
1955
|
}, [value, warningMessage]);
|
|
996
1956
|
return value;
|
|
997
1957
|
}
|
|
998
|
-
const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, showDevConsole = false, useSingleEndpoint
|
|
1958
|
+
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 }) => {
|
|
1959
|
+
var _openGenerativeUI$des;
|
|
999
1960
|
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
|
|
1000
1961
|
const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
|
|
1962
|
+
const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = (0, react.useState)(false);
|
|
1963
|
+
const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;
|
|
1001
1964
|
const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
|
|
1002
1965
|
(0, react.useEffect)(() => {
|
|
1003
1966
|
if (typeof window === "undefined") return;
|
|
@@ -1026,12 +1989,25 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1026
1989
|
content: MCPAppsActivityContentSchema,
|
|
1027
1990
|
render: MCPAppsActivityRenderer
|
|
1028
1991
|
}];
|
|
1992
|
+
if (openGenUIActive) renderers.push({
|
|
1993
|
+
activityType: OpenGenerativeUIActivityType,
|
|
1994
|
+
content: OpenGenerativeUIContentSchema,
|
|
1995
|
+
render: OpenGenerativeUIActivityRenderer
|
|
1996
|
+
});
|
|
1029
1997
|
if (runtimeA2UIEnabled) {
|
|
1030
1998
|
var _a2ui$theme;
|
|
1031
|
-
renderers.unshift(createA2UIMessageRenderer({
|
|
1999
|
+
renderers.unshift(createA2UIMessageRenderer({
|
|
2000
|
+
theme: (_a2ui$theme = a2ui === null || a2ui === void 0 ? void 0 : a2ui.theme) !== null && _a2ui$theme !== void 0 ? _a2ui$theme : _copilotkit_a2ui_renderer.viewerTheme,
|
|
2001
|
+
catalog: a2ui === null || a2ui === void 0 ? void 0 : a2ui.catalog,
|
|
2002
|
+
loadingComponent: a2ui === null || a2ui === void 0 ? void 0 : a2ui.loadingComponent
|
|
2003
|
+
}));
|
|
1032
2004
|
}
|
|
1033
2005
|
return renderers;
|
|
1034
|
-
}, [
|
|
2006
|
+
}, [
|
|
2007
|
+
runtimeA2UIEnabled,
|
|
2008
|
+
openGenUIActive,
|
|
2009
|
+
a2ui
|
|
2010
|
+
]);
|
|
1035
2011
|
const allActivityRenderers = (0, react.useMemo)(() => {
|
|
1036
2012
|
return [...renderActivityMessagesList, ...builtInActivityRenderers];
|
|
1037
2013
|
}, [renderActivityMessagesList, builtInActivityRenderers]);
|
|
@@ -1057,6 +2033,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1057
2033
|
const chatApiEndpoint = runtimeUrl !== null && runtimeUrl !== void 0 ? runtimeUrl : resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL$1 : void 0;
|
|
1058
2034
|
const frontendToolsList = useStableArrayProp(frontendTools, "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.");
|
|
1059
2035
|
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.");
|
|
2036
|
+
const sandboxFunctionsList = useStableArrayProp(openGenerativeUI === null || openGenerativeUI === void 0 ? void 0 : openGenerativeUI.sandboxFunctions, "openGenerativeUI.sandboxFunctions must be a stable array.");
|
|
1060
2037
|
const processedHumanInTheLoopTools = (0, react.useMemo)(() => {
|
|
1061
2038
|
const processedTools = [];
|
|
1062
2039
|
const processedRenderToolCalls = [];
|
|
@@ -1087,15 +2064,31 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1087
2064
|
renderToolCalls: processedRenderToolCalls
|
|
1088
2065
|
};
|
|
1089
2066
|
}, [humanInTheLoopList]);
|
|
2067
|
+
const builtInFrontendTools = (0, react.useMemo)(() => {
|
|
2068
|
+
if (!openGenUIActive) return [];
|
|
2069
|
+
return [{
|
|
2070
|
+
name: "generateSandboxedUi",
|
|
2071
|
+
description: GENERATE_SANDBOXED_UI_DESCRIPTION,
|
|
2072
|
+
parameters: GenerateSandboxedUiArgsSchema,
|
|
2073
|
+
handler: async () => "UI generated",
|
|
2074
|
+
followUp: true,
|
|
2075
|
+
render: OpenGenerativeUIToolRenderer
|
|
2076
|
+
}];
|
|
2077
|
+
}, [openGenUIActive]);
|
|
1090
2078
|
const allTools = (0, react.useMemo)(() => {
|
|
1091
2079
|
const tools = [];
|
|
1092
2080
|
tools.push(...frontendToolsList);
|
|
2081
|
+
tools.push(...builtInFrontendTools);
|
|
1093
2082
|
tools.push(...processedHumanInTheLoopTools.tools);
|
|
1094
2083
|
return tools;
|
|
1095
|
-
}, [
|
|
2084
|
+
}, [
|
|
2085
|
+
frontendToolsList,
|
|
2086
|
+
builtInFrontendTools,
|
|
2087
|
+
processedHumanInTheLoopTools
|
|
2088
|
+
]);
|
|
1096
2089
|
const allRenderToolCalls = (0, react.useMemo)(() => {
|
|
1097
2090
|
const combined = [...renderToolCallsList];
|
|
1098
|
-
frontendToolsList.forEach((tool) => {
|
|
2091
|
+
[...frontendToolsList, ...builtInFrontendTools].forEach((tool) => {
|
|
1099
2092
|
if (tool.render) {
|
|
1100
2093
|
const args = tool.parameters || (tool.name === "*" ? zod.z.any() : void 0);
|
|
1101
2094
|
if (args) combined.push({
|
|
@@ -1110,25 +2103,31 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1110
2103
|
}, [
|
|
1111
2104
|
renderToolCallsList,
|
|
1112
2105
|
frontendToolsList,
|
|
2106
|
+
builtInFrontendTools,
|
|
1113
2107
|
processedHumanInTheLoopTools
|
|
1114
2108
|
]);
|
|
1115
2109
|
const copilotkitRef = (0, react.useRef)(null);
|
|
1116
|
-
if (copilotkitRef.current === null)
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
2110
|
+
if (copilotkitRef.current === null) {
|
|
2111
|
+
copilotkitRef.current = new CopilotKitCoreReact({
|
|
2112
|
+
runtimeUrl: chatApiEndpoint,
|
|
2113
|
+
runtimeTransport: useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto",
|
|
2114
|
+
headers: mergedHeaders,
|
|
2115
|
+
credentials,
|
|
2116
|
+
properties,
|
|
2117
|
+
agents__unsafe_dev_only: mergedAgents,
|
|
2118
|
+
tools: allTools,
|
|
2119
|
+
renderToolCalls: allRenderToolCalls,
|
|
2120
|
+
renderActivityMessages: allActivityRenderers,
|
|
2121
|
+
renderCustomMessages: renderCustomMessagesList
|
|
2122
|
+
});
|
|
2123
|
+
if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
|
|
2124
|
+
}
|
|
1128
2125
|
const copilotkit = copilotkitRef.current;
|
|
1129
2126
|
(0, react.useEffect)(() => {
|
|
2127
|
+
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
1130
2128
|
const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
1131
2129
|
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
2130
|
+
setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
|
|
1132
2131
|
setRuntimeLicenseStatus(copilotkit.licenseStatus);
|
|
1133
2132
|
} });
|
|
1134
2133
|
return () => {
|
|
@@ -1188,7 +2187,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1188
2187
|
}, [copilotkit]);
|
|
1189
2188
|
(0, react.useEffect)(() => {
|
|
1190
2189
|
copilotkit.setRuntimeUrl(chatApiEndpoint);
|
|
1191
|
-
copilotkit.setRuntimeTransport(useSingleEndpoint ? "single" : "rest");
|
|
2190
|
+
copilotkit.setRuntimeTransport(useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto");
|
|
1192
2191
|
copilotkit.setHeaders(mergedHeaders);
|
|
1193
2192
|
copilotkit.setCredentials(credentials);
|
|
1194
2193
|
copilotkit.setProperties(properties);
|
|
@@ -1222,23 +2221,75 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1222
2221
|
(0, react.useEffect)(() => {
|
|
1223
2222
|
didMountRef.current = true;
|
|
1224
2223
|
}, []);
|
|
2224
|
+
(0, react.useEffect)(() => {
|
|
2225
|
+
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.`);
|
|
2226
|
+
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
2227
|
+
}, [copilotkit, defaultThrottleMs]);
|
|
2228
|
+
const designSkill = (_openGenerativeUI$des = openGenerativeUI === null || openGenerativeUI === void 0 ? void 0 : openGenerativeUI.designSkill) !== null && _openGenerativeUI$des !== void 0 ? _openGenerativeUI$des : DEFAULT_DESIGN_SKILL;
|
|
2229
|
+
(0, react.useLayoutEffect)(() => {
|
|
2230
|
+
if (!copilotkit || !openGenUIActive) return;
|
|
2231
|
+
const id = copilotkit.addContext({
|
|
2232
|
+
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
2233
|
+
value: designSkill
|
|
2234
|
+
});
|
|
2235
|
+
return () => {
|
|
2236
|
+
copilotkit.removeContext(id);
|
|
2237
|
+
};
|
|
2238
|
+
}, [
|
|
2239
|
+
copilotkit,
|
|
2240
|
+
designSkill,
|
|
2241
|
+
openGenUIActive
|
|
2242
|
+
]);
|
|
2243
|
+
const sandboxFunctionsDescriptors = (0, react.useMemo)(() => {
|
|
2244
|
+
if (sandboxFunctionsList.length === 0) return null;
|
|
2245
|
+
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
2246
|
+
name: fn.name,
|
|
2247
|
+
description: fn.description,
|
|
2248
|
+
parameters: (0, _copilotkit_shared.schemaToJsonSchema)(fn.parameters, { zodToJsonSchema: zod_to_json_schema.zodToJsonSchema })
|
|
2249
|
+
})));
|
|
2250
|
+
}, [sandboxFunctionsList]);
|
|
2251
|
+
(0, react.useLayoutEffect)(() => {
|
|
2252
|
+
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
2253
|
+
const id = copilotkit.addContext({
|
|
2254
|
+
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
2255
|
+
value: sandboxFunctionsDescriptors
|
|
2256
|
+
});
|
|
2257
|
+
return () => {
|
|
2258
|
+
copilotkit.removeContext(id);
|
|
2259
|
+
};
|
|
2260
|
+
}, [
|
|
2261
|
+
copilotkit,
|
|
2262
|
+
sandboxFunctionsDescriptors,
|
|
2263
|
+
openGenUIActive
|
|
2264
|
+
]);
|
|
1225
2265
|
const contextValue = (0, react.useMemo)(() => ({
|
|
1226
2266
|
copilotkit,
|
|
1227
2267
|
executingToolCallIds
|
|
1228
2268
|
}), [copilotkit, executingToolCallIds]);
|
|
1229
2269
|
const licenseContextValue = (0, react.useMemo)(() => (0, _copilotkit_shared.createLicenseContextValue)(null), []);
|
|
1230
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1231
|
-
value:
|
|
1232
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1233
|
-
value:
|
|
1234
|
-
children:
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
2270
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
|
|
2271
|
+
value: sandboxFunctionsList,
|
|
2272
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
|
|
2273
|
+
value: contextValue,
|
|
2274
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LicenseContext.Provider, {
|
|
2275
|
+
value: licenseContextValue,
|
|
2276
|
+
children: [
|
|
2277
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuiltInToolCallRenderer, {}),
|
|
2278
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UICatalogContext, {
|
|
2279
|
+
catalog: a2ui === null || a2ui === void 0 ? void 0 : a2ui.catalog,
|
|
2280
|
+
includeSchema: a2ui === null || a2ui === void 0 ? void 0 : a2ui.includeSchema
|
|
2281
|
+
}),
|
|
2282
|
+
children,
|
|
2283
|
+
shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, {
|
|
2284
|
+
core: copilotkit,
|
|
2285
|
+
defaultAnchor: inspectorDefaultAnchor
|
|
2286
|
+
}) : null,
|
|
2287
|
+
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
|
|
2288
|
+
runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
|
|
2289
|
+
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
|
|
2290
|
+
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
|
|
2291
|
+
]
|
|
2292
|
+
})
|
|
1242
2293
|
})
|
|
1243
2294
|
});
|
|
1244
2295
|
};
|
|
@@ -1383,12 +2434,23 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1383
2434
|
byThread.set(threadId, clone);
|
|
1384
2435
|
return clone;
|
|
1385
2436
|
}
|
|
1386
|
-
function useAgent({ agentId, threadId, updates } = {}) {
|
|
2437
|
+
function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
1387
2438
|
var _agentId, _threadId;
|
|
1388
2439
|
(_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
|
|
1389
2440
|
const { copilotkit } = useCopilotKit();
|
|
2441
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
1390
2442
|
const chatConfig = useCopilotChatConfiguration();
|
|
1391
2443
|
(_threadId = threadId) !== null && _threadId !== void 0 || (threadId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.threadId);
|
|
2444
|
+
const effectiveThrottleMs = (0, react.useMemo)(() => {
|
|
2445
|
+
var _ref;
|
|
2446
|
+
const resolved = (_ref = throttleMs !== null && throttleMs !== void 0 ? throttleMs : providerThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
|
|
2447
|
+
if (!Number.isFinite(resolved) || resolved < 0) {
|
|
2448
|
+
const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
|
|
2449
|
+
console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
|
|
2450
|
+
return 0;
|
|
2451
|
+
}
|
|
2452
|
+
return resolved;
|
|
2453
|
+
}, [throttleMs, providerThrottleMs]);
|
|
1392
2454
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1393
2455
|
const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
|
|
1394
2456
|
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -1453,9 +2515,32 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1453
2515
|
(0, react.useEffect)(() => {
|
|
1454
2516
|
if (updateFlags.length === 0) return;
|
|
1455
2517
|
const handlers = {};
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
2518
|
+
let timerId = null;
|
|
2519
|
+
let active = true;
|
|
2520
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
|
|
2521
|
+
const ms = effectiveThrottleMs;
|
|
2522
|
+
if (ms > 0) {
|
|
2523
|
+
let throttleActive = false;
|
|
2524
|
+
let pending = false;
|
|
2525
|
+
const throttledNotify = () => {
|
|
2526
|
+
if (!active) return;
|
|
2527
|
+
if (!throttleActive) {
|
|
2528
|
+
throttleActive = true;
|
|
2529
|
+
pending = false;
|
|
2530
|
+
forceUpdate();
|
|
2531
|
+
timerId = setTimeout(function trailingEdge() {
|
|
2532
|
+
timerId = null;
|
|
2533
|
+
if (active && pending) {
|
|
2534
|
+
pending = false;
|
|
2535
|
+
forceUpdate();
|
|
2536
|
+
timerId = setTimeout(trailingEdge, ms);
|
|
2537
|
+
} else throttleActive = false;
|
|
2538
|
+
}, ms);
|
|
2539
|
+
} else pending = true;
|
|
2540
|
+
};
|
|
2541
|
+
handlers.onMessagesChanged = throttledNotify;
|
|
2542
|
+
} else handlers.onMessagesChanged = forceUpdate;
|
|
2543
|
+
}
|
|
1459
2544
|
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
|
|
1460
2545
|
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
1461
2546
|
handlers.onRunInitialized = forceUpdate;
|
|
@@ -1463,11 +2548,16 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1463
2548
|
handlers.onRunFailed = forceUpdate;
|
|
1464
2549
|
}
|
|
1465
2550
|
const subscription = agent.subscribe(handlers);
|
|
1466
|
-
return () =>
|
|
2551
|
+
return () => {
|
|
2552
|
+
active = false;
|
|
2553
|
+
if (timerId !== null) clearTimeout(timerId);
|
|
2554
|
+
subscription.unsubscribe();
|
|
2555
|
+
};
|
|
1467
2556
|
}, [
|
|
1468
2557
|
agent,
|
|
1469
2558
|
forceUpdate,
|
|
1470
|
-
|
|
2559
|
+
effectiveThrottleMs,
|
|
2560
|
+
updateFlags
|
|
1471
2561
|
]);
|
|
1472
2562
|
(0, react.useEffect)(() => {
|
|
1473
2563
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
@@ -1538,7 +2628,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1538
2628
|
copilotkit.removeTool(name, tool.agentId);
|
|
1539
2629
|
}
|
|
1540
2630
|
copilotkit.addTool(tool);
|
|
1541
|
-
if (tool.render
|
|
2631
|
+
if (tool.render) copilotkit.addHookRenderToolCall({
|
|
1542
2632
|
name,
|
|
1543
2633
|
args: tool.parameters,
|
|
1544
2634
|
agentId: tool.agentId,
|
|
@@ -1556,18 +2646,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1556
2646
|
]);
|
|
1557
2647
|
}
|
|
1558
2648
|
|
|
1559
|
-
//#endregion
|
|
1560
|
-
//#region src/v2/types/defineToolCallRenderer.ts
|
|
1561
|
-
function defineToolCallRenderer(def) {
|
|
1562
|
-
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
1563
|
-
return {
|
|
1564
|
-
name: def.name,
|
|
1565
|
-
args: argsSchema,
|
|
1566
|
-
render: def.render,
|
|
1567
|
-
...def.agentId ? { agentId: def.agentId } : {}
|
|
1568
|
-
};
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
2649
|
//#endregion
|
|
1572
2650
|
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
1573
2651
|
function useHumanInTheLoop$1(tool, deps) {
|
|
@@ -2309,6 +3387,227 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2309
3387
|
if (!context) throw new Error("useToast must be used within a ToastProvider");
|
|
2310
3388
|
return context;
|
|
2311
3389
|
}
|
|
3390
|
+
function formatBannerMessage(message) {
|
|
3391
|
+
const jsonMatch = message.match(/'message':\s*'([^']+)'/);
|
|
3392
|
+
if (jsonMatch) return jsonMatch[1];
|
|
3393
|
+
let cleaned = message.split(" - ")[0];
|
|
3394
|
+
cleaned = cleaned.split(": Error code")[0];
|
|
3395
|
+
cleaned = cleaned.replace(/:\s*\d{3}$/, "");
|
|
3396
|
+
cleaned = cleaned.replace(/See more:.*$/g, "");
|
|
3397
|
+
cleaned = cleaned.trim();
|
|
3398
|
+
return cleaned || "An error occurred.";
|
|
3399
|
+
}
|
|
3400
|
+
function extractUrl(message) {
|
|
3401
|
+
const markdownMatch = /\[([^\]]+)\]\(([^)]+)\)/.exec(message);
|
|
3402
|
+
if (markdownMatch) return {
|
|
3403
|
+
url: markdownMatch[2],
|
|
3404
|
+
text: "See More"
|
|
3405
|
+
};
|
|
3406
|
+
const plainMatch = /(https?:\/\/[^\s)]+)/.exec(message);
|
|
3407
|
+
if (plainMatch) return {
|
|
3408
|
+
url: plainMatch[0].replace(/[.,;:'"]*$/, ""),
|
|
3409
|
+
text: "See More"
|
|
3410
|
+
};
|
|
3411
|
+
return null;
|
|
3412
|
+
}
|
|
3413
|
+
function BannerErrorDisplay({ bannerError, onDismiss }) {
|
|
3414
|
+
const [detailsExpanded, setDetailsExpanded] = (0, react.useState)(false);
|
|
3415
|
+
const colors = getErrorColors(getErrorSeverity(bannerError));
|
|
3416
|
+
const details = bannerError.details;
|
|
3417
|
+
const link = extractUrl(bannerError.message);
|
|
3418
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3419
|
+
style: {
|
|
3420
|
+
position: "fixed",
|
|
3421
|
+
bottom: "20px",
|
|
3422
|
+
left: "50%",
|
|
3423
|
+
transform: "translateX(-50%)",
|
|
3424
|
+
zIndex: 9999,
|
|
3425
|
+
backgroundColor: colors.background,
|
|
3426
|
+
border: `1px solid ${colors.border}`,
|
|
3427
|
+
borderLeft: `4px solid ${colors.border}`,
|
|
3428
|
+
borderRadius: "8px",
|
|
3429
|
+
padding: "12px 16px",
|
|
3430
|
+
fontSize: "13px",
|
|
3431
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3432
|
+
backdropFilter: "blur(8px)",
|
|
3433
|
+
maxWidth: "min(90vw, 700px)",
|
|
3434
|
+
width: "100%",
|
|
3435
|
+
boxSizing: "border-box",
|
|
3436
|
+
overflow: "hidden"
|
|
3437
|
+
},
|
|
3438
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3439
|
+
style: {
|
|
3440
|
+
display: "flex",
|
|
3441
|
+
justifyContent: "space-between",
|
|
3442
|
+
alignItems: "center",
|
|
3443
|
+
gap: "10px"
|
|
3444
|
+
},
|
|
3445
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3446
|
+
style: {
|
|
3447
|
+
display: "flex",
|
|
3448
|
+
alignItems: "center",
|
|
3449
|
+
gap: "8px",
|
|
3450
|
+
flex: 1,
|
|
3451
|
+
minWidth: 0
|
|
3452
|
+
},
|
|
3453
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
3454
|
+
width: "12px",
|
|
3455
|
+
height: "12px",
|
|
3456
|
+
borderRadius: "50%",
|
|
3457
|
+
backgroundColor: colors.border,
|
|
3458
|
+
flexShrink: 0
|
|
3459
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3460
|
+
style: {
|
|
3461
|
+
display: "flex",
|
|
3462
|
+
alignItems: "center",
|
|
3463
|
+
gap: "10px",
|
|
3464
|
+
flex: 1,
|
|
3465
|
+
minWidth: 0
|
|
3466
|
+
},
|
|
3467
|
+
children: [
|
|
3468
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3469
|
+
style: {
|
|
3470
|
+
color: colors.text,
|
|
3471
|
+
lineHeight: "1.4",
|
|
3472
|
+
fontWeight: "400",
|
|
3473
|
+
fontSize: "13px",
|
|
3474
|
+
flex: 1,
|
|
3475
|
+
wordBreak: "break-all",
|
|
3476
|
+
overflowWrap: "break-word",
|
|
3477
|
+
maxWidth: "550px",
|
|
3478
|
+
overflow: "hidden",
|
|
3479
|
+
display: "-webkit-box",
|
|
3480
|
+
WebkitLineClamp: 10,
|
|
3481
|
+
WebkitBoxOrient: "vertical"
|
|
3482
|
+
},
|
|
3483
|
+
children: formatBannerMessage(bannerError.message)
|
|
3484
|
+
}),
|
|
3485
|
+
link && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3486
|
+
onClick: () => window.open(link.url, "_blank", "noopener,noreferrer"),
|
|
3487
|
+
style: {
|
|
3488
|
+
background: colors.border,
|
|
3489
|
+
color: "white",
|
|
3490
|
+
border: "none",
|
|
3491
|
+
borderRadius: "5px",
|
|
3492
|
+
padding: "4px 10px",
|
|
3493
|
+
fontSize: "11px",
|
|
3494
|
+
fontWeight: "500",
|
|
3495
|
+
cursor: "pointer",
|
|
3496
|
+
transition: "all 0.2s ease",
|
|
3497
|
+
flexShrink: 0
|
|
3498
|
+
},
|
|
3499
|
+
onMouseEnter: (e) => {
|
|
3500
|
+
e.currentTarget.style.opacity = "0.9";
|
|
3501
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
3502
|
+
},
|
|
3503
|
+
onMouseLeave: (e) => {
|
|
3504
|
+
e.currentTarget.style.opacity = "1";
|
|
3505
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
3506
|
+
},
|
|
3507
|
+
children: link.text
|
|
3508
|
+
}),
|
|
3509
|
+
details && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3510
|
+
onClick: () => setDetailsExpanded(!detailsExpanded),
|
|
3511
|
+
style: {
|
|
3512
|
+
background: "transparent",
|
|
3513
|
+
border: `1px solid ${colors.border}`,
|
|
3514
|
+
borderRadius: "5px",
|
|
3515
|
+
padding: "4px 10px",
|
|
3516
|
+
fontSize: "11px",
|
|
3517
|
+
fontWeight: "500",
|
|
3518
|
+
cursor: "pointer",
|
|
3519
|
+
color: colors.text,
|
|
3520
|
+
flexShrink: 0,
|
|
3521
|
+
transition: "all 0.2s ease"
|
|
3522
|
+
},
|
|
3523
|
+
onMouseEnter: (e) => {
|
|
3524
|
+
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
3525
|
+
},
|
|
3526
|
+
onMouseLeave: (e) => {
|
|
3527
|
+
e.currentTarget.style.background = "transparent";
|
|
3528
|
+
},
|
|
3529
|
+
children: detailsExpanded ? "Hide Details" : "Show Details"
|
|
3530
|
+
})
|
|
3531
|
+
]
|
|
3532
|
+
})]
|
|
3533
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3534
|
+
onClick: onDismiss,
|
|
3535
|
+
style: {
|
|
3536
|
+
background: "transparent",
|
|
3537
|
+
border: "none",
|
|
3538
|
+
color: colors.text,
|
|
3539
|
+
cursor: "pointer",
|
|
3540
|
+
padding: "2px",
|
|
3541
|
+
borderRadius: "3px",
|
|
3542
|
+
fontSize: "14px",
|
|
3543
|
+
lineHeight: "1",
|
|
3544
|
+
opacity: .6,
|
|
3545
|
+
transition: "all 0.2s ease",
|
|
3546
|
+
flexShrink: 0
|
|
3547
|
+
},
|
|
3548
|
+
title: "Dismiss",
|
|
3549
|
+
onMouseEnter: (e) => {
|
|
3550
|
+
e.currentTarget.style.opacity = "1";
|
|
3551
|
+
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
3552
|
+
},
|
|
3553
|
+
onMouseLeave: (e) => {
|
|
3554
|
+
e.currentTarget.style.opacity = "0.6";
|
|
3555
|
+
e.currentTarget.style.background = "transparent";
|
|
3556
|
+
},
|
|
3557
|
+
children: "x"
|
|
3558
|
+
})]
|
|
3559
|
+
}), detailsExpanded && details && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3560
|
+
style: {
|
|
3561
|
+
marginTop: "10px",
|
|
3562
|
+
padding: "10px",
|
|
3563
|
+
background: "rgba(0, 0, 0, 0.04)",
|
|
3564
|
+
borderRadius: "6px",
|
|
3565
|
+
fontSize: "11px",
|
|
3566
|
+
fontFamily: "monospace",
|
|
3567
|
+
color: colors.text,
|
|
3568
|
+
lineHeight: "1.5",
|
|
3569
|
+
maxHeight: "200px",
|
|
3570
|
+
overflowY: "auto",
|
|
3571
|
+
whiteSpace: "pre-wrap",
|
|
3572
|
+
wordBreak: "break-all"
|
|
3573
|
+
},
|
|
3574
|
+
children: [
|
|
3575
|
+
details.code && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
3576
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Code:" }),
|
|
3577
|
+
" ",
|
|
3578
|
+
details.code
|
|
3579
|
+
] }),
|
|
3580
|
+
details.originalMessage && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3581
|
+
style: { marginTop: "4px" },
|
|
3582
|
+
children: [
|
|
3583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Message:" }),
|
|
3584
|
+
" ",
|
|
3585
|
+
details.originalMessage
|
|
3586
|
+
]
|
|
3587
|
+
}),
|
|
3588
|
+
details.context && Object.keys(details.context).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3589
|
+
style: { marginTop: "4px" },
|
|
3590
|
+
children: [
|
|
3591
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Context:" }),
|
|
3592
|
+
" ",
|
|
3593
|
+
JSON.stringify(details.context, null, 2)
|
|
3594
|
+
]
|
|
3595
|
+
}),
|
|
3596
|
+
details.stack && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3597
|
+
style: {
|
|
3598
|
+
marginTop: "4px",
|
|
3599
|
+
opacity: .7
|
|
3600
|
+
},
|
|
3601
|
+
children: [
|
|
3602
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Stack:" }),
|
|
3603
|
+
"\n",
|
|
3604
|
+
details.stack
|
|
3605
|
+
]
|
|
3606
|
+
})
|
|
3607
|
+
]
|
|
3608
|
+
})]
|
|
3609
|
+
});
|
|
3610
|
+
}
|
|
2312
3611
|
function ToastProvider({ enabled, children }) {
|
|
2313
3612
|
const [toasts, setToasts] = (0, react.useState)([]);
|
|
2314
3613
|
const [bannerError, setBannerErrorState] = (0, react.useState)(null);
|
|
@@ -2347,156 +3646,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2347
3646
|
};
|
|
2348
3647
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ToastContext.Provider, {
|
|
2349
3648
|
value,
|
|
2350
|
-
children: [bannerError && ((
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
position: "fixed",
|
|
2355
|
-
bottom: "20px",
|
|
2356
|
-
left: "50%",
|
|
2357
|
-
transform: "translateX(-50%)",
|
|
2358
|
-
zIndex: 9999,
|
|
2359
|
-
backgroundColor: colors.background,
|
|
2360
|
-
border: `1px solid ${colors.border}`,
|
|
2361
|
-
borderLeft: `4px solid ${colors.border}`,
|
|
2362
|
-
borderRadius: "8px",
|
|
2363
|
-
padding: "12px 16px",
|
|
2364
|
-
fontSize: "13px",
|
|
2365
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
2366
|
-
backdropFilter: "blur(8px)",
|
|
2367
|
-
maxWidth: "min(90vw, 700px)",
|
|
2368
|
-
width: "100%",
|
|
2369
|
-
boxSizing: "border-box",
|
|
2370
|
-
overflow: "hidden"
|
|
2371
|
-
},
|
|
2372
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2373
|
-
style: {
|
|
2374
|
-
display: "flex",
|
|
2375
|
-
justifyContent: "space-between",
|
|
2376
|
-
alignItems: "center",
|
|
2377
|
-
gap: "10px"
|
|
2378
|
-
},
|
|
2379
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2380
|
-
style: {
|
|
2381
|
-
display: "flex",
|
|
2382
|
-
alignItems: "center",
|
|
2383
|
-
gap: "8px",
|
|
2384
|
-
flex: 1,
|
|
2385
|
-
minWidth: 0
|
|
2386
|
-
},
|
|
2387
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
2388
|
-
width: "12px",
|
|
2389
|
-
height: "12px",
|
|
2390
|
-
borderRadius: "50%",
|
|
2391
|
-
backgroundColor: colors.border,
|
|
2392
|
-
flexShrink: 0
|
|
2393
|
-
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2394
|
-
style: {
|
|
2395
|
-
display: "flex",
|
|
2396
|
-
alignItems: "center",
|
|
2397
|
-
gap: "10px",
|
|
2398
|
-
flex: 1,
|
|
2399
|
-
minWidth: 0
|
|
2400
|
-
},
|
|
2401
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2402
|
-
style: {
|
|
2403
|
-
color: colors.text,
|
|
2404
|
-
lineHeight: "1.4",
|
|
2405
|
-
fontWeight: "400",
|
|
2406
|
-
fontSize: "13px",
|
|
2407
|
-
flex: 1,
|
|
2408
|
-
wordBreak: "break-all",
|
|
2409
|
-
overflowWrap: "break-word",
|
|
2410
|
-
maxWidth: "550px",
|
|
2411
|
-
overflow: "hidden",
|
|
2412
|
-
display: "-webkit-box",
|
|
2413
|
-
WebkitLineClamp: 10,
|
|
2414
|
-
WebkitBoxOrient: "vertical"
|
|
2415
|
-
},
|
|
2416
|
-
children: (() => {
|
|
2417
|
-
let message = bannerError.message;
|
|
2418
|
-
const jsonMatch = message.match(/'message':\s*'([^']+)'/);
|
|
2419
|
-
if (jsonMatch) return jsonMatch[1];
|
|
2420
|
-
message = message.split(" - ")[0];
|
|
2421
|
-
message = message.split(": Error code")[0];
|
|
2422
|
-
message = message.replace(/:\s*\d{3}$/, "");
|
|
2423
|
-
message = message.replace(/See more:.*$/g, "");
|
|
2424
|
-
message = message.trim();
|
|
2425
|
-
return message || "Configuration error occurred.";
|
|
2426
|
-
})()
|
|
2427
|
-
}), (() => {
|
|
2428
|
-
const message = bannerError.message;
|
|
2429
|
-
const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
2430
|
-
const plainUrlRegex = /(https?:\/\/[^\s)]+)/g;
|
|
2431
|
-
let url = null;
|
|
2432
|
-
let buttonText = "See More";
|
|
2433
|
-
const markdownMatch = markdownLinkRegex.exec(message);
|
|
2434
|
-
if (markdownMatch) {
|
|
2435
|
-
url = markdownMatch[2];
|
|
2436
|
-
buttonText = "See More";
|
|
2437
|
-
} else {
|
|
2438
|
-
const urlMatch = plainUrlRegex.exec(message);
|
|
2439
|
-
if (urlMatch) {
|
|
2440
|
-
url = urlMatch[0].replace(/[.,;:'"]*$/, "");
|
|
2441
|
-
buttonText = "See More";
|
|
2442
|
-
}
|
|
2443
|
-
}
|
|
2444
|
-
if (!url) return null;
|
|
2445
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2446
|
-
onClick: () => window.open(url, "_blank", "noopener,noreferrer"),
|
|
2447
|
-
style: {
|
|
2448
|
-
background: colors.border,
|
|
2449
|
-
color: "white",
|
|
2450
|
-
border: "none",
|
|
2451
|
-
borderRadius: "5px",
|
|
2452
|
-
padding: "4px 10px",
|
|
2453
|
-
fontSize: "11px",
|
|
2454
|
-
fontWeight: "500",
|
|
2455
|
-
cursor: "pointer",
|
|
2456
|
-
transition: "all 0.2s ease",
|
|
2457
|
-
flexShrink: 0
|
|
2458
|
-
},
|
|
2459
|
-
onMouseEnter: (e) => {
|
|
2460
|
-
e.currentTarget.style.opacity = "0.9";
|
|
2461
|
-
e.currentTarget.style.transform = "translateY(-1px)";
|
|
2462
|
-
},
|
|
2463
|
-
onMouseLeave: (e) => {
|
|
2464
|
-
e.currentTarget.style.opacity = "1";
|
|
2465
|
-
e.currentTarget.style.transform = "translateY(0)";
|
|
2466
|
-
},
|
|
2467
|
-
children: buttonText
|
|
2468
|
-
});
|
|
2469
|
-
})()]
|
|
2470
|
-
})]
|
|
2471
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2472
|
-
onClick: () => setBannerError(null),
|
|
2473
|
-
style: {
|
|
2474
|
-
background: "transparent",
|
|
2475
|
-
border: "none",
|
|
2476
|
-
color: colors.text,
|
|
2477
|
-
cursor: "pointer",
|
|
2478
|
-
padding: "2px",
|
|
2479
|
-
borderRadius: "3px",
|
|
2480
|
-
fontSize: "14px",
|
|
2481
|
-
lineHeight: "1",
|
|
2482
|
-
opacity: .6,
|
|
2483
|
-
transition: "all 0.2s ease",
|
|
2484
|
-
flexShrink: 0
|
|
2485
|
-
},
|
|
2486
|
-
title: "Dismiss",
|
|
2487
|
-
onMouseEnter: (e) => {
|
|
2488
|
-
e.currentTarget.style.opacity = "1";
|
|
2489
|
-
e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
|
|
2490
|
-
},
|
|
2491
|
-
onMouseLeave: (e) => {
|
|
2492
|
-
e.currentTarget.style.opacity = "0.6";
|
|
2493
|
-
e.currentTarget.style.background = "transparent";
|
|
2494
|
-
},
|
|
2495
|
-
children: "×"
|
|
2496
|
-
})]
|
|
2497
|
-
})
|
|
2498
|
-
});
|
|
2499
|
-
})(), children]
|
|
3649
|
+
children: [bannerError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerErrorDisplay, {
|
|
3650
|
+
bannerError,
|
|
3651
|
+
onDismiss: () => setBannerError(null)
|
|
3652
|
+
}), children]
|
|
2500
3653
|
});
|
|
2501
3654
|
}
|
|
2502
3655
|
|
|
@@ -3537,12 +4690,21 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3537
4690
|
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
3538
4691
|
usePredictStateSubscription(agent);
|
|
3539
4692
|
(0, react.useEffect)(() => {
|
|
3540
|
-
const subscription = copilotkit.subscribe({ onError: ({ error }) => {
|
|
3541
|
-
|
|
4693
|
+
const subscription = copilotkit.subscribe({ onError: ({ error, code, context }) => {
|
|
4694
|
+
if (error.name === "AbortError" || error.message === "Fetch is aborted" || error.message === "signal is aborted without reason" || error.message === "component unmounted" || !error.message) return;
|
|
4695
|
+
if (process.env.NODE_ENV === "development") console.error("[CopilotKit] Agent error:", error.message, "\n Code:", code, "\n Context:", context, "\n Stack:", error.stack);
|
|
4696
|
+
const ckError = new _copilotkit_shared.CopilotKitLowLevelError({
|
|
3542
4697
|
error,
|
|
3543
4698
|
message: error.message,
|
|
3544
4699
|
url: typeof window !== "undefined" ? window.location.href : ""
|
|
3545
|
-
})
|
|
4700
|
+
});
|
|
4701
|
+
ckError.details = {
|
|
4702
|
+
code,
|
|
4703
|
+
context,
|
|
4704
|
+
stack: error.stack,
|
|
4705
|
+
originalMessage: error.message
|
|
4706
|
+
};
|
|
4707
|
+
setBannerError(ckError);
|
|
3546
4708
|
} });
|
|
3547
4709
|
return () => {
|
|
3548
4710
|
subscription.unsubscribe();
|