@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.
Files changed (81) hide show
  1. package/CHANGELOG.md +46 -6
  2. package/dist/{copilotkit-DeOzjPsb.mjs → copilotkit-BY5S1-0P.mjs} +2402 -552
  3. package/dist/copilotkit-BY5S1-0P.mjs.map +1 -0
  4. package/dist/{copilotkit-BqcyhQjT.d.mts → copilotkit-BuhSUZHb.d.mts} +228 -17
  5. package/dist/copilotkit-BuhSUZHb.d.mts.map +1 -0
  6. package/dist/{copilotkit-BDNjFNmk.cjs → copilotkit-Bz5-ImDl.cjs} +2421 -541
  7. package/dist/copilotkit-Bz5-ImDl.cjs.map +1 -0
  8. package/dist/{copilotkit-l-IBF4Xp.d.cts → copilotkit-dwDWYpya.d.cts} +228 -17
  9. package/dist/copilotkit-dwDWYpya.d.cts.map +1 -0
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.mts +1 -1
  13. package/dist/index.mjs +1 -1
  14. package/dist/index.umd.js +1400 -238
  15. package/dist/index.umd.js.map +1 -1
  16. package/dist/v2/index.cjs +13 -1
  17. package/dist/v2/index.css +1 -1
  18. package/dist/v2/index.d.cts +3 -3
  19. package/dist/v2/index.d.mts +3 -3
  20. package/dist/v2/index.mjs +3 -2
  21. package/dist/v2/index.umd.js +2442 -552
  22. package/dist/v2/index.umd.js.map +1 -1
  23. package/package.json +62 -54
  24. package/scripts/scope-preflight.mjs +1 -2
  25. package/src/components/CopilotListeners.tsx +41 -8
  26. package/src/components/copilot-provider/copilotkit-props.tsx +4 -2
  27. package/src/components/toast/toast-provider.tsx +269 -194
  28. package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +86 -22
  29. package/src/v2/__tests__/utils/test-helpers.tsx +67 -0
  30. package/src/v2/a2ui/A2UICatalogContext.tsx +79 -0
  31. package/src/v2/a2ui/A2UIMessageRenderer.tsx +125 -37
  32. package/src/v2/a2ui/A2UIToolCallRenderer.tsx +290 -0
  33. package/src/v2/components/CopilotKitInspector.tsx +2 -0
  34. package/src/v2/components/OpenGenerativeUIRenderer.tsx +598 -0
  35. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.tsx +665 -0
  36. package/src/v2/components/chat/CopilotChat.tsx +193 -50
  37. package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +17 -2
  38. package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +481 -0
  39. package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +139 -0
  40. package/src/v2/components/chat/CopilotChatInput.tsx +146 -77
  41. package/src/v2/components/chat/CopilotChatMessageView.tsx +253 -149
  42. package/src/v2/components/chat/CopilotChatSuggestionView.tsx +1 -0
  43. package/src/v2/components/chat/CopilotChatUserMessage.tsx +54 -0
  44. package/src/v2/components/chat/CopilotChatView.tsx +179 -66
  45. package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.tsx +168 -0
  46. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +63 -2
  47. package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +544 -1
  48. package/src/v2/components/chat/__tests__/CopilotChatPerf.e2e.test.tsx +268 -0
  49. package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.tsx +249 -0
  50. package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +43 -2
  51. package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +138 -0
  52. package/src/v2/components/chat/index.ts +9 -0
  53. package/src/v2/components/chat/scroll-element-context.ts +13 -0
  54. package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +1003 -0
  55. package/src/v2/hooks/__tests__/use-attachments.test.tsx +169 -0
  56. package/src/v2/hooks/__tests__/use-threads.test.tsx +54 -0
  57. package/src/v2/hooks/index.ts +5 -0
  58. package/src/v2/hooks/use-agent.tsx +95 -10
  59. package/src/v2/hooks/use-attachments.tsx +269 -0
  60. package/src/v2/hooks/use-frontend-tool.tsx +5 -2
  61. package/src/v2/hooks/use-render-activity-message.tsx +9 -2
  62. package/src/v2/hooks/use-threads.tsx +35 -15
  63. package/src/v2/index.ts +5 -1
  64. package/src/v2/lib/__tests__/processPartialHtml.test.ts +112 -0
  65. package/src/v2/lib/__tests__/slots.test.ts +56 -0
  66. package/src/v2/lib/processPartialHtml.ts +45 -0
  67. package/src/v2/lib/slots.tsx +42 -1
  68. package/src/v2/providers/CopilotChatConfigurationProvider.tsx +9 -3
  69. package/src/v2/providers/CopilotKitProvider.tsx +268 -32
  70. package/src/v2/providers/SandboxFunctionsContext.ts +10 -0
  71. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.tsx +198 -0
  72. package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +71 -0
  73. package/src/v2/providers/index.ts +7 -0
  74. package/src/v2/styles/globals.css +2 -1
  75. package/src/v2/types/index.ts +1 -0
  76. package/src/v2/types/sandbox-function.ts +11 -0
  77. package/dist/copilotkit-BDNjFNmk.cjs.map +0 -1
  78. package/dist/copilotkit-BqcyhQjT.d.mts.map +0 -1
  79. package/dist/copilotkit-DeOzjPsb.mjs.map +0 -1
  80. package/dist/copilotkit-l-IBF4Xp.d.cts.map +0 -1
  81. 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 photos or files",
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
- ...labels !== null && labels !== void 0 ? labels : {}
157
+ ...stableLabels !== null && stableLabels !== void 0 ? stableLabels : {}
72
158
  };
73
- }, [labels, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels]);
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 (!content || !Array.isArray(content.operations)) {
774
- lastSignatureRef.current = null;
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)(_copilotkit_a2ui_renderer.A2UIRenderer, {
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 lastProcessedRef = (0, react.useRef)("");
1356
+ const { processMessages, getSurface } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
1357
+ const lastHashRef = (0, react.useRef)("");
851
1358
  (0, react.useEffect)(() => {
852
- const key = `${surfaceId}-${JSON.stringify(operations)}`;
853
- if (key === lastProcessedRef.current) return;
854
- lastProcessedRef.current = key;
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$beginRende, _operation$beginRende2, _operation$surfaceUpd, _operation$dataModelU, _operation$deleteSurf;
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$beginRende = operation === null || operation === void 0 || (_operation$beginRende2 = operation.beginRendering) === null || _operation$beginRende2 === void 0 ? void 0 : _operation$beginRende2.surfaceId) !== null && _operation$beginRende !== void 0 ? _operation$beginRende : operation === null || operation === void 0 || (_operation$surfaceUpd = operation.surfaceUpdate) === null || _operation$surfaceUpd === void 0 ? void 0 : _operation$surfaceUpd.surfaceId) !== null && _ref3 !== void 0 ? _ref3 : operation === null || operation === void 0 || (_operation$dataModelU = operation.dataModelUpdate) === null || _operation$dataModelU === void 0 ? void 0 : _operation$dataModelU.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;
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
- function stringifyOperations(ops) {
870
- try {
871
- return JSON.stringify(ops);
872
- } catch (error) {
873
- return null;
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 = false, onError, a2ui }) => {
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({ theme: (_a2ui$theme = a2ui === null || a2ui === void 0 ? void 0 : a2ui.theme) !== null && _a2ui$theme !== void 0 ? _a2ui$theme : _copilotkit_a2ui_renderer.viewerTheme }));
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
- }, [runtimeA2UIEnabled, a2ui]);
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
- }, [frontendToolsList, processedHumanInTheLoopTools]);
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) copilotkitRef.current = new CopilotKitCoreReact({
1117
- runtimeUrl: chatApiEndpoint,
1118
- runtimeTransport: useSingleEndpoint ? "single" : "rest",
1119
- headers: mergedHeaders,
1120
- credentials,
1121
- properties,
1122
- agents__unsafe_dev_only: mergedAgents,
1123
- tools: allTools,
1124
- renderToolCalls: allRenderToolCalls,
1125
- renderActivityMessages: allActivityRenderers,
1126
- renderCustomMessages: renderCustomMessagesList
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)(CopilotKitContext.Provider, {
1231
- value: contextValue,
1232
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LicenseContext.Provider, {
1233
- value: licenseContextValue,
1234
- children: [
1235
- children,
1236
- shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, { core: copilotkit }) : null,
1237
- runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
1238
- runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
1239
- runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
1240
- runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
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
- if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = () => {
1457
- forceUpdate();
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 () => subscription.unsubscribe();
2551
+ return () => {
2552
+ active = false;
2553
+ if (timerId !== null) clearTimeout(timerId);
2554
+ subscription.unsubscribe();
2555
+ };
1467
2556
  }, [
1468
2557
  agent,
1469
2558
  forceUpdate,
1470
- JSON.stringify(updateFlags)
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 && tool.parameters) copilotkit.addHookRenderToolCall({
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
- const colors = getErrorColors(getErrorSeverity(bannerError));
2352
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2353
- style: {
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
- setBannerError(new _copilotkit_shared.CopilotKitLowLevelError({
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();