@copilotkit/react-core 1.69.3 → 1.70.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{copilotkit-CrNUgJiq.d.cts → copilotkit-CtF2clxZ.d.cts} +50 -23
- package/dist/copilotkit-CtF2clxZ.d.cts.map +1 -0
- package/dist/{copilotkit-BPeh62mW.cjs → copilotkit-CxLT6zFx.cjs} +214 -230
- package/dist/copilotkit-CxLT6zFx.cjs.map +1 -0
- package/dist/{copilotkit-JdHy0xdu.mjs → copilotkit-DiUK2Bhq.mjs} +209 -231
- package/dist/copilotkit-DiUK2Bhq.mjs.map +1 -0
- package/dist/{copilotkit-DgO31tBq.d.mts → copilotkit-DsWuxPUQ.d.mts} +50 -23
- package/dist/copilotkit-DsWuxPUQ.d.mts.map +1 -0
- package/dist/index.cjs +97 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +18 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +97 -24
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +275 -239
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +16 -8
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.d.cts.map +1 -1
- package/dist/v2/headless.d.mts.map +1 -1
- package/dist/v2/headless.mjs +16 -8
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +2 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/index.umd.js +208 -229
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +13 -10
- package/skills/react-core/SKILL.md +1 -1
- package/skills/react-core/references/threads.md +1 -1
- package/dist/copilotkit-BPeh62mW.cjs.map +0 -1
- package/dist/copilotkit-CrNUgJiq.d.cts.map +0 -1
- package/dist/copilotkit-DgO31tBq.d.mts.map +0 -1
- package/dist/copilotkit-JdHy0xdu.mjs.map +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -688,7 +688,6 @@ react_markdown = __toESM(react_markdown);
|
|
|
688
688
|
newMessages: []
|
|
689
689
|
};
|
|
690
690
|
}
|
|
691
|
-
const PROTOCOL_VERSION = "2025-06-18";
|
|
692
691
|
function buildSandboxHTML(extraCspDomains) {
|
|
693
692
|
const baseScriptSrc = "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*";
|
|
694
693
|
const baseFrameSrc = "* blob: data: http://localhost:* https://localhost:*";
|
|
@@ -800,6 +799,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
800
799
|
}
|
|
801
800
|
};
|
|
802
801
|
const mcpAppsRequestQueue = new MCPAppsRequestQueue();
|
|
802
|
+
const MCP_OPEN_LINK_BLOCKED_SCHEMES = new Set([
|
|
803
|
+
"javascript:",
|
|
804
|
+
"data:",
|
|
805
|
+
"vbscript:",
|
|
806
|
+
"blob:",
|
|
807
|
+
"file:"
|
|
808
|
+
]);
|
|
803
809
|
/**
|
|
804
810
|
* Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType
|
|
805
811
|
*/
|
|
@@ -815,18 +821,32 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
815
821
|
serverId: zod.z.string().optional(),
|
|
816
822
|
toolInput: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
817
823
|
});
|
|
818
|
-
function isRequest(msg) {
|
|
819
|
-
return "id" in msg && "method" in msg;
|
|
820
|
-
}
|
|
821
|
-
function isNotification(msg) {
|
|
822
|
-
return !("id" in msg) && "method" in msg;
|
|
823
|
-
}
|
|
824
824
|
/**
|
|
825
825
|
* MCP Apps Extension Activity Renderer
|
|
826
826
|
*
|
|
827
827
|
* Renders MCP Apps UI in a sandboxed iframe with full protocol support.
|
|
828
828
|
* Fetches resource content on-demand via proxied MCP requests.
|
|
829
829
|
*/
|
|
830
|
+
/**
|
|
831
|
+
* Permissive `ui/message` schema. ext-apps restricts the request to
|
|
832
|
+
* `role: "user"` with no `followUp`, but CopilotKit intentionally extends
|
|
833
|
+
* `ui/message` with `role` ("user" | "assistant") and `followUp` (documented
|
|
834
|
+
* behavior with dedicated tests). We register our own handler (instead of the
|
|
835
|
+
* bridge's strict `onmessage`) so those extensions survive the migration.
|
|
836
|
+
*
|
|
837
|
+
* Going forward, widgets SHOULD pass the extensions under
|
|
838
|
+
* `params._meta.copilotkit`; the top-level `role`/`followUp` fields are the
|
|
839
|
+
* legacy channel, kept for backward compatibility and slated for deprecation.
|
|
840
|
+
*/
|
|
841
|
+
const CopilotKitUiMessageSchema = zod.z.object({
|
|
842
|
+
method: zod.z.literal("ui/message"),
|
|
843
|
+
params: zod.z.object({
|
|
844
|
+
role: zod.z.string().optional(),
|
|
845
|
+
content: zod.z.array(zod.z.any()).optional(),
|
|
846
|
+
followUp: zod.z.boolean().optional(),
|
|
847
|
+
_meta: zod.z.record(zod.z.string(), zod.z.any()).optional()
|
|
848
|
+
}).passthrough()
|
|
849
|
+
});
|
|
830
850
|
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, agent }) {
|
|
831
851
|
const { copilotkit } = useCopilotKit();
|
|
832
852
|
const containerRef = (0, react.useRef)(null);
|
|
@@ -840,41 +860,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
840
860
|
contentRef.current = content;
|
|
841
861
|
const agentRef = (0, react.useRef)(agent);
|
|
842
862
|
agentRef.current = agent;
|
|
863
|
+
const bridgeRef = (0, react.useRef)(null);
|
|
843
864
|
const fetchStateRef = (0, react.useRef)({
|
|
844
865
|
inProgress: false,
|
|
845
866
|
promise: null,
|
|
846
867
|
resourceUri: null
|
|
847
868
|
});
|
|
848
|
-
const sendToIframe = (0, react.useCallback)((msg) => {
|
|
849
|
-
if (iframeRef.current?.contentWindow) {
|
|
850
|
-
console.log("[MCPAppsRenderer] Sending to iframe:", msg);
|
|
851
|
-
iframeRef.current.contentWindow.postMessage(msg, "*");
|
|
852
|
-
}
|
|
853
|
-
}, []);
|
|
854
|
-
const sendResponse = (0, react.useCallback)((id, result) => {
|
|
855
|
-
sendToIframe({
|
|
856
|
-
jsonrpc: "2.0",
|
|
857
|
-
id,
|
|
858
|
-
result
|
|
859
|
-
});
|
|
860
|
-
}, [sendToIframe]);
|
|
861
|
-
const sendErrorResponse = (0, react.useCallback)((id, code, message) => {
|
|
862
|
-
sendToIframe({
|
|
863
|
-
jsonrpc: "2.0",
|
|
864
|
-
id,
|
|
865
|
-
error: {
|
|
866
|
-
code,
|
|
867
|
-
message
|
|
868
|
-
}
|
|
869
|
-
});
|
|
870
|
-
}, [sendToIframe]);
|
|
871
|
-
const sendNotification = (0, react.useCallback)((method, params) => {
|
|
872
|
-
sendToIframe({
|
|
873
|
-
jsonrpc: "2.0",
|
|
874
|
-
method,
|
|
875
|
-
params: params || {}
|
|
876
|
-
});
|
|
877
|
-
}, [sendToIframe]);
|
|
878
869
|
(0, react.useEffect)(() => {
|
|
879
870
|
const { resourceUri, serverHash, serverId } = content;
|
|
880
871
|
if (fetchStateRef.current.inProgress && fetchStateRef.current.resourceUri === resourceUri) {
|
|
@@ -929,11 +920,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
929
920
|
const container = containerRef.current;
|
|
930
921
|
if (!container) return;
|
|
931
922
|
let mounted = true;
|
|
932
|
-
let
|
|
933
|
-
let initialListener = null;
|
|
923
|
+
let bridge = null;
|
|
934
924
|
let createdIframe = null;
|
|
935
925
|
const setup = async () => {
|
|
936
926
|
try {
|
|
927
|
+
const bridgeModule = await import("@modelcontextprotocol/ext-apps/app-bridge").catch((importErr) => {
|
|
928
|
+
throw new Error("MCP Apps require '@modelcontextprotocol/ext-apps' and its peer '@modelcontextprotocol/sdk'. Install them with: npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk", { cause: importErr });
|
|
929
|
+
});
|
|
930
|
+
if (!mounted) return;
|
|
931
|
+
const { AppBridge, PostMessageTransport } = bridgeModule;
|
|
937
932
|
const iframe = document.createElement("iframe");
|
|
938
933
|
createdIframe = iframe;
|
|
939
934
|
iframe.style.width = "100%";
|
|
@@ -944,151 +939,108 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
944
939
|
iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
945
940
|
iframe.setAttribute("data-testid", "mcp-app-iframe");
|
|
946
941
|
iframe.setAttribute("title", "Interactive MCP application");
|
|
947
|
-
const sandboxReady = new Promise((resolve) => {
|
|
948
|
-
initialListener = (event) => {
|
|
949
|
-
if (event.source === iframe.contentWindow) {
|
|
950
|
-
if (event.data?.method === "ui/notifications/sandbox-proxy-ready") {
|
|
951
|
-
if (initialListener) {
|
|
952
|
-
window.removeEventListener("message", initialListener);
|
|
953
|
-
initialListener = null;
|
|
954
|
-
}
|
|
955
|
-
resolve();
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
};
|
|
959
|
-
window.addEventListener("message", initialListener);
|
|
960
|
-
});
|
|
961
|
-
if (!mounted) {
|
|
962
|
-
if (initialListener) {
|
|
963
|
-
window.removeEventListener("message", initialListener);
|
|
964
|
-
initialListener = null;
|
|
965
|
-
}
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
968
942
|
const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;
|
|
969
943
|
iframe.srcdoc = buildSandboxHTML(cspDomains);
|
|
970
944
|
iframeRef.current = iframe;
|
|
971
945
|
container.appendChild(iframe);
|
|
972
|
-
|
|
973
|
-
if (!
|
|
974
|
-
console.log("[MCPAppsRenderer] Sandbox proxy ready");
|
|
975
|
-
messageHandler = async (event) => {
|
|
976
|
-
if (event.source !== iframe.contentWindow) return;
|
|
977
|
-
const msg = event.data;
|
|
978
|
-
if (!msg || typeof msg !== "object" || msg.jsonrpc !== "2.0") return;
|
|
979
|
-
console.log("[MCPAppsRenderer] Received from iframe:", msg);
|
|
980
|
-
if (isRequest(msg)) switch (msg.method) {
|
|
981
|
-
case "ui/initialize":
|
|
982
|
-
sendResponse(msg.id, {
|
|
983
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
984
|
-
hostInfo: {
|
|
985
|
-
name: "CopilotKit MCP Apps Host",
|
|
986
|
-
version: "1.0.0"
|
|
987
|
-
},
|
|
988
|
-
hostCapabilities: {
|
|
989
|
-
openLinks: {},
|
|
990
|
-
logging: {}
|
|
991
|
-
},
|
|
992
|
-
hostContext: {
|
|
993
|
-
theme: "light",
|
|
994
|
-
platform: "web"
|
|
995
|
-
}
|
|
996
|
-
});
|
|
997
|
-
break;
|
|
998
|
-
case "ui/message": {
|
|
999
|
-
const currentAgent = agentRef.current;
|
|
1000
|
-
if (!currentAgent) {
|
|
1001
|
-
console.warn("[MCPAppsRenderer] ui/message: No agent available");
|
|
1002
|
-
sendResponse(msg.id, { isError: false });
|
|
1003
|
-
break;
|
|
1004
|
-
}
|
|
1005
|
-
try {
|
|
1006
|
-
const params = msg.params;
|
|
1007
|
-
const role = params.role || "user";
|
|
1008
|
-
const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
|
|
1009
|
-
if (textContent) currentAgent.addMessage({
|
|
1010
|
-
id: crypto.randomUUID(),
|
|
1011
|
-
role,
|
|
1012
|
-
content: textContent
|
|
1013
|
-
});
|
|
1014
|
-
sendResponse(msg.id, { isError: false });
|
|
1015
|
-
if ((params.followUp ?? role === "user") && textContent) {
|
|
1016
|
-
const capturedThreadId = currentAgent.threadId || "default";
|
|
1017
|
-
mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
|
|
1018
|
-
host: copilotkit,
|
|
1019
|
-
agent: currentAgent,
|
|
1020
|
-
capturedThreadId
|
|
1021
|
-
})).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
|
|
1022
|
-
}
|
|
1023
|
-
} catch (err) {
|
|
1024
|
-
console.error("[MCPAppsRenderer] ui/message error:", err);
|
|
1025
|
-
sendResponse(msg.id, { isError: true });
|
|
1026
|
-
}
|
|
1027
|
-
break;
|
|
1028
|
-
}
|
|
1029
|
-
case "ui/open-link": {
|
|
1030
|
-
const url = msg.params?.url;
|
|
1031
|
-
if (url) {
|
|
1032
|
-
window.open(url, "_blank", "noopener,noreferrer");
|
|
1033
|
-
sendResponse(msg.id, { isError: false });
|
|
1034
|
-
} else sendErrorResponse(msg.id, -32602, "Missing url parameter");
|
|
1035
|
-
break;
|
|
1036
|
-
}
|
|
1037
|
-
case "tools/call": {
|
|
1038
|
-
const { serverHash, serverId } = contentRef.current;
|
|
1039
|
-
const currentAgent = agentRef.current;
|
|
1040
|
-
if (!serverHash) {
|
|
1041
|
-
sendErrorResponse(msg.id, -32603, "No server hash available for proxying");
|
|
1042
|
-
break;
|
|
1043
|
-
}
|
|
1044
|
-
if (!currentAgent) {
|
|
1045
|
-
sendErrorResponse(msg.id, -32603, "No agent available for proxying");
|
|
1046
|
-
break;
|
|
1047
|
-
}
|
|
1048
|
-
try {
|
|
1049
|
-
const runResult = await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
1050
|
-
serverHash,
|
|
1051
|
-
serverId,
|
|
1052
|
-
method: "tools/call",
|
|
1053
|
-
params: msg.params
|
|
1054
|
-
} } }));
|
|
1055
|
-
sendResponse(msg.id, runResult.result || {});
|
|
1056
|
-
} catch (err) {
|
|
1057
|
-
console.error("[MCPAppsRenderer] tools/call error:", err);
|
|
1058
|
-
sendErrorResponse(msg.id, -32603, String(err));
|
|
1059
|
-
}
|
|
1060
|
-
break;
|
|
1061
|
-
}
|
|
1062
|
-
default: sendErrorResponse(msg.id, -32601, `Method not found: ${msg.method}`);
|
|
1063
|
-
}
|
|
1064
|
-
if (isNotification(msg)) switch (msg.method) {
|
|
1065
|
-
case "ui/notifications/initialized":
|
|
1066
|
-
console.log("[MCPAppsRenderer] Inner iframe initialized");
|
|
1067
|
-
if (mounted) setIframeReady(true);
|
|
1068
|
-
break;
|
|
1069
|
-
case "ui/notifications/size-changed": {
|
|
1070
|
-
const { width, height } = msg.params || {};
|
|
1071
|
-
console.log("[MCPAppsRenderer] Size change:", {
|
|
1072
|
-
width,
|
|
1073
|
-
height
|
|
1074
|
-
});
|
|
1075
|
-
if (mounted) setIframeSize({
|
|
1076
|
-
width: typeof width === "number" ? width : void 0,
|
|
1077
|
-
height: typeof height === "number" ? height : void 0
|
|
1078
|
-
});
|
|
1079
|
-
break;
|
|
1080
|
-
}
|
|
1081
|
-
case "notifications/message":
|
|
1082
|
-
console.log("[MCPAppsRenderer] App log:", msg.params);
|
|
1083
|
-
break;
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
window.addEventListener("message", messageHandler);
|
|
946
|
+
const win = iframe.contentWindow;
|
|
947
|
+
if (!win) throw new Error("Sandbox iframe has no contentWindow");
|
|
1087
948
|
let html;
|
|
1088
949
|
if (fetchedResource.text) html = fetchedResource.text;
|
|
1089
950
|
else if (fetchedResource.blob) html = atob(fetchedResource.blob);
|
|
1090
951
|
else throw new Error("Resource has no text or blob content");
|
|
1091
|
-
|
|
952
|
+
bridge = new AppBridge(null, {
|
|
953
|
+
name: "CopilotKit MCP Apps Host",
|
|
954
|
+
version: "1.0.0"
|
|
955
|
+
}, {
|
|
956
|
+
openLinks: {},
|
|
957
|
+
logging: {},
|
|
958
|
+
message: { text: {} }
|
|
959
|
+
}, { hostContext: {
|
|
960
|
+
theme: "light",
|
|
961
|
+
platform: "web"
|
|
962
|
+
} });
|
|
963
|
+
bridge.onsandboxready = () => {
|
|
964
|
+
bridge?.sendSandboxResourceReady({ html });
|
|
965
|
+
};
|
|
966
|
+
bridge.setRequestHandler(CopilotKitUiMessageSchema, async (req) => {
|
|
967
|
+
const currentAgent = agentRef.current;
|
|
968
|
+
if (!currentAgent) {
|
|
969
|
+
console.warn("[MCPAppsRenderer] ui/message: No agent available");
|
|
970
|
+
return { isError: false };
|
|
971
|
+
}
|
|
972
|
+
try {
|
|
973
|
+
const params = req.params;
|
|
974
|
+
const ck = params._meta?.copilotkit ?? {};
|
|
975
|
+
const role = ck.role || params.role || "user";
|
|
976
|
+
const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
|
|
977
|
+
if (textContent) currentAgent.addMessage({
|
|
978
|
+
id: crypto.randomUUID(),
|
|
979
|
+
role,
|
|
980
|
+
content: textContent
|
|
981
|
+
});
|
|
982
|
+
if ((ck.followUp ?? params.followUp ?? role === "user") && textContent) {
|
|
983
|
+
const capturedThreadId = currentAgent.threadId || "default";
|
|
984
|
+
mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
|
|
985
|
+
host: copilotkit,
|
|
986
|
+
agent: currentAgent,
|
|
987
|
+
capturedThreadId
|
|
988
|
+
})).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
|
|
989
|
+
}
|
|
990
|
+
return { isError: false };
|
|
991
|
+
} catch (err) {
|
|
992
|
+
console.error("[MCPAppsRenderer] ui/message error:", err);
|
|
993
|
+
return { isError: true };
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
bridge.onopenlink = async ({ url }) => {
|
|
997
|
+
let parsed;
|
|
998
|
+
try {
|
|
999
|
+
parsed = new URL(url);
|
|
1000
|
+
} catch {
|
|
1001
|
+
console.warn("[MCPAppsRenderer] ui/open-link rejected: unparseable url");
|
|
1002
|
+
return { isError: true };
|
|
1003
|
+
}
|
|
1004
|
+
if (MCP_OPEN_LINK_BLOCKED_SCHEMES.has(parsed.protocol)) {
|
|
1005
|
+
console.warn("[MCPAppsRenderer] ui/open-link rejected: blocked scheme", parsed.protocol);
|
|
1006
|
+
return { isError: true };
|
|
1007
|
+
}
|
|
1008
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
1009
|
+
return { isError: false };
|
|
1010
|
+
};
|
|
1011
|
+
bridge.oncalltool = async (params) => {
|
|
1012
|
+
const { serverHash, serverId } = contentRef.current;
|
|
1013
|
+
const currentAgent = agentRef.current;
|
|
1014
|
+
if (!serverHash) throw new Error("No server hash available for proxying");
|
|
1015
|
+
if (!currentAgent) throw new Error("No agent available for proxying");
|
|
1016
|
+
return (await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
1017
|
+
serverHash,
|
|
1018
|
+
serverId,
|
|
1019
|
+
method: "tools/call",
|
|
1020
|
+
params
|
|
1021
|
+
} } }))).result || { content: [] };
|
|
1022
|
+
};
|
|
1023
|
+
bridge.onsizechange = (p) => {
|
|
1024
|
+
if (!mounted) return;
|
|
1025
|
+
const { width, height } = p || {};
|
|
1026
|
+
setIframeSize({
|
|
1027
|
+
width: typeof width === "number" ? width : void 0,
|
|
1028
|
+
height: typeof height === "number" ? height : void 0
|
|
1029
|
+
});
|
|
1030
|
+
};
|
|
1031
|
+
bridge.oninitialized = () => {
|
|
1032
|
+
if (mounted) setIframeReady(true);
|
|
1033
|
+
};
|
|
1034
|
+
bridge.onloggingmessage = (p) => {
|
|
1035
|
+
console.log("[MCPAppsRenderer] App log:", p);
|
|
1036
|
+
};
|
|
1037
|
+
const transport = new PostMessageTransport(win, win);
|
|
1038
|
+
await bridge.connect(transport);
|
|
1039
|
+
if (!mounted) {
|
|
1040
|
+
await bridge.close();
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
bridgeRef.current = bridge;
|
|
1092
1044
|
} catch (err) {
|
|
1093
1045
|
console.error("[MCPAppsRenderer] Setup error:", err);
|
|
1094
1046
|
if (mounted) setError(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -1097,11 +1049,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1097
1049
|
setup();
|
|
1098
1050
|
return () => {
|
|
1099
1051
|
mounted = false;
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
initialListener = null;
|
|
1103
|
-
}
|
|
1104
|
-
if (messageHandler) window.removeEventListener("message", messageHandler);
|
|
1052
|
+
bridgeRef.current = null;
|
|
1053
|
+
bridge?.close();
|
|
1105
1054
|
if (createdIframe) {
|
|
1106
1055
|
createdIframe.remove();
|
|
1107
1056
|
createdIframe = null;
|
|
@@ -1111,9 +1060,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1111
1060
|
}, [
|
|
1112
1061
|
isLoading,
|
|
1113
1062
|
fetchedResource,
|
|
1114
|
-
|
|
1115
|
-
sendResponse,
|
|
1116
|
-
sendErrorResponse
|
|
1063
|
+
copilotkit
|
|
1117
1064
|
]);
|
|
1118
1065
|
(0, react.useEffect)(() => {
|
|
1119
1066
|
if (iframeRef.current) {
|
|
@@ -1125,25 +1072,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1125
1072
|
}
|
|
1126
1073
|
}, [iframeSize]);
|
|
1127
1074
|
(0, react.useEffect)(() => {
|
|
1128
|
-
if (iframeReady && content.toolInput) {
|
|
1129
|
-
|
|
1130
|
-
sendNotification("ui/notifications/tool-input", { arguments: content.toolInput });
|
|
1131
|
-
}
|
|
1132
|
-
}, [
|
|
1133
|
-
iframeReady,
|
|
1134
|
-
content.toolInput,
|
|
1135
|
-
sendNotification
|
|
1136
|
-
]);
|
|
1075
|
+
if (iframeReady && content.toolInput) bridgeRef.current?.sendToolInput({ arguments: content.toolInput });
|
|
1076
|
+
}, [iframeReady, content.toolInput]);
|
|
1137
1077
|
(0, react.useEffect)(() => {
|
|
1138
|
-
if (iframeReady && content.result)
|
|
1139
|
-
|
|
1140
|
-
sendNotification("ui/notifications/tool-result", content.result);
|
|
1141
|
-
}
|
|
1142
|
-
}, [
|
|
1143
|
-
iframeReady,
|
|
1144
|
-
content.result,
|
|
1145
|
-
sendNotification
|
|
1146
|
-
]);
|
|
1078
|
+
if (iframeReady && content.result) bridgeRef.current?.sendToolResult(content.result);
|
|
1079
|
+
}, [iframeReady, content.result]);
|
|
1147
1080
|
const borderStyle = fetchedResource?._meta?.ui?.prefersBorder === true ? {
|
|
1148
1081
|
borderRadius: "8px",
|
|
1149
1082
|
backgroundColor: "#f9f9f9",
|
|
@@ -2363,6 +2296,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2363
2296
|
const a2uiCatalogProvided = !!a2ui?.catalog;
|
|
2364
2297
|
const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;
|
|
2365
2298
|
const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
|
|
2299
|
+
const [runtimeEntitlements, setRuntimeEntitlements] = (0, react.useState)(void 0);
|
|
2300
|
+
const [runtimeEntitlementRetryPending, setRuntimeEntitlementRetryPending] = (0, react.useState)(false);
|
|
2366
2301
|
const requestInspectorOpen = (0, react.useCallback)((request) => {
|
|
2367
2302
|
setInspectorOpenRequest({ ...request });
|
|
2368
2303
|
}, []);
|
|
@@ -2553,6 +2488,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2553
2488
|
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
|
|
2554
2489
|
setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
|
|
2555
2490
|
setRuntimeLicenseStatus(copilotkit.licenseStatus);
|
|
2491
|
+
setRuntimeEntitlements(copilotkit.runtimeEntitlements);
|
|
2492
|
+
setRuntimeEntitlementRetryPending(copilotkit.runtimeEntitlementRetryPending);
|
|
2556
2493
|
};
|
|
2557
2494
|
const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: syncRuntimeInfo });
|
|
2558
2495
|
syncRuntimeInfo();
|
|
@@ -2693,7 +2630,26 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2693
2630
|
copilotkit,
|
|
2694
2631
|
executingToolCallIds
|
|
2695
2632
|
}), [copilotkit, executingToolCallIds]);
|
|
2696
|
-
const
|
|
2633
|
+
const retryableRuntimeEntitlementFailure = runtimeEntitlements?.status !== "ready" && runtimeEntitlements?.error.retryable === true;
|
|
2634
|
+
const hasNonReadyRuntimeEntitlement = runtimeEntitlements !== void 0 && runtimeEntitlements.status !== "ready";
|
|
2635
|
+
const hasLegacyRuntimeEntitlementFallback = runtimeLicenseStatus === "valid" || runtimeLicenseStatus === "expiring";
|
|
2636
|
+
const runtimeEntitlementRetryInProgress = retryableRuntimeEntitlementFailure && runtimeEntitlementRetryPending && !hasLegacyRuntimeEntitlementFallback;
|
|
2637
|
+
const runtimeEntitlementFailureSettled = hasNonReadyRuntimeEntitlement && !runtimeEntitlementRetryInProgress && !hasLegacyRuntimeEntitlementFallback;
|
|
2638
|
+
const licenseContextValue = (0, react.useMemo)(() => {
|
|
2639
|
+
const runtimeLicenseContext = (0, _copilotkit_shared.createLicenseContextValue)(runtimeEntitlementRetryInProgress ? void 0 : runtimeLicenseStatus, runtimeEntitlements);
|
|
2640
|
+
if (!runtimeEntitlementFailureSettled) return runtimeLicenseContext;
|
|
2641
|
+
return {
|
|
2642
|
+
...runtimeLicenseContext,
|
|
2643
|
+
checkFeature: () => false,
|
|
2644
|
+
getLimit: () => null
|
|
2645
|
+
};
|
|
2646
|
+
}, [
|
|
2647
|
+
runtimeEntitlementFailureSettled,
|
|
2648
|
+
runtimeEntitlementRetryInProgress,
|
|
2649
|
+
runtimeEntitlements,
|
|
2650
|
+
runtimeLicenseStatus
|
|
2651
|
+
]);
|
|
2652
|
+
const runtimeLicenseWarningStatus = runtimeEntitlementRetryInProgress ? void 0 : licenseContextValue.status ?? void 0;
|
|
2697
2653
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
|
|
2698
2654
|
value: sandboxFunctionsList,
|
|
2699
2655
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
|
|
@@ -2713,10 +2669,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2713
2669
|
openRequest: inspectorOpenRequest
|
|
2714
2670
|
}) : null]
|
|
2715
2671
|
}),
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2672
|
+
runtimeLicenseWarningStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
|
|
2673
|
+
runtimeLicenseWarningStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
|
|
2674
|
+
runtimeLicenseWarningStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
|
|
2675
|
+
runtimeLicenseWarningStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
|
|
2720
2676
|
]
|
|
2721
2677
|
})
|
|
2722
2678
|
})
|
|
@@ -2774,7 +2730,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2774
2730
|
function useFrontendTool$1(tool, deps) {
|
|
2775
2731
|
const { copilotkit } = useCopilotKit();
|
|
2776
2732
|
const extraDeps = deps ?? EMPTY_DEPS;
|
|
2777
|
-
(0, react.
|
|
2733
|
+
(0, react.useLayoutEffect)(() => {
|
|
2778
2734
|
const name = tool.name;
|
|
2779
2735
|
if (copilotkit.getTool({
|
|
2780
2736
|
toolName: name,
|
|
@@ -2797,12 +2753,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2797
2753
|
tool.name,
|
|
2798
2754
|
tool.available,
|
|
2799
2755
|
copilotkit,
|
|
2800
|
-
JSON.stringify(extraDeps)
|
|
2756
|
+
JSON.stringify(extraDeps),
|
|
2757
|
+
JSON.stringify(tool.webmcp ?? null)
|
|
2801
2758
|
]);
|
|
2802
2759
|
}
|
|
2803
2760
|
|
|
2804
2761
|
//#endregion
|
|
2805
2762
|
//#region src/v2/hooks/use-human-in-the-loop.tsx
|
|
2763
|
+
/** Registration name of a catch-all tool: handles any otherwise-unhandled call. */
|
|
2764
|
+
const WILDCARD_TOOL_NAME = "*";
|
|
2806
2765
|
function useHumanInTheLoop$1(tool, deps) {
|
|
2807
2766
|
const { copilotkit } = useCopilotKit();
|
|
2808
2767
|
const resolvePromiseRef = (0, react.useRef)(null);
|
|
@@ -2838,10 +2797,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2838
2797
|
}, []);
|
|
2839
2798
|
const RenderComponent = (0, react.useCallback)((props) => {
|
|
2840
2799
|
const ToolComponent = tool.render;
|
|
2800
|
+
const name = tool.name === WILDCARD_TOOL_NAME ? props.name : tool.name;
|
|
2841
2801
|
if (props.status === _copilotkit_core.ToolCallStatus.InProgress) {
|
|
2842
2802
|
const enhancedProps = {
|
|
2843
2803
|
...props,
|
|
2844
|
-
name
|
|
2804
|
+
name,
|
|
2845
2805
|
description: tool.description || "",
|
|
2846
2806
|
agentId: tool.agentId,
|
|
2847
2807
|
respond: void 0
|
|
@@ -2850,7 +2810,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2850
2810
|
} else if (props.status === _copilotkit_core.ToolCallStatus.Executing) {
|
|
2851
2811
|
const enhancedProps = {
|
|
2852
2812
|
...props,
|
|
2853
|
-
name
|
|
2813
|
+
name,
|
|
2854
2814
|
description: tool.description || "",
|
|
2855
2815
|
agentId: tool.agentId,
|
|
2856
2816
|
respond
|
|
@@ -2859,7 +2819,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2859
2819
|
} else if (props.status === _copilotkit_core.ToolCallStatus.Complete) {
|
|
2860
2820
|
const enhancedProps = {
|
|
2861
2821
|
...props,
|
|
2862
|
-
name
|
|
2822
|
+
name,
|
|
2863
2823
|
description: tool.description || "",
|
|
2864
2824
|
agentId: tool.agentId,
|
|
2865
2825
|
respond: void 0
|
|
@@ -2879,7 +2839,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2879
2839
|
handler,
|
|
2880
2840
|
render: RenderComponent
|
|
2881
2841
|
}, deps);
|
|
2882
|
-
(0, react.
|
|
2842
|
+
(0, react.useLayoutEffect)(() => {
|
|
2883
2843
|
return () => {
|
|
2884
2844
|
copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
|
|
2885
2845
|
};
|
|
@@ -3299,8 +3259,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3299
3259
|
}
|
|
3300
3260
|
|
|
3301
3261
|
//#endregion
|
|
3302
|
-
//#region src/v2/
|
|
3262
|
+
//#region src/v2/types/interrupt.ts
|
|
3263
|
+
/** Name of the legacy custom event agents emit to signal an interrupt. */
|
|
3303
3264
|
const INTERRUPT_EVENT_NAME = "on_interrupt";
|
|
3265
|
+
|
|
3266
|
+
//#endregion
|
|
3267
|
+
//#region src/v2/hooks/use-interrupt.tsx
|
|
3304
3268
|
function isPromiseLike(value) {
|
|
3305
3269
|
return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
|
|
3306
3270
|
}
|
|
@@ -4507,7 +4471,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4507
4471
|
switch (error.code) {
|
|
4508
4472
|
case _copilotkit_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR: return { primary: {
|
|
4509
4473
|
label: "Show me how",
|
|
4510
|
-
onClick: () => window.open("https://docs.copilotkit.ai/
|
|
4474
|
+
onClick: () => window.open("https://docs.copilotkit.ai/intelligence/overview#plans-and-access", "_blank", "noopener,noreferrer")
|
|
4511
4475
|
} };
|
|
4512
4476
|
case _copilotkit_shared.CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR: return { primary: {
|
|
4513
4477
|
label: "Upgrade",
|
|
@@ -5753,13 +5717,18 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5753
5717
|
const renderToolCall = useRenderToolCall$1();
|
|
5754
5718
|
return (0, react.useCallback)((message, messages) => {
|
|
5755
5719
|
if (!message?.toolCalls?.length) return null;
|
|
5756
|
-
const
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5720
|
+
const toolCalls = message.toolCalls;
|
|
5721
|
+
return () => {
|
|
5722
|
+
const renderedToolCalls = toolCalls.map((toolCall) => {
|
|
5723
|
+
const toolMessage = messages?.find((m) => m.role === "tool" && m.toolCallId === toolCall.id);
|
|
5724
|
+
return renderToolCall({
|
|
5725
|
+
toolCall,
|
|
5726
|
+
toolMessage
|
|
5727
|
+
});
|
|
5728
|
+
}).filter((renderedToolCall) => renderedToolCall !== null);
|
|
5729
|
+
if (!renderedToolCalls.length) return null;
|
|
5730
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderedToolCalls });
|
|
5731
|
+
};
|
|
5763
5732
|
}, [renderToolCall]);
|
|
5764
5733
|
}
|
|
5765
5734
|
|
|
@@ -6094,7 +6063,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6094
6063
|
* `useCopilotChatHeadless_c` is for building fully custom UI (headless UI) implementations.
|
|
6095
6064
|
*
|
|
6096
6065
|
* <Callout title="This is a CopilotKit Intelligence feature">
|
|
6097
|
-
* Read more about <a href="/
|
|
6066
|
+
* Read more about <a href="/intelligence/overview">CopilotKit Intelligence</a>.
|
|
6098
6067
|
*
|
|
6099
6068
|
* Usage is generous and **free** to get started.
|
|
6100
6069
|
* </Callout>
|
|
@@ -6325,7 +6294,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6325
6294
|
* See https://docs.copilotkit.ai/reference/v2/hooks/useFrontendTool
|
|
6326
6295
|
*/
|
|
6327
6296
|
function useFrontendTool(tool, dependencies) {
|
|
6328
|
-
const { name, description, parameters, render, followUp, available } = tool;
|
|
6297
|
+
const { name, description, parameters, render, followUp, available, webmcp } = tool;
|
|
6329
6298
|
const zodParameters = (0, _copilotkit_shared.getZodParameters)(parameters);
|
|
6330
6299
|
const renderRef = (0, react.useRef)(render);
|
|
6331
6300
|
(0, react.useEffect)(() => {
|
|
@@ -6356,7 +6325,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6356
6325
|
handler: tool.handler ? (args) => handlerRef.current?.(args) : void 0,
|
|
6357
6326
|
followUp,
|
|
6358
6327
|
render: normalizedRender,
|
|
6359
|
-
available: available === void 0 ? void 0 : available !== "disabled"
|
|
6328
|
+
available: available === void 0 ? void 0 : available !== "disabled",
|
|
6329
|
+
webmcp
|
|
6360
6330
|
});
|
|
6361
6331
|
}
|
|
6362
6332
|
|
|
@@ -6454,20 +6424,24 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6454
6424
|
if (!render) return null;
|
|
6455
6425
|
const rendered = render((() => {
|
|
6456
6426
|
const mappedArgs = args.args;
|
|
6427
|
+
const toolCallName = args.name;
|
|
6457
6428
|
switch (args.status) {
|
|
6458
6429
|
case _copilotkit_core.ToolCallStatus.InProgress: return {
|
|
6430
|
+
name: toolCallName,
|
|
6459
6431
|
args: mappedArgs,
|
|
6460
6432
|
respond: args.respond,
|
|
6461
6433
|
status: args.status,
|
|
6462
6434
|
handler: void 0
|
|
6463
6435
|
};
|
|
6464
6436
|
case _copilotkit_core.ToolCallStatus.Executing: return {
|
|
6437
|
+
name: toolCallName,
|
|
6465
6438
|
args: mappedArgs,
|
|
6466
6439
|
respond: args.respond,
|
|
6467
6440
|
status: args.status,
|
|
6468
6441
|
handler: () => {}
|
|
6469
6442
|
};
|
|
6470
6443
|
case _copilotkit_core.ToolCallStatus.Complete: return {
|
|
6444
|
+
name: toolCallName,
|
|
6471
6445
|
args: mappedArgs,
|
|
6472
6446
|
respond: args.respond,
|
|
6473
6447
|
status: args.status,
|
|
@@ -6627,10 +6601,21 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6627
6601
|
* This hooks enables you to dynamically generate UI elements and render them in the copilot chat. For more information, check out the [Generative UI](/guides/generative-ui) page.
|
|
6628
6602
|
*/
|
|
6629
6603
|
function getActionConfig(action) {
|
|
6630
|
-
if (action.name === "*")
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6604
|
+
if (action.name === "*") {
|
|
6605
|
+
const catchAll = action;
|
|
6606
|
+
const waitRender = catchAll.renderAndWaitForResponse ?? catchAll.renderAndWait;
|
|
6607
|
+
if (waitRender) return {
|
|
6608
|
+
type: "hitl",
|
|
6609
|
+
action: {
|
|
6610
|
+
...catchAll,
|
|
6611
|
+
render: waitRender
|
|
6612
|
+
}
|
|
6613
|
+
};
|
|
6614
|
+
return {
|
|
6615
|
+
type: "render",
|
|
6616
|
+
action
|
|
6617
|
+
};
|
|
6618
|
+
}
|
|
6634
6619
|
if ("renderAndWaitForResponse" in action || "renderAndWait" in action) {
|
|
6635
6620
|
let render = action.render;
|
|
6636
6621
|
if (!render && "renderAndWaitForResponse" in action) render = action.renderAndWaitForResponse;
|
|
@@ -6941,37 +6926,87 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6941
6926
|
|
|
6942
6927
|
//#endregion
|
|
6943
6928
|
//#region src/v1-deprecated/hooks/use-agent-nodename.ts
|
|
6944
|
-
|
|
6929
|
+
const initialAgentNodeNameState = {
|
|
6930
|
+
nodeName: "start",
|
|
6931
|
+
lastActiveNodeName: "start",
|
|
6932
|
+
hasLegacyInterrupt: false
|
|
6933
|
+
};
|
|
6934
|
+
const transitionAgentNodeName = (state, event) => {
|
|
6935
|
+
switch (event.type) {
|
|
6936
|
+
case "reset":
|
|
6937
|
+
case "runStarted": return initialAgentNodeNameState;
|
|
6938
|
+
case "stepStarted": return {
|
|
6939
|
+
...state,
|
|
6940
|
+
nodeName: event.nodeName,
|
|
6941
|
+
lastActiveNodeName: event.nodeName
|
|
6942
|
+
};
|
|
6943
|
+
case "legacyInterruptReceived": return {
|
|
6944
|
+
...state,
|
|
6945
|
+
hasLegacyInterrupt: true
|
|
6946
|
+
};
|
|
6947
|
+
case "runFinished":
|
|
6948
|
+
if (event.outcome === "interrupt" || state.hasLegacyInterrupt) return {
|
|
6949
|
+
...state,
|
|
6950
|
+
nodeName: state.lastActiveNodeName,
|
|
6951
|
+
hasLegacyInterrupt: false
|
|
6952
|
+
};
|
|
6953
|
+
return {
|
|
6954
|
+
...state,
|
|
6955
|
+
nodeName: "end",
|
|
6956
|
+
hasLegacyInterrupt: false
|
|
6957
|
+
};
|
|
6958
|
+
case "runError": return {
|
|
6959
|
+
...state,
|
|
6960
|
+
nodeName: "end",
|
|
6961
|
+
hasLegacyInterrupt: false
|
|
6962
|
+
};
|
|
6963
|
+
}
|
|
6964
|
+
};
|
|
6965
|
+
/**
|
|
6945
6966
|
* Tracks the node the agent is currently executing.
|
|
6946
6967
|
*
|
|
6947
6968
|
* Backed by state rather than a ref: mutating a ref schedules no render, so
|
|
6948
6969
|
* consumers such as `useCoAgent().nodeName` kept reporting whichever node was
|
|
6949
|
-
* current at their last render and never updated on their own.
|
|
6970
|
+
* current at their last render and never updated on their own. Interrupt-aware
|
|
6971
|
+
* transitions keep the last active node available while an interrupt is pending.
|
|
6950
6972
|
*/
|
|
6951
6973
|
function useAgentNodeName(agentName) {
|
|
6952
6974
|
const { agent } = useAgent({ agentId: agentName });
|
|
6953
|
-
const [
|
|
6975
|
+
const [nodeNameState, setNodeNameState] = (0, react.useState)(initialAgentNodeNameState);
|
|
6954
6976
|
(0, react.useEffect)(() => {
|
|
6977
|
+
const transition = (event) => {
|
|
6978
|
+
setNodeNameState((state) => transitionAgentNodeName(state, event));
|
|
6979
|
+
};
|
|
6980
|
+
transition({ type: "reset" });
|
|
6955
6981
|
if (!agent) return;
|
|
6956
6982
|
const subscription = agent.subscribe({
|
|
6957
6983
|
onStepStartedEvent: ({ event }) => {
|
|
6958
|
-
|
|
6984
|
+
transition({
|
|
6985
|
+
type: "stepStarted",
|
|
6986
|
+
nodeName: event.stepName
|
|
6987
|
+
});
|
|
6959
6988
|
},
|
|
6960
6989
|
onRunStartedEvent: () => {
|
|
6961
|
-
|
|
6990
|
+
transition({ type: "runStarted" });
|
|
6962
6991
|
},
|
|
6963
|
-
onRunFinishedEvent: () => {
|
|
6964
|
-
|
|
6992
|
+
onRunFinishedEvent: ({ outcome }) => {
|
|
6993
|
+
transition({
|
|
6994
|
+
type: "runFinished",
|
|
6995
|
+
outcome
|
|
6996
|
+
});
|
|
6965
6997
|
},
|
|
6966
6998
|
onRunErrorEvent: () => {
|
|
6967
|
-
|
|
6999
|
+
transition({ type: "runError" });
|
|
7000
|
+
},
|
|
7001
|
+
onCustomEvent: ({ event }) => {
|
|
7002
|
+
if (event.name === INTERRUPT_EVENT_NAME) transition({ type: "legacyInterruptReceived" });
|
|
6968
7003
|
}
|
|
6969
7004
|
});
|
|
6970
7005
|
return () => {
|
|
6971
7006
|
subscription.unsubscribe();
|
|
6972
7007
|
};
|
|
6973
|
-
}, [agent]);
|
|
6974
|
-
return nodeName;
|
|
7008
|
+
}, [agent, agentName]);
|
|
7009
|
+
return nodeNameState.nodeName;
|
|
6975
7010
|
}
|
|
6976
7011
|
|
|
6977
7012
|
//#endregion
|
|
@@ -7174,6 +7209,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7174
7209
|
agent?.threadId,
|
|
7175
7210
|
agent?.isRunning,
|
|
7176
7211
|
agent?.agentId,
|
|
7212
|
+
nodeName,
|
|
7177
7213
|
handleStateUpdate,
|
|
7178
7214
|
options.name
|
|
7179
7215
|
]);
|