@copilotkit/react-core 1.70.0 → 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 (35) hide show
  1. package/dist/{copilotkit-BuzP0VeG.d.cts → copilotkit-CtF2clxZ.d.cts} +20 -20
  2. package/dist/copilotkit-CtF2clxZ.d.cts.map +1 -0
  3. package/dist/{copilotkit-BE76j111.cjs → copilotkit-CxLT6zFx.cjs} +145 -211
  4. package/dist/copilotkit-CxLT6zFx.cjs.map +1 -0
  5. package/dist/{copilotkit-B7aFKfQR.mjs → copilotkit-DiUK2Bhq.mjs} +145 -211
  6. package/dist/copilotkit-DiUK2Bhq.mjs.map +1 -0
  7. package/dist/{copilotkit-CbZGwElm.d.mts → copilotkit-DsWuxPUQ.d.mts} +20 -20
  8. package/dist/copilotkit-DsWuxPUQ.d.mts.map +1 -0
  9. package/dist/index.cjs +5 -4
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +2 -2
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts +2 -2
  14. package/dist/index.d.mts.map +1 -1
  15. package/dist/index.mjs +5 -4
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/index.umd.js +142 -207
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/v2/headless.cjs +2 -1
  20. package/dist/v2/headless.cjs.map +1 -1
  21. package/dist/v2/headless.mjs +2 -1
  22. package/dist/v2/headless.mjs.map +1 -1
  23. package/dist/v2/index.cjs +1 -1
  24. package/dist/v2/index.d.cts +1 -1
  25. package/dist/v2/index.d.mts +1 -1
  26. package/dist/v2/index.mjs +1 -1
  27. package/dist/v2/index.umd.js +144 -210
  28. package/dist/v2/index.umd.js.map +1 -1
  29. package/package.json +11 -8
  30. package/skills/react-core/SKILL.md +1 -1
  31. package/skills/react-core/references/threads.md +1 -1
  32. package/dist/copilotkit-B7aFKfQR.mjs.map +0 -1
  33. package/dist/copilotkit-BE76j111.cjs.map +0 -1
  34. package/dist/copilotkit-BuzP0VeG.d.cts.map +0 -1
  35. package/dist/copilotkit-CbZGwElm.d.mts.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 messageHandler = null;
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
- await sandboxReady;
973
- if (!mounted) return;
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
- sendNotification("ui/notifications/sandbox-resource-ready", { html });
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
- if (initialListener) {
1101
- window.removeEventListener("message", initialListener);
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
- sendNotification,
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
- console.log("[MCPAppsRenderer] Sending tool input:", content.toolInput);
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
- console.log("[MCPAppsRenderer] Sending tool result:", content.result);
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",
@@ -2820,7 +2753,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2820
2753
  tool.name,
2821
2754
  tool.available,
2822
2755
  copilotkit,
2823
- JSON.stringify(extraDeps)
2756
+ JSON.stringify(extraDeps),
2757
+ JSON.stringify(tool.webmcp ?? null)
2824
2758
  ]);
2825
2759
  }
2826
2760
 
@@ -4537,7 +4471,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
4537
4471
  switch (error.code) {
4538
4472
  case _copilotkit_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR: return { primary: {
4539
4473
  label: "Show me how",
4540
- onClick: () => window.open("https://docs.copilotkit.ai/premium/overview#getting-access", "_blank", "noopener,noreferrer")
4474
+ onClick: () => window.open("https://docs.copilotkit.ai/intelligence/overview#plans-and-access", "_blank", "noopener,noreferrer")
4541
4475
  } };
4542
4476
  case _copilotkit_shared.CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR: return { primary: {
4543
4477
  label: "Upgrade",
@@ -6129,7 +6063,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6129
6063
  * `useCopilotChatHeadless_c` is for building fully custom UI (headless UI) implementations.
6130
6064
  *
6131
6065
  * <Callout title="This is a CopilotKit Intelligence feature">
6132
- * Read more about <a href="/premium/overview">CopilotKit Intelligence</a>.
6066
+ * Read more about <a href="/intelligence/overview">CopilotKit Intelligence</a>.
6133
6067
  *
6134
6068
  * Usage is generous and **free** to get started.
6135
6069
  * </Callout>
@@ -6360,7 +6294,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6360
6294
  * See https://docs.copilotkit.ai/reference/v2/hooks/useFrontendTool
6361
6295
  */
6362
6296
  function useFrontendTool(tool, dependencies) {
6363
- const { name, description, parameters, render, followUp, available } = tool;
6297
+ const { name, description, parameters, render, followUp, available, webmcp } = tool;
6364
6298
  const zodParameters = (0, _copilotkit_shared.getZodParameters)(parameters);
6365
6299
  const renderRef = (0, react.useRef)(render);
6366
6300
  (0, react.useEffect)(() => {
@@ -6391,7 +6325,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
6391
6325
  handler: tool.handler ? (args) => handlerRef.current?.(args) : void 0,
6392
6326
  followUp,
6393
6327
  render: normalizedRender,
6394
- available: available === void 0 ? void 0 : available !== "disabled"
6328
+ available: available === void 0 ? void 0 : available !== "disabled",
6329
+ webmcp
6395
6330
  });
6396
6331
  }
6397
6332