@copilotkit/react-core 1.54.1 → 1.55.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -116
- package/dist/copilotkit-B3Mb1yVE.cjs +7975 -0
- package/dist/copilotkit-B3Mb1yVE.cjs.map +1 -0
- package/dist/copilotkit-DBzgOMby.d.cts +2182 -0
- package/dist/copilotkit-DBzgOMby.d.cts.map +1 -0
- package/dist/copilotkit-DNYSFuz5.mjs +7562 -0
- package/dist/copilotkit-DNYSFuz5.mjs.map +1 -0
- package/dist/copilotkit-Dy5w3qEV.d.mts +2182 -0
- package/dist/copilotkit-Dy5w3qEV.d.mts.map +1 -0
- package/dist/index.cjs +27 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -5
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1941 -35
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +77 -7
- package/dist/v2/index.css +1 -2
- package/dist/v2/index.d.cts +6 -4
- package/dist/v2/index.d.mts +6 -4
- package/dist/v2/index.mjs +7 -4
- package/dist/v2/index.umd.js +5725 -24
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +37 -9
- package/scripts/scope-preflight.mjs +101 -0
- package/src/components/CopilotListeners.tsx +2 -6
- package/src/components/copilot-provider/copilot-messages.tsx +1 -1
- package/src/components/copilot-provider/copilotkit-props.tsx +1 -1
- package/src/components/copilot-provider/copilotkit.tsx +4 -4
- package/src/context/copilot-messages-context.tsx +1 -1
- package/src/hooks/__tests__/use-coagent-config.test.ts +2 -2
- package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +2 -2
- package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +3 -7
- package/src/hooks/__tests__/use-frontend-tool-available.test.tsx +1 -1
- package/src/hooks/__tests__/use-frontend-tool-remount.e2e.test.tsx +4 -4
- package/src/hooks/use-agent-nodename.ts +1 -1
- package/src/hooks/use-coagent-state-render-bridge.tsx +1 -4
- package/src/hooks/use-coagent.ts +1 -1
- package/src/hooks/use-configure-chat-suggestions.tsx +2 -2
- package/src/hooks/use-copilot-chat-suggestions.tsx +2 -2
- package/src/hooks/use-copilot-chat_internal.ts +2 -2
- package/src/hooks/use-copilot-readable.ts +1 -1
- package/src/hooks/use-frontend-tool.ts +2 -2
- package/src/hooks/use-human-in-the-loop.ts +2 -2
- package/src/hooks/use-langgraph-interrupt.ts +2 -5
- package/src/hooks/use-lazy-tool-renderer.tsx +1 -1
- package/src/hooks/use-render-tool-call.ts +1 -1
- package/src/lib/copilot-task.ts +1 -1
- package/src/setupTests.ts +18 -14
- package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +176 -0
- package/src/v2/__tests__/globalSetup.ts +14 -0
- package/src/v2/__tests__/setup.ts +93 -0
- package/src/v2/__tests__/utils/test-helpers.tsx +470 -0
- package/src/v2/a2ui/A2UIMessageRenderer.tsx +206 -0
- package/src/v2/components/CopilotKitInspector.tsx +50 -0
- package/src/v2/components/MCPAppsActivityRenderer.tsx +785 -0
- package/src/v2/components/WildcardToolCallRender.tsx +86 -0
- package/src/v2/components/__tests__/license-warning-banner.test.tsx +46 -0
- package/src/v2/components/chat/CopilotChat.tsx +431 -0
- package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +375 -0
- package/src/v2/components/chat/CopilotChatAudioRecorder.tsx +350 -0
- package/src/v2/components/chat/CopilotChatInput.tsx +1302 -0
- package/src/v2/components/chat/CopilotChatMessageView.tsx +556 -0
- package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +252 -0
- package/src/v2/components/chat/CopilotChatSuggestionPill.tsx +59 -0
- package/src/v2/components/chat/CopilotChatSuggestionView.tsx +133 -0
- package/src/v2/components/chat/CopilotChatToggleButton.tsx +171 -0
- package/src/v2/components/chat/CopilotChatToolCallsView.tsx +40 -0
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +388 -0
- package/src/v2/components/chat/CopilotChatView.tsx +598 -0
- package/src/v2/components/chat/CopilotModalHeader.tsx +129 -0
- package/src/v2/components/chat/CopilotPopup.tsx +81 -0
- package/src/v2/components/chat/CopilotPopupView.tsx +317 -0
- package/src/v2/components/chat/CopilotSidebar.tsx +76 -0
- package/src/v2/components/chat/CopilotSidebarView.tsx +255 -0
- package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +1113 -0
- package/src/v2/components/chat/__tests__/CopilotChat.onError.test.tsx +73 -0
- package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.tsx +432 -0
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +150 -0
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.tsx +624 -0
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +702 -0
- package/src/v2/components/chat/__tests__/CopilotChatCssClasses.test.tsx +107 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.tsx +929 -0
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +986 -0
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.tsx +1004 -0
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx +169 -0
- package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.tsx +530 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +782 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +2413 -0
- package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.tsx +621 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.tsx +853 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.tsx +1050 -0
- package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.tsx +484 -0
- package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.tsx +612 -0
- package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.tsx +502 -0
- package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +1011 -0
- package/src/v2/components/chat/__tests__/setup.ts +1 -0
- package/src/v2/components/chat/index.ts +79 -0
- package/src/v2/components/index.ts +7 -0
- package/src/v2/components/license-warning-banner.tsx +198 -0
- package/src/v2/components/ui/button.tsx +123 -0
- package/src/v2/components/ui/dropdown-menu.tsx +258 -0
- package/src/v2/components/ui/tooltip.tsx +60 -0
- package/src/v2/hooks/__tests__/standard-schema-types.test.tsx +152 -0
- package/src/v2/hooks/__tests__/standard-schema.test.tsx +282 -0
- package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +132 -0
- package/src/v2/hooks/__tests__/use-agent-context.test.tsx +401 -0
- package/src/v2/hooks/__tests__/use-agent-error-state.test.tsx +44 -0
- package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +205 -0
- package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +148 -0
- package/src/v2/hooks/__tests__/use-component.test.tsx +123 -0
- package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.tsx +696 -0
- package/src/v2/hooks/__tests__/use-default-render-tool.test.tsx +153 -0
- package/src/v2/hooks/__tests__/use-frontend-tool-available.test.tsx +167 -0
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +2129 -0
- package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx +1261 -0
- package/src/v2/hooks/__tests__/use-interrupt.test.tsx +397 -0
- package/src/v2/hooks/__tests__/use-katex-styles.test.tsx +56 -0
- package/src/v2/hooks/__tests__/use-keyboard-height.test.tsx +192 -0
- package/src/v2/hooks/__tests__/use-render-tool.test.tsx +259 -0
- package/src/v2/hooks/__tests__/use-suggestions.e2e.test.tsx +524 -0
- package/src/v2/hooks/__tests__/use-threads.test.tsx +433 -0
- package/src/v2/hooks/__tests__/zod-regression.test.tsx +311 -0
- package/src/v2/hooks/index.ts +18 -0
- package/src/v2/hooks/use-agent-context.tsx +45 -0
- package/src/v2/hooks/use-agent.tsx +155 -0
- package/src/v2/hooks/use-component.tsx +89 -0
- package/src/v2/hooks/use-configure-suggestions.tsx +187 -0
- package/src/v2/hooks/use-default-render-tool.tsx +254 -0
- package/src/v2/hooks/use-frontend-tool.tsx +43 -0
- package/src/v2/hooks/use-human-in-the-loop.tsx +81 -0
- package/src/v2/hooks/use-interrupt.tsx +305 -0
- package/src/v2/hooks/use-keyboard-height.tsx +67 -0
- package/src/v2/hooks/use-render-activity-message.tsx +73 -0
- package/src/v2/hooks/use-render-custom-messages.tsx +93 -0
- package/src/v2/hooks/use-render-tool-call.tsx +175 -0
- package/src/v2/hooks/use-render-tool.tsx +181 -0
- package/src/v2/hooks/use-suggestions.tsx +91 -0
- package/src/v2/hooks/use-threads.tsx +256 -0
- package/src/v2/hooks/useKatexStyles.ts +27 -0
- package/src/v2/index.css +1 -1
- package/src/v2/index.ts +18 -2
- package/src/v2/lib/__tests__/completePartialMarkdown.test.ts +495 -0
- package/src/v2/lib/__tests__/renderSlot.test.tsx +588 -0
- package/src/v2/lib/react-core.ts +156 -0
- package/src/v2/lib/slots.tsx +143 -0
- package/src/v2/lib/transcription-client.ts +184 -0
- package/src/v2/lib/utils.ts +8 -0
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +162 -0
- package/src/v2/providers/CopilotKitProvider.tsx +600 -0
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.tsx +546 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.license.test.tsx +101 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.tsx +69 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.tsx +881 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.tsx +740 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +642 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +294 -0
- package/src/v2/providers/index.ts +14 -0
- package/src/v2/styles/globals.css +230 -0
- package/src/v2/types/__tests__/defineToolCallRenderer.test.tsx +525 -0
- package/src/v2/types/defineToolCallRenderer.ts +65 -0
- package/src/v2/types/frontend-tool.ts +8 -0
- package/src/v2/types/human-in-the-loop.ts +33 -0
- package/src/v2/types/index.ts +7 -0
- package/src/v2/types/interrupt.ts +15 -0
- package/src/v2/types/react-activity-message-renderer.ts +27 -0
- package/src/v2/types/react-custom-message-renderer.ts +17 -0
- package/src/v2/types/react-tool-call-renderer.ts +32 -0
- package/tsdown.config.ts +34 -10
- package/vitest.config.mjs +4 -3
- package/LICENSE +0 -21
- package/dist/copilotkit-BRPQ2sqS.d.cts +0 -670
- package/dist/copilotkit-BRPQ2sqS.d.cts.map +0 -1
- package/dist/copilotkit-C94ayZbs.cjs +0 -2161
- package/dist/copilotkit-C94ayZbs.cjs.map +0 -1
- package/dist/copilotkit-CwZMFmSK.d.mts +0 -670
- package/dist/copilotkit-CwZMFmSK.d.mts.map +0 -1
- package/dist/copilotkit-Yh_Ld_FX.mjs +0 -2031
- package/dist/copilotkit-Yh_Ld_FX.mjs.map +0 -1
- package/dist/v2/index.css.map +0 -1
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('@
|
|
5
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@
|
|
6
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCore = {}), global.React,global.
|
|
7
|
-
})(this, function(exports, react,
|
|
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) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -36,6 +36,1912 @@ 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/providers/CopilotChatConfigurationProvider.tsx
|
|
40
|
+
const CopilotChatDefaultLabels = {
|
|
41
|
+
chatInputPlaceholder: "Type a message...",
|
|
42
|
+
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
|
43
|
+
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
|
44
|
+
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
45
|
+
chatInputToolbarAddButtonLabel: "Add photos or files",
|
|
46
|
+
chatInputToolbarToolsButtonLabel: "Tools",
|
|
47
|
+
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
48
|
+
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
49
|
+
assistantMessageToolbarCopyMessageLabel: "Copy",
|
|
50
|
+
assistantMessageToolbarThumbsUpLabel: "Good response",
|
|
51
|
+
assistantMessageToolbarThumbsDownLabel: "Bad response",
|
|
52
|
+
assistantMessageToolbarReadAloudLabel: "Read aloud",
|
|
53
|
+
assistantMessageToolbarRegenerateLabel: "Regenerate",
|
|
54
|
+
userMessageToolbarCopyMessageLabel: "Copy",
|
|
55
|
+
userMessageToolbarEditMessageLabel: "Edit",
|
|
56
|
+
chatDisclaimerText: "AI can make mistakes. Please verify important information.",
|
|
57
|
+
chatToggleOpenLabel: "Open chat",
|
|
58
|
+
chatToggleCloseLabel: "Close chat",
|
|
59
|
+
modalHeaderTitle: "CopilotKit Chat",
|
|
60
|
+
welcomeMessageText: "How can I help you today?"
|
|
61
|
+
};
|
|
62
|
+
const CopilotChatConfiguration = (0, react.createContext)(null);
|
|
63
|
+
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
|
|
64
|
+
var _ref, _parentConfig$isModal, _parentConfig$setModa;
|
|
65
|
+
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
66
|
+
const mergedLabels = (0, react.useMemo)(() => {
|
|
67
|
+
var _parentConfig$labels;
|
|
68
|
+
return {
|
|
69
|
+
...CopilotChatDefaultLabels,
|
|
70
|
+
...(_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 : {}
|
|
72
|
+
};
|
|
73
|
+
}, [labels, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels]);
|
|
74
|
+
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
|
+
const resolvedThreadId = (0, react.useMemo)(() => {
|
|
76
|
+
if (threadId) return threadId;
|
|
77
|
+
if (parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId) return parentConfig.threadId;
|
|
78
|
+
return (0, _copilotkit_shared.randomUUID)();
|
|
79
|
+
}, [threadId, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId]);
|
|
80
|
+
const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen !== null && isModalDefaultOpen !== void 0 ? isModalDefaultOpen : true);
|
|
81
|
+
const hasExplicitDefault = isModalDefaultOpen !== void 0;
|
|
82
|
+
const setAndSync = (0, react.useCallback)((open) => {
|
|
83
|
+
setInternalModalOpen(open);
|
|
84
|
+
parentConfig === null || parentConfig === void 0 || parentConfig.setModalOpen(open);
|
|
85
|
+
}, [parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.setModalOpen]);
|
|
86
|
+
const isMounted = (0, react.useRef)(false);
|
|
87
|
+
(0, react.useEffect)(() => {
|
|
88
|
+
if (!hasExplicitDefault) return;
|
|
89
|
+
if (!isMounted.current) {
|
|
90
|
+
isMounted.current = true;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if ((parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.isModalOpen) === void 0) return;
|
|
94
|
+
setInternalModalOpen(parentConfig.isModalOpen);
|
|
95
|
+
}, [parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.isModalOpen, hasExplicitDefault]);
|
|
96
|
+
const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : (_parentConfig$isModal = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.isModalOpen) !== null && _parentConfig$isModal !== void 0 ? _parentConfig$isModal : internalModalOpen;
|
|
97
|
+
const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : (_parentConfig$setModa = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.setModalOpen) !== null && _parentConfig$setModa !== void 0 ? _parentConfig$setModa : setInternalModalOpen;
|
|
98
|
+
const configurationValue = (0, react.useMemo)(() => ({
|
|
99
|
+
labels: mergedLabels,
|
|
100
|
+
agentId: resolvedAgentId,
|
|
101
|
+
threadId: resolvedThreadId,
|
|
102
|
+
isModalOpen: resolvedIsModalOpen,
|
|
103
|
+
setModalOpen: resolvedSetModalOpen
|
|
104
|
+
}), [
|
|
105
|
+
mergedLabels,
|
|
106
|
+
resolvedAgentId,
|
|
107
|
+
resolvedThreadId,
|
|
108
|
+
resolvedIsModalOpen,
|
|
109
|
+
resolvedSetModalOpen
|
|
110
|
+
]);
|
|
111
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
|
|
112
|
+
value: configurationValue,
|
|
113
|
+
children
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
const useCopilotChatConfiguration = () => {
|
|
117
|
+
return (0, react.useContext)(CopilotChatConfiguration);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/v2/components/CopilotKitInspector.tsx
|
|
122
|
+
const CopilotKitInspector = ({ core, ...rest }) => {
|
|
123
|
+
const [InspectorComponent, setInspectorComponent] = react.useState(null);
|
|
124
|
+
react.useEffect(() => {
|
|
125
|
+
let mounted = true;
|
|
126
|
+
import("@copilotkit/web-inspector").then((mod) => {
|
|
127
|
+
var _mod$defineWebInspect;
|
|
128
|
+
(_mod$defineWebInspect = mod.defineWebInspector) === null || _mod$defineWebInspect === void 0 || _mod$defineWebInspect.call(mod);
|
|
129
|
+
const Component = (0, _lit_labs_react.createComponent)({
|
|
130
|
+
tagName: mod.WEB_INSPECTOR_TAG,
|
|
131
|
+
elementClass: mod.WebInspectorElement,
|
|
132
|
+
react
|
|
133
|
+
});
|
|
134
|
+
if (mounted) setInspectorComponent(() => Component);
|
|
135
|
+
});
|
|
136
|
+
return () => {
|
|
137
|
+
mounted = false;
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
140
|
+
if (!InspectorComponent) return null;
|
|
141
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InspectorComponent, {
|
|
142
|
+
...rest,
|
|
143
|
+
core: core !== null && core !== void 0 ? core : null
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
CopilotKitInspector.displayName = "CopilotKitInspector";
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/v2/components/license-warning-banner.tsx
|
|
150
|
+
const BANNER_STYLES = {
|
|
151
|
+
base: {
|
|
152
|
+
position: "fixed",
|
|
153
|
+
bottom: "8px",
|
|
154
|
+
left: "50%",
|
|
155
|
+
transform: "translateX(-50%)",
|
|
156
|
+
zIndex: 99999,
|
|
157
|
+
display: "inline-flex",
|
|
158
|
+
alignItems: "center",
|
|
159
|
+
gap: "12px",
|
|
160
|
+
whiteSpace: "nowrap",
|
|
161
|
+
padding: "8px 16px",
|
|
162
|
+
fontSize: "13px",
|
|
163
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
|
|
164
|
+
borderRadius: "6px",
|
|
165
|
+
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
|
|
166
|
+
},
|
|
167
|
+
info: {
|
|
168
|
+
backgroundColor: "#eff6ff",
|
|
169
|
+
border: "1px solid #93c5fd",
|
|
170
|
+
color: "#1e40af"
|
|
171
|
+
},
|
|
172
|
+
warning: {
|
|
173
|
+
backgroundColor: "#fffbeb",
|
|
174
|
+
border: "1px solid #fbbf24",
|
|
175
|
+
color: "#92400e"
|
|
176
|
+
},
|
|
177
|
+
critical: {
|
|
178
|
+
backgroundColor: "#fef2f2",
|
|
179
|
+
border: "1px solid #fca5a5",
|
|
180
|
+
color: "#991b1b"
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
function getSeverityStyle(severity) {
|
|
184
|
+
switch (severity) {
|
|
185
|
+
case "warning": return BANNER_STYLES.warning;
|
|
186
|
+
case "critical": return BANNER_STYLES.critical;
|
|
187
|
+
default: return BANNER_STYLES.info;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function BannerShell({ severity, message, actionLabel, actionUrl, onDismiss }) {
|
|
191
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
192
|
+
style: {
|
|
193
|
+
...BANNER_STYLES.base,
|
|
194
|
+
...getSeverityStyle(severity)
|
|
195
|
+
},
|
|
196
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: message }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
197
|
+
style: {
|
|
198
|
+
display: "flex",
|
|
199
|
+
gap: "8px",
|
|
200
|
+
alignItems: "center"
|
|
201
|
+
},
|
|
202
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
203
|
+
href: actionUrl,
|
|
204
|
+
target: "_blank",
|
|
205
|
+
rel: "noopener noreferrer",
|
|
206
|
+
style: {
|
|
207
|
+
fontWeight: 600,
|
|
208
|
+
textDecoration: "underline",
|
|
209
|
+
color: "inherit"
|
|
210
|
+
},
|
|
211
|
+
children: actionLabel
|
|
212
|
+
}), onDismiss && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
213
|
+
onClick: onDismiss,
|
|
214
|
+
style: {
|
|
215
|
+
background: "none",
|
|
216
|
+
border: "none",
|
|
217
|
+
cursor: "pointer",
|
|
218
|
+
color: "inherit",
|
|
219
|
+
fontSize: "16px"
|
|
220
|
+
},
|
|
221
|
+
children: "×"
|
|
222
|
+
})]
|
|
223
|
+
})]
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function LicenseWarningBanner({ type, featureName, expiryDate, graceRemaining, onDismiss }) {
|
|
227
|
+
switch (type) {
|
|
228
|
+
case "no_license": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
229
|
+
severity: "info",
|
|
230
|
+
message: "Powered by CopilotKit",
|
|
231
|
+
actionLabel: "Get a license",
|
|
232
|
+
actionUrl: "https://copilotkit.ai/pricing",
|
|
233
|
+
onDismiss
|
|
234
|
+
});
|
|
235
|
+
case "feature_unlicensed": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
236
|
+
severity: "warning",
|
|
237
|
+
message: `⚠ The "${featureName}" feature requires a CopilotKit license.`,
|
|
238
|
+
actionLabel: "Get a license",
|
|
239
|
+
actionUrl: "https://copilotkit.ai/pricing",
|
|
240
|
+
onDismiss
|
|
241
|
+
});
|
|
242
|
+
case "expiring": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
243
|
+
severity: "warning",
|
|
244
|
+
message: `Your CopilotKit license expires in ${graceRemaining} day${graceRemaining !== 1 ? "s" : ""}. Please renew.`,
|
|
245
|
+
actionLabel: "Renew",
|
|
246
|
+
actionUrl: "https://cloud.copilotkit.ai",
|
|
247
|
+
onDismiss
|
|
248
|
+
});
|
|
249
|
+
case "expired": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
250
|
+
severity: "critical",
|
|
251
|
+
message: `Your CopilotKit license expired${expiryDate ? ` on ${expiryDate}` : ""}. Please renew at copilotkit.ai/pricing`,
|
|
252
|
+
actionLabel: "Renew now",
|
|
253
|
+
actionUrl: "https://copilotkit.ai/pricing",
|
|
254
|
+
onDismiss
|
|
255
|
+
});
|
|
256
|
+
case "invalid": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
257
|
+
severity: "critical",
|
|
258
|
+
message: "Invalid CopilotKit license token. Please check your configuration.",
|
|
259
|
+
actionLabel: "Get a license",
|
|
260
|
+
actionUrl: "https://copilotkit.ai/pricing",
|
|
261
|
+
onDismiss
|
|
262
|
+
});
|
|
263
|
+
default: return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/v2/components/MCPAppsActivityRenderer.tsx
|
|
269
|
+
const PROTOCOL_VERSION = "2025-06-18";
|
|
270
|
+
function buildSandboxHTML(extraCspDomains) {
|
|
271
|
+
const baseScriptSrc = "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*";
|
|
272
|
+
const baseFrameSrc = "* blob: data: http://localhost:* https://localhost:*";
|
|
273
|
+
const extra = (extraCspDomains === null || extraCspDomains === void 0 ? void 0 : extraCspDomains.length) ? " " + extraCspDomains.join(" ") : "";
|
|
274
|
+
return `<!doctype html>
|
|
275
|
+
<html>
|
|
276
|
+
<head>
|
|
277
|
+
<meta charset="utf-8" />
|
|
278
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data: blob: 'unsafe-inline'; media-src * blob: data:; font-src * blob: data:; script-src ${baseScriptSrc + extra}; style-src * blob: data: 'unsafe-inline'; connect-src *; frame-src ${baseFrameSrc + extra}; base-uri 'self';" />
|
|
279
|
+
<style>html,body{margin:0;padding:0;height:100%;width:100%;overflow:hidden}*{box-sizing:border-box}iframe{background-color:transparent;border:none;padding:0;overflow:hidden;width:100%;height:100%}</style>
|
|
280
|
+
</head>
|
|
281
|
+
<body>
|
|
282
|
+
<script>
|
|
283
|
+
if(window.self===window.top){throw new Error("This file must be used in an iframe.")}
|
|
284
|
+
const inner=document.createElement("iframe");
|
|
285
|
+
inner.style="width:100%;height:100%;border:none;";
|
|
286
|
+
inner.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms");
|
|
287
|
+
document.body.appendChild(inner);
|
|
288
|
+
window.addEventListener("message",async(event)=>{
|
|
289
|
+
if(event.source===window.parent){
|
|
290
|
+
if(event.data&&event.data.method==="ui/notifications/sandbox-resource-ready"){
|
|
291
|
+
const{html,sandbox}=event.data.params;
|
|
292
|
+
if(typeof sandbox==="string")inner.setAttribute("sandbox",sandbox);
|
|
293
|
+
if(typeof html==="string")inner.srcdoc=html;
|
|
294
|
+
}else if(inner&&inner.contentWindow){
|
|
295
|
+
inner.contentWindow.postMessage(event.data,"*");
|
|
296
|
+
}
|
|
297
|
+
}else if(event.source===inner.contentWindow){
|
|
298
|
+
window.parent.postMessage(event.data,"*");
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-ready",params:{}},"*");
|
|
302
|
+
<\/script>
|
|
303
|
+
</body>
|
|
304
|
+
</html>`;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Queue for serializing MCP app requests to an agent.
|
|
308
|
+
* Ensures requests wait for the agent to stop running and are processed one at a time.
|
|
309
|
+
*/
|
|
310
|
+
var MCPAppsRequestQueue = class {
|
|
311
|
+
constructor() {
|
|
312
|
+
this.queues = /* @__PURE__ */ new Map();
|
|
313
|
+
this.processing = /* @__PURE__ */ new Map();
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Add a request to the queue for a specific agent thread.
|
|
317
|
+
* Returns a promise that resolves when the request completes.
|
|
318
|
+
*/
|
|
319
|
+
async enqueue(agent, request) {
|
|
320
|
+
const threadId = agent.threadId || "default";
|
|
321
|
+
return new Promise((resolve, reject) => {
|
|
322
|
+
let queue = this.queues.get(threadId);
|
|
323
|
+
if (!queue) {
|
|
324
|
+
queue = [];
|
|
325
|
+
this.queues.set(threadId, queue);
|
|
326
|
+
}
|
|
327
|
+
queue.push({
|
|
328
|
+
execute: request,
|
|
329
|
+
resolve,
|
|
330
|
+
reject
|
|
331
|
+
});
|
|
332
|
+
this.processQueue(threadId, agent);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
async processQueue(threadId, agent) {
|
|
336
|
+
if (this.processing.get(threadId)) return;
|
|
337
|
+
this.processing.set(threadId, true);
|
|
338
|
+
try {
|
|
339
|
+
const queue = this.queues.get(threadId);
|
|
340
|
+
if (!queue) return;
|
|
341
|
+
while (queue.length > 0) {
|
|
342
|
+
const item = queue[0];
|
|
343
|
+
try {
|
|
344
|
+
await this.waitForAgentIdle(agent);
|
|
345
|
+
const result = await item.execute();
|
|
346
|
+
item.resolve(result);
|
|
347
|
+
} catch (error) {
|
|
348
|
+
item.reject(error instanceof Error ? error : new Error(String(error)));
|
|
349
|
+
}
|
|
350
|
+
queue.shift();
|
|
351
|
+
}
|
|
352
|
+
} finally {
|
|
353
|
+
this.processing.set(threadId, false);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
waitForAgentIdle(agent) {
|
|
357
|
+
return new Promise((resolve) => {
|
|
358
|
+
if (!agent.isRunning) {
|
|
359
|
+
resolve();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
let done = false;
|
|
363
|
+
const finish = () => {
|
|
364
|
+
if (done) return;
|
|
365
|
+
done = true;
|
|
366
|
+
clearInterval(checkInterval);
|
|
367
|
+
sub.unsubscribe();
|
|
368
|
+
resolve();
|
|
369
|
+
};
|
|
370
|
+
const sub = agent.subscribe({
|
|
371
|
+
onRunFinalized: finish,
|
|
372
|
+
onRunFailed: finish
|
|
373
|
+
});
|
|
374
|
+
const checkInterval = setInterval(() => {
|
|
375
|
+
if (!agent.isRunning) finish();
|
|
376
|
+
}, 500);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
const mcpAppsRequestQueue = new MCPAppsRequestQueue();
|
|
381
|
+
/**
|
|
382
|
+
* Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType
|
|
383
|
+
*/
|
|
384
|
+
const MCPAppsActivityType = "mcp-apps";
|
|
385
|
+
const MCPAppsActivityContentSchema = zod.z.object({
|
|
386
|
+
result: zod.z.object({
|
|
387
|
+
content: zod.z.array(zod.z.any()).optional(),
|
|
388
|
+
structuredContent: zod.z.any().optional(),
|
|
389
|
+
isError: zod.z.boolean().optional()
|
|
390
|
+
}),
|
|
391
|
+
resourceUri: zod.z.string(),
|
|
392
|
+
serverHash: zod.z.string(),
|
|
393
|
+
serverId: zod.z.string().optional(),
|
|
394
|
+
toolInput: zod.z.record(zod.z.unknown()).optional()
|
|
395
|
+
});
|
|
396
|
+
function isRequest(msg) {
|
|
397
|
+
return "id" in msg && "method" in msg;
|
|
398
|
+
}
|
|
399
|
+
function isNotification(msg) {
|
|
400
|
+
return !("id" in msg) && "method" in msg;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* MCP Apps Extension Activity Renderer
|
|
404
|
+
*
|
|
405
|
+
* Renders MCP Apps UI in a sandboxed iframe with full protocol support.
|
|
406
|
+
* Fetches resource content on-demand via proxied MCP requests.
|
|
407
|
+
*/
|
|
408
|
+
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, agent }) {
|
|
409
|
+
var _fetchedResource$_met2;
|
|
410
|
+
const containerRef = (0, react.useRef)(null);
|
|
411
|
+
const iframeRef = (0, react.useRef)(null);
|
|
412
|
+
const [iframeReady, setIframeReady] = (0, react.useState)(false);
|
|
413
|
+
const [error, setError] = (0, react.useState)(null);
|
|
414
|
+
const [isLoading, setIsLoading] = (0, react.useState)(true);
|
|
415
|
+
const [iframeSize, setIframeSize] = (0, react.useState)({});
|
|
416
|
+
const [fetchedResource, setFetchedResource] = (0, react.useState)(null);
|
|
417
|
+
const contentRef = (0, react.useRef)(content);
|
|
418
|
+
contentRef.current = content;
|
|
419
|
+
const agentRef = (0, react.useRef)(agent);
|
|
420
|
+
agentRef.current = agent;
|
|
421
|
+
const fetchStateRef = (0, react.useRef)({
|
|
422
|
+
inProgress: false,
|
|
423
|
+
promise: null,
|
|
424
|
+
resourceUri: null
|
|
425
|
+
});
|
|
426
|
+
const sendToIframe = (0, react.useCallback)((msg) => {
|
|
427
|
+
var _iframeRef$current;
|
|
428
|
+
if ((_iframeRef$current = iframeRef.current) === null || _iframeRef$current === void 0 ? void 0 : _iframeRef$current.contentWindow) {
|
|
429
|
+
console.log("[MCPAppsRenderer] Sending to iframe:", msg);
|
|
430
|
+
iframeRef.current.contentWindow.postMessage(msg, "*");
|
|
431
|
+
}
|
|
432
|
+
}, []);
|
|
433
|
+
const sendResponse = (0, react.useCallback)((id, result) => {
|
|
434
|
+
sendToIframe({
|
|
435
|
+
jsonrpc: "2.0",
|
|
436
|
+
id,
|
|
437
|
+
result
|
|
438
|
+
});
|
|
439
|
+
}, [sendToIframe]);
|
|
440
|
+
const sendErrorResponse = (0, react.useCallback)((id, code, message) => {
|
|
441
|
+
sendToIframe({
|
|
442
|
+
jsonrpc: "2.0",
|
|
443
|
+
id,
|
|
444
|
+
error: {
|
|
445
|
+
code,
|
|
446
|
+
message
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
}, [sendToIframe]);
|
|
450
|
+
const sendNotification = (0, react.useCallback)((method, params) => {
|
|
451
|
+
sendToIframe({
|
|
452
|
+
jsonrpc: "2.0",
|
|
453
|
+
method,
|
|
454
|
+
params: params || {}
|
|
455
|
+
});
|
|
456
|
+
}, [sendToIframe]);
|
|
457
|
+
(0, react.useEffect)(() => {
|
|
458
|
+
const { resourceUri, serverHash, serverId } = content;
|
|
459
|
+
if (fetchStateRef.current.inProgress && fetchStateRef.current.resourceUri === resourceUri) {
|
|
460
|
+
var _fetchStateRef$curren;
|
|
461
|
+
(_fetchStateRef$curren = fetchStateRef.current.promise) === null || _fetchStateRef$curren === void 0 || _fetchStateRef$curren.then((resource) => {
|
|
462
|
+
if (resource) {
|
|
463
|
+
setFetchedResource(resource);
|
|
464
|
+
setIsLoading(false);
|
|
465
|
+
}
|
|
466
|
+
}).catch((err) => {
|
|
467
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
468
|
+
setIsLoading(false);
|
|
469
|
+
});
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if (!agent) {
|
|
473
|
+
setError(/* @__PURE__ */ new Error("No agent available to fetch resource"));
|
|
474
|
+
setIsLoading(false);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
fetchStateRef.current.inProgress = true;
|
|
478
|
+
fetchStateRef.current.resourceUri = resourceUri;
|
|
479
|
+
const fetchPromise = (async () => {
|
|
480
|
+
try {
|
|
481
|
+
var _resultData$contents;
|
|
482
|
+
const resultData = (await mcpAppsRequestQueue.enqueue(agent, () => agent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
483
|
+
serverHash,
|
|
484
|
+
serverId,
|
|
485
|
+
method: "resources/read",
|
|
486
|
+
params: { uri: resourceUri }
|
|
487
|
+
} } }))).result;
|
|
488
|
+
const resource = resultData === null || resultData === void 0 || (_resultData$contents = resultData.contents) === null || _resultData$contents === void 0 ? void 0 : _resultData$contents[0];
|
|
489
|
+
if (!resource) throw new Error("No resource content in response");
|
|
490
|
+
return resource;
|
|
491
|
+
} catch (err) {
|
|
492
|
+
console.error("[MCPAppsRenderer] Failed to fetch resource:", err);
|
|
493
|
+
throw err;
|
|
494
|
+
} finally {
|
|
495
|
+
fetchStateRef.current.inProgress = false;
|
|
496
|
+
}
|
|
497
|
+
})();
|
|
498
|
+
fetchStateRef.current.promise = fetchPromise;
|
|
499
|
+
fetchPromise.then((resource) => {
|
|
500
|
+
if (resource) {
|
|
501
|
+
setFetchedResource(resource);
|
|
502
|
+
setIsLoading(false);
|
|
503
|
+
}
|
|
504
|
+
}).catch((err) => {
|
|
505
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
506
|
+
setIsLoading(false);
|
|
507
|
+
});
|
|
508
|
+
}, [agent, content]);
|
|
509
|
+
(0, react.useEffect)(() => {
|
|
510
|
+
if (isLoading || !fetchedResource) return;
|
|
511
|
+
const container = containerRef.current;
|
|
512
|
+
if (!container) return;
|
|
513
|
+
let mounted = true;
|
|
514
|
+
let messageHandler = null;
|
|
515
|
+
let initialListener = null;
|
|
516
|
+
let createdIframe = null;
|
|
517
|
+
const setup = async () => {
|
|
518
|
+
try {
|
|
519
|
+
var _fetchedResource$_met;
|
|
520
|
+
const iframe = document.createElement("iframe");
|
|
521
|
+
createdIframe = iframe;
|
|
522
|
+
iframe.style.width = "100%";
|
|
523
|
+
iframe.style.height = "100px";
|
|
524
|
+
iframe.style.border = "none";
|
|
525
|
+
iframe.style.backgroundColor = "transparent";
|
|
526
|
+
iframe.style.display = "block";
|
|
527
|
+
iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
528
|
+
const sandboxReady = new Promise((resolve) => {
|
|
529
|
+
initialListener = (event) => {
|
|
530
|
+
if (event.source === iframe.contentWindow) {
|
|
531
|
+
var _event$data;
|
|
532
|
+
if (((_event$data = event.data) === null || _event$data === void 0 ? void 0 : _event$data.method) === "ui/notifications/sandbox-proxy-ready") {
|
|
533
|
+
if (initialListener) {
|
|
534
|
+
window.removeEventListener("message", initialListener);
|
|
535
|
+
initialListener = null;
|
|
536
|
+
}
|
|
537
|
+
resolve();
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
window.addEventListener("message", initialListener);
|
|
542
|
+
});
|
|
543
|
+
if (!mounted) {
|
|
544
|
+
if (initialListener) {
|
|
545
|
+
window.removeEventListener("message", initialListener);
|
|
546
|
+
initialListener = null;
|
|
547
|
+
}
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
iframe.srcdoc = buildSandboxHTML((_fetchedResource$_met = fetchedResource._meta) === null || _fetchedResource$_met === void 0 || (_fetchedResource$_met = _fetchedResource$_met.ui) === null || _fetchedResource$_met === void 0 || (_fetchedResource$_met = _fetchedResource$_met.csp) === null || _fetchedResource$_met === void 0 ? void 0 : _fetchedResource$_met.resourceDomains);
|
|
551
|
+
iframeRef.current = iframe;
|
|
552
|
+
container.appendChild(iframe);
|
|
553
|
+
await sandboxReady;
|
|
554
|
+
if (!mounted) return;
|
|
555
|
+
console.log("[MCPAppsRenderer] Sandbox proxy ready");
|
|
556
|
+
messageHandler = async (event) => {
|
|
557
|
+
if (event.source !== iframe.contentWindow) return;
|
|
558
|
+
const msg = event.data;
|
|
559
|
+
if (!msg || typeof msg !== "object" || msg.jsonrpc !== "2.0") return;
|
|
560
|
+
console.log("[MCPAppsRenderer] Received from iframe:", msg);
|
|
561
|
+
if (isRequest(msg)) switch (msg.method) {
|
|
562
|
+
case "ui/initialize":
|
|
563
|
+
sendResponse(msg.id, {
|
|
564
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
565
|
+
hostInfo: {
|
|
566
|
+
name: "CopilotKit MCP Apps Host",
|
|
567
|
+
version: "1.0.0"
|
|
568
|
+
},
|
|
569
|
+
hostCapabilities: {
|
|
570
|
+
openLinks: {},
|
|
571
|
+
logging: {}
|
|
572
|
+
},
|
|
573
|
+
hostContext: {
|
|
574
|
+
theme: "light",
|
|
575
|
+
platform: "web"
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
break;
|
|
579
|
+
case "ui/message": {
|
|
580
|
+
const currentAgent = agentRef.current;
|
|
581
|
+
if (!currentAgent) {
|
|
582
|
+
console.warn("[MCPAppsRenderer] ui/message: No agent available");
|
|
583
|
+
sendResponse(msg.id, { isError: false });
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
try {
|
|
587
|
+
var _params$content;
|
|
588
|
+
const params = msg.params;
|
|
589
|
+
const textContent = ((_params$content = params.content) === null || _params$content === void 0 ? void 0 : _params$content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n")) || "";
|
|
590
|
+
if (textContent) currentAgent.addMessage({
|
|
591
|
+
id: crypto.randomUUID(),
|
|
592
|
+
role: params.role || "user",
|
|
593
|
+
content: textContent
|
|
594
|
+
});
|
|
595
|
+
sendResponse(msg.id, { isError: false });
|
|
596
|
+
} catch (err) {
|
|
597
|
+
console.error("[MCPAppsRenderer] ui/message error:", err);
|
|
598
|
+
sendResponse(msg.id, { isError: true });
|
|
599
|
+
}
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
case "ui/open-link": {
|
|
603
|
+
var _msg$params;
|
|
604
|
+
const url = (_msg$params = msg.params) === null || _msg$params === void 0 ? void 0 : _msg$params.url;
|
|
605
|
+
if (url) {
|
|
606
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
607
|
+
sendResponse(msg.id, { isError: false });
|
|
608
|
+
} else sendErrorResponse(msg.id, -32602, "Missing url parameter");
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
case "tools/call": {
|
|
612
|
+
const { serverHash, serverId } = contentRef.current;
|
|
613
|
+
const currentAgent = agentRef.current;
|
|
614
|
+
if (!serverHash) {
|
|
615
|
+
sendErrorResponse(msg.id, -32603, "No server hash available for proxying");
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
if (!currentAgent) {
|
|
619
|
+
sendErrorResponse(msg.id, -32603, "No agent available for proxying");
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
622
|
+
try {
|
|
623
|
+
const runResult = await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
624
|
+
serverHash,
|
|
625
|
+
serverId,
|
|
626
|
+
method: "tools/call",
|
|
627
|
+
params: msg.params
|
|
628
|
+
} } }));
|
|
629
|
+
sendResponse(msg.id, runResult.result || {});
|
|
630
|
+
} catch (err) {
|
|
631
|
+
console.error("[MCPAppsRenderer] tools/call error:", err);
|
|
632
|
+
sendErrorResponse(msg.id, -32603, String(err));
|
|
633
|
+
}
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
636
|
+
default: sendErrorResponse(msg.id, -32601, `Method not found: ${msg.method}`);
|
|
637
|
+
}
|
|
638
|
+
if (isNotification(msg)) switch (msg.method) {
|
|
639
|
+
case "ui/notifications/initialized":
|
|
640
|
+
console.log("[MCPAppsRenderer] Inner iframe initialized");
|
|
641
|
+
if (mounted) setIframeReady(true);
|
|
642
|
+
break;
|
|
643
|
+
case "ui/notifications/size-changed": {
|
|
644
|
+
const { width, height } = msg.params || {};
|
|
645
|
+
console.log("[MCPAppsRenderer] Size change:", {
|
|
646
|
+
width,
|
|
647
|
+
height
|
|
648
|
+
});
|
|
649
|
+
if (mounted) setIframeSize({
|
|
650
|
+
width: typeof width === "number" ? width : void 0,
|
|
651
|
+
height: typeof height === "number" ? height : void 0
|
|
652
|
+
});
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
case "notifications/message":
|
|
656
|
+
console.log("[MCPAppsRenderer] App log:", msg.params);
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
window.addEventListener("message", messageHandler);
|
|
661
|
+
let html;
|
|
662
|
+
if (fetchedResource.text) html = fetchedResource.text;
|
|
663
|
+
else if (fetchedResource.blob) html = atob(fetchedResource.blob);
|
|
664
|
+
else throw new Error("Resource has no text or blob content");
|
|
665
|
+
sendNotification("ui/notifications/sandbox-resource-ready", { html });
|
|
666
|
+
} catch (err) {
|
|
667
|
+
console.error("[MCPAppsRenderer] Setup error:", err);
|
|
668
|
+
if (mounted) setError(err instanceof Error ? err : new Error(String(err)));
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
setup();
|
|
672
|
+
return () => {
|
|
673
|
+
mounted = false;
|
|
674
|
+
if (initialListener) {
|
|
675
|
+
window.removeEventListener("message", initialListener);
|
|
676
|
+
initialListener = null;
|
|
677
|
+
}
|
|
678
|
+
if (messageHandler) window.removeEventListener("message", messageHandler);
|
|
679
|
+
if (createdIframe) {
|
|
680
|
+
createdIframe.remove();
|
|
681
|
+
createdIframe = null;
|
|
682
|
+
}
|
|
683
|
+
iframeRef.current = null;
|
|
684
|
+
};
|
|
685
|
+
}, [
|
|
686
|
+
isLoading,
|
|
687
|
+
fetchedResource,
|
|
688
|
+
sendNotification,
|
|
689
|
+
sendResponse,
|
|
690
|
+
sendErrorResponse
|
|
691
|
+
]);
|
|
692
|
+
(0, react.useEffect)(() => {
|
|
693
|
+
if (iframeRef.current) {
|
|
694
|
+
if (iframeSize.width !== void 0) {
|
|
695
|
+
iframeRef.current.style.minWidth = `min(${iframeSize.width}px, 100%)`;
|
|
696
|
+
iframeRef.current.style.width = "100%";
|
|
697
|
+
}
|
|
698
|
+
if (iframeSize.height !== void 0) iframeRef.current.style.height = `${iframeSize.height}px`;
|
|
699
|
+
}
|
|
700
|
+
}, [iframeSize]);
|
|
701
|
+
(0, react.useEffect)(() => {
|
|
702
|
+
if (iframeReady && content.toolInput) {
|
|
703
|
+
console.log("[MCPAppsRenderer] Sending tool input:", content.toolInput);
|
|
704
|
+
sendNotification("ui/notifications/tool-input", { arguments: content.toolInput });
|
|
705
|
+
}
|
|
706
|
+
}, [
|
|
707
|
+
iframeReady,
|
|
708
|
+
content.toolInput,
|
|
709
|
+
sendNotification
|
|
710
|
+
]);
|
|
711
|
+
(0, react.useEffect)(() => {
|
|
712
|
+
if (iframeReady && content.result) {
|
|
713
|
+
console.log("[MCPAppsRenderer] Sending tool result:", content.result);
|
|
714
|
+
sendNotification("ui/notifications/tool-result", content.result);
|
|
715
|
+
}
|
|
716
|
+
}, [
|
|
717
|
+
iframeReady,
|
|
718
|
+
content.result,
|
|
719
|
+
sendNotification
|
|
720
|
+
]);
|
|
721
|
+
const borderStyle = (fetchedResource === null || fetchedResource === void 0 || (_fetchedResource$_met2 = fetchedResource._meta) === null || _fetchedResource$_met2 === void 0 || (_fetchedResource$_met2 = _fetchedResource$_met2.ui) === null || _fetchedResource$_met2 === void 0 ? void 0 : _fetchedResource$_met2.prefersBorder) === true ? {
|
|
722
|
+
borderRadius: "8px",
|
|
723
|
+
backgroundColor: "#f9f9f9",
|
|
724
|
+
border: "1px solid #e0e0e0"
|
|
725
|
+
} : {};
|
|
726
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
727
|
+
ref: containerRef,
|
|
728
|
+
style: {
|
|
729
|
+
width: "100%",
|
|
730
|
+
height: iframeSize.height ? `${iframeSize.height}px` : "auto",
|
|
731
|
+
minHeight: "100px",
|
|
732
|
+
overflow: "hidden",
|
|
733
|
+
position: "relative",
|
|
734
|
+
...borderStyle
|
|
735
|
+
},
|
|
736
|
+
children: [isLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
737
|
+
style: {
|
|
738
|
+
padding: "1rem",
|
|
739
|
+
color: "#666"
|
|
740
|
+
},
|
|
741
|
+
children: "Loading..."
|
|
742
|
+
}), error && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
743
|
+
style: {
|
|
744
|
+
color: "red",
|
|
745
|
+
padding: "1rem"
|
|
746
|
+
},
|
|
747
|
+
children: ["Error: ", error.message]
|
|
748
|
+
})]
|
|
749
|
+
});
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
//#endregion
|
|
753
|
+
//#region src/v2/a2ui/A2UIMessageRenderer.tsx
|
|
754
|
+
let initialized = false;
|
|
755
|
+
function ensureInitialized() {
|
|
756
|
+
if (!initialized) {
|
|
757
|
+
(0, _copilotkit_a2ui_renderer.initializeDefaultCatalog)();
|
|
758
|
+
(0, _copilotkit_a2ui_renderer.injectStyles)();
|
|
759
|
+
initialized = true;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
function createA2UIMessageRenderer(options) {
|
|
763
|
+
const { theme } = options;
|
|
764
|
+
return {
|
|
765
|
+
activityType: "a2ui-surface",
|
|
766
|
+
content: zod.z.any(),
|
|
767
|
+
render: ({ content, agent }) => {
|
|
768
|
+
ensureInitialized();
|
|
769
|
+
const [operations, setOperations] = (0, react.useState)([]);
|
|
770
|
+
const lastSignatureRef = (0, react.useRef)(null);
|
|
771
|
+
const { copilotkit } = useCopilotKit();
|
|
772
|
+
(0, react.useEffect)(() => {
|
|
773
|
+
if (!content || !Array.isArray(content.operations)) {
|
|
774
|
+
lastSignatureRef.current = null;
|
|
775
|
+
setOperations([]);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
const incoming = content.operations;
|
|
779
|
+
const signature = stringifyOperations(incoming);
|
|
780
|
+
if (signature && signature === lastSignatureRef.current) return;
|
|
781
|
+
lastSignatureRef.current = signature;
|
|
782
|
+
setOperations(incoming);
|
|
783
|
+
}, [content]);
|
|
784
|
+
const groupedOperations = (0, react.useMemo)(() => {
|
|
785
|
+
const groups = /* @__PURE__ */ new Map();
|
|
786
|
+
for (const operation of operations) {
|
|
787
|
+
var _getOperationSurfaceI;
|
|
788
|
+
const surfaceId = (_getOperationSurfaceI = getOperationSurfaceId(operation)) !== null && _getOperationSurfaceI !== void 0 ? _getOperationSurfaceI : _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
|
|
789
|
+
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
|
|
790
|
+
groups.get(surfaceId).push(operation);
|
|
791
|
+
}
|
|
792
|
+
return groups;
|
|
793
|
+
}, [operations]);
|
|
794
|
+
if (!groupedOperations.size) return null;
|
|
795
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
796
|
+
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
797
|
+
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
798
|
+
surfaceId,
|
|
799
|
+
operations: ops,
|
|
800
|
+
theme,
|
|
801
|
+
agent,
|
|
802
|
+
copilotkit
|
|
803
|
+
}, surfaceId))
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Renders a single A2UI surface using the React renderer.
|
|
810
|
+
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
|
|
811
|
+
*/
|
|
812
|
+
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit }) {
|
|
813
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
814
|
+
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
815
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
816
|
+
onAction: (0, react.useCallback)(async (message) => {
|
|
817
|
+
if (!agent) return;
|
|
818
|
+
try {
|
|
819
|
+
var _copilotkit$propertie;
|
|
820
|
+
console.info("[A2UI] Action dispatched", message.userAction);
|
|
821
|
+
copilotkit.setProperties({
|
|
822
|
+
...(_copilotkit$propertie = copilotkit.properties) !== null && _copilotkit$propertie !== void 0 ? _copilotkit$propertie : {},
|
|
823
|
+
a2uiAction: message
|
|
824
|
+
});
|
|
825
|
+
await copilotkit.runAgent({ agent });
|
|
826
|
+
} finally {
|
|
827
|
+
if (copilotkit.properties) {
|
|
828
|
+
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
829
|
+
copilotkit.setProperties(rest);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}, [agent, copilotkit]),
|
|
833
|
+
theme,
|
|
834
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
835
|
+
surfaceId,
|
|
836
|
+
operations
|
|
837
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_a2ui_renderer.A2UIRenderer, {
|
|
838
|
+
surfaceId,
|
|
839
|
+
className: "cpk:flex cpk:flex-1"
|
|
840
|
+
})]
|
|
841
|
+
})
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Processes A2UI operations into the provider's message processor.
|
|
846
|
+
* Must be a child of A2UIProvider to access the actions context.
|
|
847
|
+
*/
|
|
848
|
+
function SurfaceMessageProcessor({ surfaceId, operations }) {
|
|
849
|
+
const { processMessages } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
850
|
+
const lastProcessedRef = (0, react.useRef)("");
|
|
851
|
+
(0, react.useEffect)(() => {
|
|
852
|
+
const key = `${surfaceId}-${JSON.stringify(operations)}`;
|
|
853
|
+
if (key === lastProcessedRef.current) return;
|
|
854
|
+
lastProcessedRef.current = key;
|
|
855
|
+
processMessages(operations);
|
|
856
|
+
}, [
|
|
857
|
+
processMessages,
|
|
858
|
+
surfaceId,
|
|
859
|
+
operations
|
|
860
|
+
]);
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
function getOperationSurfaceId(operation) {
|
|
864
|
+
var _ref, _ref2, _ref3, _operation$beginRende, _operation$beginRende2, _operation$surfaceUpd, _operation$dataModelU, _operation$deleteSurf;
|
|
865
|
+
if (!operation || typeof operation !== "object") return null;
|
|
866
|
+
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;
|
|
868
|
+
}
|
|
869
|
+
function stringifyOperations(ops) {
|
|
870
|
+
try {
|
|
871
|
+
return JSON.stringify(ops);
|
|
872
|
+
} catch (error) {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
//#endregion
|
|
878
|
+
//#region src/v2/lib/react-core.ts
|
|
879
|
+
var CopilotKitCoreReact = class extends _copilotkit_core.CopilotKitCore {
|
|
880
|
+
constructor(config) {
|
|
881
|
+
var _config$renderToolCal, _config$renderCustomM, _config$renderActivit;
|
|
882
|
+
super(config);
|
|
883
|
+
this._renderToolCalls = [];
|
|
884
|
+
this._hookRenderToolCalls = /* @__PURE__ */ new Map();
|
|
885
|
+
this._cachedMergedRenderToolCalls = null;
|
|
886
|
+
this._renderCustomMessages = [];
|
|
887
|
+
this._renderActivityMessages = [];
|
|
888
|
+
this._interruptElement = null;
|
|
889
|
+
this._renderToolCalls = (_config$renderToolCal = config.renderToolCalls) !== null && _config$renderToolCal !== void 0 ? _config$renderToolCal : [];
|
|
890
|
+
this._renderCustomMessages = (_config$renderCustomM = config.renderCustomMessages) !== null && _config$renderCustomM !== void 0 ? _config$renderCustomM : [];
|
|
891
|
+
this._renderActivityMessages = (_config$renderActivit = config.renderActivityMessages) !== null && _config$renderActivit !== void 0 ? _config$renderActivit : [];
|
|
892
|
+
}
|
|
893
|
+
get renderCustomMessages() {
|
|
894
|
+
return this._renderCustomMessages;
|
|
895
|
+
}
|
|
896
|
+
get renderActivityMessages() {
|
|
897
|
+
return this._renderActivityMessages;
|
|
898
|
+
}
|
|
899
|
+
get renderToolCalls() {
|
|
900
|
+
if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
|
|
901
|
+
if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
|
|
902
|
+
const merged = /* @__PURE__ */ new Map();
|
|
903
|
+
for (const rc of this._renderToolCalls) {
|
|
904
|
+
var _rc$agentId;
|
|
905
|
+
merged.set(`${(_rc$agentId = rc.agentId) !== null && _rc$agentId !== void 0 ? _rc$agentId : ""}:${rc.name}`, rc);
|
|
906
|
+
}
|
|
907
|
+
for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
|
|
908
|
+
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
909
|
+
return this._cachedMergedRenderToolCalls;
|
|
910
|
+
}
|
|
911
|
+
setRenderActivityMessages(renderers) {
|
|
912
|
+
this._renderActivityMessages = renderers;
|
|
913
|
+
}
|
|
914
|
+
setRenderCustomMessages(renderers) {
|
|
915
|
+
this._renderCustomMessages = renderers;
|
|
916
|
+
}
|
|
917
|
+
setRenderToolCalls(renderToolCalls) {
|
|
918
|
+
this._renderToolCalls = renderToolCalls;
|
|
919
|
+
this._cachedMergedRenderToolCalls = null;
|
|
920
|
+
this._notifyRenderToolCallsChanged();
|
|
921
|
+
}
|
|
922
|
+
addHookRenderToolCall(entry) {
|
|
923
|
+
var _entry$agentId;
|
|
924
|
+
const key = `${(_entry$agentId = entry.agentId) !== null && _entry$agentId !== void 0 ? _entry$agentId : ""}:${entry.name}`;
|
|
925
|
+
this._hookRenderToolCalls.set(key, entry);
|
|
926
|
+
this._cachedMergedRenderToolCalls = null;
|
|
927
|
+
this._notifyRenderToolCallsChanged();
|
|
928
|
+
}
|
|
929
|
+
removeHookRenderToolCall(name, agentId) {
|
|
930
|
+
const key = `${agentId !== null && agentId !== void 0 ? agentId : ""}:${name}`;
|
|
931
|
+
if (this._hookRenderToolCalls.delete(key)) {
|
|
932
|
+
this._cachedMergedRenderToolCalls = null;
|
|
933
|
+
this._notifyRenderToolCallsChanged();
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
_notifyRenderToolCallsChanged() {
|
|
937
|
+
this.notifySubscribers((subscriber) => {
|
|
938
|
+
const reactSubscriber = subscriber;
|
|
939
|
+
if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
|
|
940
|
+
copilotkit: this,
|
|
941
|
+
renderToolCalls: this.renderToolCalls
|
|
942
|
+
});
|
|
943
|
+
}, "Subscriber onRenderToolCallsChanged error:");
|
|
944
|
+
}
|
|
945
|
+
get interruptElement() {
|
|
946
|
+
return this._interruptElement;
|
|
947
|
+
}
|
|
948
|
+
setInterruptElement(element) {
|
|
949
|
+
this._interruptElement = element;
|
|
950
|
+
this.notifySubscribers((subscriber) => {
|
|
951
|
+
var _reactSubscriber$onIn;
|
|
952
|
+
const reactSubscriber = subscriber;
|
|
953
|
+
(_reactSubscriber$onIn = reactSubscriber.onInterruptElementChanged) === null || _reactSubscriber$onIn === void 0 || _reactSubscriber$onIn.call(reactSubscriber, {
|
|
954
|
+
copilotkit: this,
|
|
955
|
+
interruptElement: this._interruptElement
|
|
956
|
+
});
|
|
957
|
+
}, "Subscriber onInterruptElementChanged error:");
|
|
958
|
+
}
|
|
959
|
+
subscribe(subscriber) {
|
|
960
|
+
return super.subscribe(subscriber);
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Wait for pending React state updates before the follow-up agent run.
|
|
964
|
+
*
|
|
965
|
+
* When a frontend tool handler calls setState(), React 18 batches the update
|
|
966
|
+
* and schedules a commit via its internal scheduler (MessageChannel). The
|
|
967
|
+
* useAgentContext hook registers context via useLayoutEffect, which runs
|
|
968
|
+
* synchronously after React commits that batch.
|
|
969
|
+
*
|
|
970
|
+
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
971
|
+
* MessageChannel task runs first, committing the pending state and running
|
|
972
|
+
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
973
|
+
* call then reads fresh context.
|
|
974
|
+
*/
|
|
975
|
+
async waitForPendingFrameworkUpdates() {
|
|
976
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
//#endregion
|
|
981
|
+
//#region src/v2/providers/CopilotKitProvider.tsx
|
|
982
|
+
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
983
|
+
const COPILOT_CLOUD_CHAT_URL$1 = "https://api.cloud.copilotkit.ai/copilotkit/v1";
|
|
984
|
+
const CopilotKitContext = (0, react.createContext)({
|
|
985
|
+
copilotkit: null,
|
|
986
|
+
executingToolCallIds: /* @__PURE__ */ new Set()
|
|
987
|
+
});
|
|
988
|
+
const LicenseContext = (0, react.createContext)((0, _copilotkit_shared.createLicenseContextValue)(null));
|
|
989
|
+
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
990
|
+
const empty = (0, react.useMemo)(() => [], []);
|
|
991
|
+
const value = prop !== null && prop !== void 0 ? prop : empty;
|
|
992
|
+
const initial = (0, react.useRef)(value);
|
|
993
|
+
(0, react.useEffect)(() => {
|
|
994
|
+
if (warningMessage && value !== initial.current && (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)) console.error(warningMessage);
|
|
995
|
+
}, [value, warningMessage]);
|
|
996
|
+
return value;
|
|
997
|
+
}
|
|
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 }) => {
|
|
999
|
+
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
|
|
1000
|
+
const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
|
|
1001
|
+
const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
|
|
1002
|
+
(0, react.useEffect)(() => {
|
|
1003
|
+
if (typeof window === "undefined") return;
|
|
1004
|
+
if (showDevConsole === true) setShouldRenderInspector(true);
|
|
1005
|
+
else if (showDevConsole === "auto") if (new Set(["localhost", "127.0.0.1"]).has(window.location.hostname)) setShouldRenderInspector(true);
|
|
1006
|
+
else setShouldRenderInspector(false);
|
|
1007
|
+
else setShouldRenderInspector(false);
|
|
1008
|
+
}, [showDevConsole]);
|
|
1009
|
+
const renderToolCallsList = useStableArrayProp(renderToolCalls, "renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.", (initial, next) => {
|
|
1010
|
+
const key = (rc) => {
|
|
1011
|
+
var _rc$agentId, _rc$name;
|
|
1012
|
+
return `${(_rc$agentId = rc === null || rc === void 0 ? void 0 : rc.agentId) !== null && _rc$agentId !== void 0 ? _rc$agentId : ""}:${(_rc$name = rc === null || rc === void 0 ? void 0 : rc.name) !== null && _rc$name !== void 0 ? _rc$name : ""}`;
|
|
1013
|
+
};
|
|
1014
|
+
const setFrom = (arr) => new Set(arr.map(key));
|
|
1015
|
+
const a = setFrom(initial);
|
|
1016
|
+
const b = setFrom(next);
|
|
1017
|
+
if (a.size !== b.size) return true;
|
|
1018
|
+
for (const k of a) if (!b.has(k)) return true;
|
|
1019
|
+
return false;
|
|
1020
|
+
});
|
|
1021
|
+
const renderCustomMessagesList = useStableArrayProp(renderCustomMessages, "renderCustomMessages must be a stable array.");
|
|
1022
|
+
const renderActivityMessagesList = useStableArrayProp(renderActivityMessages, "renderActivityMessages must be a stable array.");
|
|
1023
|
+
const builtInActivityRenderers = (0, react.useMemo)(() => {
|
|
1024
|
+
const renderers = [{
|
|
1025
|
+
activityType: MCPAppsActivityType,
|
|
1026
|
+
content: MCPAppsActivityContentSchema,
|
|
1027
|
+
render: MCPAppsActivityRenderer
|
|
1028
|
+
}];
|
|
1029
|
+
if (runtimeA2UIEnabled) {
|
|
1030
|
+
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 }));
|
|
1032
|
+
}
|
|
1033
|
+
return renderers;
|
|
1034
|
+
}, [runtimeA2UIEnabled, a2ui]);
|
|
1035
|
+
const allActivityRenderers = (0, react.useMemo)(() => {
|
|
1036
|
+
return [...renderActivityMessagesList, ...builtInActivityRenderers];
|
|
1037
|
+
}, [renderActivityMessagesList, builtInActivityRenderers]);
|
|
1038
|
+
const resolvedPublicKey = publicApiKey !== null && publicApiKey !== void 0 ? publicApiKey : publicLicenseKey;
|
|
1039
|
+
const mergedAgents = (0, react.useMemo)(() => ({
|
|
1040
|
+
...agents,
|
|
1041
|
+
...selfManagedAgents
|
|
1042
|
+
}), [agents, selfManagedAgents]);
|
|
1043
|
+
const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
|
|
1044
|
+
const mergedHeaders = (0, react.useMemo)(() => {
|
|
1045
|
+
if (!resolvedPublicKey) return headers;
|
|
1046
|
+
if (headers[HEADER_NAME]) return headers;
|
|
1047
|
+
return {
|
|
1048
|
+
...headers,
|
|
1049
|
+
[HEADER_NAME]: resolvedPublicKey
|
|
1050
|
+
};
|
|
1051
|
+
}, [headers, resolvedPublicKey]);
|
|
1052
|
+
if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {
|
|
1053
|
+
const message = "Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'";
|
|
1054
|
+
if (process.env.NODE_ENV === "production") throw new Error(message);
|
|
1055
|
+
else console.warn(message);
|
|
1056
|
+
}
|
|
1057
|
+
const chatApiEndpoint = runtimeUrl !== null && runtimeUrl !== void 0 ? runtimeUrl : resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL$1 : void 0;
|
|
1058
|
+
const frontendToolsList = useStableArrayProp(frontendTools, "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.");
|
|
1059
|
+
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.");
|
|
1060
|
+
const processedHumanInTheLoopTools = (0, react.useMemo)(() => {
|
|
1061
|
+
const processedTools = [];
|
|
1062
|
+
const processedRenderToolCalls = [];
|
|
1063
|
+
humanInTheLoopList.forEach((tool) => {
|
|
1064
|
+
const frontendTool = {
|
|
1065
|
+
name: tool.name,
|
|
1066
|
+
description: tool.description,
|
|
1067
|
+
parameters: tool.parameters,
|
|
1068
|
+
followUp: tool.followUp,
|
|
1069
|
+
...tool.agentId && { agentId: tool.agentId },
|
|
1070
|
+
handler: async () => {
|
|
1071
|
+
return new Promise((resolve) => {
|
|
1072
|
+
console.warn(`Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`);
|
|
1073
|
+
resolve(void 0);
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
processedTools.push(frontendTool);
|
|
1078
|
+
if (tool.render) processedRenderToolCalls.push({
|
|
1079
|
+
name: tool.name,
|
|
1080
|
+
args: tool.parameters,
|
|
1081
|
+
render: tool.render,
|
|
1082
|
+
...tool.agentId && { agentId: tool.agentId }
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
1085
|
+
return {
|
|
1086
|
+
tools: processedTools,
|
|
1087
|
+
renderToolCalls: processedRenderToolCalls
|
|
1088
|
+
};
|
|
1089
|
+
}, [humanInTheLoopList]);
|
|
1090
|
+
const allTools = (0, react.useMemo)(() => {
|
|
1091
|
+
const tools = [];
|
|
1092
|
+
tools.push(...frontendToolsList);
|
|
1093
|
+
tools.push(...processedHumanInTheLoopTools.tools);
|
|
1094
|
+
return tools;
|
|
1095
|
+
}, [frontendToolsList, processedHumanInTheLoopTools]);
|
|
1096
|
+
const allRenderToolCalls = (0, react.useMemo)(() => {
|
|
1097
|
+
const combined = [...renderToolCallsList];
|
|
1098
|
+
frontendToolsList.forEach((tool) => {
|
|
1099
|
+
if (tool.render) {
|
|
1100
|
+
const args = tool.parameters || (tool.name === "*" ? zod.z.any() : void 0);
|
|
1101
|
+
if (args) combined.push({
|
|
1102
|
+
name: tool.name,
|
|
1103
|
+
args,
|
|
1104
|
+
render: tool.render
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
combined.push(...processedHumanInTheLoopTools.renderToolCalls);
|
|
1109
|
+
return combined;
|
|
1110
|
+
}, [
|
|
1111
|
+
renderToolCallsList,
|
|
1112
|
+
frontendToolsList,
|
|
1113
|
+
processedHumanInTheLoopTools
|
|
1114
|
+
]);
|
|
1115
|
+
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
|
+
});
|
|
1128
|
+
const copilotkit = copilotkitRef.current;
|
|
1129
|
+
(0, react.useEffect)(() => {
|
|
1130
|
+
const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
1131
|
+
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
1132
|
+
setRuntimeLicenseStatus(copilotkit.licenseStatus);
|
|
1133
|
+
} });
|
|
1134
|
+
return () => {
|
|
1135
|
+
subscription.unsubscribe();
|
|
1136
|
+
};
|
|
1137
|
+
}, [copilotkit]);
|
|
1138
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1139
|
+
(0, react.useEffect)(() => {
|
|
1140
|
+
const subscription = copilotkit.subscribe({ onRenderToolCallsChanged: () => {
|
|
1141
|
+
forceUpdate();
|
|
1142
|
+
} });
|
|
1143
|
+
return () => {
|
|
1144
|
+
subscription.unsubscribe();
|
|
1145
|
+
};
|
|
1146
|
+
}, [copilotkit]);
|
|
1147
|
+
const [executingToolCallIds, setExecutingToolCallIds] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
1148
|
+
(0, react.useEffect)(() => {
|
|
1149
|
+
const subscription = copilotkit.subscribe({
|
|
1150
|
+
onToolExecutionStart: ({ toolCallId }) => {
|
|
1151
|
+
setExecutingToolCallIds((prev) => {
|
|
1152
|
+
if (prev.has(toolCallId)) return prev;
|
|
1153
|
+
const next = new Set(prev);
|
|
1154
|
+
next.add(toolCallId);
|
|
1155
|
+
return next;
|
|
1156
|
+
});
|
|
1157
|
+
},
|
|
1158
|
+
onToolExecutionEnd: ({ toolCallId }) => {
|
|
1159
|
+
setExecutingToolCallIds((prev) => {
|
|
1160
|
+
if (!prev.has(toolCallId)) return prev;
|
|
1161
|
+
const next = new Set(prev);
|
|
1162
|
+
next.delete(toolCallId);
|
|
1163
|
+
return next;
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
return () => {
|
|
1168
|
+
subscription.unsubscribe();
|
|
1169
|
+
};
|
|
1170
|
+
}, [copilotkit]);
|
|
1171
|
+
const onErrorRef = (0, react.useRef)(onError);
|
|
1172
|
+
(0, react.useEffect)(() => {
|
|
1173
|
+
onErrorRef.current = onError;
|
|
1174
|
+
}, [onError]);
|
|
1175
|
+
(0, react.useEffect)(() => {
|
|
1176
|
+
if (!onErrorRef.current) return;
|
|
1177
|
+
const subscription = copilotkit.subscribe({ onError: (event) => {
|
|
1178
|
+
var _onErrorRef$current;
|
|
1179
|
+
(_onErrorRef$current = onErrorRef.current) === null || _onErrorRef$current === void 0 || _onErrorRef$current.call(onErrorRef, {
|
|
1180
|
+
error: event.error,
|
|
1181
|
+
code: event.code,
|
|
1182
|
+
context: event.context
|
|
1183
|
+
});
|
|
1184
|
+
} });
|
|
1185
|
+
return () => {
|
|
1186
|
+
subscription.unsubscribe();
|
|
1187
|
+
};
|
|
1188
|
+
}, [copilotkit]);
|
|
1189
|
+
(0, react.useEffect)(() => {
|
|
1190
|
+
copilotkit.setRuntimeUrl(chatApiEndpoint);
|
|
1191
|
+
copilotkit.setRuntimeTransport(useSingleEndpoint ? "single" : "rest");
|
|
1192
|
+
copilotkit.setHeaders(mergedHeaders);
|
|
1193
|
+
copilotkit.setCredentials(credentials);
|
|
1194
|
+
copilotkit.setProperties(properties);
|
|
1195
|
+
copilotkit.setAgents__unsafe_dev_only(mergedAgents);
|
|
1196
|
+
}, [
|
|
1197
|
+
copilotkit,
|
|
1198
|
+
chatApiEndpoint,
|
|
1199
|
+
mergedHeaders,
|
|
1200
|
+
credentials,
|
|
1201
|
+
properties,
|
|
1202
|
+
mergedAgents,
|
|
1203
|
+
useSingleEndpoint
|
|
1204
|
+
]);
|
|
1205
|
+
const didMountRef = (0, react.useRef)(false);
|
|
1206
|
+
(0, react.useEffect)(() => {
|
|
1207
|
+
if (!didMountRef.current) return;
|
|
1208
|
+
copilotkit.setTools(allTools);
|
|
1209
|
+
}, [copilotkit, allTools]);
|
|
1210
|
+
(0, react.useEffect)(() => {
|
|
1211
|
+
if (!didMountRef.current) return;
|
|
1212
|
+
copilotkit.setRenderToolCalls(allRenderToolCalls);
|
|
1213
|
+
}, [copilotkit, allRenderToolCalls]);
|
|
1214
|
+
(0, react.useEffect)(() => {
|
|
1215
|
+
if (!didMountRef.current) return;
|
|
1216
|
+
copilotkit.setRenderActivityMessages(allActivityRenderers);
|
|
1217
|
+
}, [copilotkit, allActivityRenderers]);
|
|
1218
|
+
(0, react.useEffect)(() => {
|
|
1219
|
+
if (!didMountRef.current) return;
|
|
1220
|
+
copilotkit.setRenderCustomMessages(renderCustomMessagesList);
|
|
1221
|
+
}, [copilotkit, renderCustomMessagesList]);
|
|
1222
|
+
(0, react.useEffect)(() => {
|
|
1223
|
+
didMountRef.current = true;
|
|
1224
|
+
}, []);
|
|
1225
|
+
const contextValue = (0, react.useMemo)(() => ({
|
|
1226
|
+
copilotkit,
|
|
1227
|
+
executingToolCallIds
|
|
1228
|
+
}), [copilotkit, executingToolCallIds]);
|
|
1229
|
+
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
|
+
]
|
|
1242
|
+
})
|
|
1243
|
+
});
|
|
1244
|
+
};
|
|
1245
|
+
const useCopilotKit = () => {
|
|
1246
|
+
const context = (0, react.useContext)(CopilotKitContext);
|
|
1247
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1248
|
+
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1249
|
+
(0, react.useEffect)(() => {
|
|
1250
|
+
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
1251
|
+
forceUpdate();
|
|
1252
|
+
} });
|
|
1253
|
+
return () => {
|
|
1254
|
+
subscription.unsubscribe();
|
|
1255
|
+
};
|
|
1256
|
+
}, []);
|
|
1257
|
+
return context;
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
//#endregion
|
|
1261
|
+
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
1262
|
+
/**
|
|
1263
|
+
* Memoized component that renders a single tool call.
|
|
1264
|
+
* This prevents unnecessary re-renders when parent components update
|
|
1265
|
+
* but the tool call data hasn't changed.
|
|
1266
|
+
*/
|
|
1267
|
+
const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
1268
|
+
const args = (0, react.useMemo)(() => (0, _copilotkit_shared.partialJSONParse)(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
1269
|
+
const toolName = toolCall.function.name;
|
|
1270
|
+
if (toolMessage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1271
|
+
name: toolName,
|
|
1272
|
+
args,
|
|
1273
|
+
status: _copilotkit_core.ToolCallStatus.Complete,
|
|
1274
|
+
result: toolMessage.content
|
|
1275
|
+
});
|
|
1276
|
+
else if (isExecuting) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1277
|
+
name: toolName,
|
|
1278
|
+
args,
|
|
1279
|
+
status: _copilotkit_core.ToolCallStatus.Executing,
|
|
1280
|
+
result: void 0
|
|
1281
|
+
});
|
|
1282
|
+
else return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1283
|
+
name: toolName,
|
|
1284
|
+
args,
|
|
1285
|
+
status: _copilotkit_core.ToolCallStatus.InProgress,
|
|
1286
|
+
result: void 0
|
|
1287
|
+
});
|
|
1288
|
+
}, (prevProps, nextProps) => {
|
|
1289
|
+
var _prevProps$toolMessag, _nextProps$toolMessag;
|
|
1290
|
+
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
1291
|
+
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
1292
|
+
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
1293
|
+
if (((_prevProps$toolMessag = prevProps.toolMessage) === null || _prevProps$toolMessag === void 0 ? void 0 : _prevProps$toolMessag.content) !== ((_nextProps$toolMessag = nextProps.toolMessage) === null || _nextProps$toolMessag === void 0 ? void 0 : _nextProps$toolMessag.content)) return false;
|
|
1294
|
+
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
1295
|
+
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
1296
|
+
return true;
|
|
1297
|
+
});
|
|
1298
|
+
/**
|
|
1299
|
+
* Hook that returns a function to render tool calls based on the render functions
|
|
1300
|
+
* defined in CopilotKitProvider.
|
|
1301
|
+
*
|
|
1302
|
+
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
1303
|
+
*/
|
|
1304
|
+
function useRenderToolCall$1() {
|
|
1305
|
+
var _config$agentId;
|
|
1306
|
+
const { copilotkit, executingToolCallIds } = useCopilotKit();
|
|
1307
|
+
const config = useCopilotChatConfiguration();
|
|
1308
|
+
const agentId = (_config$agentId = config === null || config === void 0 ? void 0 : config.agentId) !== null && _config$agentId !== void 0 ? _config$agentId : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1309
|
+
const renderToolCalls = (0, react.useSyncExternalStore)((callback) => {
|
|
1310
|
+
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
1311
|
+
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1312
|
+
return (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1313
|
+
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1314
|
+
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1315
|
+
if (!renderConfig) return null;
|
|
1316
|
+
const RenderComponent = renderConfig.render;
|
|
1317
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
1318
|
+
toolCall,
|
|
1319
|
+
toolMessage,
|
|
1320
|
+
RenderComponent,
|
|
1321
|
+
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
1322
|
+
}, toolCall.id);
|
|
1323
|
+
}, [
|
|
1324
|
+
renderToolCalls,
|
|
1325
|
+
executingToolCallIds,
|
|
1326
|
+
agentId
|
|
1327
|
+
]);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
//#endregion
|
|
1331
|
+
//#region src/v2/hooks/use-render-custom-messages.tsx
|
|
1332
|
+
function useRenderCustomMessages() {
|
|
1333
|
+
const { copilotkit } = useCopilotKit();
|
|
1334
|
+
const config = useCopilotChatConfiguration();
|
|
1335
|
+
if (!config) return null;
|
|
1336
|
+
const { agentId, threadId } = config;
|
|
1337
|
+
const customMessageRenderers = copilotkit.renderCustomMessages.filter((renderer) => renderer.agentId === void 0 || renderer.agentId === agentId).sort((a, b) => {
|
|
1338
|
+
const aHasAgent = a.agentId !== void 0;
|
|
1339
|
+
if (aHasAgent === (b.agentId !== void 0)) return 0;
|
|
1340
|
+
return aHasAgent ? -1 : 1;
|
|
1341
|
+
});
|
|
1342
|
+
return function(params) {
|
|
1343
|
+
var _copilotkit$getRunIdF;
|
|
1344
|
+
if (!customMessageRenderers.length) return null;
|
|
1345
|
+
const { message, position } = params;
|
|
1346
|
+
const resolvedRunId = (_copilotkit$getRunIdF = copilotkit.getRunIdForMessage(agentId, threadId, message.id)) !== null && _copilotkit$getRunIdF !== void 0 ? _copilotkit$getRunIdF : copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
1347
|
+
const runId = resolvedRunId !== null && resolvedRunId !== void 0 ? resolvedRunId : `missing-run-id:${message.id}`;
|
|
1348
|
+
const agent = copilotkit.getAgent(agentId);
|
|
1349
|
+
if (!agent) throw new Error("Agent not found");
|
|
1350
|
+
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
1351
|
+
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
1352
|
+
const messageIndex = rawMessageIndex >= 0 ? rawMessageIndex : 0;
|
|
1353
|
+
const messageIndexInRun = resolvedRunId ? Math.max(messagesIdsInRun.indexOf(message.id), 0) : 0;
|
|
1354
|
+
const numberOfMessagesInRun = resolvedRunId ? messagesIdsInRun.length : 1;
|
|
1355
|
+
const stateSnapshot = resolvedRunId ? copilotkit.getStateByRun(agentId, threadId, resolvedRunId) : void 0;
|
|
1356
|
+
let result = null;
|
|
1357
|
+
for (const renderer of customMessageRenderers) {
|
|
1358
|
+
if (!renderer.render) continue;
|
|
1359
|
+
const Component = renderer.render;
|
|
1360
|
+
result = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
1361
|
+
message,
|
|
1362
|
+
position,
|
|
1363
|
+
runId,
|
|
1364
|
+
messageIndex,
|
|
1365
|
+
messageIndexInRun,
|
|
1366
|
+
numberOfMessagesInRun,
|
|
1367
|
+
agentId,
|
|
1368
|
+
stateSnapshot
|
|
1369
|
+
}, `${runId}-${message.id}-${position}`);
|
|
1370
|
+
if (result) break;
|
|
1371
|
+
}
|
|
1372
|
+
return result;
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
//#endregion
|
|
1377
|
+
//#region src/v2/hooks/use-frontend-tool.tsx
|
|
1378
|
+
const EMPTY_DEPS = [];
|
|
1379
|
+
function useFrontendTool$1(tool, deps) {
|
|
1380
|
+
const { copilotkit } = useCopilotKit();
|
|
1381
|
+
const extraDeps = deps !== null && deps !== void 0 ? deps : EMPTY_DEPS;
|
|
1382
|
+
(0, react.useEffect)(() => {
|
|
1383
|
+
const name = tool.name;
|
|
1384
|
+
if (copilotkit.getTool({
|
|
1385
|
+
toolName: name,
|
|
1386
|
+
agentId: tool.agentId
|
|
1387
|
+
})) {
|
|
1388
|
+
console.warn(`Tool '${name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`);
|
|
1389
|
+
copilotkit.removeTool(name, tool.agentId);
|
|
1390
|
+
}
|
|
1391
|
+
copilotkit.addTool(tool);
|
|
1392
|
+
if (tool.render && tool.parameters) copilotkit.addHookRenderToolCall({
|
|
1393
|
+
name,
|
|
1394
|
+
args: tool.parameters,
|
|
1395
|
+
agentId: tool.agentId,
|
|
1396
|
+
render: tool.render
|
|
1397
|
+
});
|
|
1398
|
+
return () => {
|
|
1399
|
+
copilotkit.removeTool(name, tool.agentId);
|
|
1400
|
+
};
|
|
1401
|
+
}, [
|
|
1402
|
+
tool.name,
|
|
1403
|
+
tool.available,
|
|
1404
|
+
copilotkit,
|
|
1405
|
+
extraDeps.length,
|
|
1406
|
+
...extraDeps
|
|
1407
|
+
]);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
//#endregion
|
|
1411
|
+
//#region src/v2/types/defineToolCallRenderer.ts
|
|
1412
|
+
function defineToolCallRenderer(def) {
|
|
1413
|
+
const argsSchema = def.name === "*" && !def.args ? zod.z.any() : def.args;
|
|
1414
|
+
return {
|
|
1415
|
+
name: def.name,
|
|
1416
|
+
args: argsSchema,
|
|
1417
|
+
render: def.render,
|
|
1418
|
+
...def.agentId ? { agentId: def.agentId } : {}
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
//#endregion
|
|
1423
|
+
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
1424
|
+
function useHumanInTheLoop$1(tool, deps) {
|
|
1425
|
+
const { copilotkit } = useCopilotKit();
|
|
1426
|
+
const resolvePromiseRef = (0, react.useRef)(null);
|
|
1427
|
+
const respond = (0, react.useCallback)(async (result) => {
|
|
1428
|
+
if (resolvePromiseRef.current) {
|
|
1429
|
+
resolvePromiseRef.current(result);
|
|
1430
|
+
resolvePromiseRef.current = null;
|
|
1431
|
+
}
|
|
1432
|
+
}, []);
|
|
1433
|
+
const handler = (0, react.useCallback)(async () => {
|
|
1434
|
+
return new Promise((resolve) => {
|
|
1435
|
+
resolvePromiseRef.current = resolve;
|
|
1436
|
+
});
|
|
1437
|
+
}, []);
|
|
1438
|
+
const RenderComponent = (0, react.useCallback)((props) => {
|
|
1439
|
+
const ToolComponent = tool.render;
|
|
1440
|
+
if (props.status === "inProgress") {
|
|
1441
|
+
const enhancedProps = {
|
|
1442
|
+
...props,
|
|
1443
|
+
name: tool.name,
|
|
1444
|
+
description: tool.description || "",
|
|
1445
|
+
respond: void 0
|
|
1446
|
+
};
|
|
1447
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
1448
|
+
} else if (props.status === "executing") {
|
|
1449
|
+
const enhancedProps = {
|
|
1450
|
+
...props,
|
|
1451
|
+
name: tool.name,
|
|
1452
|
+
description: tool.description || "",
|
|
1453
|
+
respond
|
|
1454
|
+
};
|
|
1455
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
1456
|
+
} else if (props.status === "complete") {
|
|
1457
|
+
const enhancedProps = {
|
|
1458
|
+
...props,
|
|
1459
|
+
name: tool.name,
|
|
1460
|
+
description: tool.description || "",
|
|
1461
|
+
respond: void 0
|
|
1462
|
+
};
|
|
1463
|
+
return react.default.createElement(ToolComponent, enhancedProps);
|
|
1464
|
+
}
|
|
1465
|
+
return react.default.createElement(ToolComponent, props);
|
|
1466
|
+
}, [
|
|
1467
|
+
tool.render,
|
|
1468
|
+
tool.name,
|
|
1469
|
+
tool.description,
|
|
1470
|
+
respond
|
|
1471
|
+
]);
|
|
1472
|
+
useFrontendTool$1({
|
|
1473
|
+
...tool,
|
|
1474
|
+
handler,
|
|
1475
|
+
render: RenderComponent
|
|
1476
|
+
}, deps);
|
|
1477
|
+
(0, react.useEffect)(() => {
|
|
1478
|
+
return () => {
|
|
1479
|
+
copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
|
|
1480
|
+
};
|
|
1481
|
+
}, [
|
|
1482
|
+
copilotkit,
|
|
1483
|
+
tool.name,
|
|
1484
|
+
tool.agentId
|
|
1485
|
+
]);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
//#endregion
|
|
1489
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
1490
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
1491
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
1492
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
1493
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
1494
|
+
return UseAgentUpdate;
|
|
1495
|
+
}({});
|
|
1496
|
+
const ALL_UPDATES = [
|
|
1497
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
1498
|
+
UseAgentUpdate.OnStateChanged,
|
|
1499
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
1500
|
+
];
|
|
1501
|
+
function useAgent({ agentId, updates } = {}) {
|
|
1502
|
+
var _agentId;
|
|
1503
|
+
(_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
|
|
1504
|
+
const { copilotkit } = useCopilotKit();
|
|
1505
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1506
|
+
const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
|
|
1507
|
+
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
1508
|
+
const agent = (0, react.useMemo)(() => {
|
|
1509
|
+
var _copilotkit$agents;
|
|
1510
|
+
const existing = copilotkit.getAgent(agentId);
|
|
1511
|
+
if (existing) {
|
|
1512
|
+
provisionalAgentCache.current.delete(agentId);
|
|
1513
|
+
return existing;
|
|
1514
|
+
}
|
|
1515
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
1516
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
1517
|
+
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
1518
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
1519
|
+
if (cached) {
|
|
1520
|
+
cached.headers = { ...copilotkit.headers };
|
|
1521
|
+
return cached;
|
|
1522
|
+
}
|
|
1523
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
1524
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
1525
|
+
agentId,
|
|
1526
|
+
transport: copilotkit.runtimeTransport,
|
|
1527
|
+
runtimeMode: "pending"
|
|
1528
|
+
});
|
|
1529
|
+
provisional.headers = { ...copilotkit.headers };
|
|
1530
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
1531
|
+
return provisional;
|
|
1532
|
+
}
|
|
1533
|
+
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
1534
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
1535
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
1536
|
+
agentId,
|
|
1537
|
+
transport: copilotkit.runtimeTransport,
|
|
1538
|
+
runtimeMode: "pending"
|
|
1539
|
+
});
|
|
1540
|
+
provisional.headers = { ...copilotkit.headers };
|
|
1541
|
+
return provisional;
|
|
1542
|
+
}
|
|
1543
|
+
const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
|
|
1544
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
1545
|
+
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
1546
|
+
}, [
|
|
1547
|
+
agentId,
|
|
1548
|
+
copilotkit.agents,
|
|
1549
|
+
copilotkit.runtimeConnectionStatus,
|
|
1550
|
+
copilotkit.runtimeUrl,
|
|
1551
|
+
copilotkit.runtimeTransport,
|
|
1552
|
+
JSON.stringify(copilotkit.headers)
|
|
1553
|
+
]);
|
|
1554
|
+
(0, react.useEffect)(() => {
|
|
1555
|
+
if (updateFlags.length === 0) return;
|
|
1556
|
+
const handlers = {};
|
|
1557
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = () => {
|
|
1558
|
+
forceUpdate();
|
|
1559
|
+
};
|
|
1560
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = forceUpdate;
|
|
1561
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
1562
|
+
handlers.onRunInitialized = forceUpdate;
|
|
1563
|
+
handlers.onRunFinalized = forceUpdate;
|
|
1564
|
+
handlers.onRunFailed = forceUpdate;
|
|
1565
|
+
}
|
|
1566
|
+
const subscription = agent.subscribe(handlers);
|
|
1567
|
+
return () => subscription.unsubscribe();
|
|
1568
|
+
}, [
|
|
1569
|
+
agent,
|
|
1570
|
+
forceUpdate,
|
|
1571
|
+
JSON.stringify(updateFlags)
|
|
1572
|
+
]);
|
|
1573
|
+
return { agent };
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
//#endregion
|
|
1577
|
+
//#region src/v2/hooks/use-suggestions.tsx
|
|
1578
|
+
function useSuggestions({ agentId } = {}) {
|
|
1579
|
+
const { copilotkit } = useCopilotKit();
|
|
1580
|
+
const config = useCopilotChatConfiguration();
|
|
1581
|
+
const resolvedAgentId = (0, react.useMemo)(() => {
|
|
1582
|
+
var _ref;
|
|
1583
|
+
return (_ref = agentId !== null && agentId !== void 0 ? agentId : config === null || config === void 0 ? void 0 : config.agentId) !== null && _ref !== void 0 ? _ref : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1584
|
+
}, [agentId, config === null || config === void 0 ? void 0 : config.agentId]);
|
|
1585
|
+
const [suggestions, setSuggestions] = (0, react.useState)(() => {
|
|
1586
|
+
return copilotkit.getSuggestions(resolvedAgentId).suggestions;
|
|
1587
|
+
});
|
|
1588
|
+
const [isLoading, setIsLoading] = (0, react.useState)(() => {
|
|
1589
|
+
return copilotkit.getSuggestions(resolvedAgentId).isLoading;
|
|
1590
|
+
});
|
|
1591
|
+
(0, react.useEffect)(() => {
|
|
1592
|
+
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1593
|
+
setSuggestions(result.suggestions);
|
|
1594
|
+
setIsLoading(result.isLoading);
|
|
1595
|
+
}, [copilotkit, resolvedAgentId]);
|
|
1596
|
+
(0, react.useEffect)(() => {
|
|
1597
|
+
const subscription = copilotkit.subscribe({
|
|
1598
|
+
onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {
|
|
1599
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1600
|
+
setSuggestions(suggestions);
|
|
1601
|
+
},
|
|
1602
|
+
onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {
|
|
1603
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1604
|
+
setIsLoading(true);
|
|
1605
|
+
},
|
|
1606
|
+
onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {
|
|
1607
|
+
if (changedAgentId !== resolvedAgentId) return;
|
|
1608
|
+
setIsLoading(false);
|
|
1609
|
+
},
|
|
1610
|
+
onSuggestionsConfigChanged: () => {
|
|
1611
|
+
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1612
|
+
setSuggestions(result.suggestions);
|
|
1613
|
+
setIsLoading(result.isLoading);
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
return () => {
|
|
1617
|
+
subscription.unsubscribe();
|
|
1618
|
+
};
|
|
1619
|
+
}, [copilotkit, resolvedAgentId]);
|
|
1620
|
+
return {
|
|
1621
|
+
suggestions,
|
|
1622
|
+
reloadSuggestions: (0, react.useCallback)(() => {
|
|
1623
|
+
copilotkit.reloadSuggestions(resolvedAgentId);
|
|
1624
|
+
}, [copilotkit, resolvedAgentId]),
|
|
1625
|
+
clearSuggestions: (0, react.useCallback)(() => {
|
|
1626
|
+
copilotkit.clearSuggestions(resolvedAgentId);
|
|
1627
|
+
}, [copilotkit, resolvedAgentId]),
|
|
1628
|
+
isLoading
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
//#endregion
|
|
1633
|
+
//#region src/v2/hooks/use-configure-suggestions.tsx
|
|
1634
|
+
function useConfigureSuggestions(config, deps) {
|
|
1635
|
+
const { copilotkit } = useCopilotKit();
|
|
1636
|
+
const chatConfig = useCopilotChatConfiguration();
|
|
1637
|
+
const extraDeps = deps !== null && deps !== void 0 ? deps : [];
|
|
1638
|
+
const resolvedConsumerAgentId = (0, react.useMemo)(() => {
|
|
1639
|
+
var _chatConfig$agentId;
|
|
1640
|
+
return (_chatConfig$agentId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.agentId) !== null && _chatConfig$agentId !== void 0 ? _chatConfig$agentId : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1641
|
+
}, [chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.agentId]);
|
|
1642
|
+
const rawConsumerAgentId = (0, react.useMemo)(() => config ? config.consumerAgentId : void 0, [config]);
|
|
1643
|
+
const normalizationCacheRef = (0, react.useRef)({
|
|
1644
|
+
serialized: null,
|
|
1645
|
+
config: null
|
|
1646
|
+
});
|
|
1647
|
+
const { normalizedConfig, serializedConfig } = (0, react.useMemo)(() => {
|
|
1648
|
+
if (!config) {
|
|
1649
|
+
normalizationCacheRef.current = {
|
|
1650
|
+
serialized: null,
|
|
1651
|
+
config: null
|
|
1652
|
+
};
|
|
1653
|
+
return {
|
|
1654
|
+
normalizedConfig: null,
|
|
1655
|
+
serializedConfig: null
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
if (config.available === "disabled") {
|
|
1659
|
+
normalizationCacheRef.current = {
|
|
1660
|
+
serialized: null,
|
|
1661
|
+
config: null
|
|
1662
|
+
};
|
|
1663
|
+
return {
|
|
1664
|
+
normalizedConfig: null,
|
|
1665
|
+
serializedConfig: null
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
let built;
|
|
1669
|
+
if (isDynamicConfig(config)) built = { ...config };
|
|
1670
|
+
else {
|
|
1671
|
+
const normalizedSuggestions = normalizeStaticSuggestions(config.suggestions);
|
|
1672
|
+
built = {
|
|
1673
|
+
...config,
|
|
1674
|
+
suggestions: normalizedSuggestions
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
const serialized = JSON.stringify(built);
|
|
1678
|
+
const cache = normalizationCacheRef.current;
|
|
1679
|
+
if (cache.serialized === serialized && cache.config) return {
|
|
1680
|
+
normalizedConfig: cache.config,
|
|
1681
|
+
serializedConfig: serialized
|
|
1682
|
+
};
|
|
1683
|
+
normalizationCacheRef.current = {
|
|
1684
|
+
serialized,
|
|
1685
|
+
config: built
|
|
1686
|
+
};
|
|
1687
|
+
return {
|
|
1688
|
+
normalizedConfig: built,
|
|
1689
|
+
serializedConfig: serialized
|
|
1690
|
+
};
|
|
1691
|
+
}, [
|
|
1692
|
+
config,
|
|
1693
|
+
resolvedConsumerAgentId,
|
|
1694
|
+
...extraDeps
|
|
1695
|
+
]);
|
|
1696
|
+
const latestConfigRef = (0, react.useRef)(null);
|
|
1697
|
+
latestConfigRef.current = normalizedConfig;
|
|
1698
|
+
const previousSerializedConfigRef = (0, react.useRef)(null);
|
|
1699
|
+
const targetAgentId = (0, react.useMemo)(() => {
|
|
1700
|
+
if (!normalizedConfig) return resolvedConsumerAgentId;
|
|
1701
|
+
const consumer = normalizedConfig.consumerAgentId;
|
|
1702
|
+
if (!consumer || consumer === "*") return resolvedConsumerAgentId;
|
|
1703
|
+
return consumer;
|
|
1704
|
+
}, [normalizedConfig, resolvedConsumerAgentId]);
|
|
1705
|
+
const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
|
|
1706
|
+
const requestReload = (0, react.useCallback)(() => {
|
|
1707
|
+
if (!normalizedConfig) return;
|
|
1708
|
+
if (isGlobalConfig) {
|
|
1709
|
+
var _copilotkit$agents;
|
|
1710
|
+
const agents = Object.values((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
|
|
1711
|
+
for (const entry of agents) {
|
|
1712
|
+
const agentId = entry.agentId;
|
|
1713
|
+
if (!agentId) continue;
|
|
1714
|
+
if (!entry.isRunning) copilotkit.reloadSuggestions(agentId);
|
|
1715
|
+
}
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
if (!targetAgentId) return;
|
|
1719
|
+
copilotkit.reloadSuggestions(targetAgentId);
|
|
1720
|
+
}, [
|
|
1721
|
+
copilotkit,
|
|
1722
|
+
isGlobalConfig,
|
|
1723
|
+
normalizedConfig,
|
|
1724
|
+
targetAgentId
|
|
1725
|
+
]);
|
|
1726
|
+
(0, react.useEffect)(() => {
|
|
1727
|
+
if (!serializedConfig || !latestConfigRef.current) return;
|
|
1728
|
+
const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);
|
|
1729
|
+
requestReload();
|
|
1730
|
+
return () => {
|
|
1731
|
+
copilotkit.removeSuggestionsConfig(id);
|
|
1732
|
+
};
|
|
1733
|
+
}, [
|
|
1734
|
+
copilotkit,
|
|
1735
|
+
serializedConfig,
|
|
1736
|
+
requestReload
|
|
1737
|
+
]);
|
|
1738
|
+
(0, react.useEffect)(() => {
|
|
1739
|
+
if (!normalizedConfig) {
|
|
1740
|
+
previousSerializedConfigRef.current = null;
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
if (serializedConfig && previousSerializedConfigRef.current === serializedConfig) return;
|
|
1744
|
+
if (serializedConfig) previousSerializedConfigRef.current = serializedConfig;
|
|
1745
|
+
requestReload();
|
|
1746
|
+
}, [
|
|
1747
|
+
normalizedConfig,
|
|
1748
|
+
requestReload,
|
|
1749
|
+
serializedConfig
|
|
1750
|
+
]);
|
|
1751
|
+
(0, react.useEffect)(() => {
|
|
1752
|
+
if (!normalizedConfig || extraDeps.length === 0) return;
|
|
1753
|
+
requestReload();
|
|
1754
|
+
}, [
|
|
1755
|
+
extraDeps.length,
|
|
1756
|
+
normalizedConfig,
|
|
1757
|
+
requestReload,
|
|
1758
|
+
...extraDeps
|
|
1759
|
+
]);
|
|
1760
|
+
}
|
|
1761
|
+
function isDynamicConfig(config) {
|
|
1762
|
+
return "instructions" in config;
|
|
1763
|
+
}
|
|
1764
|
+
function normalizeStaticSuggestions(suggestions) {
|
|
1765
|
+
return suggestions.map((suggestion) => {
|
|
1766
|
+
var _suggestion$isLoading;
|
|
1767
|
+
return {
|
|
1768
|
+
...suggestion,
|
|
1769
|
+
isLoading: (_suggestion$isLoading = suggestion.isLoading) !== null && _suggestion$isLoading !== void 0 ? _suggestion$isLoading : false
|
|
1770
|
+
};
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
//#endregion
|
|
1775
|
+
//#region src/v2/hooks/use-interrupt.tsx
|
|
1776
|
+
const INTERRUPT_EVENT_NAME = "on_interrupt";
|
|
1777
|
+
function isPromiseLike(value) {
|
|
1778
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.
|
|
1782
|
+
*
|
|
1783
|
+
* The hook listens to custom events on the active agent, stores interrupt payloads per run,
|
|
1784
|
+
* and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume
|
|
1785
|
+
* execution with user-provided data.
|
|
1786
|
+
*
|
|
1787
|
+
* - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.
|
|
1788
|
+
* - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.
|
|
1789
|
+
*
|
|
1790
|
+
* `event.value` is typed as `any` since the interrupt payload shape depends on your agent.
|
|
1791
|
+
* Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.
|
|
1792
|
+
*
|
|
1793
|
+
* @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.
|
|
1794
|
+
* @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).
|
|
1795
|
+
* @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).
|
|
1796
|
+
* Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always
|
|
1797
|
+
* either the handler's resolved return value or `null` (including when no handler is provided,
|
|
1798
|
+
* when filtering skips the interrupt, or when handler execution fails).
|
|
1799
|
+
*
|
|
1800
|
+
* @example
|
|
1801
|
+
* ```tsx
|
|
1802
|
+
* import { useInterrupt } from "@copilotkit/react-core/v2";
|
|
1803
|
+
*
|
|
1804
|
+
* function InterruptUI() {
|
|
1805
|
+
* useInterrupt({
|
|
1806
|
+
* render: ({ event, resolve }) => (
|
|
1807
|
+
* <div>
|
|
1808
|
+
* <p>{event.value.question}</p>
|
|
1809
|
+
* <button onClick={() => resolve({ approved: true })}>Approve</button>
|
|
1810
|
+
* <button onClick={() => resolve({ approved: false })}>Reject</button>
|
|
1811
|
+
* </div>
|
|
1812
|
+
* ),
|
|
1813
|
+
* });
|
|
1814
|
+
*
|
|
1815
|
+
* return null;
|
|
1816
|
+
* }
|
|
1817
|
+
* ```
|
|
1818
|
+
*
|
|
1819
|
+
* @example
|
|
1820
|
+
* ```tsx
|
|
1821
|
+
* import { useInterrupt } from "@copilotkit/react-core/v2";
|
|
1822
|
+
*
|
|
1823
|
+
* function CustomPanel() {
|
|
1824
|
+
* const interruptElement = useInterrupt({
|
|
1825
|
+
* renderInChat: false,
|
|
1826
|
+
* enabled: (event) => event.value.startsWith("approval:"),
|
|
1827
|
+
* handler: async ({ event }) => ({ label: event.value.toUpperCase() }),
|
|
1828
|
+
* render: ({ event, result, resolve }) => (
|
|
1829
|
+
* <aside>
|
|
1830
|
+
* <strong>{result?.label ?? ""}</strong>
|
|
1831
|
+
* <button onClick={() => resolve({ value: event.value })}>Continue</button>
|
|
1832
|
+
* </aside>
|
|
1833
|
+
* ),
|
|
1834
|
+
* });
|
|
1835
|
+
*
|
|
1836
|
+
* return <>{interruptElement}</>;
|
|
1837
|
+
* }
|
|
1838
|
+
* ```
|
|
1839
|
+
*/
|
|
1840
|
+
function useInterrupt(config) {
|
|
1841
|
+
const { copilotkit } = useCopilotKit();
|
|
1842
|
+
const { agent } = useAgent({ agentId: config.agentId });
|
|
1843
|
+
const [pendingEvent, setPendingEvent] = (0, react.useState)(null);
|
|
1844
|
+
const pendingEventRef = (0, react.useRef)(pendingEvent);
|
|
1845
|
+
pendingEventRef.current = pendingEvent;
|
|
1846
|
+
const [handlerResult, setHandlerResult] = (0, react.useState)(null);
|
|
1847
|
+
(0, react.useEffect)(() => {
|
|
1848
|
+
let localInterrupt = null;
|
|
1849
|
+
const subscription = agent.subscribe({
|
|
1850
|
+
onCustomEvent: ({ event }) => {
|
|
1851
|
+
if (event.name === INTERRUPT_EVENT_NAME) localInterrupt = {
|
|
1852
|
+
name: event.name,
|
|
1853
|
+
value: event.value
|
|
1854
|
+
};
|
|
1855
|
+
},
|
|
1856
|
+
onRunStartedEvent: () => {
|
|
1857
|
+
localInterrupt = null;
|
|
1858
|
+
setPendingEvent(null);
|
|
1859
|
+
},
|
|
1860
|
+
onRunFinalized: () => {
|
|
1861
|
+
if (localInterrupt) {
|
|
1862
|
+
setPendingEvent(localInterrupt);
|
|
1863
|
+
localInterrupt = null;
|
|
1864
|
+
}
|
|
1865
|
+
},
|
|
1866
|
+
onRunFailed: () => {
|
|
1867
|
+
localInterrupt = null;
|
|
1868
|
+
}
|
|
1869
|
+
});
|
|
1870
|
+
return () => subscription.unsubscribe();
|
|
1871
|
+
}, [agent]);
|
|
1872
|
+
const resolve = (0, react.useCallback)((response) => {
|
|
1873
|
+
var _pendingEventRef$curr;
|
|
1874
|
+
setPendingEvent(null);
|
|
1875
|
+
copilotkit.runAgent({
|
|
1876
|
+
agent,
|
|
1877
|
+
forwardedProps: { command: {
|
|
1878
|
+
resume: response,
|
|
1879
|
+
interruptEvent: (_pendingEventRef$curr = pendingEventRef.current) === null || _pendingEventRef$curr === void 0 ? void 0 : _pendingEventRef$curr.value
|
|
1880
|
+
} }
|
|
1881
|
+
});
|
|
1882
|
+
}, [agent, copilotkit]);
|
|
1883
|
+
(0, react.useEffect)(() => {
|
|
1884
|
+
if (!pendingEvent) {
|
|
1885
|
+
setHandlerResult(null);
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
if (config.enabled && !config.enabled(pendingEvent)) {
|
|
1889
|
+
setHandlerResult(null);
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
const handler = config.handler;
|
|
1893
|
+
if (!handler) {
|
|
1894
|
+
setHandlerResult(null);
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
let cancelled = false;
|
|
1898
|
+
const maybePromise = handler({
|
|
1899
|
+
event: pendingEvent,
|
|
1900
|
+
resolve
|
|
1901
|
+
});
|
|
1902
|
+
if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => {
|
|
1903
|
+
if (!cancelled) setHandlerResult(resolved);
|
|
1904
|
+
}).catch(() => {
|
|
1905
|
+
if (!cancelled) setHandlerResult(null);
|
|
1906
|
+
});
|
|
1907
|
+
else setHandlerResult(maybePromise);
|
|
1908
|
+
return () => {
|
|
1909
|
+
cancelled = true;
|
|
1910
|
+
};
|
|
1911
|
+
}, [
|
|
1912
|
+
pendingEvent,
|
|
1913
|
+
config.enabled,
|
|
1914
|
+
config.handler,
|
|
1915
|
+
resolve
|
|
1916
|
+
]);
|
|
1917
|
+
const element = (0, react.useMemo)(() => {
|
|
1918
|
+
if (!pendingEvent) return null;
|
|
1919
|
+
if (config.enabled && !config.enabled(pendingEvent)) return null;
|
|
1920
|
+
return config.render({
|
|
1921
|
+
event: pendingEvent,
|
|
1922
|
+
result: handlerResult,
|
|
1923
|
+
resolve
|
|
1924
|
+
});
|
|
1925
|
+
}, [
|
|
1926
|
+
pendingEvent,
|
|
1927
|
+
handlerResult,
|
|
1928
|
+
config.enabled,
|
|
1929
|
+
config.render,
|
|
1930
|
+
resolve
|
|
1931
|
+
]);
|
|
1932
|
+
(0, react.useEffect)(() => {
|
|
1933
|
+
if (config.renderInChat === false) return;
|
|
1934
|
+
copilotkit.setInterruptElement(element);
|
|
1935
|
+
return () => copilotkit.setInterruptElement(null);
|
|
1936
|
+
}, [
|
|
1937
|
+
element,
|
|
1938
|
+
config.renderInChat,
|
|
1939
|
+
copilotkit
|
|
1940
|
+
]);
|
|
1941
|
+
if (config.renderInChat === false) return element;
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
//#endregion
|
|
39
1945
|
//#region src/context/copilot-context.tsx
|
|
40
1946
|
const emptyCopilotContext$1 = {
|
|
41
1947
|
actions: {},
|
|
@@ -1454,7 +3360,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
1454
3360
|
var _props$runId;
|
|
1455
3361
|
const { stateSnapshot, message } = props;
|
|
1456
3362
|
const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();
|
|
1457
|
-
const { agent } =
|
|
3363
|
+
const { agent } = useAgent({ agentId });
|
|
1458
3364
|
const [nodeName, setNodeName] = (0, react.useState)(void 0);
|
|
1459
3365
|
const [, forceUpdate] = (0, react.useState)(0);
|
|
1460
3366
|
(0, react.useEffect)(() => {
|
|
@@ -1563,11 +3469,11 @@ react_markdown = __toESM(react_markdown);
|
|
|
1563
3469
|
}, [agent, getSubscriber]);
|
|
1564
3470
|
};
|
|
1565
3471
|
function CopilotListeners() {
|
|
1566
|
-
const { copilotkit } =
|
|
1567
|
-
const existingConfig =
|
|
3472
|
+
const { copilotkit } = useCopilotKit();
|
|
3473
|
+
const existingConfig = useCopilotChatConfiguration();
|
|
1568
3474
|
const resolvedAgentId = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId;
|
|
1569
3475
|
const { setBannerError } = useToast();
|
|
1570
|
-
const { agent } =
|
|
3476
|
+
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
1571
3477
|
usePredictStateSubscription(agent);
|
|
1572
3478
|
(0, react.useEffect)(() => {
|
|
1573
3479
|
const subscription = copilotkit.subscribe({ onError: ({ error }) => {
|
|
@@ -1614,7 +3520,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
1614
3520
|
showUsageBanner: enabled,
|
|
1615
3521
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadsProvider, {
|
|
1616
3522
|
threadId: props.threadId,
|
|
1617
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3523
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitProvider, {
|
|
1618
3524
|
...props,
|
|
1619
3525
|
showDevConsole: showInspector,
|
|
1620
3526
|
renderCustomMessages: renderArr,
|
|
@@ -1635,7 +3541,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
1635
3541
|
* Chat components are rendered.
|
|
1636
3542
|
*/
|
|
1637
3543
|
function CopilotKitErrorBridge() {
|
|
1638
|
-
const { copilotkit } =
|
|
3544
|
+
const { copilotkit } = useCopilotKit();
|
|
1639
3545
|
const { onError, copilotApiConfig } = useCopilotContext();
|
|
1640
3546
|
(0, react.useEffect)(() => {
|
|
1641
3547
|
if (!copilotkit) return;
|
|
@@ -2053,7 +3959,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2053
3959
|
setInternalErrorHandler,
|
|
2054
3960
|
removeInternalErrorHandler
|
|
2055
3961
|
]);
|
|
2056
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3962
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
2057
3963
|
agentId: (_props$agent2 = props.agent) !== null && _props$agent2 !== void 0 ? _props$agent2 : "default",
|
|
2058
3964
|
threadId,
|
|
2059
3965
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotContext.Provider, {
|
|
@@ -2108,7 +4014,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2108
4014
|
//#endregion
|
|
2109
4015
|
//#region src/hooks/use-lazy-tool-renderer.tsx
|
|
2110
4016
|
function useLazyToolRenderer() {
|
|
2111
|
-
const renderToolCall =
|
|
4017
|
+
const renderToolCall = useRenderToolCall$1();
|
|
2112
4018
|
return (0, react.useCallback)((message, messages) => {
|
|
2113
4019
|
var _message$toolCalls;
|
|
2114
4020
|
if (!(message === null || message === void 0 || (_message$toolCalls = message.toolCalls) === null || _message$toolCalls === void 0 ? void 0 : _message$toolCalls.length)) return null;
|
|
@@ -2126,12 +4032,12 @@ react_markdown = __toESM(react_markdown);
|
|
|
2126
4032
|
//#region src/hooks/use-copilot-chat_internal.ts
|
|
2127
4033
|
function useCopilotChatInternal({ suggestions, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages } = {}) {
|
|
2128
4034
|
var _existingConfig$agent, _existingConfig$threa, _agent$messages5;
|
|
2129
|
-
const { copilotkit } =
|
|
4035
|
+
const { copilotkit } = useCopilotKit();
|
|
2130
4036
|
const { threadId, agentSession } = useCopilotContext();
|
|
2131
|
-
const existingConfig =
|
|
4037
|
+
const existingConfig = useCopilotChatConfiguration();
|
|
2132
4038
|
const [agentAvailable, setAgentAvailable] = (0, react.useState)(false);
|
|
2133
4039
|
const resolvedAgentId = (_existingConfig$agent = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _existingConfig$agent !== void 0 ? _existingConfig$agent : "default";
|
|
2134
|
-
const { agent } =
|
|
4040
|
+
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
2135
4041
|
(0, react.useEffect)(() => {
|
|
2136
4042
|
let detached = false;
|
|
2137
4043
|
const connectAbortController = new AbortController();
|
|
@@ -2146,7 +4052,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2146
4052
|
if (error instanceof _ag_ui_client.AGUIConnectNotImplementedError) {} else console.error("CopilotChat: connectAgent failed", error);
|
|
2147
4053
|
}
|
|
2148
4054
|
};
|
|
2149
|
-
if (agent && (existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId) && agent.threadId !== existingConfig.threadId && copilotkit.runtimeConnectionStatus ===
|
|
4055
|
+
if (agent && (existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId) && agent.threadId !== existingConfig.threadId && copilotkit.runtimeConnectionStatus === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected) {
|
|
2150
4056
|
agent.threadId = existingConfig.threadId;
|
|
2151
4057
|
connect(agent);
|
|
2152
4058
|
}
|
|
@@ -2185,7 +4091,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2185
4091
|
const latestDeleteFunc = (0, react.useCallback)((messageId) => {
|
|
2186
4092
|
return latestDelete.current(messageId);
|
|
2187
4093
|
}, [latestDelete]);
|
|
2188
|
-
const currentSuggestions =
|
|
4094
|
+
const currentSuggestions = useSuggestions({ agentId: resolvedAgentId });
|
|
2189
4095
|
const reload = useAsyncCallback(async (reloadMessageId) => {
|
|
2190
4096
|
var _agent$messages2;
|
|
2191
4097
|
if (!agent) return;
|
|
@@ -2285,7 +4191,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2285
4191
|
return latestReset.current();
|
|
2286
4192
|
}, [latestReset]);
|
|
2287
4193
|
const lazyToolRendered = useLazyToolRenderer();
|
|
2288
|
-
const renderCustomMessage =
|
|
4194
|
+
const renderCustomMessage = useRenderCustomMessages();
|
|
2289
4195
|
const legacyCustomMessageRenderer = useLegacyCoagentRenderer({
|
|
2290
4196
|
copilotkit,
|
|
2291
4197
|
agent,
|
|
@@ -2776,7 +4682,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2776
4682
|
(0, react.useEffect)(() => {
|
|
2777
4683
|
handlerRef.current = tool.handler;
|
|
2778
4684
|
}, [tool.handler, ...dependencies !== null && dependencies !== void 0 ? dependencies : []]);
|
|
2779
|
-
|
|
4685
|
+
useFrontendTool$1({
|
|
2780
4686
|
name,
|
|
2781
4687
|
description,
|
|
2782
4688
|
parameters: zodParameters,
|
|
@@ -2793,12 +4699,12 @@ react_markdown = __toESM(react_markdown);
|
|
|
2793
4699
|
//#endregion
|
|
2794
4700
|
//#region src/hooks/use-render-tool-call.ts
|
|
2795
4701
|
function useRenderToolCall(tool, dependencies) {
|
|
2796
|
-
const { copilotkit } =
|
|
4702
|
+
const { copilotkit } = useCopilotKit();
|
|
2797
4703
|
const hasAddedRef = (0, react.useRef)(false);
|
|
2798
4704
|
(0, react.useEffect)(() => {
|
|
2799
4705
|
const { name, parameters, render } = tool;
|
|
2800
4706
|
const zodParameters = (0, _copilotkit_shared.getZodParameters)(parameters);
|
|
2801
|
-
const renderToolCall = name === "*" ?
|
|
4707
|
+
const renderToolCall = name === "*" ? defineToolCallRenderer({
|
|
2802
4708
|
name: "*",
|
|
2803
4709
|
render: ((args) => {
|
|
2804
4710
|
return render({
|
|
@@ -2806,7 +4712,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2806
4712
|
result: args.result ? (0, _copilotkit_shared.parseJson)(args.result, args.result) : args.result
|
|
2807
4713
|
});
|
|
2808
4714
|
})
|
|
2809
|
-
}) :
|
|
4715
|
+
}) : defineToolCallRenderer({
|
|
2810
4716
|
name,
|
|
2811
4717
|
args: zodParameters,
|
|
2812
4718
|
render: ((args) => {
|
|
@@ -2844,19 +4750,19 @@ react_markdown = __toESM(react_markdown);
|
|
|
2844
4750
|
const rendered = render((() => {
|
|
2845
4751
|
const mappedArgs = args.args;
|
|
2846
4752
|
switch (args.status) {
|
|
2847
|
-
case
|
|
4753
|
+
case _copilotkit_core.ToolCallStatus.InProgress: return {
|
|
2848
4754
|
args: mappedArgs,
|
|
2849
4755
|
respond: args.respond,
|
|
2850
4756
|
status: args.status,
|
|
2851
4757
|
handler: void 0
|
|
2852
4758
|
};
|
|
2853
|
-
case
|
|
4759
|
+
case _copilotkit_core.ToolCallStatus.Executing: return {
|
|
2854
4760
|
args: mappedArgs,
|
|
2855
4761
|
respond: args.respond,
|
|
2856
4762
|
status: args.status,
|
|
2857
4763
|
handler: () => {}
|
|
2858
4764
|
};
|
|
2859
|
-
case
|
|
4765
|
+
case _copilotkit_core.ToolCallStatus.Complete: return {
|
|
2860
4766
|
args: mappedArgs,
|
|
2861
4767
|
respond: args.respond,
|
|
2862
4768
|
status: args.status,
|
|
@@ -2873,7 +4779,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
2873
4779
|
return rendered !== null && rendered !== void 0 ? rendered : null;
|
|
2874
4780
|
};
|
|
2875
4781
|
}, [render, ...dependencies !== null && dependencies !== void 0 ? dependencies : []]);
|
|
2876
|
-
|
|
4782
|
+
useHumanInTheLoop$1({
|
|
2877
4783
|
name,
|
|
2878
4784
|
description,
|
|
2879
4785
|
followUp,
|
|
@@ -3287,7 +5193,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
3287
5193
|
* Adds the given information to the Copilot context to make it readable by Copilot.
|
|
3288
5194
|
*/
|
|
3289
5195
|
function useCopilotReadable({ description, value, convert, available }, dependencies) {
|
|
3290
|
-
const { copilotkit } =
|
|
5196
|
+
const { copilotkit } = useCopilotKit();
|
|
3291
5197
|
const ctxIdRef = (0, react.useRef)(void 0);
|
|
3292
5198
|
(0, react.useEffect)(() => {
|
|
3293
5199
|
if (!copilotkit) return;
|
|
@@ -3322,7 +5228,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
3322
5228
|
//#endregion
|
|
3323
5229
|
//#region src/hooks/use-agent-nodename.ts
|
|
3324
5230
|
function useAgentNodeName(agentName) {
|
|
3325
|
-
const { agent } =
|
|
5231
|
+
const { agent } = useAgent({ agentId: agentName });
|
|
3326
5232
|
const nodeNameRef = (0, react.useRef)("start");
|
|
3327
5233
|
(0, react.useEffect)(() => {
|
|
3328
5234
|
if (!agent) return;
|
|
@@ -3442,8 +5348,8 @@ react_markdown = __toESM(react_markdown);
|
|
|
3442
5348
|
* we refer to as CoAgents, checkout the documentation at https://docs.copilotkit.ai/coagents/quickstart/langgraph.
|
|
3443
5349
|
*/
|
|
3444
5350
|
function useCoAgent(options) {
|
|
3445
|
-
const { agent } =
|
|
3446
|
-
const { copilotkit } =
|
|
5351
|
+
const { agent } = useAgent({ agentId: options.name });
|
|
5352
|
+
const { copilotkit } = useCopilotKit();
|
|
3447
5353
|
const nodeName = useAgentNodeName(options.name);
|
|
3448
5354
|
const handleStateUpdate = (0, react.useCallback)((newState) => {
|
|
3449
5355
|
if (!agent) return;
|
|
@@ -3721,7 +5627,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
3721
5627
|
var _ref, _action$agentId;
|
|
3722
5628
|
const actionRef = (0, react.useRef)(action);
|
|
3723
5629
|
actionRef.current = action;
|
|
3724
|
-
const existingConfig =
|
|
5630
|
+
const existingConfig = useCopilotChatConfiguration();
|
|
3725
5631
|
const resolvedAgentId = (_ref = (_action$agentId = action.agentId) !== null && _action$agentId !== void 0 ? _action$agentId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _ref !== void 0 ? _ref : "default";
|
|
3726
5632
|
const threadId = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId;
|
|
3727
5633
|
const nodeName = useAgentNodeName(resolvedAgentId);
|
|
@@ -3735,7 +5641,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
3735
5641
|
threadId,
|
|
3736
5642
|
nodeName
|
|
3737
5643
|
};
|
|
3738
|
-
|
|
5644
|
+
useInterrupt({
|
|
3739
5645
|
render: (0, react.useCallback)(({ event, result, resolve }) => {
|
|
3740
5646
|
const renderFn = actionRef.current.render;
|
|
3741
5647
|
if (!renderFn) return react.default.createElement(react.default.Fragment);
|
|
@@ -3897,10 +5803,10 @@ react_markdown = __toESM(react_markdown);
|
|
|
3897
5803
|
*/
|
|
3898
5804
|
function useCopilotChatSuggestions(config, dependencies = []) {
|
|
3899
5805
|
var _existingConfig$agent, _ref;
|
|
3900
|
-
const existingConfig =
|
|
5806
|
+
const existingConfig = useCopilotChatConfiguration();
|
|
3901
5807
|
const resolvedAgentId = (_existingConfig$agent = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _existingConfig$agent !== void 0 ? _existingConfig$agent : "default";
|
|
3902
5808
|
const available = (_ref = config.available === "enabled" ? "always" : config.available) !== null && _ref !== void 0 ? _ref : "before-first-message";
|
|
3903
|
-
|
|
5809
|
+
useConfigureSuggestions({
|
|
3904
5810
|
...config,
|
|
3905
5811
|
available,
|
|
3906
5812
|
consumerAgentId: resolvedAgentId
|
|
@@ -3971,7 +5877,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
3971
5877
|
* }
|
|
3972
5878
|
* ```
|
|
3973
5879
|
*
|
|
3974
|
-
* Have a look at the [Presentation Example App](https://github.com/CopilotKit/CopilotKit/blob/main/
|
|
5880
|
+
* Have a look at the [Presentation Example App](https://github.com/CopilotKit/CopilotKit/blob/main/examples/v1/next-openai/src/app/presentation/page.tsx) for a more complete example.
|
|
3975
5881
|
*/
|
|
3976
5882
|
var CopilotTask = class {
|
|
3977
5883
|
constructor(config) {
|