shadow-claw 1.32.0 → 1.33.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/.well-known/mcp/server-card.json +1 -1
- package/.well-known/mcp.json +1 -1
- package/dist/electron/main.cjs +1 -1
- package/dist/lib/components/index.js +26 -26
- package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/settings/shadow-claw-git.js +1 -1
- package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
- package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw-a2ui.js +1 -1
- package/dist/lib/components/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/shadow-claw-channels.js +1 -1
- package/dist/lib/components/shadow-claw-chat.js +1 -1
- package/dist/lib/components/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/shadow-claw-conversations.js +1 -1
- package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
- package/dist/lib/components/shadow-claw-files.js +1 -1
- package/dist/lib/components/shadow-claw-git.js +1 -1
- package/dist/lib/components/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/shadow-claw-llm.js +1 -1
- package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/shadow-claw-page-header.js +1 -1
- package/dist/lib/components/shadow-claw-pages.js +1 -1
- package/dist/lib/components/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/shadow-claw-settings.js +1 -1
- package/dist/lib/components/shadow-claw-storage.js +1 -1
- package/dist/lib/components/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/shadow-claw-tasks.js +1 -1
- package/dist/lib/components/shadow-claw-terminal.js +1 -1
- package/dist/lib/components/shadow-claw-tools.js +1 -1
- package/dist/lib/components/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw.js +1 -1
- package/dist/lib/{config-DjZ9QWc4.js → config-BcFbkaQv.js} +21 -4
- package/dist/lib/config-BcFbkaQv.js.map +1 -0
- package/dist/lib/{configurePeerJs-DD3G3Pms.js → configurePeerJs-CBMPHbwa.js} +3 -3
- package/dist/lib/{configurePeerJs-DD3G3Pms.js.map → configurePeerJs-CBMPHbwa.js.map} +1 -1
- package/dist/lib/{connections-BURqMIUv.js → connections-PZrUDf49.js} +2 -2
- package/dist/lib/{connections-BURqMIUv.js.map → connections-PZrUDf49.js.map} +1 -1
- package/dist/lib/{downloadGroupFile-B8J4up2a.js → downloadGroupFile-DSRUa9Au.js} +2 -2
- package/dist/lib/{downloadGroupFile-B8J4up2a.js.map → downloadGroupFile-DSRUa9Au.js.map} +1 -1
- package/dist/lib/{file-viewer-DoHM75Jz.js → file-viewer-11VVOpJv.js} +5 -5
- package/dist/lib/{file-viewer-DoHM75Jz.js.map → file-viewer-11VVOpJv.js.map} +1 -1
- package/dist/lib/{getGroupDir-QrN2aTo8.js → getGroupDir-BxKMYPPm.js} +3 -3
- package/dist/lib/{getGroupDir-QrN2aTo8.js.map → getGroupDir-BxKMYPPm.js.map} +1 -1
- package/dist/lib/{git-Brr7JIbs.js → git-BppibnJW.js} +3 -3
- package/dist/lib/{git-Brr7JIbs.js.map → git-BppibnJW.js.map} +1 -1
- package/dist/lib/{iframe-sanitizer-Bujgq14T.js → iframe-sanitizer-Dp8EYffI.js} +2 -2
- package/dist/lib/{iframe-sanitizer-Bujgq14T.js.map → iframe-sanitizer-Dp8EYffI.js.map} +1 -1
- package/dist/lib/index.js +27 -27
- package/dist/lib/{initChatSplitResize-BjiWoqC_.js → initChatSplitResize-CE_kWaLf.js} +2 -2
- package/dist/lib/{initChatSplitResize-BjiWoqC_.js.map → initChatSplitResize-CE_kWaLf.js.map} +1 -1
- package/dist/lib/{initControlPlane-3TUdhRBM.js → initControlPlane-BRIIOzoH.js} +18 -17
- package/dist/lib/{initControlPlane-3TUdhRBM.js.map → initControlPlane-BRIIOzoH.js.map} +1 -1
- package/dist/lib/{markdown-BFUTPQoO.js → markdown-Cq4sVwUT.js} +4 -4
- package/dist/lib/{markdown-BFUTPQoO.js.map → markdown-Cq4sVwUT.js.map} +1 -1
- package/dist/lib/{mcp-reconnect-BxJ77WSb.js → mcp-reconnect-CoHDMjmY.js} +2 -2
- package/dist/lib/{mcp-reconnect-BxJ77WSb.js.map → mcp-reconnect-CoHDMjmY.js.map} +1 -1
- package/dist/lib/{memoryStorage-D3FBwO9T.js → memoryStorage-DcFWrn_y.js} +2 -2
- package/dist/lib/{memoryStorage-D3FBwO9T.js.map → memoryStorage-DcFWrn_y.js.map} +1 -1
- package/dist/lib/{orchestrator-DW5l2bbW.js → orchestrator-C3TgDZvq.js} +81 -18
- package/dist/lib/{orchestrator-DW5l2bbW.js.map → orchestrator-C3TgDZvq.js.map} +1 -1
- package/dist/lib/{orchestrator-DLnCmeTZ.js → orchestrator-Ce9_lmL2.js} +12 -12
- package/dist/lib/{orchestrator-DLnCmeTZ.js.map → orchestrator-Ce9_lmL2.js.map} +1 -1
- package/dist/lib/{peerjs-BXlMuIQn.js → peerjs-PTYQ7yEG.js} +6 -6
- package/dist/lib/{peerjs-BXlMuIQn.js.map → peerjs-PTYQ7yEG.js.map} +1 -1
- package/dist/lib/{push-client-B419nn-i.js → push-client-DDV5Rcg6.js} +3 -3
- package/dist/lib/{push-client-B419nn-i.js.map → push-client-DDV5Rcg6.js.map} +1 -1
- package/dist/lib/{readGroupFileBytes-CSA7u-nJ.js → readGroupFileBytes-7C8G-yps.js} +2 -2
- package/dist/lib/{readGroupFileBytes-CSA7u-nJ.js.map → readGroupFileBytes-7C8G-yps.js.map} +1 -1
- package/dist/lib/{shadow-claw-DmMO4vVG.js → shadow-claw-WrWoPqFx.js} +10 -10
- package/dist/lib/{shadow-claw-DmMO4vVG.js.map → shadow-claw-WrWoPqFx.js.map} +1 -1
- package/dist/lib/{shadow-claw-a2ui-2I5nffIn.js → shadow-claw-a2ui-CcmJNXQP.js} +2 -2
- package/dist/lib/{shadow-claw-a2ui-2I5nffIn.js.map → shadow-claw-a2ui-CcmJNXQP.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-DMb0y4ca.js → shadow-claw-accounts-CcB2429E.js} +3 -3
- package/dist/lib/{shadow-claw-accounts-DMb0y4ca.js.map → shadow-claw-accounts-CcB2429E.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-BhxHf6wZ.js → shadow-claw-channel-config-C4v0h8oa.js} +3 -3
- package/dist/lib/{shadow-claw-channel-config-BhxHf6wZ.js.map → shadow-claw-channel-config-C4v0h8oa.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-B5vzE9Z2.js → shadow-claw-channels-CyV88k9T.js} +3 -3
- package/dist/lib/{shadow-claw-channels-B5vzE9Z2.js.map → shadow-claw-channels-CyV88k9T.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-BsYnJ4-G.js → shadow-claw-chat-DSYtuZod.js} +11 -11
- package/dist/lib/{shadow-claw-chat-BsYnJ4-G.js.map → shadow-claw-chat-DSYtuZod.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-DqcgQsun.js → shadow-claw-control-plane-DBSGuDT1.js} +7 -7
- package/dist/lib/{shadow-claw-control-plane-DqcgQsun.js.map → shadow-claw-control-plane-DBSGuDT1.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-B9Pn58g3.js → shadow-claw-conversations-Cp8pK4PM.js} +5 -5
- package/dist/lib/{shadow-claw-conversations-B9Pn58g3.js.map → shadow-claw-conversations-Cp8pK4PM.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-DL6c4oPK.js → shadow-claw-file-viewer-B8G8yo48.js} +8 -8
- package/dist/lib/{shadow-claw-file-viewer-DL6c4oPK.js.map → shadow-claw-file-viewer-B8G8yo48.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-C_ksPb8W.js → shadow-claw-files-D1COKzuC.js} +9 -9
- package/dist/lib/{shadow-claw-files-C_ksPb8W.js.map → shadow-claw-files-D1COKzuC.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-jwsY7L1N.js → shadow-claw-git-60tWU4Ee.js} +6 -6
- package/dist/lib/{shadow-claw-git-jwsY7L1N.js.map → shadow-claw-git-60tWU4Ee.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-yT7j07TM.js → shadow-claw-integrations-Bw1cG1ze.js} +4 -4
- package/dist/lib/{shadow-claw-integrations-yT7j07TM.js.map → shadow-claw-integrations-Bw1cG1ze.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-CEPJh1Jh.js → shadow-claw-llm-By5CvsFJ.js} +6 -6
- package/dist/lib/{shadow-claw-llm-CEPJh1Jh.js.map → shadow-claw-llm-By5CvsFJ.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-DGDWjByQ.js → shadow-claw-mcp-remote-BaNODd1v.js} +4 -4
- package/dist/lib/{shadow-claw-mcp-remote-DGDWjByQ.js.map → shadow-claw-mcp-remote-BaNODd1v.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-Bi4yvc73.js → shadow-claw-networking-DtZ5bsTz.js} +2 -2
- package/dist/lib/{shadow-claw-networking-Bi4yvc73.js.map → shadow-claw-networking-DtZ5bsTz.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-C-JgGqQx.js → shadow-claw-notifications-C3VEba_A.js} +3 -3
- package/dist/lib/{shadow-claw-notifications-C-JgGqQx.js.map → shadow-claw-notifications-C3VEba_A.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-DrAcWCZ9.js → shadow-claw-page-header-BLowJopA.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-DrAcWCZ9.js.map → shadow-claw-page-header-BLowJopA.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-OEOClgA8.js → shadow-claw-pages-CpeUV-hw.js} +9 -9
- package/dist/lib/{shadow-claw-pages-OEOClgA8.js.map → shadow-claw-pages-CpeUV-hw.js.map} +1 -1
- package/dist/lib/{shadow-claw-peerjs-DmC2CV-9.js → shadow-claw-peerjs-DYAzJbTy.js} +3 -3
- package/dist/lib/{shadow-claw-peerjs-DmC2CV-9.js.map → shadow-claw-peerjs-DYAzJbTy.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-xAtFog0T.js → shadow-claw-settings-ByxwW3WK.js} +9 -9
- package/dist/lib/{shadow-claw-settings-xAtFog0T.js.map → shadow-claw-settings-ByxwW3WK.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-B4UHl-po.js → shadow-claw-storage-CsSPYVDJ.js} +5 -5
- package/dist/lib/{shadow-claw-storage-B4UHl-po.js.map → shadow-claw-storage-CsSPYVDJ.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-B0eWzg57.js → shadow-claw-task-server-De2WCEw4.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-B0eWzg57.js.map → shadow-claw-task-server-De2WCEw4.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-HHU_8Gyg.js → shadow-claw-tasks-zHWT4GaE.js} +7 -7
- package/dist/lib/{shadow-claw-tasks-HHU_8Gyg.js.map → shadow-claw-tasks-zHWT4GaE.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-CdC2G6Zz.js → shadow-claw-terminal-Bpawfv4N.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-CdC2G6Zz.js.map → shadow-claw-terminal-Bpawfv4N.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-2AICxVXA.js → shadow-claw-tools-BbKdWcps.js} +7 -7
- package/dist/lib/{shadow-claw-tools-2AICxVXA.js.map → shadow-claw-tools-BbKdWcps.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-Cy-Ia2vs.js → shadow-claw-webvm-DLqK0AxW.js} +3 -3
- package/dist/lib/{shadow-claw-webvm-Cy-Ia2vs.js.map → shadow-claw-webvm-DLqK0AxW.js.map} +1 -1
- package/dist/lib/subsystems/mcp/webmcp.d.ts +37 -0
- package/dist/lib/subsystems/providers/model-registry.d.ts +4 -1
- package/dist/lib/subsystems/providers/providers.d.ts +10 -0
- package/dist/lib/{syncWebMcpRegistration-CaAPPg2V.js → syncWebMcpRegistration-mlbbvcdm.js} +5 -5
- package/dist/lib/{syncWebMcpRegistration-CaAPPg2V.js.map → syncWebMcpRegistration-mlbbvcdm.js.map} +1 -1
- package/dist/lib/{tools-f1WPNDSS.js → tools-Bb2ujM2E.js} +4 -4
- package/dist/lib/{tools-f1WPNDSS.js.map → tools-Bb2ujM2E.js.map} +1 -1
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/{utils-B99XP70b.js → utils-mpsYPfS7.js} +3 -3
- package/dist/lib/{utils-B99XP70b.js.map → utils-mpsYPfS7.js.map} +1 -1
- package/dist/lib/webmcp-BVR2lBVo.js +1544 -0
- package/dist/lib/webmcp-BVR2lBVo.js.map +1 -0
- package/dist/public/.well-known/mcp/server-card.json +1 -1
- package/dist/public/.well-known/mcp.json +1 -1
- package/dist/public/agent.worker.js +44 -44
- package/dist/public/config-BqecTktB.js +1 -0
- package/dist/public/{configurePeerJs--JGpJVti.js → configurePeerJs-BPKfWuEt.js} +1 -1
- package/dist/public/{connections-6575KDGE.js → connections-C_3tYsmX.js} +1 -1
- package/dist/public/{custom-element-security-Da_6HQ6X.js → custom-element-security-DXwU3Lae.js} +1 -1
- package/dist/public/docs/example/article/index.html +2 -2
- package/dist/public/docs/publishing/index.html +2 -2
- package/dist/public/docs/skill-creator/index.html +2 -2
- package/dist/public/docs/subsystems/tools.md +4 -3
- package/dist/public/docs/subsystems/webmcp.md +58 -13
- package/dist/public/{downloadGroupFile-Dj-AMNsd.js → downloadGroupFile-DTyf5DIC.js} +1 -1
- package/dist/public/{e2e-bridge-CbYqdMp-.js → e2e-bridge-DXwWCQKw.js} +1 -1
- package/dist/public/{file-viewer-vHJ5Zsgk.js → file-viewer-ConEyDDG.js} +1 -1
- package/dist/public/{getGroupDir-BwprrdrQ.js → getGroupDir-ZfZsiq6d.js} +1 -1
- package/dist/public/{git-8F7wvoUB.js → git-BtBaLC1-.js} +2 -2
- package/dist/public/{iframe-sanitizer-viROQkRn.js → iframe-sanitizer-Corkvo_d.js} +1 -1
- package/dist/public/index.html +2 -2
- package/dist/public/index.js +1 -1
- package/dist/public/{initChatSplitResize-BA18wLQQ.js → initChatSplitResize-CUc-TEmT.js} +1 -1
- package/dist/public/{initControlPlane-C5v0FtJE.js → initControlPlane-B_uYS8a4.js} +1 -1
- package/dist/public/main/index.html +2 -2
- package/dist/public/main/memory/index.html +2 -2
- package/dist/public/{markdown-eFKxxpVP.js → markdown-Cfa6GuJs.js} +1 -1
- package/dist/public/{mcp-reconnect-CBHuaYdF.js → mcp-reconnect-CUOkdPEz.js} +1 -1
- package/dist/public/{memoryStorage-C1llaYus.js → memoryStorage-Bh8fjmip.js} +1 -1
- package/dist/public/{orchestrator-DNr2HDI2.js → orchestrator-BcSzrg6E.js} +2 -2
- package/dist/public/{orchestrator-BeJfwtvz.js → orchestrator-Bi5OdVZD.js} +11 -11
- package/dist/public/{peerjs-mG30TAJ_.js → peerjs-CzCXG-NW.js} +1 -1
- package/dist/public/{push-client-C2zMT3Sf.js → push-client-Cr3Ruahp.js} +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-Ble6l0Iw.js → shadow-claw-CzUYuuOa.js} +2 -2
- package/dist/public/{shadow-claw-accounts-D1y-zbMs.js → shadow-claw-accounts-BgIHB_aP.js} +1 -1
- package/dist/public/{shadow-claw-channels-D_xfBoWp.js → shadow-claw-channels-Ce_trJ5D.js} +1 -1
- package/dist/public/{shadow-claw-chat-D_Lbi5oH.js → shadow-claw-chat-CdECLLwL.js} +1 -1
- package/dist/public/{shadow-claw-control-plane-CrnA5lM0.js → shadow-claw-control-plane-DM62UmOz.js} +2 -2
- package/dist/public/{shadow-claw-conversations-BN-hFmN1.js → shadow-claw-conversations-AM5g3C00.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-BKEpzpbx.js → shadow-claw-file-viewer-BP7gWS5g.js} +1 -1
- package/dist/public/{shadow-claw-files-DDZMk5AA.js → shadow-claw-files-RPPGszcK.js} +1 -1
- package/dist/public/{shadow-claw-git-CqOO97Re.js → shadow-claw-git-BsHEvLrb.js} +2 -2
- package/dist/public/{shadow-claw-integrations-CRGL78Fy.js → shadow-claw-integrations-B0vbcOqg.js} +1 -1
- package/dist/public/{shadow-claw-llm-DoGxEHQL.js → shadow-claw-llm-FNNamrc_.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-DyGnK4S_.js → shadow-claw-mcp-remote-7mDgniQu.js} +1 -1
- package/dist/public/{shadow-claw-networking-DJeCdb7e.js → shadow-claw-networking-CGsetaLp.js} +1 -1
- package/dist/public/{shadow-claw-notifications-hSKJeMXb.js → shadow-claw-notifications-pnwRcR-4.js} +1 -1
- package/dist/public/{shadow-claw-page-header-DA-FG08G.js → shadow-claw-page-header-BUy15Poz.js} +1 -1
- package/dist/public/{shadow-claw-pages-DTS98Zbi.js → shadow-claw-pages-ILAjGWNk.js} +1 -1
- package/dist/public/{shadow-claw-settings-5w0ce8SP.js → shadow-claw-settings-Bx5IgVqN.js} +3 -3
- package/dist/public/{shadow-claw-storage-DqlVt27X.js → shadow-claw-storage-PAtNykaF.js} +1 -1
- package/dist/public/{shadow-claw-task-server-ByZwKI6S.js → shadow-claw-task-server-Cbbi_2OO.js} +1 -1
- package/dist/public/{shadow-claw-tasks-Dc4G4zBu.js → shadow-claw-tasks-B-jKYWZJ.js} +1 -1
- package/dist/public/{shadow-claw-terminal-DvusP7wg.js → shadow-claw-terminal-BRejND-Z.js} +1 -1
- package/dist/public/{shadow-claw-tools-BEsid8q-.js → shadow-claw-tools-DNQe3oa-.js} +1 -1
- package/dist/public/{shadow-claw-webvm-BWlIeK78.js → shadow-claw-webvm-BFuwRifU.js} +1 -1
- package/dist/public/{syncWebMcpRegistration-CqVCB6m8.js → syncWebMcpRegistration-FxKAPwaz.js} +1 -1
- package/dist/public/theme-init.js +1 -1
- package/dist/public/{tools-Cp1gequ8.js → tools-BwQKGsro.js} +1 -1
- package/dist/public/transformers-js.worker.js +1 -1
- package/dist/public/webmcp-C28PAlfy.js +1 -0
- package/dist/server.js +1 -1
- package/package.json +3 -3
- package/src/core/utils/initControlPlane.test.ts +122 -1
- package/src/core/utils/initControlPlane.ts +12 -8
- package/src/subsystems/mcp/webmcp.test.ts +253 -1
- package/src/subsystems/mcp/webmcp.ts +147 -4
- package/src/subsystems/providers/model-registry.test.ts +139 -0
- package/src/subsystems/providers/model-registry.ts +54 -2
- package/src/subsystems/providers/providers.test.ts +329 -0
- package/src/subsystems/providers/providers.ts +135 -11
- package/dist/lib/config-DjZ9QWc4.js.map +0 -1
- package/dist/lib/webmcp-BC8_WafM.js +0 -1710
- package/dist/lib/webmcp-BC8_WafM.js.map +0 -1
- package/dist/public/config-Bnwx4EfS.js +0 -1
- package/dist/public/webmcp-DBONjQWd.js +0 -2
|
@@ -235,6 +235,72 @@ export async function getWebMcpTools(): Promise<
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Gracefully execute a WebMCP tool on a ModelContext instance with backwards compatibility.
|
|
240
|
+
*
|
|
241
|
+
* Starting in Chrome 155.0.8052.0 (PR #246, PR #251), `document.modelContext.executeTool()`
|
|
242
|
+
* accepts an optional JavaScript object directly instead of a JSON DOMString.
|
|
243
|
+
* In Chrome < 155 and earlier polyfills, `executeTool()` required a stringified JSON arguments string.
|
|
244
|
+
*
|
|
245
|
+
* This function practices graceful degradation:
|
|
246
|
+
* 1. Prepares both an `inputObject` (for Chrome 155+) and an `inputStr` (for Chrome < 155 & polyfills).
|
|
247
|
+
* 2. Attempts to execute `executeTool(tool, inputObject, options)` first.
|
|
248
|
+
* 3. Catches errors starting with "Failed to parse input" (or TypeErrors from WebIDL DOMString checks)
|
|
249
|
+
* and retries transparently with `JSON.stringify(inputObject)`.
|
|
250
|
+
* 4. Re-throws any unrelated execution errors.
|
|
251
|
+
*/
|
|
252
|
+
export async function executeWebMcpTool(
|
|
253
|
+
modelContext: any,
|
|
254
|
+
tool: any,
|
|
255
|
+
input?: unknown,
|
|
256
|
+
options?: WebMcpExecuteContext | AbortSignal,
|
|
257
|
+
): Promise<unknown> {
|
|
258
|
+
if (!modelContext || typeof modelContext.executeTool !== "function") {
|
|
259
|
+
throw new Error("ModelContext executeTool is not available");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let inputObject: Record<string, unknown>;
|
|
263
|
+
let inputStr: string;
|
|
264
|
+
|
|
265
|
+
if (typeof input === "string") {
|
|
266
|
+
inputStr = input;
|
|
267
|
+
try {
|
|
268
|
+
const parsed = JSON.parse(input);
|
|
269
|
+
inputObject =
|
|
270
|
+
parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
271
|
+
? (parsed as Record<string, unknown>)
|
|
272
|
+
: {};
|
|
273
|
+
} catch {
|
|
274
|
+
inputObject = {};
|
|
275
|
+
}
|
|
276
|
+
} else if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
277
|
+
inputObject = input as Record<string, unknown>;
|
|
278
|
+
try {
|
|
279
|
+
inputStr = JSON.stringify(input);
|
|
280
|
+
} catch {
|
|
281
|
+
inputStr = "{}";
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
inputObject = {};
|
|
285
|
+
inputStr = "{}";
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
try {
|
|
289
|
+
return await modelContext.executeTool(tool, inputObject, options);
|
|
290
|
+
} catch (err: any) {
|
|
291
|
+
const isParseError =
|
|
292
|
+
typeof err?.message === "string" &&
|
|
293
|
+
err.message.startsWith("Failed to parse input");
|
|
294
|
+
const isTypeError = err instanceof TypeError;
|
|
295
|
+
|
|
296
|
+
if (isParseError || isTypeError) {
|
|
297
|
+
return await modelContext.executeTool(tool, inputStr, options);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
throw err;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
238
304
|
/**
|
|
239
305
|
* Feature detection for the WebMCP imperative API.
|
|
240
306
|
*
|
|
@@ -246,6 +312,83 @@ export function isWebMcpSupported(): boolean {
|
|
|
246
312
|
return !!getModelContextApi();
|
|
247
313
|
}
|
|
248
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Consequential tools that perform high-stakes, irreversible, or external real-world actions
|
|
317
|
+
* (such as deleting data, executing arbitrary system commands, or transmitting live communications).
|
|
318
|
+
* Signals consuming agents to require explicit user confirmation prior to execution (Chrome 154.0.8017.0+).
|
|
319
|
+
*/
|
|
320
|
+
export const CONSEQUENTIAL_TOOL_NAMES: ReadonlySet<string> = new Set([
|
|
321
|
+
"bash",
|
|
322
|
+
"clear_chat",
|
|
323
|
+
"delete_file",
|
|
324
|
+
"delete_task",
|
|
325
|
+
"email_send_message",
|
|
326
|
+
"git_delete_branch",
|
|
327
|
+
"git_delete_repo",
|
|
328
|
+
"git_push",
|
|
329
|
+
"git_reset",
|
|
330
|
+
]);
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Read-only tools that query information without mutating state.
|
|
334
|
+
*/
|
|
335
|
+
export const READ_ONLY_TOOL_NAMES: ReadonlySet<string> = new Set([
|
|
336
|
+
"ask_user",
|
|
337
|
+
"detect_language",
|
|
338
|
+
"diff_files",
|
|
339
|
+
"email_read_messages",
|
|
340
|
+
"fetch_url",
|
|
341
|
+
"get_current_time",
|
|
342
|
+
"git_branches",
|
|
343
|
+
"git_diff",
|
|
344
|
+
"git_list_repos",
|
|
345
|
+
"git_log",
|
|
346
|
+
"git_read_file_at_ref",
|
|
347
|
+
"git_show",
|
|
348
|
+
"git_status",
|
|
349
|
+
"list_components",
|
|
350
|
+
"list_files",
|
|
351
|
+
"list_room_members",
|
|
352
|
+
"list_tasks",
|
|
353
|
+
"list_tool_profiles",
|
|
354
|
+
"proofread_text",
|
|
355
|
+
"read_file",
|
|
356
|
+
"remote_mcp_list_tools",
|
|
357
|
+
"rewrite_text",
|
|
358
|
+
"search_files",
|
|
359
|
+
"summarize_text",
|
|
360
|
+
"translate_text",
|
|
361
|
+
"web_search",
|
|
362
|
+
"write_text",
|
|
363
|
+
]);
|
|
364
|
+
|
|
365
|
+
export interface WebMcpToolAnnotations {
|
|
366
|
+
readOnlyHint?: boolean;
|
|
367
|
+
consequentialHint?: boolean;
|
|
368
|
+
untrustedContentHint?: boolean;
|
|
369
|
+
[key: string]: unknown;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Resolve annotations for a WebMCP tool registration.
|
|
374
|
+
* Allows custom annotations (from declarative or customized tool definitions)
|
|
375
|
+
* to override defaults.
|
|
376
|
+
*/
|
|
377
|
+
export function resolveWebMcpToolAnnotations(
|
|
378
|
+
toolName: string,
|
|
379
|
+
customAnnotations?: Record<string, unknown>,
|
|
380
|
+
): WebMcpToolAnnotations {
|
|
381
|
+
const isConsequential = CONSEQUENTIAL_TOOL_NAMES.has(toolName);
|
|
382
|
+
const isReadOnly = !isConsequential && READ_ONLY_TOOL_NAMES.has(toolName);
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
readOnlyHint: isReadOnly,
|
|
386
|
+
consequentialHint: isConsequential,
|
|
387
|
+
untrustedContentHint: true,
|
|
388
|
+
...(customAnnotations || {}),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
249
392
|
/**
|
|
250
393
|
* Register ShadowClaw tools with the WebMCP ModelContext API.
|
|
251
394
|
*
|
|
@@ -292,10 +435,10 @@ export async function registerWebMcpTools(
|
|
|
292
435
|
name: def.name,
|
|
293
436
|
description: def.description,
|
|
294
437
|
inputSchema: parseWebMcpInputSchema(def.input_schema),
|
|
295
|
-
annotations:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
438
|
+
annotations: resolveWebMcpToolAnnotations(
|
|
439
|
+
def.name,
|
|
440
|
+
(def as any).annotations,
|
|
441
|
+
),
|
|
299
442
|
execute: (
|
|
300
443
|
input: Record<string, unknown>,
|
|
301
444
|
context?: WebMcpExecuteContext | AbortSignal,
|
|
@@ -19,11 +19,150 @@ describe("ModelRegistry", () => {
|
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
+
it("should register and get model info with supportsPromptCaching", () => {
|
|
23
|
+
modelRegistry.registerModelInfo("test-cached-model", {
|
|
24
|
+
contextWindow: 128000,
|
|
25
|
+
maxOutput: 4096,
|
|
26
|
+
supportsPromptCaching: true,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const info = modelRegistry.getModelInfo("test-cached-model");
|
|
30
|
+
expect(info).toEqual({
|
|
31
|
+
contextWindow: 128000,
|
|
32
|
+
maxOutput: 4096,
|
|
33
|
+
supportsPromptCaching: true,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("should extract supportsPromptCaching from supported_parameters in fetchModelInfo", async () => {
|
|
38
|
+
const mockData: any = {
|
|
39
|
+
data: [
|
|
40
|
+
{
|
|
41
|
+
id: "custom/cached-model",
|
|
42
|
+
context_length: 128000,
|
|
43
|
+
supported_parameters: ["tools", "cache_control"],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "custom/non-cached-model",
|
|
47
|
+
context_length: 32000,
|
|
48
|
+
supported_parameters: ["tools"],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "custom/explicit-cached-model",
|
|
52
|
+
context_length: 64000,
|
|
53
|
+
supports_prompt_caching: true,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const originalFetch = (globalThis as any).fetch;
|
|
59
|
+
(globalThis as any).fetch = async () => ({
|
|
60
|
+
ok: true,
|
|
61
|
+
json: async () => mockData,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
await modelRegistry.fetchModelInfo({
|
|
66
|
+
id: "openrouter",
|
|
67
|
+
modelsUrl: "https://openrouter.ai/api/v1/models",
|
|
68
|
+
headers: {},
|
|
69
|
+
} as any);
|
|
70
|
+
|
|
71
|
+
expect(
|
|
72
|
+
modelRegistry.getModelInfo("custom/cached-model")
|
|
73
|
+
?.supportsPromptCaching,
|
|
74
|
+
).toBe(true);
|
|
75
|
+
expect(
|
|
76
|
+
modelRegistry.getModelInfo("custom/non-cached-model")
|
|
77
|
+
?.supportsPromptCaching,
|
|
78
|
+
).toBeUndefined();
|
|
79
|
+
expect(
|
|
80
|
+
modelRegistry.getModelInfo("custom/explicit-cached-model")
|
|
81
|
+
?.supportsPromptCaching,
|
|
82
|
+
).toBe(true);
|
|
83
|
+
} finally {
|
|
84
|
+
(globalThis as any).fetch = originalFetch;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
22
88
|
it("should return null for unknown model", () => {
|
|
23
89
|
const info = modelRegistry.getModelInfo("unknown");
|
|
24
90
|
expect(info).toBeNull();
|
|
25
91
|
});
|
|
26
92
|
|
|
93
|
+
it("should resolve models with prefix aliases, without prefixes, and with tag suffixes", () => {
|
|
94
|
+
modelRegistry.registerModelInfo("anthropic/claude-3.7-sonnet", {
|
|
95
|
+
contextWindow: 200000,
|
|
96
|
+
maxOutput: 8192,
|
|
97
|
+
supportsPromptCaching: true,
|
|
98
|
+
});
|
|
99
|
+
modelRegistry.registerModelInfo("gpt-4o", {
|
|
100
|
+
contextWindow: 128000,
|
|
101
|
+
maxOutput: 4096,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Lookup bare name when registered with provider prefix
|
|
105
|
+
expect(
|
|
106
|
+
modelRegistry.getModelInfo("claude-3.7-sonnet")?.supportsPromptCaching,
|
|
107
|
+
).toBe(true);
|
|
108
|
+
// Lookup with tag suffix
|
|
109
|
+
expect(
|
|
110
|
+
modelRegistry.getModelInfo("anthropic/claude-3.7-sonnet:thinking")
|
|
111
|
+
?.supportsPromptCaching,
|
|
112
|
+
).toBe(true);
|
|
113
|
+
// Lookup with provider prefix when registered as bare name
|
|
114
|
+
expect(modelRegistry.getModelInfo("openai/gpt-4o")?.contextWindow).toBe(
|
|
115
|
+
128000,
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should update alias metadata when a model is re-registered with updated capabilities", () => {
|
|
120
|
+
modelRegistry.registerModelInfo("provider/dynamic-model", {
|
|
121
|
+
contextWindow: 100000,
|
|
122
|
+
maxOutput: 4096,
|
|
123
|
+
supportsPromptCaching: false,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(
|
|
127
|
+
modelRegistry.getModelInfo("dynamic-model")?.supportsPromptCaching,
|
|
128
|
+
).toBe(false);
|
|
129
|
+
|
|
130
|
+
// Re-register with updated capabilities (e.g. on provider model refresh)
|
|
131
|
+
modelRegistry.registerModelInfo("provider/dynamic-model", {
|
|
132
|
+
contextWindow: 128000,
|
|
133
|
+
maxOutput: 8192,
|
|
134
|
+
supportsPromptCaching: true,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
expect(
|
|
138
|
+
modelRegistry.getModelInfo("dynamic-model")?.supportsPromptCaching,
|
|
139
|
+
).toBe(true);
|
|
140
|
+
expect(modelRegistry.getModelInfo("dynamic-model")?.contextWindow).toBe(
|
|
141
|
+
128000,
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should not retain stale alias lookups when models map is cleared directly", () => {
|
|
146
|
+
modelRegistry.registerModelInfo("provider/temp-model", {
|
|
147
|
+
contextWindow: 100000,
|
|
148
|
+
maxOutput: 4096,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
expect(modelRegistry.getModelInfo("temp-model")).not.toBeNull();
|
|
152
|
+
|
|
153
|
+
// Directly clear models Map as done in external test setups
|
|
154
|
+
modelRegistry.models.clear();
|
|
155
|
+
|
|
156
|
+
// Re-register a different model
|
|
157
|
+
modelRegistry.registerModelInfo("provider/other-model", {
|
|
158
|
+
contextWindow: 50000,
|
|
159
|
+
maxOutput: 2048,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
expect(modelRegistry.getModelInfo("temp-model")).toBeNull();
|
|
163
|
+
expect(modelRegistry.getModelInfo("other-model")).not.toBeNull();
|
|
164
|
+
});
|
|
165
|
+
|
|
27
166
|
it("should fetch model info from OpenRouter format", async () => {
|
|
28
167
|
const mockData: any = {
|
|
29
168
|
data: [
|
|
@@ -18,6 +18,7 @@ export interface ModelMetadata {
|
|
|
18
18
|
supportsVideoInput?: boolean;
|
|
19
19
|
supportsDocumentInput?: boolean;
|
|
20
20
|
routesByRequestFeatures?: boolean;
|
|
21
|
+
supportsPromptCaching?: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -34,10 +35,48 @@ class ModelRegistry {
|
|
|
34
35
|
models: Map<string, ModelMetadata> = new Map();
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
|
-
* Get metadata for a model ID. Lookup is case-insensitive
|
|
38
|
+
* Get metadata for a model ID. Lookup is case-insensitive and resilient
|
|
39
|
+
* to provider prefixes (e.g. "anthropic/claude-3.7-sonnet" vs "claude-3.7-sonnet")
|
|
40
|
+
* and variant tags (e.g. ":thinking").
|
|
38
41
|
*/
|
|
39
42
|
getModelInfo(modelId: string): ModelMetadata | null {
|
|
40
|
-
|
|
43
|
+
if (!modelId || typeof modelId !== "string") {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const key = modelId.toLowerCase().trim();
|
|
48
|
+
const direct = this.models.get(key);
|
|
49
|
+
if (direct) {
|
|
50
|
+
return direct;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Try without provider prefix (e.g. "anthropic/claude-3.7-sonnet" -> "claude-3.7-sonnet")
|
|
54
|
+
if (key.includes("/")) {
|
|
55
|
+
const bare = key.split("/").pop();
|
|
56
|
+
if (bare && this.models.has(bare)) {
|
|
57
|
+
return this.models.get(bare)!;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
// Or if key doesn't have provider prefix, find a registered model ending in "/<key>".
|
|
61
|
+
// Note: Assumes bare model names are reasonably unique across registered providers.
|
|
62
|
+
// If duplicates exist, the first registered match is returned.
|
|
63
|
+
for (const [regKey, meta] of this.models.entries()) {
|
|
64
|
+
if (regKey.endsWith(`/${key}`)) {
|
|
65
|
+
return meta;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Try stripping tag/variant suffix (e.g. "anthropic/claude-3.7-sonnet:thinking" -> "anthropic/claude-3.7-sonnet")
|
|
71
|
+
if (key.includes(":")) {
|
|
72
|
+
const withoutTag = key.split(":")[0];
|
|
73
|
+
const match = this.getModelInfo(withoutTag);
|
|
74
|
+
if (match) {
|
|
75
|
+
return match;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null;
|
|
41
80
|
}
|
|
42
81
|
|
|
43
82
|
/**
|
|
@@ -158,6 +197,18 @@ class ModelRegistry {
|
|
|
158
197
|
"structured",
|
|
159
198
|
);
|
|
160
199
|
const reasoning = this.extractReasoning(model);
|
|
200
|
+
const supportsPromptCaching =
|
|
201
|
+
typeof model.supports_prompt_caching === "boolean"
|
|
202
|
+
? model.supports_prompt_caching
|
|
203
|
+
: typeof model.supportsPromptCaching === "boolean"
|
|
204
|
+
? model.supportsPromptCaching
|
|
205
|
+
: this.supportedParametersInclude(
|
|
206
|
+
model,
|
|
207
|
+
"cache_control",
|
|
208
|
+
"prompt_caching",
|
|
209
|
+
)
|
|
210
|
+
? true
|
|
211
|
+
: undefined;
|
|
161
212
|
|
|
162
213
|
// HuggingFace Router structure nests info inside `providers` array
|
|
163
214
|
if (
|
|
@@ -179,6 +230,7 @@ class ModelRegistry {
|
|
|
179
230
|
...(supportsVideoInput !== undefined && { supportsVideoInput }),
|
|
180
231
|
...(reasoning && { reasoning }),
|
|
181
232
|
...(routesByRequestFeatures && { routesByRequestFeatures }),
|
|
233
|
+
...(supportsPromptCaching !== undefined && { supportsPromptCaching }),
|
|
182
234
|
});
|
|
183
235
|
}
|
|
184
236
|
|