@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.
Files changed (37) hide show
  1. package/dist/{copilotkit-CrNUgJiq.d.cts → copilotkit-CtF2clxZ.d.cts} +50 -23
  2. package/dist/copilotkit-CtF2clxZ.d.cts.map +1 -0
  3. package/dist/{copilotkit-BPeh62mW.cjs → copilotkit-CxLT6zFx.cjs} +214 -230
  4. package/dist/copilotkit-CxLT6zFx.cjs.map +1 -0
  5. package/dist/{copilotkit-JdHy0xdu.mjs → copilotkit-DiUK2Bhq.mjs} +209 -231
  6. package/dist/copilotkit-DiUK2Bhq.mjs.map +1 -0
  7. package/dist/{copilotkit-DgO31tBq.d.mts → copilotkit-DsWuxPUQ.d.mts} +50 -23
  8. package/dist/copilotkit-DsWuxPUQ.d.mts.map +1 -0
  9. package/dist/index.cjs +97 -24
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +18 -3
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts +18 -3
  14. package/dist/index.d.mts.map +1 -1
  15. package/dist/index.mjs +97 -24
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/index.umd.js +275 -239
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/v2/headless.cjs +16 -8
  20. package/dist/v2/headless.cjs.map +1 -1
  21. package/dist/v2/headless.d.cts.map +1 -1
  22. package/dist/v2/headless.d.mts.map +1 -1
  23. package/dist/v2/headless.mjs +16 -8
  24. package/dist/v2/headless.mjs.map +1 -1
  25. package/dist/v2/index.cjs +2 -1
  26. package/dist/v2/index.d.cts +2 -2
  27. package/dist/v2/index.d.mts +2 -2
  28. package/dist/v2/index.mjs +2 -2
  29. package/dist/v2/index.umd.js +208 -229
  30. package/dist/v2/index.umd.js.map +1 -1
  31. package/package.json +13 -10
  32. package/skills/react-core/SKILL.md +1 -1
  33. package/skills/react-core/references/threads.md +1 -1
  34. package/dist/copilotkit-BPeh62mW.cjs.map +0 -1
  35. package/dist/copilotkit-CrNUgJiq.d.cts.map +0 -1
  36. package/dist/copilotkit-DgO31tBq.d.mts.map +0 -1
  37. package/dist/copilotkit-JdHy0xdu.mjs.map +0 -1
@@ -1367,7 +1367,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1367
1367
  side: "bottom",
1368
1368
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1369
1369
  className: "cpk:flex cpk:items-center cpk:gap-1 cpk:text-xs cpk:font-medium",
1370
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Add attachments" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1370
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: labels.chatInputToolbarAddButtonLabel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1371
1371
  className: "cpk:rounded cpk:bg-[#4a4a4a] cpk:px-1 cpk:py-[1px] cpk:font-mono cpk:text-[11px] cpk:text-white cpk:dark:bg-[#e0e0e0] cpk:dark:text-black",
1372
1372
  children: "/"
1373
1373
  })]
@@ -1876,7 +1876,6 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
1876
1876
  newMessages: []
1877
1877
  };
1878
1878
  }
1879
- const PROTOCOL_VERSION = "2025-06-18";
1880
1879
  function buildSandboxHTML(extraCspDomains) {
1881
1880
  const baseScriptSrc = "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*";
1882
1881
  const baseFrameSrc = "* blob: data: http://localhost:* https://localhost:*";
@@ -1988,6 +1987,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
1988
1987
  }
1989
1988
  };
1990
1989
  const mcpAppsRequestQueue = new MCPAppsRequestQueue();
1990
+ const MCP_OPEN_LINK_BLOCKED_SCHEMES = new Set([
1991
+ "javascript:",
1992
+ "data:",
1993
+ "vbscript:",
1994
+ "blob:",
1995
+ "file:"
1996
+ ]);
1991
1997
  /**
1992
1998
  * Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType
1993
1999
  */
@@ -2003,18 +2009,32 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2003
2009
  serverId: zod.z.string().optional(),
2004
2010
  toolInput: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
2005
2011
  });
2006
- function isRequest(msg) {
2007
- return "id" in msg && "method" in msg;
2008
- }
2009
- function isNotification(msg) {
2010
- return !("id" in msg) && "method" in msg;
2011
- }
2012
2012
  /**
2013
2013
  * MCP Apps Extension Activity Renderer
2014
2014
  *
2015
2015
  * Renders MCP Apps UI in a sandboxed iframe with full protocol support.
2016
2016
  * Fetches resource content on-demand via proxied MCP requests.
2017
2017
  */
2018
+ /**
2019
+ * Permissive `ui/message` schema. ext-apps restricts the request to
2020
+ * `role: "user"` with no `followUp`, but CopilotKit intentionally extends
2021
+ * `ui/message` with `role` ("user" | "assistant") and `followUp` (documented
2022
+ * behavior with dedicated tests). We register our own handler (instead of the
2023
+ * bridge's strict `onmessage`) so those extensions survive the migration.
2024
+ *
2025
+ * Going forward, widgets SHOULD pass the extensions under
2026
+ * `params._meta.copilotkit`; the top-level `role`/`followUp` fields are the
2027
+ * legacy channel, kept for backward compatibility and slated for deprecation.
2028
+ */
2029
+ const CopilotKitUiMessageSchema = zod.z.object({
2030
+ method: zod.z.literal("ui/message"),
2031
+ params: zod.z.object({
2032
+ role: zod.z.string().optional(),
2033
+ content: zod.z.array(zod.z.any()).optional(),
2034
+ followUp: zod.z.boolean().optional(),
2035
+ _meta: zod.z.record(zod.z.string(), zod.z.any()).optional()
2036
+ }).passthrough()
2037
+ });
2018
2038
  const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, agent }) {
2019
2039
  const { copilotkit } = useCopilotKit();
2020
2040
  const containerRef = (0, react.useRef)(null);
@@ -2028,41 +2048,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2028
2048
  contentRef.current = content;
2029
2049
  const agentRef = (0, react.useRef)(agent);
2030
2050
  agentRef.current = agent;
2051
+ const bridgeRef = (0, react.useRef)(null);
2031
2052
  const fetchStateRef = (0, react.useRef)({
2032
2053
  inProgress: false,
2033
2054
  promise: null,
2034
2055
  resourceUri: null
2035
2056
  });
2036
- const sendToIframe = (0, react.useCallback)((msg) => {
2037
- if (iframeRef.current?.contentWindow) {
2038
- console.log("[MCPAppsRenderer] Sending to iframe:", msg);
2039
- iframeRef.current.contentWindow.postMessage(msg, "*");
2040
- }
2041
- }, []);
2042
- const sendResponse = (0, react.useCallback)((id, result) => {
2043
- sendToIframe({
2044
- jsonrpc: "2.0",
2045
- id,
2046
- result
2047
- });
2048
- }, [sendToIframe]);
2049
- const sendErrorResponse = (0, react.useCallback)((id, code, message) => {
2050
- sendToIframe({
2051
- jsonrpc: "2.0",
2052
- id,
2053
- error: {
2054
- code,
2055
- message
2056
- }
2057
- });
2058
- }, [sendToIframe]);
2059
- const sendNotification = (0, react.useCallback)((method, params) => {
2060
- sendToIframe({
2061
- jsonrpc: "2.0",
2062
- method,
2063
- params: params || {}
2064
- });
2065
- }, [sendToIframe]);
2066
2057
  (0, react.useEffect)(() => {
2067
2058
  const { resourceUri, serverHash, serverId } = content;
2068
2059
  if (fetchStateRef.current.inProgress && fetchStateRef.current.resourceUri === resourceUri) {
@@ -2117,11 +2108,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2117
2108
  const container = containerRef.current;
2118
2109
  if (!container) return;
2119
2110
  let mounted = true;
2120
- let messageHandler = null;
2121
- let initialListener = null;
2111
+ let bridge = null;
2122
2112
  let createdIframe = null;
2123
2113
  const setup = async () => {
2124
2114
  try {
2115
+ const bridgeModule = await import("@modelcontextprotocol/ext-apps/app-bridge").catch((importErr) => {
2116
+ 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 });
2117
+ });
2118
+ if (!mounted) return;
2119
+ const { AppBridge, PostMessageTransport } = bridgeModule;
2125
2120
  const iframe = document.createElement("iframe");
2126
2121
  createdIframe = iframe;
2127
2122
  iframe.style.width = "100%";
@@ -2132,151 +2127,108 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2132
2127
  iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
2133
2128
  iframe.setAttribute("data-testid", "mcp-app-iframe");
2134
2129
  iframe.setAttribute("title", "Interactive MCP application");
2135
- const sandboxReady = new Promise((resolve) => {
2136
- initialListener = (event) => {
2137
- if (event.source === iframe.contentWindow) {
2138
- if (event.data?.method === "ui/notifications/sandbox-proxy-ready") {
2139
- if (initialListener) {
2140
- window.removeEventListener("message", initialListener);
2141
- initialListener = null;
2142
- }
2143
- resolve();
2144
- }
2145
- }
2146
- };
2147
- window.addEventListener("message", initialListener);
2148
- });
2149
- if (!mounted) {
2150
- if (initialListener) {
2151
- window.removeEventListener("message", initialListener);
2152
- initialListener = null;
2153
- }
2154
- return;
2155
- }
2156
2130
  const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;
2157
2131
  iframe.srcdoc = buildSandboxHTML(cspDomains);
2158
2132
  iframeRef.current = iframe;
2159
2133
  container.appendChild(iframe);
2160
- await sandboxReady;
2161
- if (!mounted) return;
2162
- console.log("[MCPAppsRenderer] Sandbox proxy ready");
2163
- messageHandler = async (event) => {
2164
- if (event.source !== iframe.contentWindow) return;
2165
- const msg = event.data;
2166
- if (!msg || typeof msg !== "object" || msg.jsonrpc !== "2.0") return;
2167
- console.log("[MCPAppsRenderer] Received from iframe:", msg);
2168
- if (isRequest(msg)) switch (msg.method) {
2169
- case "ui/initialize":
2170
- sendResponse(msg.id, {
2171
- protocolVersion: PROTOCOL_VERSION,
2172
- hostInfo: {
2173
- name: "CopilotKit MCP Apps Host",
2174
- version: "1.0.0"
2175
- },
2176
- hostCapabilities: {
2177
- openLinks: {},
2178
- logging: {}
2179
- },
2180
- hostContext: {
2181
- theme: "light",
2182
- platform: "web"
2183
- }
2184
- });
2185
- break;
2186
- case "ui/message": {
2187
- const currentAgent = agentRef.current;
2188
- if (!currentAgent) {
2189
- console.warn("[MCPAppsRenderer] ui/message: No agent available");
2190
- sendResponse(msg.id, { isError: false });
2191
- break;
2192
- }
2193
- try {
2194
- const params = msg.params;
2195
- const role = params.role || "user";
2196
- const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
2197
- if (textContent) currentAgent.addMessage({
2198
- id: crypto.randomUUID(),
2199
- role,
2200
- content: textContent
2201
- });
2202
- sendResponse(msg.id, { isError: false });
2203
- if ((params.followUp ?? role === "user") && textContent) {
2204
- const capturedThreadId = currentAgent.threadId || "default";
2205
- mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
2206
- host: copilotkit,
2207
- agent: currentAgent,
2208
- capturedThreadId
2209
- })).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
2210
- }
2211
- } catch (err) {
2212
- console.error("[MCPAppsRenderer] ui/message error:", err);
2213
- sendResponse(msg.id, { isError: true });
2214
- }
2215
- break;
2216
- }
2217
- case "ui/open-link": {
2218
- const url = msg.params?.url;
2219
- if (url) {
2220
- window.open(url, "_blank", "noopener,noreferrer");
2221
- sendResponse(msg.id, { isError: false });
2222
- } else sendErrorResponse(msg.id, -32602, "Missing url parameter");
2223
- break;
2224
- }
2225
- case "tools/call": {
2226
- const { serverHash, serverId } = contentRef.current;
2227
- const currentAgent = agentRef.current;
2228
- if (!serverHash) {
2229
- sendErrorResponse(msg.id, -32603, "No server hash available for proxying");
2230
- break;
2231
- }
2232
- if (!currentAgent) {
2233
- sendErrorResponse(msg.id, -32603, "No agent available for proxying");
2234
- break;
2235
- }
2236
- try {
2237
- const runResult = await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
2238
- serverHash,
2239
- serverId,
2240
- method: "tools/call",
2241
- params: msg.params
2242
- } } }));
2243
- sendResponse(msg.id, runResult.result || {});
2244
- } catch (err) {
2245
- console.error("[MCPAppsRenderer] tools/call error:", err);
2246
- sendErrorResponse(msg.id, -32603, String(err));
2247
- }
2248
- break;
2249
- }
2250
- default: sendErrorResponse(msg.id, -32601, `Method not found: ${msg.method}`);
2251
- }
2252
- if (isNotification(msg)) switch (msg.method) {
2253
- case "ui/notifications/initialized":
2254
- console.log("[MCPAppsRenderer] Inner iframe initialized");
2255
- if (mounted) setIframeReady(true);
2256
- break;
2257
- case "ui/notifications/size-changed": {
2258
- const { width, height } = msg.params || {};
2259
- console.log("[MCPAppsRenderer] Size change:", {
2260
- width,
2261
- height
2262
- });
2263
- if (mounted) setIframeSize({
2264
- width: typeof width === "number" ? width : void 0,
2265
- height: typeof height === "number" ? height : void 0
2266
- });
2267
- break;
2268
- }
2269
- case "notifications/message":
2270
- console.log("[MCPAppsRenderer] App log:", msg.params);
2271
- break;
2272
- }
2273
- };
2274
- window.addEventListener("message", messageHandler);
2134
+ const win = iframe.contentWindow;
2135
+ if (!win) throw new Error("Sandbox iframe has no contentWindow");
2275
2136
  let html;
2276
2137
  if (fetchedResource.text) html = fetchedResource.text;
2277
2138
  else if (fetchedResource.blob) html = atob(fetchedResource.blob);
2278
2139
  else throw new Error("Resource has no text or blob content");
2279
- sendNotification("ui/notifications/sandbox-resource-ready", { html });
2140
+ bridge = new AppBridge(null, {
2141
+ name: "CopilotKit MCP Apps Host",
2142
+ version: "1.0.0"
2143
+ }, {
2144
+ openLinks: {},
2145
+ logging: {},
2146
+ message: { text: {} }
2147
+ }, { hostContext: {
2148
+ theme: "light",
2149
+ platform: "web"
2150
+ } });
2151
+ bridge.onsandboxready = () => {
2152
+ bridge?.sendSandboxResourceReady({ html });
2153
+ };
2154
+ bridge.setRequestHandler(CopilotKitUiMessageSchema, async (req) => {
2155
+ const currentAgent = agentRef.current;
2156
+ if (!currentAgent) {
2157
+ console.warn("[MCPAppsRenderer] ui/message: No agent available");
2158
+ return { isError: false };
2159
+ }
2160
+ try {
2161
+ const params = req.params;
2162
+ const ck = params._meta?.copilotkit ?? {};
2163
+ const role = ck.role || params.role || "user";
2164
+ const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
2165
+ if (textContent) currentAgent.addMessage({
2166
+ id: crypto.randomUUID(),
2167
+ role,
2168
+ content: textContent
2169
+ });
2170
+ if ((ck.followUp ?? params.followUp ?? role === "user") && textContent) {
2171
+ const capturedThreadId = currentAgent.threadId || "default";
2172
+ mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
2173
+ host: copilotkit,
2174
+ agent: currentAgent,
2175
+ capturedThreadId
2176
+ })).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
2177
+ }
2178
+ return { isError: false };
2179
+ } catch (err) {
2180
+ console.error("[MCPAppsRenderer] ui/message error:", err);
2181
+ return { isError: true };
2182
+ }
2183
+ });
2184
+ bridge.onopenlink = async ({ url }) => {
2185
+ let parsed;
2186
+ try {
2187
+ parsed = new URL(url);
2188
+ } catch {
2189
+ console.warn("[MCPAppsRenderer] ui/open-link rejected: unparseable url");
2190
+ return { isError: true };
2191
+ }
2192
+ if (MCP_OPEN_LINK_BLOCKED_SCHEMES.has(parsed.protocol)) {
2193
+ console.warn("[MCPAppsRenderer] ui/open-link rejected: blocked scheme", parsed.protocol);
2194
+ return { isError: true };
2195
+ }
2196
+ window.open(url, "_blank", "noopener,noreferrer");
2197
+ return { isError: false };
2198
+ };
2199
+ bridge.oncalltool = async (params) => {
2200
+ const { serverHash, serverId } = contentRef.current;
2201
+ const currentAgent = agentRef.current;
2202
+ if (!serverHash) throw new Error("No server hash available for proxying");
2203
+ if (!currentAgent) throw new Error("No agent available for proxying");
2204
+ return (await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
2205
+ serverHash,
2206
+ serverId,
2207
+ method: "tools/call",
2208
+ params
2209
+ } } }))).result || { content: [] };
2210
+ };
2211
+ bridge.onsizechange = (p) => {
2212
+ if (!mounted) return;
2213
+ const { width, height } = p || {};
2214
+ setIframeSize({
2215
+ width: typeof width === "number" ? width : void 0,
2216
+ height: typeof height === "number" ? height : void 0
2217
+ });
2218
+ };
2219
+ bridge.oninitialized = () => {
2220
+ if (mounted) setIframeReady(true);
2221
+ };
2222
+ bridge.onloggingmessage = (p) => {
2223
+ console.log("[MCPAppsRenderer] App log:", p);
2224
+ };
2225
+ const transport = new PostMessageTransport(win, win);
2226
+ await bridge.connect(transport);
2227
+ if (!mounted) {
2228
+ await bridge.close();
2229
+ return;
2230
+ }
2231
+ bridgeRef.current = bridge;
2280
2232
  } catch (err) {
2281
2233
  console.error("[MCPAppsRenderer] Setup error:", err);
2282
2234
  if (mounted) setError(err instanceof Error ? err : new Error(String(err)));
@@ -2285,11 +2237,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2285
2237
  setup();
2286
2238
  return () => {
2287
2239
  mounted = false;
2288
- if (initialListener) {
2289
- window.removeEventListener("message", initialListener);
2290
- initialListener = null;
2291
- }
2292
- if (messageHandler) window.removeEventListener("message", messageHandler);
2240
+ bridgeRef.current = null;
2241
+ bridge?.close();
2293
2242
  if (createdIframe) {
2294
2243
  createdIframe.remove();
2295
2244
  createdIframe = null;
@@ -2299,9 +2248,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2299
2248
  }, [
2300
2249
  isLoading,
2301
2250
  fetchedResource,
2302
- sendNotification,
2303
- sendResponse,
2304
- sendErrorResponse
2251
+ copilotkit
2305
2252
  ]);
2306
2253
  (0, react.useEffect)(() => {
2307
2254
  if (iframeRef.current) {
@@ -2313,25 +2260,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2313
2260
  }
2314
2261
  }, [iframeSize]);
2315
2262
  (0, react.useEffect)(() => {
2316
- if (iframeReady && content.toolInput) {
2317
- console.log("[MCPAppsRenderer] Sending tool input:", content.toolInput);
2318
- sendNotification("ui/notifications/tool-input", { arguments: content.toolInput });
2319
- }
2320
- }, [
2321
- iframeReady,
2322
- content.toolInput,
2323
- sendNotification
2324
- ]);
2263
+ if (iframeReady && content.toolInput) bridgeRef.current?.sendToolInput({ arguments: content.toolInput });
2264
+ }, [iframeReady, content.toolInput]);
2325
2265
  (0, react.useEffect)(() => {
2326
- if (iframeReady && content.result) {
2327
- console.log("[MCPAppsRenderer] Sending tool result:", content.result);
2328
- sendNotification("ui/notifications/tool-result", content.result);
2329
- }
2330
- }, [
2331
- iframeReady,
2332
- content.result,
2333
- sendNotification
2334
- ]);
2266
+ if (iframeReady && content.result) bridgeRef.current?.sendToolResult(content.result);
2267
+ }, [iframeReady, content.result]);
2335
2268
  const borderStyle = fetchedResource?._meta?.ui?.prefersBorder === true ? {
2336
2269
  borderRadius: "8px",
2337
2270
  backgroundColor: "#f9f9f9",
@@ -3551,6 +3484,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3551
3484
  const a2uiCatalogProvided = !!a2ui?.catalog;
3552
3485
  const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;
3553
3486
  const [runtimeLicenseStatus, setRuntimeLicenseStatus] = (0, react.useState)(void 0);
3487
+ const [runtimeEntitlements, setRuntimeEntitlements] = (0, react.useState)(void 0);
3488
+ const [runtimeEntitlementRetryPending, setRuntimeEntitlementRetryPending] = (0, react.useState)(false);
3554
3489
  const requestInspectorOpen = (0, react.useCallback)((request) => {
3555
3490
  setInspectorOpenRequest({ ...request });
3556
3491
  }, []);
@@ -3741,6 +3676,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3741
3676
  setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
3742
3677
  setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
3743
3678
  setRuntimeLicenseStatus(copilotkit.licenseStatus);
3679
+ setRuntimeEntitlements(copilotkit.runtimeEntitlements);
3680
+ setRuntimeEntitlementRetryPending(copilotkit.runtimeEntitlementRetryPending);
3744
3681
  };
3745
3682
  const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: syncRuntimeInfo });
3746
3683
  syncRuntimeInfo();
@@ -3881,7 +3818,26 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3881
3818
  copilotkit,
3882
3819
  executingToolCallIds
3883
3820
  }), [copilotkit, executingToolCallIds]);
3884
- const licenseContextValue = (0, react.useMemo)(() => (0, _copilotkit_shared.createLicenseContextValue)(runtimeLicenseStatus), [runtimeLicenseStatus]);
3821
+ const retryableRuntimeEntitlementFailure = runtimeEntitlements?.status !== "ready" && runtimeEntitlements?.error.retryable === true;
3822
+ const hasNonReadyRuntimeEntitlement = runtimeEntitlements !== void 0 && runtimeEntitlements.status !== "ready";
3823
+ const hasLegacyRuntimeEntitlementFallback = runtimeLicenseStatus === "valid" || runtimeLicenseStatus === "expiring";
3824
+ const runtimeEntitlementRetryInProgress = retryableRuntimeEntitlementFailure && runtimeEntitlementRetryPending && !hasLegacyRuntimeEntitlementFallback;
3825
+ const runtimeEntitlementFailureSettled = hasNonReadyRuntimeEntitlement && !runtimeEntitlementRetryInProgress && !hasLegacyRuntimeEntitlementFallback;
3826
+ const licenseContextValue = (0, react.useMemo)(() => {
3827
+ const runtimeLicenseContext = (0, _copilotkit_shared.createLicenseContextValue)(runtimeEntitlementRetryInProgress ? void 0 : runtimeLicenseStatus, runtimeEntitlements);
3828
+ if (!runtimeEntitlementFailureSettled) return runtimeLicenseContext;
3829
+ return {
3830
+ ...runtimeLicenseContext,
3831
+ checkFeature: () => false,
3832
+ getLimit: () => null
3833
+ };
3834
+ }, [
3835
+ runtimeEntitlementFailureSettled,
3836
+ runtimeEntitlementRetryInProgress,
3837
+ runtimeEntitlements,
3838
+ runtimeLicenseStatus
3839
+ ]);
3840
+ const runtimeLicenseWarningStatus = runtimeEntitlementRetryInProgress ? void 0 : licenseContextValue.status ?? void 0;
3885
3841
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
3886
3842
  value: sandboxFunctionsList,
3887
3843
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
@@ -3901,10 +3857,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
3901
3857
  openRequest: inspectorOpenRequest
3902
3858
  }) : null]
3903
3859
  }),
3904
- runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
3905
- runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
3906
- runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
3907
- runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
3860
+ runtimeLicenseWarningStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
3861
+ runtimeLicenseWarningStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
3862
+ runtimeLicenseWarningStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
3863
+ runtimeLicenseWarningStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
3908
3864
  ]
3909
3865
  })
3910
3866
  })
@@ -4004,7 +3960,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4004
3960
  function useFrontendTool(tool, deps) {
4005
3961
  const { copilotkit } = useCopilotKit();
4006
3962
  const extraDeps = deps ?? EMPTY_DEPS$1;
4007
- (0, react.useEffect)(() => {
3963
+ (0, react.useLayoutEffect)(() => {
4008
3964
  const name = tool.name;
4009
3965
  if (copilotkit.getTool({
4010
3966
  toolName: name,
@@ -4027,7 +3983,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4027
3983
  tool.name,
4028
3984
  tool.available,
4029
3985
  copilotkit,
4030
- JSON.stringify(extraDeps)
3986
+ JSON.stringify(extraDeps),
3987
+ JSON.stringify(tool.webmcp ?? null)
4031
3988
  ]);
4032
3989
  }
4033
3990
 
@@ -4371,6 +4328,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4371
4328
 
4372
4329
  //#endregion
4373
4330
  //#region src/v2/hooks/use-human-in-the-loop.tsx
4331
+ /** Registration name of a catch-all tool: handles any otherwise-unhandled call. */
4332
+ const WILDCARD_TOOL_NAME = "*";
4374
4333
  function useHumanInTheLoop(tool, deps) {
4375
4334
  const { copilotkit } = useCopilotKit();
4376
4335
  const resolvePromiseRef = (0, react.useRef)(null);
@@ -4406,10 +4365,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4406
4365
  }, []);
4407
4366
  const RenderComponent = (0, react.useCallback)((props) => {
4408
4367
  const ToolComponent = tool.render;
4368
+ const name = tool.name === WILDCARD_TOOL_NAME ? props.name : tool.name;
4409
4369
  if (props.status === _copilotkit_core.ToolCallStatus.InProgress) {
4410
4370
  const enhancedProps = {
4411
4371
  ...props,
4412
- name: tool.name,
4372
+ name,
4413
4373
  description: tool.description || "",
4414
4374
  agentId: tool.agentId,
4415
4375
  respond: void 0
@@ -4418,7 +4378,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4418
4378
  } else if (props.status === _copilotkit_core.ToolCallStatus.Executing) {
4419
4379
  const enhancedProps = {
4420
4380
  ...props,
4421
- name: tool.name,
4381
+ name,
4422
4382
  description: tool.description || "",
4423
4383
  agentId: tool.agentId,
4424
4384
  respond
@@ -4427,7 +4387,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4427
4387
  } else if (props.status === _copilotkit_core.ToolCallStatus.Complete) {
4428
4388
  const enhancedProps = {
4429
4389
  ...props,
4430
- name: tool.name,
4390
+ name,
4431
4391
  description: tool.description || "",
4432
4392
  agentId: tool.agentId,
4433
4393
  respond: void 0
@@ -4447,7 +4407,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4447
4407
  handler,
4448
4408
  render: RenderComponent
4449
4409
  }, deps);
4450
- (0, react.useEffect)(() => {
4410
+ (0, react.useLayoutEffect)(() => {
4451
4411
  return () => {
4452
4412
  copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
4453
4413
  };
@@ -4912,8 +4872,12 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4912
4872
  }
4913
4873
 
4914
4874
  //#endregion
4915
- //#region src/v2/hooks/use-interrupt.tsx
4875
+ //#region src/v2/types/interrupt.ts
4876
+ /** Name of the legacy custom event agents emit to signal an interrupt. */
4916
4877
  const INTERRUPT_EVENT_NAME = "on_interrupt";
4878
+
4879
+ //#endregion
4880
+ //#region src/v2/hooks/use-interrupt.tsx
4917
4881
  function isPromiseLike(value) {
4918
4882
  return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
4919
4883
  }
@@ -5250,7 +5214,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5250
5214
  */
5251
5215
  function useThreads({ agentId, includeArchived, limit, enabled = true }) {
5252
5216
  const { copilotkit } = useCopilotKit();
5253
- const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
5217
+ const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: copilotkit.ɵruntimeFetch }));
5254
5218
  const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
5255
5219
  const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
5256
5220
  id,
@@ -5814,9 +5778,9 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5814
5778
  * }
5815
5779
  * ```
5816
5780
  *
5817
- * @deprecated Legacy plural-container annotation compatibility only. New
5818
- * Intelligence runtimes assign one container with `ɵlearning.containerId` on
5819
- * `CopilotRuntime`.
5781
+ * @deprecated This hook supports only the legacy plural-container annotation.
5782
+ * Configure `getLearningContainerId` on `CopilotKitIntelligence` for new
5783
+ * Intelligence runtimes.
5820
5784
  */
5821
5785
  function useLearningContainers({ threadId, learningContainers }) {
5822
5786
  const { copilotkit } = useCopilotKit();
@@ -5920,9 +5884,9 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5920
5884
  * }
5921
5885
  * ```
5922
5886
  *
5923
- * @deprecated Legacy plural-container annotation compatibility only. New
5924
- * Intelligence runtimes assign one container with `ɵlearning.containerId` on
5925
- * `CopilotRuntime`.
5887
+ * @deprecated This hook supports only the legacy plural-container annotation.
5888
+ * Configure `getLearningContainerId` on `CopilotKitIntelligence` for new
5889
+ * Intelligence runtimes.
5926
5890
  */
5927
5891
  function useLearningContainersInCurrentThread({ learningContainers }) {
5928
5892
  const threadId = useCopilotChatConfiguration()?.threadId;
@@ -5949,21 +5913,35 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5949
5913
 
5950
5914
  //#endregion
5951
5915
  //#region src/v2/components/chat/CopilotChatAssistantMessage.tsx
5916
+ /**
5917
+ * Binds the Inspector action to the active chat without making the full
5918
+ * assistant message subscribe to chat configuration changes.
5919
+ */
5920
+ function BoundInspectorButton({ inspectorButton, messageId, openInspector, ...props }) {
5921
+ const chatConfiguration = useCopilotChatConfiguration();
5922
+ return renderSlot(inspectorButton, CopilotChatAssistantMessage.InspectorButton, {
5923
+ ...props,
5924
+ onClick: () => openInspector({
5925
+ messageId,
5926
+ threadId: chatConfiguration?.threadId,
5927
+ agentId: chatConfiguration?.agentId
5928
+ })
5929
+ });
5930
+ }
5952
5931
  function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp, onThumbsDown, onReadAloud, onRegenerate, additionalToolbarItems, toolbarVisible = true, markdownRenderer, toolbar, copyButton, inspectorButton, thumbsUpButton, thumbsDownButton, readAloudButton, regenerateButton, toolCallsView, children, className, ...props }) {
5953
5932
  useKatexStyles();
5954
5933
  const { isInspectorEnabled, openInspector } = useCopilotKitInspector();
5955
- const chatConfiguration = useCopilotChatConfiguration();
5956
5934
  const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
5957
5935
  const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
5958
5936
  if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
5959
5937
  return false;
5960
5938
  } });
5961
5939
  const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp ? () => onThumbsUp(message) : void 0 });
5962
- const boundInspectorButton = renderSlot(inspectorButton, CopilotChatAssistantMessage.InspectorButton, { onClick: () => openInspector({
5940
+ const boundInspectorButton = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundInspectorButton, {
5941
+ inspectorButton,
5963
5942
  messageId: message.id,
5964
- threadId: chatConfiguration?.threadId,
5965
- agentId: chatConfiguration?.agentId
5966
- }) });
5943
+ openInspector
5944
+ });
5967
5945
  const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown ? () => onThumbsDown(message) : void 0 });
5968
5946
  const boundReadAloudButton = renderSlot(readAloudButton, CopilotChatAssistantMessage.ReadAloudButton, { onClick: onReadAloud ? () => onReadAloud(message) : void 0 });
5969
5947
  const boundRegenerateButton = renderSlot(regenerateButton, CopilotChatAssistantMessage.RegenerateButton, { onClick: onRegenerate ? () => onRegenerate(message) : void 0 });
@@ -8543,7 +8521,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
8543
8521
  const startRunActivityReconnectRef = (0, react.useRef)(null);
8544
8522
  const runtimeStatus = copilotkit.runtimeConnectionStatus === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected ? "Connected" : copilotkit.runtimeConnectionStatus;
8545
8523
  const hasNativeIntelligenceRunActivity = hasExplicitThreadId && runtimeStatus === "Connected" && !!copilotkit.intelligence?.wsUrl && copilotkit.threadEndpoints?.realtimeMetadata === true;
8546
- const [standaloneRunActivityStore] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
8524
+ const [standaloneRunActivityStore] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: copilotkit.ɵruntimeFetch }));
8547
8525
  const previousThreadRef = (0, react.useRef)(null);
8548
8526
  const hasExplicitThreadIdRef = (0, react.useRef)(hasExplicitThreadId);
8549
8527
  hasExplicitThreadIdRef.current = hasExplicitThreadId;
@@ -10908,7 +10886,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
10908
10886
  switch (error.code) {
10909
10887
  case _copilotkit_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR: return { primary: {
10910
10888
  label: "Show me how",
10911
- onClick: () => window.open("https://docs.copilotkit.ai/premium/overview#getting-access", "_blank", "noopener,noreferrer")
10889
+ onClick: () => window.open("https://docs.copilotkit.ai/intelligence/overview#plans-and-access", "_blank", "noopener,noreferrer")
10912
10890
  } };
10913
10891
  case _copilotkit_shared.CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR: return { primary: {
10914
10892
  label: "Upgrade",
@@ -12080,6 +12058,7 @@ Object.defineProperty(exports, 'CopilotSidebarView', {
12080
12058
  exports.CopilotThreadsDrawer = CopilotThreadsDrawer;
12081
12059
  exports.GenerateSandboxedUiArgsSchema = GenerateSandboxedUiArgsSchema;
12082
12060
  exports.INTELLIGENCE_TURN_HEAD = INTELLIGENCE_TURN_HEAD;
12061
+ exports.INTERRUPT_EVENT_NAME = INTERRUPT_EVENT_NAME;
12083
12062
  exports.IntelligenceIndicator = IntelligenceIndicator;
12084
12063
  exports.IntelligenceIndicatorView = IntelligenceIndicatorView;
12085
12064
  exports.MCPAppsActivityContentSchema = MCPAppsActivityContentSchema;