@copilotkit/react-core 1.71.1 → 1.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{copilotkit-DCIXZawe.d.cts → copilotkit-DoHSqB_u.d.cts} +10 -82
- package/dist/copilotkit-DoHSqB_u.d.cts.map +1 -0
- package/dist/{copilotkit-ChjzWqn6.d.mts → copilotkit-DsMFLrpY.d.mts} +10 -82
- package/dist/copilotkit-DsMFLrpY.d.mts.map +1 -0
- package/dist/{copilotkit-BkVEkUS0.cjs → copilotkit-gopQXrTQ.cjs} +74 -390
- package/dist/copilotkit-gopQXrTQ.cjs.map +1 -0
- package/dist/{copilotkit-D5BTo0YG.mjs → copilotkit-qK-Q3rmE.mjs} +72 -370
- package/dist/copilotkit-qK-Q3rmE.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +65 -371
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +20 -4
- package/dist/v2/index.d.cts +1 -1
- package/dist/v2/index.d.mts +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +94 -378
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +8 -10
- package/dist/copilotkit-BkVEkUS0.cjs.map +0 -1
- package/dist/copilotkit-ChjzWqn6.d.mts.map +0 -1
- package/dist/copilotkit-D5BTo0YG.mjs.map +0 -1
- package/dist/copilotkit-DCIXZawe.d.cts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
-
const require_copilotkit = require('./copilotkit-
|
|
4
|
+
const require_copilotkit = require('./copilotkit-gopQXrTQ.cjs');
|
|
5
5
|
let react = require("react");
|
|
6
6
|
react = require_copilotkit.__toESM(react);
|
|
7
7
|
let _copilotkit_core = require("@copilotkit/core");
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $n as LangGraphInterruptAction, Cr as CatchAllFrontendAction, Er as RenderFunctionStatus, Jn as CopilotApiConfig, Qn as CoAgentStateRender, Sr as CatchAllActionRenderPropsWait, Tr as FrontendActionAvailability, X as useAgent, Xn as CopilotContextParams, Yn as CopilotContext, Zn as useCopilotContext, _r as ActionRenderProps, ar as QueuedInterruptEvent, br as ActionRenderPropsWait, bt as useRenderToolCall$1, cr as CrewsResponseStatus, dr as CrewsToolStateItem, er as LangGraphInterruptActionSetter, fr as CopilotChatSuggestionConfiguration, gr as TreeNode, hr as Tree, ir as LangGraphInterruptRenderProps, lr as CrewsStateItem, mr as DocumentPointer, n as defaultCopilotContextCategories, nr as LangGraphInterruptRender, or as CrewsAgentState, pr as SystemMessageFunction, qn as CoagentInChatRenderFunction, r as CopilotKitProps, rr as LangGraphInterruptRenderHandlerProps, sr as CrewsResponse, t as CopilotKit, tr as LangGraphInterruptActionSetterArgs, ur as CrewsTaskStateItem, vr as ActionRenderPropsNoArgs, wr as FrontendAction, xr as CatchAllActionRenderProps, yr as ActionRenderPropsNoArgsWait } from "./copilotkit-
|
|
1
|
+
import { $n as LangGraphInterruptAction, Cr as CatchAllFrontendAction, Er as RenderFunctionStatus, Jn as CopilotApiConfig, Qn as CoAgentStateRender, Sr as CatchAllActionRenderPropsWait, Tr as FrontendActionAvailability, X as useAgent, Xn as CopilotContextParams, Yn as CopilotContext, Zn as useCopilotContext, _r as ActionRenderProps, ar as QueuedInterruptEvent, br as ActionRenderPropsWait, bt as useRenderToolCall$1, cr as CrewsResponseStatus, dr as CrewsToolStateItem, er as LangGraphInterruptActionSetter, fr as CopilotChatSuggestionConfiguration, gr as TreeNode, hr as Tree, ir as LangGraphInterruptRenderProps, lr as CrewsStateItem, mr as DocumentPointer, n as defaultCopilotContextCategories, nr as LangGraphInterruptRender, or as CrewsAgentState, pr as SystemMessageFunction, qn as CoagentInChatRenderFunction, r as CopilotKitProps, rr as LangGraphInterruptRenderHandlerProps, sr as CrewsResponse, t as CopilotKit, tr as LangGraphInterruptActionSetterArgs, ur as CrewsTaskStateItem, vr as ActionRenderPropsNoArgs, wr as FrontendAction, xr as CatchAllActionRenderProps, yr as ActionRenderPropsNoArgsWait } from "./copilotkit-DoHSqB_u.cjs";
|
|
2
2
|
import "./v2/index.cjs";
|
|
3
3
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
import { CopilotRuntimeClient, CopilotRuntimeClientOptions, ForwardedParametersInput, Message } from "@copilotkit/runtime-client-gql";
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $n as LangGraphInterruptAction, Cr as CatchAllFrontendAction, Er as RenderFunctionStatus, Jn as CopilotApiConfig, Qn as CoAgentStateRender, Sr as CatchAllActionRenderPropsWait, Tr as FrontendActionAvailability, X as useAgent, Xn as CopilotContextParams, Yn as CopilotContext, Zn as useCopilotContext, _r as ActionRenderProps, ar as QueuedInterruptEvent, br as ActionRenderPropsWait, bt as useRenderToolCall$1, cr as CrewsResponseStatus, dr as CrewsToolStateItem, er as LangGraphInterruptActionSetter, fr as CopilotChatSuggestionConfiguration, gr as TreeNode, hr as Tree, ir as LangGraphInterruptRenderProps, lr as CrewsStateItem, mr as DocumentPointer, n as defaultCopilotContextCategories, nr as LangGraphInterruptRender, or as CrewsAgentState, pr as SystemMessageFunction, qn as CoagentInChatRenderFunction, r as CopilotKitProps, rr as LangGraphInterruptRenderHandlerProps, sr as CrewsResponse, t as CopilotKit, tr as LangGraphInterruptActionSetterArgs, ur as CrewsTaskStateItem, vr as ActionRenderPropsNoArgs, wr as FrontendAction, xr as CatchAllActionRenderProps, yr as ActionRenderPropsNoArgsWait } from "./copilotkit-
|
|
1
|
+
import { $n as LangGraphInterruptAction, Cr as CatchAllFrontendAction, Er as RenderFunctionStatus, Jn as CopilotApiConfig, Qn as CoAgentStateRender, Sr as CatchAllActionRenderPropsWait, Tr as FrontendActionAvailability, X as useAgent, Xn as CopilotContextParams, Yn as CopilotContext, Zn as useCopilotContext, _r as ActionRenderProps, ar as QueuedInterruptEvent, br as ActionRenderPropsWait, bt as useRenderToolCall$1, cr as CrewsResponseStatus, dr as CrewsToolStateItem, er as LangGraphInterruptActionSetter, fr as CopilotChatSuggestionConfiguration, gr as TreeNode, hr as Tree, ir as LangGraphInterruptRenderProps, lr as CrewsStateItem, mr as DocumentPointer, n as defaultCopilotContextCategories, nr as LangGraphInterruptRender, or as CrewsAgentState, pr as SystemMessageFunction, qn as CoagentInChatRenderFunction, r as CopilotKitProps, rr as LangGraphInterruptRenderHandlerProps, sr as CrewsResponse, t as CopilotKit, tr as LangGraphInterruptActionSetterArgs, ur as CrewsTaskStateItem, vr as ActionRenderPropsNoArgs, wr as FrontendAction, xr as CatchAllActionRenderProps, yr as ActionRenderPropsNoArgsWait } from "./copilotkit-DsMFLrpY.mjs";
|
|
2
2
|
import "./v2/index.mjs";
|
|
3
3
|
import React, { ReactNode, RefObject, SetStateAction } from "react";
|
|
4
4
|
import { StaticSuggestionsConfig, Suggestion } from "@copilotkit/core";
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { Nt as useCopilotChatConfiguration, Ot as useRenderToolCall$1, Q as useSuggestions, X as INTERRUPT_EVENT_NAME, Y as useInterrupt, Z as useConfigureSuggestions, a as ThreadsProvider, c as CoAgentStateRendersProvider, d as shouldShowDevConsole, dt as useCopilotKit, f as useToast, g as useCopilotContext, h as CopilotContext, i as ThreadsContext, l as useCoAgentStateRenders, lt as useRenderCustomMessages, m as useCopilotMessagesContext, mt as defineToolCallRenderer, n as defaultCopilotContextCategories, nt as useAgent, o as useThreads, p as CopilotMessagesContext, r as CoAgentStateRenderBridge, rt as useHumanInTheLoop$1, s as CoAgentStateRendersContext, st as useFrontendTool$1, t as CopilotKit, u as useAsyncCallback } from "./copilotkit-
|
|
3
|
+
import { Nt as useCopilotChatConfiguration, Ot as useRenderToolCall$1, Q as useSuggestions, X as INTERRUPT_EVENT_NAME, Y as useInterrupt, Z as useConfigureSuggestions, a as ThreadsProvider, c as CoAgentStateRendersProvider, d as shouldShowDevConsole, dt as useCopilotKit, f as useToast, g as useCopilotContext, h as CopilotContext, i as ThreadsContext, l as useCoAgentStateRenders, lt as useRenderCustomMessages, m as useCopilotMessagesContext, mt as defineToolCallRenderer, n as defaultCopilotContextCategories, nt as useAgent, o as useThreads, p as CopilotMessagesContext, r as CoAgentStateRenderBridge, rt as useHumanInTheLoop$1, s as CoAgentStateRendersContext, st as useFrontendTool$1, t as CopilotKit, u as useAsyncCallback } from "./copilotkit-qK-Q3rmE.mjs";
|
|
4
4
|
import React, { Fragment, createElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { CopilotKitCoreRuntimeConnectionStatus, ToolCallStatus } from "@copilotkit/core";
|
|
6
6
|
import { AGUIConnectNotImplementedError, HttpAgent } from "@ag-ui/client";
|
package/dist/index.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
(function(global, factory) {
|
|
4
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@copilotkit/core'), require('@ag-ui/client'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('zod'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('react-markdown'), require('@copilotkit/runtime-client-gql')) :
|
|
5
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@copilotkit/core', '@ag-ui/client', '@copilotkit/shared', 'react/jsx-runtime', 'zod', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', 'react-markdown', '@copilotkit/runtime-client-gql'], factory) :
|
|
6
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCore = {}), global.React,global.CopilotKitCore,global.AgUIClient,global.CopilotKitShared,global.ReactJsxRuntime,global.Zod,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global.ReactMarkdown,global.CopilotKitRuntimeClientGQL));
|
|
7
|
-
})(this, function(exports, react, _copilotkit_core, _ag_ui_client, _copilotkit_shared, react_jsx_runtime, zod, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, react_markdown, _copilotkit_runtime_client_gql) {
|
|
4
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@copilotkit/core'), require('@ag-ui/client'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('zod'), require('@copilotkit/mcp-apps-renderer/activity'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('react-markdown'), require('@copilotkit/runtime-client-gql')) :
|
|
5
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', '@copilotkit/core', '@ag-ui/client', '@copilotkit/shared', 'react/jsx-runtime', 'zod', '@copilotkit/mcp-apps-renderer/activity', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', 'react-markdown', '@copilotkit/runtime-client-gql'], factory) :
|
|
6
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCore = {}), global.React,global.CopilotKitCore,global.AgUIClient,global.CopilotKitShared,global.ReactJsxRuntime,global.Zod,global.CopilotKitMcpAppsRendererActivity,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global.ReactMarkdown,global.CopilotKitRuntimeClientGQL));
|
|
7
|
+
})(this, function(exports, react, _copilotkit_core, _ag_ui_client, _copilotkit_shared, react_jsx_runtime, zod, _copilotkit_mcp_apps_renderer_activity, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, react_markdown, _copilotkit_runtime_client_gql) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -773,197 +773,17 @@ react_markdown = __toESM(react_markdown);
|
|
|
773
773
|
//#endregion
|
|
774
774
|
//#region src/v2/components/MCPAppsActivityRenderer.tsx
|
|
775
775
|
/**
|
|
776
|
-
* Run an MCP app `ui/message` follow-up, scoped to the thread it was enqueued
|
|
777
|
-
* for (issue #5819).
|
|
778
|
-
*
|
|
779
|
-
* The MCP request queue delays follow-up work until the agent is idle. There is
|
|
780
|
-
* a single shared registry agent per id, and switching threads overwrites its
|
|
781
|
-
* `threadId`/`messages` in place. So if the host switches threads while a
|
|
782
|
-
* follow-up is queued, running it now would execute against — and stream into —
|
|
783
|
-
* the now-foreground thread.
|
|
784
|
-
*
|
|
785
|
-
* - **Same thread** (the common case): run on the shared agent, unchanged.
|
|
786
|
-
* - **Thread changed**: the shared agent has moved on, so the follow-up can no
|
|
787
|
-
* longer run in its originating thread's context. Drop it rather than leak it
|
|
788
|
-
* into the current thread. (The MCP app already received its `ui/message` ack
|
|
789
|
-
* at enqueue time; only the optional agent turn is skipped.)
|
|
790
|
-
*
|
|
791
|
-
* @internal exported for testing.
|
|
792
|
-
*/
|
|
793
|
-
async function ɵrunMcpFollowUp({ host, agent, capturedThreadId }) {
|
|
794
|
-
const currentThreadId = agent.threadId || "default";
|
|
795
|
-
const originThreadId = capturedThreadId || "default";
|
|
796
|
-
if (currentThreadId === originThreadId) return host.runAgent({ agent });
|
|
797
|
-
console.warn(`[MCPAppsRenderer] ui/message follow-up dropped: the thread changed (${originThreadId} → ${currentThreadId}) between enqueue and execution, so running it would leak into the now-foreground thread.`);
|
|
798
|
-
return {
|
|
799
|
-
result: void 0,
|
|
800
|
-
newMessages: []
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
function buildSandboxHTML(extraCspDomains) {
|
|
804
|
-
const baseScriptSrc = "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*";
|
|
805
|
-
const baseFrameSrc = "* blob: data: http://localhost:* https://localhost:*";
|
|
806
|
-
const extra = extraCspDomains?.length ? " " + extraCspDomains.join(" ") : "";
|
|
807
|
-
return `<!doctype html>
|
|
808
|
-
<html>
|
|
809
|
-
<head>
|
|
810
|
-
<meta charset="utf-8" />
|
|
811
|
-
<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';" />
|
|
812
|
-
<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>
|
|
813
|
-
</head>
|
|
814
|
-
<body>
|
|
815
|
-
<script>
|
|
816
|
-
if(window.self===window.top){throw new Error("This file must be used in an iframe.")}
|
|
817
|
-
const inner=document.createElement("iframe");
|
|
818
|
-
inner.style="width:100%;height:100%;border:none;";
|
|
819
|
-
inner.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms");
|
|
820
|
-
document.body.appendChild(inner);
|
|
821
|
-
window.addEventListener("message",async(event)=>{
|
|
822
|
-
if(event.source===window.parent){
|
|
823
|
-
if(event.data&&event.data.method==="ui/notifications/sandbox-resource-ready"){
|
|
824
|
-
const{html,sandbox}=event.data.params;
|
|
825
|
-
if(typeof sandbox==="string")inner.setAttribute("sandbox",sandbox);
|
|
826
|
-
if(typeof html==="string")inner.srcdoc=html;
|
|
827
|
-
}else if(inner&&inner.contentWindow){
|
|
828
|
-
inner.contentWindow.postMessage(event.data,"*");
|
|
829
|
-
}
|
|
830
|
-
}else if(event.source===inner.contentWindow){
|
|
831
|
-
window.parent.postMessage(event.data,"*");
|
|
832
|
-
}
|
|
833
|
-
});
|
|
834
|
-
window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-ready",params:{}},"*");
|
|
835
|
-
<\/script>
|
|
836
|
-
</body>
|
|
837
|
-
</html>`;
|
|
838
|
-
}
|
|
839
|
-
/**
|
|
840
|
-
* Queue for serializing MCP app requests to an agent.
|
|
841
|
-
* Ensures requests wait for the agent to stop running and are processed one at a time.
|
|
842
|
-
*/
|
|
843
|
-
var MCPAppsRequestQueue = class {
|
|
844
|
-
constructor() {
|
|
845
|
-
this.queues = /* @__PURE__ */ new Map();
|
|
846
|
-
this.processing = /* @__PURE__ */ new Map();
|
|
847
|
-
}
|
|
848
|
-
/**
|
|
849
|
-
* Add a request to the queue for a specific agent thread.
|
|
850
|
-
* Returns a promise that resolves when the request completes.
|
|
851
|
-
*/
|
|
852
|
-
async enqueue(agent, request) {
|
|
853
|
-
const threadId = agent.threadId || "default";
|
|
854
|
-
return new Promise((resolve, reject) => {
|
|
855
|
-
let queue = this.queues.get(threadId);
|
|
856
|
-
if (!queue) {
|
|
857
|
-
queue = [];
|
|
858
|
-
this.queues.set(threadId, queue);
|
|
859
|
-
}
|
|
860
|
-
queue.push({
|
|
861
|
-
execute: request,
|
|
862
|
-
resolve,
|
|
863
|
-
reject
|
|
864
|
-
});
|
|
865
|
-
this.processQueue(threadId, agent);
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
async processQueue(threadId, agent) {
|
|
869
|
-
if (this.processing.get(threadId)) return;
|
|
870
|
-
this.processing.set(threadId, true);
|
|
871
|
-
try {
|
|
872
|
-
const queue = this.queues.get(threadId);
|
|
873
|
-
if (!queue) return;
|
|
874
|
-
while (queue.length > 0) {
|
|
875
|
-
const item = queue[0];
|
|
876
|
-
try {
|
|
877
|
-
await this.waitForAgentIdle(agent);
|
|
878
|
-
const result = await item.execute();
|
|
879
|
-
item.resolve(result);
|
|
880
|
-
} catch (error) {
|
|
881
|
-
item.reject(error instanceof Error ? error : new Error(String(error)));
|
|
882
|
-
}
|
|
883
|
-
queue.shift();
|
|
884
|
-
}
|
|
885
|
-
} finally {
|
|
886
|
-
this.processing.set(threadId, false);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
waitForAgentIdle(agent) {
|
|
890
|
-
return new Promise((resolve) => {
|
|
891
|
-
if (!agent.isRunning) {
|
|
892
|
-
resolve();
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
let done = false;
|
|
896
|
-
const finish = () => {
|
|
897
|
-
if (done) return;
|
|
898
|
-
done = true;
|
|
899
|
-
clearInterval(checkInterval);
|
|
900
|
-
sub.unsubscribe();
|
|
901
|
-
resolve();
|
|
902
|
-
};
|
|
903
|
-
const sub = agent.subscribe({
|
|
904
|
-
onRunFinalized: finish,
|
|
905
|
-
onRunFailed: finish
|
|
906
|
-
});
|
|
907
|
-
const checkInterval = setInterval(() => {
|
|
908
|
-
if (!agent.isRunning) finish();
|
|
909
|
-
}, 500);
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
const mcpAppsRequestQueue = new MCPAppsRequestQueue();
|
|
914
|
-
const MCP_OPEN_LINK_BLOCKED_SCHEMES = new Set([
|
|
915
|
-
"javascript:",
|
|
916
|
-
"data:",
|
|
917
|
-
"vbscript:",
|
|
918
|
-
"blob:",
|
|
919
|
-
"file:"
|
|
920
|
-
]);
|
|
921
|
-
/**
|
|
922
|
-
* Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType
|
|
923
|
-
*/
|
|
924
|
-
const MCPAppsActivityType = "mcp-apps";
|
|
925
|
-
const MCPAppsActivityContentSchema = zod.z.object({
|
|
926
|
-
result: zod.z.object({
|
|
927
|
-
content: zod.z.array(zod.z.any()).optional(),
|
|
928
|
-
structuredContent: zod.z.any().optional(),
|
|
929
|
-
isError: zod.z.boolean().optional()
|
|
930
|
-
}),
|
|
931
|
-
resourceUri: zod.z.string(),
|
|
932
|
-
serverHash: zod.z.string(),
|
|
933
|
-
serverId: zod.z.string().optional(),
|
|
934
|
-
toolInput: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
935
|
-
});
|
|
936
|
-
/**
|
|
937
776
|
* MCP Apps Extension Activity Renderer
|
|
938
777
|
*
|
|
939
778
|
* Renders MCP Apps UI in a sandboxed iframe with full protocol support.
|
|
940
|
-
* Fetches resource content on-demand via proxied MCP requests.
|
|
779
|
+
* Fetches resource content on-demand via proxied MCP requests. The React shell
|
|
780
|
+
* owns the iframe; `bindMcpApp` owns the protocol.
|
|
941
781
|
*/
|
|
942
|
-
/**
|
|
943
|
-
* Permissive `ui/message` schema. ext-apps restricts the request to
|
|
944
|
-
* `role: "user"` with no `followUp`, but CopilotKit intentionally extends
|
|
945
|
-
* `ui/message` with `role` ("user" | "assistant") and `followUp` (documented
|
|
946
|
-
* behavior with dedicated tests). We register our own handler (instead of the
|
|
947
|
-
* bridge's strict `onmessage`) so those extensions survive the migration.
|
|
948
|
-
*
|
|
949
|
-
* Going forward, widgets SHOULD pass the extensions under
|
|
950
|
-
* `params._meta.copilotkit`; the top-level `role`/`followUp` fields are the
|
|
951
|
-
* legacy channel, kept for backward compatibility and slated for deprecation.
|
|
952
|
-
*/
|
|
953
|
-
const CopilotKitUiMessageSchema = zod.z.object({
|
|
954
|
-
method: zod.z.literal("ui/message"),
|
|
955
|
-
params: zod.z.object({
|
|
956
|
-
role: zod.z.string().optional(),
|
|
957
|
-
content: zod.z.array(zod.z.any()).optional(),
|
|
958
|
-
followUp: zod.z.boolean().optional(),
|
|
959
|
-
_meta: zod.z.record(zod.z.string(), zod.z.any()).optional()
|
|
960
|
-
}).passthrough()
|
|
961
|
-
});
|
|
962
782
|
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, agent }) {
|
|
963
783
|
const { copilotkit } = useCopilotKit();
|
|
964
784
|
const containerRef = (0, react.useRef)(null);
|
|
965
785
|
const iframeRef = (0, react.useRef)(null);
|
|
966
|
-
const
|
|
786
|
+
const sessionRef = (0, react.useRef)(null);
|
|
967
787
|
const [error, setError] = (0, react.useState)(null);
|
|
968
788
|
const [isLoading, setIsLoading] = (0, react.useState)(true);
|
|
969
789
|
const [iframeSize, setIframeSize] = (0, react.useState)({});
|
|
@@ -972,207 +792,81 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
972
792
|
contentRef.current = content;
|
|
973
793
|
const agentRef = (0, react.useRef)(agent);
|
|
974
794
|
agentRef.current = agent;
|
|
975
|
-
const bridgeRef = (0, react.useRef)(null);
|
|
976
|
-
const fetchStateRef = (0, react.useRef)({
|
|
977
|
-
inProgress: false,
|
|
978
|
-
promise: null,
|
|
979
|
-
resourceUri: null
|
|
980
|
-
});
|
|
981
795
|
(0, react.useEffect)(() => {
|
|
982
|
-
const
|
|
983
|
-
if (
|
|
984
|
-
fetchStateRef.current.promise?.then((resource) => {
|
|
985
|
-
if (resource) {
|
|
986
|
-
setFetchedResource(resource);
|
|
987
|
-
setIsLoading(false);
|
|
988
|
-
}
|
|
989
|
-
}).catch((err) => {
|
|
990
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
991
|
-
setIsLoading(false);
|
|
992
|
-
});
|
|
993
|
-
return;
|
|
994
|
-
}
|
|
796
|
+
const container = containerRef.current;
|
|
797
|
+
if (!container) return;
|
|
995
798
|
if (!agent) {
|
|
996
799
|
setError(/* @__PURE__ */ new Error("No agent available to fetch resource"));
|
|
997
800
|
setIsLoading(false);
|
|
998
801
|
return;
|
|
999
802
|
}
|
|
1000
|
-
fetchStateRef.current.inProgress = true;
|
|
1001
|
-
fetchStateRef.current.resourceUri = resourceUri;
|
|
1002
|
-
const fetchPromise = (async () => {
|
|
1003
|
-
try {
|
|
1004
|
-
const resource = (await mcpAppsRequestQueue.enqueue(agent, () => agent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
1005
|
-
serverHash,
|
|
1006
|
-
serverId,
|
|
1007
|
-
method: "resources/read",
|
|
1008
|
-
params: { uri: resourceUri }
|
|
1009
|
-
} } }))).result?.contents?.[0];
|
|
1010
|
-
if (!resource) throw new Error("No resource content in response");
|
|
1011
|
-
return resource;
|
|
1012
|
-
} catch (err) {
|
|
1013
|
-
console.error("[MCPAppsRenderer] Failed to fetch resource:", err);
|
|
1014
|
-
throw err;
|
|
1015
|
-
} finally {
|
|
1016
|
-
fetchStateRef.current.inProgress = false;
|
|
1017
|
-
}
|
|
1018
|
-
})();
|
|
1019
|
-
fetchStateRef.current.promise = fetchPromise;
|
|
1020
|
-
fetchPromise.then((resource) => {
|
|
1021
|
-
if (resource) {
|
|
1022
|
-
setFetchedResource(resource);
|
|
1023
|
-
setIsLoading(false);
|
|
1024
|
-
}
|
|
1025
|
-
}).catch((err) => {
|
|
1026
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1027
|
-
setIsLoading(false);
|
|
1028
|
-
});
|
|
1029
|
-
}, [agent, content]);
|
|
1030
|
-
(0, react.useEffect)(() => {
|
|
1031
|
-
if (isLoading || !fetchedResource) return;
|
|
1032
|
-
const container = containerRef.current;
|
|
1033
|
-
if (!container) return;
|
|
1034
803
|
let mounted = true;
|
|
1035
|
-
|
|
1036
|
-
|
|
804
|
+
setIsLoading(true);
|
|
805
|
+
setError(null);
|
|
806
|
+
const iframe = document.createElement("iframe");
|
|
807
|
+
iframe.style.width = "100%";
|
|
808
|
+
iframe.style.height = "100px";
|
|
809
|
+
iframe.style.border = "none";
|
|
810
|
+
iframe.style.backgroundColor = "transparent";
|
|
811
|
+
iframe.style.display = "block";
|
|
812
|
+
container.appendChild(iframe);
|
|
813
|
+
iframeRef.current = iframe;
|
|
1037
814
|
const setup = async () => {
|
|
1038
815
|
try {
|
|
1039
|
-
const
|
|
1040
|
-
throw new Error("MCP Apps require '@
|
|
1041
|
-
});
|
|
1042
|
-
if (!mounted) return;
|
|
1043
|
-
const { AppBridge, PostMessageTransport } = bridgeModule;
|
|
1044
|
-
const iframe = document.createElement("iframe");
|
|
1045
|
-
createdIframe = iframe;
|
|
1046
|
-
iframe.style.width = "100%";
|
|
1047
|
-
iframe.style.height = "100px";
|
|
1048
|
-
iframe.style.border = "none";
|
|
1049
|
-
iframe.style.backgroundColor = "transparent";
|
|
1050
|
-
iframe.style.display = "block";
|
|
1051
|
-
iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
1052
|
-
iframe.setAttribute("data-testid", "mcp-app-iframe");
|
|
1053
|
-
iframe.setAttribute("title", "Interactive MCP application");
|
|
1054
|
-
const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;
|
|
1055
|
-
iframe.srcdoc = buildSandboxHTML(cspDomains);
|
|
1056
|
-
iframeRef.current = iframe;
|
|
1057
|
-
container.appendChild(iframe);
|
|
1058
|
-
const win = iframe.contentWindow;
|
|
1059
|
-
if (!win) throw new Error("Sandbox iframe has no contentWindow");
|
|
1060
|
-
let html;
|
|
1061
|
-
if (fetchedResource.text) html = fetchedResource.text;
|
|
1062
|
-
else if (fetchedResource.blob) html = atob(fetchedResource.blob);
|
|
1063
|
-
else throw new Error("Resource has no text or blob content");
|
|
1064
|
-
bridge = new AppBridge(null, {
|
|
1065
|
-
name: "CopilotKit MCP Apps Host",
|
|
1066
|
-
version: "1.0.0"
|
|
1067
|
-
}, {
|
|
1068
|
-
openLinks: {},
|
|
1069
|
-
logging: {},
|
|
1070
|
-
message: { text: {} }
|
|
1071
|
-
}, { hostContext: {
|
|
1072
|
-
theme: "light",
|
|
1073
|
-
platform: "web"
|
|
1074
|
-
} });
|
|
1075
|
-
bridge.onsandboxready = () => {
|
|
1076
|
-
bridge?.sendSandboxResourceReady({ html });
|
|
1077
|
-
};
|
|
1078
|
-
bridge.setRequestHandler(CopilotKitUiMessageSchema, async (req) => {
|
|
1079
|
-
const currentAgent = agentRef.current;
|
|
1080
|
-
if (!currentAgent) {
|
|
1081
|
-
console.warn("[MCPAppsRenderer] ui/message: No agent available");
|
|
1082
|
-
return { isError: false };
|
|
1083
|
-
}
|
|
1084
|
-
try {
|
|
1085
|
-
const params = req.params;
|
|
1086
|
-
const ck = params._meta?.copilotkit ?? {};
|
|
1087
|
-
const role = ck.role || params.role || "user";
|
|
1088
|
-
const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
|
|
1089
|
-
if (textContent) currentAgent.addMessage({
|
|
1090
|
-
id: crypto.randomUUID(),
|
|
1091
|
-
role,
|
|
1092
|
-
content: textContent
|
|
1093
|
-
});
|
|
1094
|
-
if ((ck.followUp ?? params.followUp ?? role === "user") && textContent) {
|
|
1095
|
-
const capturedThreadId = currentAgent.threadId || "default";
|
|
1096
|
-
mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
|
|
1097
|
-
host: copilotkit,
|
|
1098
|
-
agent: currentAgent,
|
|
1099
|
-
capturedThreadId
|
|
1100
|
-
})).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
|
|
1101
|
-
}
|
|
1102
|
-
return { isError: false };
|
|
1103
|
-
} catch (err) {
|
|
1104
|
-
console.error("[MCPAppsRenderer] ui/message error:", err);
|
|
1105
|
-
return { isError: true };
|
|
1106
|
-
}
|
|
816
|
+
const mod = await import("@copilotkit/mcp-apps-renderer").catch((importErr) => {
|
|
817
|
+
throw new Error("MCP Apps require '@copilotkit/mcp-apps-renderer' and its '@modelcontextprotocol/ext-apps' dependency. Reinstall your dependencies if this package is missing.", { cause: importErr });
|
|
1107
818
|
});
|
|
1108
|
-
bridge.onopenlink = async ({ url }) => {
|
|
1109
|
-
let parsed;
|
|
1110
|
-
try {
|
|
1111
|
-
parsed = new URL(url);
|
|
1112
|
-
} catch {
|
|
1113
|
-
console.warn("[MCPAppsRenderer] ui/open-link rejected: unparseable url");
|
|
1114
|
-
return { isError: true };
|
|
1115
|
-
}
|
|
1116
|
-
if (MCP_OPEN_LINK_BLOCKED_SCHEMES.has(parsed.protocol)) {
|
|
1117
|
-
console.warn("[MCPAppsRenderer] ui/open-link rejected: blocked scheme", parsed.protocol);
|
|
1118
|
-
return { isError: true };
|
|
1119
|
-
}
|
|
1120
|
-
window.open(url, "_blank", "noopener,noreferrer");
|
|
1121
|
-
return { isError: false };
|
|
1122
|
-
};
|
|
1123
|
-
bridge.oncalltool = async (params) => {
|
|
1124
|
-
const { serverHash, serverId } = contentRef.current;
|
|
1125
|
-
const currentAgent = agentRef.current;
|
|
1126
|
-
if (!serverHash) throw new Error("No server hash available for proxying");
|
|
1127
|
-
if (!currentAgent) throw new Error("No agent available for proxying");
|
|
1128
|
-
return (await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
|
|
1129
|
-
serverHash,
|
|
1130
|
-
serverId,
|
|
1131
|
-
method: "tools/call",
|
|
1132
|
-
params
|
|
1133
|
-
} } }))).result || { content: [] };
|
|
1134
|
-
};
|
|
1135
|
-
bridge.onsizechange = (p) => {
|
|
1136
|
-
if (!mounted) return;
|
|
1137
|
-
const { width, height } = p || {};
|
|
1138
|
-
setIframeSize({
|
|
1139
|
-
width: typeof width === "number" ? width : void 0,
|
|
1140
|
-
height: typeof height === "number" ? height : void 0
|
|
1141
|
-
});
|
|
1142
|
-
};
|
|
1143
|
-
bridge.oninitialized = () => {
|
|
1144
|
-
if (mounted) setIframeReady(true);
|
|
1145
|
-
};
|
|
1146
|
-
bridge.onloggingmessage = (p) => {
|
|
1147
|
-
console.log("[MCPAppsRenderer] App log:", p);
|
|
1148
|
-
};
|
|
1149
|
-
const transport = new PostMessageTransport(win, win);
|
|
1150
|
-
await bridge.connect(transport);
|
|
1151
819
|
if (!mounted) {
|
|
1152
|
-
|
|
820
|
+
iframe.remove();
|
|
1153
821
|
return;
|
|
1154
822
|
}
|
|
1155
|
-
|
|
823
|
+
const session = mod.bindMcpApp({
|
|
824
|
+
iframe,
|
|
825
|
+
getContent: () => contentRef.current,
|
|
826
|
+
getAgent: () => agentRef.current,
|
|
827
|
+
host: copilotkit,
|
|
828
|
+
hooks: {
|
|
829
|
+
onResource: (resource) => {
|
|
830
|
+
if (!mounted) return;
|
|
831
|
+
setFetchedResource(resource);
|
|
832
|
+
setIsLoading(false);
|
|
833
|
+
},
|
|
834
|
+
onSizeChanged: (size) => {
|
|
835
|
+
if (mounted) setIframeSize(size);
|
|
836
|
+
},
|
|
837
|
+
onError: (err) => {
|
|
838
|
+
if (!mounted) return;
|
|
839
|
+
setError(err);
|
|
840
|
+
setIsLoading(false);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
sessionRef.current = session;
|
|
845
|
+
const current = contentRef.current;
|
|
846
|
+
if (current.toolInput) session.sendToolInput(current.toolInput);
|
|
847
|
+
if (current.result) session.sendToolResult(current.result);
|
|
1156
848
|
} catch (err) {
|
|
1157
849
|
console.error("[MCPAppsRenderer] Setup error:", err);
|
|
1158
|
-
if (mounted)
|
|
850
|
+
if (mounted) {
|
|
851
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
852
|
+
setIsLoading(false);
|
|
853
|
+
}
|
|
1159
854
|
}
|
|
1160
855
|
};
|
|
1161
856
|
setup();
|
|
1162
857
|
return () => {
|
|
1163
858
|
mounted = false;
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
createdIframe.remove();
|
|
1168
|
-
createdIframe = null;
|
|
1169
|
-
}
|
|
859
|
+
sessionRef.current?.teardown();
|
|
860
|
+
sessionRef.current = null;
|
|
861
|
+
iframe.remove();
|
|
1170
862
|
iframeRef.current = null;
|
|
1171
863
|
};
|
|
1172
864
|
}, [
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
865
|
+
agent,
|
|
866
|
+
copilotkit,
|
|
867
|
+
content.resourceUri,
|
|
868
|
+
content.serverHash,
|
|
869
|
+
content.serverId
|
|
1176
870
|
]);
|
|
1177
871
|
(0, react.useEffect)(() => {
|
|
1178
872
|
if (iframeRef.current) {
|
|
@@ -1184,11 +878,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1184
878
|
}
|
|
1185
879
|
}, [iframeSize]);
|
|
1186
880
|
(0, react.useEffect)(() => {
|
|
1187
|
-
if (
|
|
1188
|
-
}, [
|
|
881
|
+
if (content.toolInput) sessionRef.current?.sendToolInput(content.toolInput);
|
|
882
|
+
}, [content.toolInput]);
|
|
1189
883
|
(0, react.useEffect)(() => {
|
|
1190
|
-
if (
|
|
1191
|
-
}, [
|
|
884
|
+
if (content.result) sessionRef.current?.sendToolResult(content.result);
|
|
885
|
+
}, [content.result]);
|
|
1192
886
|
const borderStyle = fetchedResource?._meta?.ui?.prefersBorder === true ? {
|
|
1193
887
|
borderRadius: "8px",
|
|
1194
888
|
backgroundColor: "#f9f9f9",
|
|
@@ -2575,8 +2269,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2575
2269
|
}, [rawCatalog, catalogToggleVersion]);
|
|
2576
2270
|
const builtInActivityRenderers = (0, react.useMemo)(() => {
|
|
2577
2271
|
const renderers = [{
|
|
2578
|
-
activityType: MCPAppsActivityType,
|
|
2579
|
-
content: MCPAppsActivityContentSchema,
|
|
2272
|
+
activityType: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityType,
|
|
2273
|
+
content: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityContentSchema,
|
|
2580
2274
|
render: MCPAppsActivityRenderer
|
|
2581
2275
|
}];
|
|
2582
2276
|
if (openGenUIActive) renderers.push({
|