@xopcai/xopc 0.0.369 → 0.0.370

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 (384) hide show
  1. package/README.md +59 -174
  2. package/README.zh-CN.md +59 -174
  3. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/_md.js +131 -0
  4. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/_u64.js +30 -0
  5. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js +252 -0
  6. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js +16 -0
  7. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js +66 -0
  8. package/dist/browser-ext/dist/sidepanel.js +21 -1
  9. package/dist/browser-ext/manifest.json +1 -1
  10. package/dist/extensions/telegram/xopc.extension.json +1 -1
  11. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Stj17S9u.js → agent-avatar-dicebear-C61i1QbX.js} +1 -1
  12. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-0fCR1DHx.js +1 -0
  13. package/dist/gateway/static/root/assets/agent-plugin-dialog-Di99mUTT.js +1 -0
  14. package/dist/gateway/static/root/assets/agents-BRZZmYH_.js +66 -0
  15. package/dist/gateway/static/root/assets/{app-management-settings-panel-pJFe6M6c.js → app-management-settings-panel-noqqxkds.js} +1 -1
  16. package/dist/gateway/static/root/assets/{appearance-settings-BrxSpBWa.js → appearance-settings-DG8QN0gR.js} +1 -1
  17. package/dist/gateway/static/root/assets/{apps-page-DegSl5Lh.js → apps-page-CgiyzFYo.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-BZQ_VHjp.js → automations-page-CgAcRFDS.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-BIkxIpab.js +6 -0
  20. package/dist/gateway/static/root/assets/{block-editor-3XjFv3kK.js → block-editor-B1VE-jAe.js} +3 -3
  21. package/dist/gateway/static/root/assets/browser-automations-page-CIjyMS6f.js +3 -0
  22. package/dist/gateway/static/root/assets/{browser-settings-page-ch2_bQF0.js → browser-settings-page-BMAivBfp.js} +2 -2
  23. package/dist/gateway/static/root/assets/{capabilities-DO-vfNKI.js → capabilities-CY4SiHcP.js} +1 -1
  24. package/dist/gateway/static/root/assets/{capabilities-B48r0DDa.js → capabilities-gjQtMhKu.js} +1 -1
  25. package/dist/gateway/static/root/assets/capabilities-page-DRdcfo68.js +2 -0
  26. package/dist/gateway/static/root/assets/{capabilities-settings-panel-NckMsJ5N.js → capabilities-settings-panel-ZuL6pWjM.js} +4 -4
  27. package/dist/gateway/static/root/assets/{capability-header-actions-CY8KCO9j.js → capability-header-actions-D0GC1FEv.js} +1 -1
  28. package/dist/gateway/static/root/assets/{channels-CHOS2CGa.js → channels-CgE22Pzd.js} +1 -1
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-Bwknnb4c.js → chat-terminal-dock-CEjh1utz.js} +2 -2
  30. package/dist/gateway/static/root/assets/{computer-settings-page-B2xeFCSt.js → computer-settings-page-vFHJAmQr.js} +1 -1
  31. package/dist/gateway/static/root/assets/{connector-service-page-C83DnAqK.js → connector-service-page-DTrwZ4kV.js} +1 -1
  32. package/dist/gateway/static/root/assets/connectors-page-DRcMiTWu.js +1 -0
  33. package/dist/gateway/static/root/assets/copy-text-row-C1gaJwlZ.js +1 -0
  34. package/dist/gateway/static/root/assets/{date-picker-Bq9GR-DU.js → date-picker-NfGIPSYY.js} +1 -1
  35. package/dist/gateway/static/root/assets/dependency-picker-CqguveUi.js +1 -0
  36. package/dist/gateway/static/root/assets/{desktop-pet-BwsbQw8V.js → desktop-pet-CTx1zkJm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{desktop-pet-settings-sL9i44pP.js → desktop-pet-settings-BRDS3EGc.js} +1 -1
  38. package/dist/gateway/static/root/assets/device-pairing-wizard-Du4Ciuyw.js +1 -0
  39. package/dist/gateway/static/root/assets/{directory-picker-path-field-BFlDmsS5.js → directory-picker-path-field-CjstlxFl.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-debug-page-7Z1Tp7-w.js → extension-debug-page-BfAtjhoK.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-page-uGqvb8QX.js → extension-page-BJmudejr.js} +1 -1
  42. package/dist/gateway/static/root/assets/{extension-provider-xlSyz4Z6.js → extension-provider-Br6LXyIj.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-settings-page-CKHgrjOs.js → extension-settings-page-UvmHniyz.js} +1 -1
  44. package/dist/gateway/static/root/assets/{fallback-models-BwQg0G1D.js → fallback-models-euw9MGdt.js} +1 -1
  45. package/dist/gateway/static/root/assets/gateway-realtime-F6D4A7N5.js +1 -0
  46. package/dist/gateway/static/root/assets/{gateway-settings-BAQnSEMJ.js → gateway-settings-C7roPHh1.js} +1 -1
  47. package/dist/gateway/static/root/assets/home-page-BGNCTtM3.js +2 -0
  48. package/dist/gateway/static/root/assets/{imports-page-re1_Nh64.js → imports-page-DxCoT0VV.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-BGBkIIzM.css +1 -0
  50. package/dist/gateway/static/root/assets/index-FCEE325-.js +106 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B_xja9LN.js → keyboard-shortcuts-settings-CnLln9Ds.js} +1 -1
  52. package/dist/gateway/static/root/assets/{local-app-workbench-page-CErdCrPX.js → local-app-workbench-page-yXRkSrEj.js} +1 -1
  53. package/dist/gateway/static/root/assets/{local-apps-page-BPL2RXdK.js → local-apps-page-D46buzTk.js} +1 -1
  54. package/dist/gateway/static/root/assets/local-session-drafts-pox8evDV.js +1 -0
  55. package/dist/gateway/static/root/assets/logs-page-DmcCHnH0.js +2 -0
  56. package/dist/gateway/static/root/assets/management-settings-khN1ThNL.js +1 -0
  57. package/dist/gateway/static/root/assets/note-detail-panel-C_t58yha.js +5 -0
  58. package/dist/gateway/static/root/assets/notes-page-BJ0QS6xx.js +8 -0
  59. package/dist/gateway/static/root/assets/{page-context-capture-button-tf77xIz3.js → page-context-capture-button-DfRODHv1.js} +1 -1
  60. package/dist/gateway/static/root/assets/personal-page-CiiXwwQE.js +1 -0
  61. package/dist/gateway/static/root/assets/{product-open-page-Dc3Y-Y7J.js → product-open-page-_Bp6HRmm.js} +1 -1
  62. package/dist/gateway/static/root/assets/{product-preview-content-MG_hmVA3.js → product-preview-content-BUdiO0Ct.js} +1 -1
  63. package/dist/gateway/static/root/assets/project-detail-page-Clb-fXYk.js +1 -0
  64. package/dist/gateway/static/root/assets/{projects-page-MllfNLGA.js → projects-page-D9JEEqhh.js} +1 -1
  65. package/dist/gateway/static/root/assets/{remote-access-hub-Bs-C70el.js → remote-access-hub-CmyTq3_l.js} +1 -1
  66. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DpJ5jNzR.js → runtime-tools-settings-panel-B1_inj8L.js} +1 -1
  67. package/dist/gateway/static/root/assets/{scenes-page-Dpxamkw6.js → scenes-page-CUNAZN2_.js} +2 -2
  68. package/dist/gateway/static/root/assets/{schema-form-DUeyQ1zh.js → schema-form-CfT-9UVw.js} +1 -1
  69. package/dist/gateway/static/root/assets/{send-session-input-Dgn4BRk_.js → send-session-input-BW40VHiL.js} +1 -1
  70. package/dist/gateway/static/root/assets/session-manager-BqlvrjPE.js +16 -0
  71. package/dist/gateway/static/root/assets/sessions-page-CXZKScvu.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-B2vKXmzg.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-page-DouHuBXt.js → settings-page-1h3vyueg.js} +1 -1
  74. package/dist/gateway/static/root/assets/setup-status-panel-Cqc7UlZy.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-link-dialog-DJTabLAM.js → share-link-dialog-HCHM8qnf.js} +1 -1
  76. package/dist/gateway/static/root/assets/{share-preview-page-jw7h4t_B.js → share-preview-page-Ce6FNWt1.js} +1 -1
  77. package/dist/gateway/static/root/assets/shares-settings-Dh5jisCK.js +1 -0
  78. package/dist/gateway/static/root/assets/{skill-api-CfyX_0zN.js → skill-api-deDZeQS8.js} +1 -1
  79. package/dist/gateway/static/root/assets/skills-page-DZozl9U_.js +2 -0
  80. package/dist/gateway/static/root/assets/{system-settings-panel-DWf256TE.js → system-settings-panel-CtzyMxqq.js} +1 -1
  81. package/dist/gateway/static/root/assets/{task-detail-page-DE6N1ZQe.js → task-detail-page-5f_V0h-p.js} +2 -2
  82. package/dist/gateway/static/root/assets/{tunnel-api-BBm9esrY.js → tunnel-api-vMtlbJ-m.js} +1 -1
  83. package/dist/gateway/static/root/assets/{usage-page-C93x89uW.js → usage-page-B1-BCW8U.js} +1 -1
  84. package/dist/gateway/static/root/assets/{use-composer-attachments-C7Gaaai1.js → use-composer-attachments-DJya1hIL.js} +1 -1
  85. package/dist/gateway/static/root/assets/use-file-preview-expanded-C5ONO7sF.js +2 -0
  86. package/dist/gateway/static/root/assets/user-model-page-D4BSq9HJ.js +2 -0
  87. package/dist/gateway/static/root/assets/{work-discovery-overlay-Bs2MKiTv.js → work-discovery-overlay-CjiNYJV5.js} +1 -1
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BR_U_snV.js → workflow-run-setup-panel-DJOetXvm.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-CcAPFh2R.js +6 -0
  90. package/dist/gateway/static/root/assets/{workspace-api-Si2o3inw.js → workspace-api-WhbMvdBE.js} +2 -2
  91. package/dist/gateway/static/root/index.html +18 -20
  92. package/dist/package.js +1 -1
  93. package/dist/packages/endpoint-tools-client/src/index.js +189 -0
  94. package/dist/packages/endpoint-tools-protocol/src/bridge.js +105 -0
  95. package/dist/packages/endpoint-tools-protocol/src/index.js +93 -2
  96. package/dist/packages/endpoint-tools-protocol/src/location.js +109 -0
  97. package/dist/packages/gateway-contract/src/session-input-command.js +30 -5
  98. package/dist/src/agent/agent-manager.js +22 -26
  99. package/dist/src/agent/embedded/codemode-extension.d.ts +7 -0
  100. package/dist/src/agent/embedded/codemode-extension.js +232 -0
  101. package/dist/src/agent/embedded/codemode-output.d.ts +2 -0
  102. package/dist/src/agent/embedded/codemode-output.js +34 -0
  103. package/dist/src/agent/embedded/external-tool-discovery.d.ts +6 -0
  104. package/dist/src/agent/embedded/external-tool-discovery.js +60 -0
  105. package/dist/src/agent/embedded/model-runtime.js +5 -2
  106. package/dist/src/agent/embedded/run-for-session.js +10 -1
  107. package/dist/src/agent/embedded/run-turn.js +10 -3
  108. package/dist/src/agent/embedded/session-runner.d.ts +9 -1
  109. package/dist/src/agent/embedded/session-runner.js +111 -23
  110. package/dist/src/agent/embedded/session-tool-result-guard.d.ts +2 -0
  111. package/dist/src/agent/embedded/session-tool-result-guard.js +17 -0
  112. package/dist/src/agent/embedded/subscribe-session.js +14 -4
  113. package/dist/src/agent/embedded/tool-metadata.d.ts +15 -0
  114. package/dist/src/agent/embedded/tool-metadata.js +38 -0
  115. package/dist/src/agent/embedded/tool-search-extension.d.ts +5 -0
  116. package/dist/src/agent/embedded/tool-search-extension.js +31 -0
  117. package/dist/src/agent/embedded/types.d.ts +7 -0
  118. package/dist/src/agent/embedded/xopc-tools-bridge.js +6 -0
  119. package/dist/src/agent/external-tools/endpoint-provider.d.ts +1 -1
  120. package/dist/src/agent/external-tools/endpoint-provider.js +148 -56
  121. package/dist/src/agent/external-tools/extension-provider.js +8 -1
  122. package/dist/src/agent/external-tools/gateway-tools.d.ts +1 -1
  123. package/dist/src/agent/external-tools/gateway-tools.js +45 -22
  124. package/dist/src/agent/external-tools/index.js +46 -14
  125. package/dist/src/agent/external-tools/memory-provider.js +8 -1
  126. package/dist/src/agent/external-tools/read-policy.js +2 -1
  127. package/dist/src/agent/external-tools/service.d.ts +2 -0
  128. package/dist/src/agent/external-tools/service.js +25 -3
  129. package/dist/src/agent/external-tools/tool-registry.d.ts +14 -0
  130. package/dist/src/agent/external-tools/tool-registry.js +14 -0
  131. package/dist/src/agent/external-tools/types.d.ts +8 -1
  132. package/dist/src/agent/external-tools/types.js +0 -1
  133. package/dist/src/agent/mcp/config.d.ts +18 -0
  134. package/dist/src/agent/mcp/{bundle-mcp-config.js → config.js} +8 -25
  135. package/dist/src/agent/mcp/native-mcp.d.ts +6 -0
  136. package/dist/src/agent/mcp/native-mcp.js +73 -0
  137. package/dist/src/agent/service.js +2 -5
  138. package/dist/src/agent/skills/installer.js +1 -1
  139. package/dist/src/agent/skills/skill-manager.js +1 -1
  140. package/dist/src/agent/skills/skill-sources.js +1 -1
  141. package/dist/src/agent/source-context/index.d.ts +0 -1
  142. package/dist/src/agent/source-context/index.js +1 -2
  143. package/dist/src/agent/source-context/injector.js +1 -0
  144. package/dist/src/agent/source-context/types.d.ts +2 -2
  145. package/dist/src/agent/source-context/types.js +1 -1
  146. package/dist/src/agent/tools/cli-clarify.js +1 -1
  147. package/dist/src/agent/tools/codemode-permissions.d.ts +4 -0
  148. package/dist/src/agent/tools/codemode-permissions.js +23 -0
  149. package/dist/src/agent/tools/dataBatch.js +3 -1
  150. package/dist/src/agent/tools/delegation-parent-policy.js +1 -4
  151. package/dist/src/agent/tools/factory.js +4 -3
  152. package/dist/src/agent/transcript/provider-capabilities.js +0 -1
  153. package/dist/src/agent/transcript/transcript-policy.js +1 -2
  154. package/dist/src/agent-config/schema.d.ts +28 -0
  155. package/dist/src/agent-config/schema.js +7 -0
  156. package/dist/src/auth/credentials.js +7 -20
  157. package/dist/src/auth/model-credential-store.js +11 -4
  158. package/dist/src/auth/oauth/index.d.ts +1 -1
  159. package/dist/src/auth/oauth/index.js +3 -3
  160. package/dist/src/auth/oauth/openai.d.ts +2 -0
  161. package/dist/src/auth/oauth/openai.js +90 -0
  162. package/dist/src/auth/oauth/registry.js +3 -3
  163. package/dist/src/auth/oauth/types.d.ts +1 -0
  164. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  165. package/dist/src/auth/sync-provider-auth.js +5 -0
  166. package/dist/src/chat-commands/builtins/model.js +2 -2
  167. package/dist/src/cli/command-manifest.js +1 -1
  168. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  169. package/dist/src/cli/commands/extension-agent-plugin.js +0 -19
  170. package/dist/src/cli/commands/mcp.js +36 -2
  171. package/dist/src/cli/commands/models.js +1 -1
  172. package/dist/src/cli/utils/oauth-login.js +2 -2
  173. package/dist/src/config/index.js +3 -3
  174. package/dist/src/config/mcp-config-normalize.d.ts +0 -3
  175. package/dist/src/config/mcp-config-normalize.js +2 -22
  176. package/dist/src/config/models-json.d.ts +0 -5
  177. package/dist/src/config/models-json.js +13 -4
  178. package/dist/src/config/paths.d.ts +0 -1
  179. package/dist/src/config/paths.js +1 -4
  180. package/dist/src/config/schema.d.ts +130 -36
  181. package/dist/src/config/schema.js +52 -35
  182. package/dist/src/connectors/auth-provider-registry.d.ts +1 -1
  183. package/dist/src/connectors/auth-provider-registry.js +1 -21
  184. package/dist/src/connectors/china-catalog.js +5 -5
  185. package/dist/src/connectors/connection-recovery-service.d.ts +1 -6
  186. package/dist/src/connectors/connection-recovery-service.js +3 -105
  187. package/dist/src/connectors/health.d.ts +1 -2
  188. package/dist/src/connectors/health.js +2 -101
  189. package/dist/src/connectors/types.d.ts +1 -1
  190. package/dist/src/endpoint-tools/binding-service.d.ts +2 -0
  191. package/dist/src/endpoint-tools/binding-service.js +14 -2
  192. package/dist/src/endpoint-tools/bridge-host.d.ts +15 -0
  193. package/dist/src/endpoint-tools/bridge-host.js +166 -0
  194. package/dist/src/endpoint-tools/bridge.d.ts +27 -0
  195. package/dist/src/endpoint-tools/bridge.js +88 -0
  196. package/dist/src/endpoint-tools/capability-catalog.d.ts +2 -0
  197. package/dist/src/endpoint-tools/capability-catalog.js +8 -0
  198. package/dist/src/endpoint-tools/grant-service.d.ts +69 -0
  199. package/dist/src/endpoint-tools/grant-service.js +113 -0
  200. package/dist/src/endpoint-tools/index.js +1 -1
  201. package/dist/src/endpoint-tools/invocation-service.js +6 -2
  202. package/dist/src/endpoint-tools/location-task.d.ts +22 -0
  203. package/dist/src/endpoint-tools/location-task.js +114 -0
  204. package/dist/src/endpoint-tools/policy.js +16 -1
  205. package/dist/src/endpoint-tools/registry.d.ts +2 -0
  206. package/dist/src/endpoint-tools/registry.js +9 -0
  207. package/dist/src/endpoint-tools/result-projector.d.ts +15 -0
  208. package/dist/src/endpoint-tools/result-projector.js +31 -0
  209. package/dist/src/endpoint-tools/runtime.d.ts +2 -0
  210. package/dist/src/endpoint-tools/runtime.js +15 -2
  211. package/dist/src/endpoint-tools/target-resolver.d.ts +12 -0
  212. package/dist/src/endpoint-tools/target-resolver.js +27 -0
  213. package/dist/src/endpoint-tools/turn-context.d.ts +6 -0
  214. package/dist/src/endpoint-tools/turn-context.js +29 -0
  215. package/dist/src/extensions/agent-plugins/auth.d.ts +0 -2
  216. package/dist/src/extensions/agent-plugins/auth.js +2 -19
  217. package/dist/src/extensions/agent-plugins/credentials.js +3 -19
  218. package/dist/src/extensions/agent-plugins/inventory.d.ts +2 -2
  219. package/dist/src/extensions/agent-plugins/mcp-adapter.js +1 -5
  220. package/dist/src/extensions/agent-plugins/source-http-fetch.d.ts +2 -0
  221. package/dist/src/{agent/mcp/plugin-http-fetch.js → extensions/agent-plugins/source-http-fetch.js} +7 -7
  222. package/dist/src/extensions/agent-plugins/sources.js +2 -2
  223. package/dist/src/extensions/agent-plugins/store.js +1 -3
  224. package/dist/src/extensions/agent-plugins/validation.d.ts +0 -4
  225. package/dist/src/extensions/agent-plugins/validation.js +13 -20
  226. package/dist/src/gateway/agents-admin.d.ts +5 -0
  227. package/dist/src/gateway/agents-admin.js +56 -1
  228. package/dist/src/gateway/chat-stream/mapper.js +9 -0
  229. package/dist/src/gateway/chat-stream/protocol.d.ts +4 -4
  230. package/dist/src/gateway/hono/lib/config-payload.d.ts +9 -4
  231. package/dist/src/gateway/hono/lib/config-payload.js +2 -5
  232. package/dist/src/gateway/hono/oauth-async.js +9 -2
  233. package/dist/src/gateway/hono/routes/agent-plugins.js +4 -9
  234. package/dist/src/gateway/hono/routes/agents.js +4 -3
  235. package/dist/src/gateway/hono/routes/connection-waits.js +2 -5
  236. package/dist/src/gateway/hono/routes/connectors.js +5 -60
  237. package/dist/src/gateway/hono/routes/device-authorizations.d.ts +3 -0
  238. package/dist/src/gateway/hono/routes/device-authorizations.js +74 -0
  239. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +7 -0
  240. package/dist/src/gateway/hono/routes/endpoint-tools.d.ts +1 -0
  241. package/dist/src/gateway/hono/routes/endpoint-tools.js +53 -3
  242. package/dist/src/gateway/hono/routes/lazy-bundles.js +17 -1
  243. package/dist/src/gateway/hono/routes/mcp.d.ts +1 -1
  244. package/dist/src/gateway/hono/routes/mcp.js +11 -237
  245. package/dist/src/gateway/hono/routes/session-command-handler.js +11 -1
  246. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +8 -2
  247. package/dist/src/gateway/hono/routes/session-input-handler.js +25 -1
  248. package/dist/src/gateway/service/config-coordinator.js +2 -5
  249. package/dist/src/gateway/service/marketplace-service.js +2 -2
  250. package/dist/src/gateway/service/run-gateway-agent.js +13 -5
  251. package/dist/src/gateway/service/session-input-coordinator.d.ts +1 -1
  252. package/dist/src/gateway/service/session-input-coordinator.js +29 -9
  253. package/dist/src/gateway/service/sessions-api.js +0 -6
  254. package/dist/src/gateway/service.js +3 -12
  255. package/dist/src/gateway/session-reset-service.js +0 -6
  256. package/dist/src/imports/compatibility.js +12 -10
  257. package/dist/src/mcp/channel-bridge.js +1 -1
  258. package/dist/src/providers/env-keys.js +1 -1
  259. package/dist/src/providers/index.js +26 -24
  260. package/dist/src/providers/model-call.d.ts +0 -2
  261. package/dist/src/providers/model-call.js +2 -6
  262. package/dist/src/providers/model-registry.js +4 -2
  263. package/dist/src/providers/model-supplements.d.ts +3 -3
  264. package/dist/src/providers/model-supplements.js +6 -27
  265. package/dist/src/providers/presentation.js +3 -8
  266. package/dist/src/providers/prompt-cache-plan.js +1 -1
  267. package/dist/src/providers/provider-auth-service.d.ts +1 -1
  268. package/dist/src/providers/provider-auth-service.js +7 -2
  269. package/dist/src/providers/provider-policy.d.ts +3 -0
  270. package/dist/src/providers/provider-policy.js +14 -0
  271. package/dist/src/providers/register-runtime-providers.js +6 -1
  272. package/dist/src/realtime/runtime.js +1 -1
  273. package/dist/src/session/store.js +7 -1
  274. package/dist/src/session/transcript-events.d.ts +5 -0
  275. package/dist/src/session/transcript-events.js +1 -0
  276. package/dist/src/session/types.d.ts +2 -0
  277. package/dist/src/storage/sqlite/device-grant-audit-repository.d.ts +11 -0
  278. package/dist/src/storage/sqlite/device-grant-audit-repository.js +10 -0
  279. package/dist/src/storage/sqlite/endpoint-device-settings-repository.d.ts +7 -0
  280. package/dist/src/storage/sqlite/endpoint-device-settings-repository.js +17 -0
  281. package/dist/src/storage/sqlite/migrations/240_device_settings.sql +5 -0
  282. package/dist/src/storage/sqlite/migrations/241_device_grant_audit.sql +13 -0
  283. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  284. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  285. package/dist/src/storage/sqlite/schema.js +1 -1
  286. package/dist/src/storage/sqlite/session-input-repository.d.ts +1 -0
  287. package/dist/src/storage/sqlite/session-input-repository.js +5 -1
  288. package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
  289. package/dist/src/tui/xopc-tui-keybindings.d.ts +4 -4
  290. package/package.json +19 -8
  291. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CCRfvuov.js +0 -1
  292. package/dist/gateway/static/root/assets/agent-plugin-dialog-CRlzd8El.js +0 -1
  293. package/dist/gateway/static/root/assets/agents-_ug2LCQb.js +0 -66
  294. package/dist/gateway/static/root/assets/automations-workspace-BQywN6nG.js +0 -6
  295. package/dist/gateway/static/root/assets/browser-automations-page-yiEuG1v7.js +0 -3
  296. package/dist/gateway/static/root/assets/capabilities-page-BEnFt_dj.js +0 -2
  297. package/dist/gateway/static/root/assets/connectors-page-D6wTmWA6.js +0 -2
  298. package/dist/gateway/static/root/assets/copy-text-row-BHDs3cBa.js +0 -1
  299. package/dist/gateway/static/root/assets/dependency-picker-BTERkA9X.js +0 -1
  300. package/dist/gateway/static/root/assets/device-pairing-wizard-DI2bqaKO.js +0 -1
  301. package/dist/gateway/static/root/assets/dist-Che_jiQF.js +0 -1
  302. package/dist/gateway/static/root/assets/gateway-realtime-DDWymi-o.js +0 -1
  303. package/dist/gateway/static/root/assets/home-page-BZDjvwet.js +0 -2
  304. package/dist/gateway/static/root/assets/index-BB1z8QxA.js +0 -106
  305. package/dist/gateway/static/root/assets/index-D9R6tU7r.css +0 -1
  306. package/dist/gateway/static/root/assets/link-2-D_ZKYUW7.js +0 -1
  307. package/dist/gateway/static/root/assets/local-session-drafts-DRPsDCj1.js +0 -1
  308. package/dist/gateway/static/root/assets/logs-page-DL-BM0xq.js +0 -2
  309. package/dist/gateway/static/root/assets/management-settings-BOVRHhXk.js +0 -1
  310. package/dist/gateway/static/root/assets/note-detail-panel-DJJK2yL4.js +0 -5
  311. package/dist/gateway/static/root/assets/notes-page-oCxO7ZTv.js +0 -8
  312. package/dist/gateway/static/root/assets/personal-page-DOk9gUK5.js +0 -1
  313. package/dist/gateway/static/root/assets/project-detail-page-3uAzbW4T.js +0 -1
  314. package/dist/gateway/static/root/assets/session-manager-LInoZ_Yi.js +0 -16
  315. package/dist/gateway/static/root/assets/sessions-page-BCVlNHtq.js +0 -1
  316. package/dist/gateway/static/root/assets/settings-advanced-gate-Bz-ue9fZ.js +0 -1
  317. package/dist/gateway/static/root/assets/setup-status-panel-B5BoZ-1y.js +0 -1
  318. package/dist/gateway/static/root/assets/shares-settings-BlnlzGjH.js +0 -1
  319. package/dist/gateway/static/root/assets/skills-page-DjdTeYzm.js +0 -2
  320. package/dist/gateway/static/root/assets/use-file-preview-expanded-Db2VYg1b.js +0 -2
  321. package/dist/gateway/static/root/assets/user-model-page-B74LkVbp.js +0 -2
  322. package/dist/gateway/static/root/assets/workflows-page-Crk4SxtC.js +0 -6
  323. package/dist/src/agent/embedded/system-prompt-override.d.ts +0 -2
  324. package/dist/src/agent/embedded/system-prompt-override.js +0 -21
  325. package/dist/src/agent/external-tools/mcp-provider.d.ts +0 -32
  326. package/dist/src/agent/external-tools/mcp-provider.js +0 -208
  327. package/dist/src/agent/mcp/bundle-mcp-config.d.ts +0 -20
  328. package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +0 -79
  329. package/dist/src/agent/mcp/bundle-mcp-gateway.js +0 -93
  330. package/dist/src/agent/mcp/bundle-mcp-names.d.ts +0 -1
  331. package/dist/src/agent/mcp/bundle-mcp-names.js +0 -25
  332. package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +0 -1
  333. package/dist/src/agent/mcp/bundle-mcp-policy.js +0 -6
  334. package/dist/src/agent/mcp/bundle-mcp-runtime.d.ts +0 -46
  335. package/dist/src/agent/mcp/bundle-mcp-runtime.js +0 -571
  336. package/dist/src/agent/mcp/bundle-mcp-tools.d.ts +0 -2
  337. package/dist/src/agent/mcp/bundle-mcp-tools.js +0 -2
  338. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +0 -76
  339. package/dist/src/agent/mcp/bundle-mcp-types.js +0 -1
  340. package/dist/src/agent/mcp/embedded-mcp.d.ts +0 -10
  341. package/dist/src/agent/mcp/embedded-mcp.js +0 -14
  342. package/dist/src/agent/mcp/index.d.ts +0 -5
  343. package/dist/src/agent/mcp/index.js +0 -12
  344. package/dist/src/agent/mcp/mcp-config-shared.d.ts +0 -8
  345. package/dist/src/agent/mcp/mcp-config-shared.js +0 -39
  346. package/dist/src/agent/mcp/mcp-http.d.ts +0 -23
  347. package/dist/src/agent/mcp/mcp-http.js +0 -67
  348. package/dist/src/agent/mcp/mcp-resource-id.d.ts +0 -6
  349. package/dist/src/agent/mcp/mcp-resource-id.js +0 -19
  350. package/dist/src/agent/mcp/mcp-stdio-transport.d.ts +0 -26
  351. package/dist/src/agent/mcp/mcp-stdio-transport.js +0 -120
  352. package/dist/src/agent/mcp/mcp-stdio.d.ts +0 -18
  353. package/dist/src/agent/mcp/mcp-stdio.js +0 -35
  354. package/dist/src/agent/mcp/mcp-transport-config.d.ts +0 -28
  355. package/dist/src/agent/mcp/mcp-transport-config.js +0 -91
  356. package/dist/src/agent/mcp/mcp-transport.d.ts +0 -17
  357. package/dist/src/agent/mcp/mcp-transport.js +0 -141
  358. package/dist/src/agent/mcp/oauth/index.d.ts +0 -6
  359. package/dist/src/agent/mcp/oauth/index.js +0 -6
  360. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.d.ts +0 -5
  361. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.js +0 -14
  362. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +0 -30
  363. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +0 -276
  364. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.d.ts +0 -33
  365. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +0 -103
  366. package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +0 -31
  367. package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +0 -181
  368. package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +0 -12
  369. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +0 -91
  370. package/dist/src/agent/mcp/oauth/mcp-oauth-types.d.ts +0 -22
  371. package/dist/src/agent/mcp/oauth/mcp-oauth-types.js +0 -1
  372. package/dist/src/agent/mcp/plugin-http-fetch.d.ts +0 -2
  373. package/dist/src/agent/source-context/mcp-resource-context.d.ts +0 -8
  374. package/dist/src/agent/source-context/mcp-resource-context.js +0 -30
  375. package/dist/src/auth/oauth/openai-codex.d.ts +0 -9
  376. package/dist/src/auth/oauth/openai-codex.js +0 -414
  377. package/dist/src/connectors/plugin-mcp-recovery.d.ts +0 -28
  378. package/dist/src/connectors/plugin-mcp-recovery.js +0 -90
  379. package/dist/src/extensions/agent-plugins/connection.d.ts +0 -8
  380. package/dist/src/extensions/agent-plugins/connection.js +0 -41
  381. package/dist/src/extensions/agent-plugins/health.d.ts +0 -4
  382. package/dist/src/extensions/agent-plugins/health.js +0 -48
  383. package/dist/src/extensions/agent-plugins/plugin-oauth-scope.d.ts +0 -1
  384. package/dist/src/extensions/agent-plugins/plugin-oauth-scope.js +0 -8
@@ -1,8 +1,13 @@
1
- import { COMPUTER_CONTROL_TOOL, init_src } from "../../../packages/computer-control-contract/src/index.js";
2
- import { BROWSER_CONTROL_ENDPOINT_TOOL_NAME } from "../../../packages/browser-control-contract/src/index.js";
3
- import { executeExternalOperation } from "../../capabilities/runtime/external-operations.js";
1
+ import { init_src } from "../../../packages/computer-control-contract/src/index.js";
2
+ import "../../../packages/browser-control-contract/src/index.js";
3
+ import { ExternalEffectNotAppliedError, executeExternalOperation } from "../../capabilities/runtime/external-operations.js";
4
4
  import { canonicalCapabilityJson } from "../../capabilities/runtime/dispatcher.js";
5
5
  import { externalToolRef, parseExternalToolRef } from "./refs.js";
6
+ import { processLocationTask } from "../../endpoint-tools/location-task.js";
7
+ import { projectDeviceReading } from "../../endpoint-tools/result-projector.js";
8
+ import { getEndpointDeviceSettings } from "../../storage/sqlite/endpoint-device-settings-repository.js";
9
+ import { DeviceTargetResolver } from "../../endpoint-tools/target-resolver.js";
10
+ import { EndpointToolExecutionError } from "../../endpoint-tools/invocation-service.js";
6
11
  import { createHash } from "node:crypto";
7
12
  //#region src/agent/external-tools/endpoint-provider.ts
8
13
  init_src();
@@ -17,15 +22,16 @@ var EndpointToolProvider = class {
17
22
  this.deps = deps;
18
23
  }
19
24
  async search(_query) {
20
- const endpoint = this.currentEndpoint();
21
- if (!endpoint) return [];
22
- return endpoint.tools.filter(({ descriptor }) => ![BROWSER_CONTROL_ENDPOINT_TOOL_NAME, COMPUTER_CONTROL_TOOL].includes(descriptor.name)).map(({ descriptor }) => ({
25
+ const context = this.deps.getCurrentContext();
26
+ if (!context) return [];
27
+ const resolver = this.targetResolver();
28
+ return resolver.candidates(context.conversationId, context.origin).flatMap((endpoint) => endpoint.tools.filter(({ descriptor }) => !["browser.control", "desktop.computer.control"].includes(descriptor.name) && resolver.resolve(context.conversationId, context.origin, endpoint.endpointId, descriptor.name)).map(({ descriptor }) => ({
23
29
  toolRef: externalToolRef(this.source, endpoint.endpointId, descriptor.name),
24
30
  source: this.source,
25
31
  namespace: endpoint.endpointId,
26
32
  title: descriptor.title,
27
- summary: `${descriptor.description} (${endpoint.displayName})`
28
- }));
33
+ summary: `${descriptor.description} (${getEndpointDeviceSettings(endpoint.principalId)?.nickname ?? endpoint.displayName})`
34
+ })));
29
35
  }
30
36
  async describe(toolRef) {
31
37
  const resolved = this.resolve(toolRef);
@@ -36,77 +42,163 @@ var EndpointToolProvider = class {
36
42
  namespace: resolved.endpointId,
37
43
  title: resolved.tool.descriptor.title,
38
44
  summary: `${resolved.tool.descriptor.description} (${resolved.displayName})`,
39
- description: resolved.tool.descriptor.description,
40
- inputSchema: resolved.tool.descriptor.inputSchema
45
+ description: `${resolved.tool.descriptor.description} Device: ${JSON.stringify(resolved.displayName)}; endpoint: ${JSON.stringify(resolved.endpointId)}. Do not substitute another device.${resolved.approvedArguments ? ` Single-call cross-device consent requires exactly these arguments: ${JSON.stringify(resolved.approvedArguments)}.` : ""}`,
46
+ inputSchema: resolved.tool.descriptor.inputSchema,
47
+ outputSchema: {
48
+ type: "object",
49
+ properties: { content: resolved.tool.descriptor.name.endsWith(".device.get_location") ? {
50
+ type: "array",
51
+ minItems: 1,
52
+ maxItems: 1,
53
+ items: {
54
+ type: "object",
55
+ required: ["type", "value"],
56
+ properties: {
57
+ type: { const: "json" },
58
+ value: {
59
+ type: "object",
60
+ required: [
61
+ "source",
62
+ "purpose",
63
+ "data"
64
+ ]
65
+ }
66
+ }
67
+ }
68
+ } : resolved.tool.descriptor.outputSchema },
69
+ required: ["content"],
70
+ additionalProperties: false
71
+ },
72
+ contractRevision: resolved.contractRevision,
73
+ annotations: {
74
+ readOnlyHint: resolved.tool.descriptor.effect === "read",
75
+ destructiveHint: resolved.tool.descriptor.effect === "destructive",
76
+ idempotentHint: resolved.tool.descriptor.idempotent
77
+ },
78
+ batchRead: resolved.tool.descriptor.effect === "read" && resolved.tool.descriptor.sensitivity === "public" && !resolved.tool.descriptor.requiresForeground && resolved.tool.descriptor.confirmation === "never" && resolved.tool.descriptor.requiredPermissions.length === 0
41
79
  };
42
80
  }
43
81
  async execute(toolRef, args, _approvalId, context) {
44
82
  const resolved = this.resolve(toolRef);
45
83
  if (!resolved) throw new Error(`Endpoint tool is unavailable for this turn: ${toolRef}`);
46
- const invoke = () => this.deps.runtime.invocations.invoke({
47
- endpointId: resolved.endpointId,
48
- toolCallId: context.toolCallId,
49
- toolName: resolved.tool.descriptor.name,
50
- arguments: args,
51
- descriptorRevision: resolved.tool.revision,
52
- signal: context.signal,
53
- onProgress: (progress) => {
54
- context.onUpdate?.({
84
+ const revision = context.contractRevision ?? resolved.contractRevision;
85
+ let grantLease;
86
+ const invoke = () => {
87
+ context.signal?.throwIfAborted();
88
+ if (this.resolve(toolRef)?.contractRevision !== revision) throw new ExternalEffectNotAppliedError("Endpoint connection, binding or tool contract changed");
89
+ const turn = this.deps.getCurrentContext();
90
+ const grant = this.deps.runtime.grants?.find(turn.conversationId, turn.origin, resolved.endpointId, resolved.tool.descriptor.name);
91
+ if (grant) grantLease = this.deps.runtime.grants.reserve(grant.id, args);
92
+ const signal = grantLease ? AbortSignal.any([grantLease.signal, context.signal ?? new AbortController().signal]) : context.signal;
93
+ return this.deps.runtime.invocations.invoke({
94
+ endpointId: resolved.endpointId,
95
+ toolCallId: context.toolCallId,
96
+ toolName: resolved.tool.descriptor.name,
97
+ arguments: args,
98
+ descriptorRevision: resolved.tool.revision,
99
+ signal,
100
+ onProgress: (progress) => {
101
+ context.onUpdate?.({
102
+ content: [{
103
+ type: "text",
104
+ text: progress.message ?? "Endpoint tool is running"
105
+ }],
106
+ details: {
107
+ endpointId: resolved.endpointId,
108
+ ...progress.percent === void 0 ? {} : { percent: progress.percent }
109
+ }
110
+ });
111
+ }
112
+ }).catch((error) => {
113
+ if (resolved.tool.descriptor.confirmation === "always" && error instanceof EndpointToolExecutionError && error.code === "USER_DENIED") throw new ExternalEffectNotAppliedError(error.message, { cause: error });
114
+ throw error;
115
+ });
116
+ };
117
+ try {
118
+ const result = resolved.tool.descriptor.effect === "read" ? await invoke() : await executeExternalOperation({
119
+ principalId: resolved.principalId,
120
+ capabilityId: toolRef,
121
+ idempotencyKey: createHash("sha256").update(`${this.deps.getCurrentContext()?.conversationId}:${context.toolCallId}`).digest("hex"),
122
+ requestDigest: createHash("sha256").update(canonicalCapabilityJson(args)).digest("hex"),
123
+ descriptorDigest: resolved.tool.revision,
124
+ surface: "agent",
125
+ recovery: "manual"
126
+ }, invoke);
127
+ if (resolved.tool.descriptor.name.endsWith(".device.get_location")) {
128
+ const signal = grantLease ? AbortSignal.any([grantLease.signal, context.signal ?? new AbortController().signal]) : context.signal;
129
+ const summary = await processLocationTask(args, result.content, {
130
+ endpointId: resolved.endpointId,
131
+ principalId: resolved.principalId
132
+ }, signal);
133
+ signal?.throwIfAborted();
134
+ const current = this.deps.runtime.registry.get(resolved.endpointId);
135
+ if (!current || current.connectionId !== resolved.connectionId || current.availability !== "foreground" || this.deps.runtime.registry.getTool(resolved.endpointId, resolved.tool.descriptor.name)?.revision !== resolved.tool.revision) throw new ExternalEffectNotAppliedError("Location device connection or capability changed");
136
+ return {
55
137
  content: [{
56
138
  type: "text",
57
- text: progress.message ?? "Endpoint tool is running"
139
+ text: JSON.stringify(summary)
58
140
  }],
141
+ structuredContent: JSON.parse(JSON.stringify({ content: [{
142
+ type: "json",
143
+ value: summary
144
+ }] })),
59
145
  details: {
60
146
  endpointId: resolved.endpointId,
61
- ...progress.percent === void 0 ? {} : { percent: progress.percent }
147
+ endpointToolName: resolved.tool.descriptor.name,
148
+ deviceObservation: summary
62
149
  }
63
- });
64
- }
65
- });
66
- const result = resolved.tool.descriptor.effect === "read" ? await invoke() : await executeExternalOperation({
67
- principalId: resolved.principalId,
68
- capabilityId: toolRef,
69
- idempotencyKey: createHash("sha256").update(`${this.deps.getCurrentContext()?.conversationId}:${context.toolCallId}`).digest("hex"),
70
- requestDigest: createHash("sha256").update(canonicalCapabilityJson(args)).digest("hex"),
71
- descriptorDigest: resolved.tool.revision,
72
- surface: "agent",
73
- recovery: "manual"
74
- }, invoke);
75
- const files = result.content.filter((item) => item.type === "file");
76
- return {
77
- content: result.content.map((item) => ({
78
- type: "text",
79
- text: contentText(item)
80
- })),
81
- details: {
82
- endpointId: resolved.endpointId,
83
- endpointToolName: resolved.tool.descriptor.name,
84
- endpointSensitivity: resolved.tool.descriptor.sensitivity,
85
- ...result.details ?? {},
86
- ...files.length === 0 ? {} : { endpointFiles: files }
150
+ };
87
151
  }
88
- };
152
+ const observation = projectDeviceReading(resolved.tool.descriptor.name, resolved.endpointId, resolved.principalId, result.content, Date.now(), args);
153
+ const files = result.content.filter((item) => item.type === "file");
154
+ return {
155
+ content: observation ? [{
156
+ type: "text",
157
+ text: JSON.stringify(observation)
158
+ }] : result.content.map((item) => ({
159
+ type: "text",
160
+ text: contentText(item)
161
+ })),
162
+ structuredContent: JSON.parse(JSON.stringify({ content: result.content })),
163
+ details: {
164
+ ...observation ? { deviceObservation: observation } : {},
165
+ endpointId: resolved.endpointId,
166
+ endpointToolName: resolved.tool.descriptor.name,
167
+ endpointSensitivity: resolved.tool.descriptor.sensitivity,
168
+ ...result.details ?? {},
169
+ ...files.length === 0 ? {} : { endpointFiles: files }
170
+ }
171
+ };
172
+ } finally {
173
+ grantLease?.complete();
174
+ }
89
175
  }
90
- currentEndpoint() {
91
- const context = this.deps.getCurrentContext();
92
- if (!context) return void 0;
93
- if (this.deps.runtime.bindings.get(context.conversationId)) return this.deps.runtime.bindings.resolve(context.conversationId);
94
- const origin = context.origin;
95
- if (origin?.type !== "endpoint") return void 0;
96
- return this.deps.runtime.registry.get(origin.endpointId);
176
+ targetResolver() {
177
+ return new DeviceTargetResolver(this.deps.runtime.registry, this.deps.runtime.bindings, this.deps.runtime.grants);
97
178
  }
98
179
  resolve(toolRef) {
99
180
  const parsed = parseExternalToolRef(toolRef, this.source);
100
181
  if (!parsed) return void 0;
101
- const endpoint = this.currentEndpoint();
182
+ const context = this.deps.getCurrentContext();
183
+ if (!context) return void 0;
184
+ const endpoint = this.targetResolver().resolve(context.conversationId, context.origin, parsed.namespace, parsed.toolName);
102
185
  if (!endpoint || endpoint.endpointId !== parsed.namespace) return void 0;
103
186
  const tool = this.deps.runtime.registry.getTool(endpoint.endpointId, parsed.toolName);
104
187
  if (tool && ["browser.control", "desktop.computer.control"].includes(tool.descriptor.name)) return void 0;
105
188
  return tool ? {
189
+ approvedArguments: this.deps.runtime.grants.find(context.conversationId, context.origin, endpoint.endpointId, parsed.toolName)?.arguments,
190
+ connectionId: endpoint.connectionId,
106
191
  endpointId: endpoint.endpointId,
107
192
  principalId: endpoint.principalId,
108
- displayName: endpoint.displayName,
109
- tool
193
+ displayName: getEndpointDeviceSettings(endpoint.principalId)?.nickname ?? endpoint.displayName,
194
+ tool,
195
+ contractRevision: createHash("sha256").update(JSON.stringify([
196
+ endpoint.principalId,
197
+ endpoint.connectionId,
198
+ tool.revision,
199
+ this.deps.runtime.bindings.get(this.deps.getCurrentContext().conversationId)?.boundAt ?? null,
200
+ this.deps.runtime.grants?.find(context.conversationId, context.origin, endpoint.endpointId, parsed.toolName)?.id ?? null
201
+ ])).digest("hex")
110
202
  } : void 0;
111
203
  }
112
204
  };
@@ -1,5 +1,6 @@
1
1
  import { externalToolRef, parseExternalToolRef } from "./refs.js";
2
2
  import { executeToolWithProtection } from "../tools/executor.js";
3
+ import { getXopcToolMetadata } from "../embedded/tool-metadata.js";
3
4
  //#region src/agent/external-tools/extension-provider.ts
4
5
  function toolSummary(tool) {
5
6
  return tool.description || tool.label || tool.name;
@@ -28,6 +29,8 @@ var ExtensionToolProvider = class {
28
29
  if (!resolved) return void 0;
29
30
  const { extensionId, tool } = resolved;
30
31
  const summary = toolSummary(tool);
32
+ const metadata = getXopcToolMetadata(tool);
33
+ if (metadata?.exposure === "hidden") return void 0;
31
34
  return {
32
35
  toolRef,
33
36
  source: this.source,
@@ -35,7 +38,10 @@ var ExtensionToolProvider = class {
35
38
  title: tool.label || tool.name,
36
39
  summary,
37
40
  description: summary,
38
- inputSchema: tool.parameters
41
+ inputSchema: tool.parameters,
42
+ outputSchema: metadata?.outputSchema,
43
+ annotations: metadata?.annotations,
44
+ exposure: metadata?.exposure
39
45
  };
40
46
  }
41
47
  async execute(toolRef, args, _approvalId, context) {
@@ -50,6 +56,7 @@ var ExtensionToolProvider = class {
50
56
  if (!hook.allowed) throw new Error(hook.reason ?? "Extension tool call blocked by policy hook.");
51
57
  executionArgs = hook.params ?? args;
52
58
  }
59
+ context.validateArguments?.(executionArgs);
53
60
  return executeToolWithProtection(resolved.tool, context.toolCallId, executionArgs, context.signal, context.onUpdate, this.deps.toolExecutorConfig);
54
61
  }
55
62
  resolve(toolRef) {
@@ -9,4 +9,4 @@ export declare const EXTERNAL_TOOL_NAMES: {
9
9
  readonly requireConnection: "xopc_require_connection";
10
10
  readonly updateConnectionObjective: "xopc_update_connection_objective";
11
11
  };
12
- export declare function createExternalToolGatewayTools(providers: ExternalToolProvider[], getContext?: () => ExternalToolTurnContext | null, getConfig?: () => Config | undefined): AgentTool[];
12
+ export declare function createExternalToolGatewayTools(providers: ExternalToolProvider[], getContext?: () => ExternalToolTurnContext | null, getConfig?: () => Config | undefined, getExecutionConversationId?: () => string | undefined, nativeSources?: readonly import('./types.js').ExternalToolSource[], executorConfig?: Partial<import('../tools/executor.js').ToolExecutorConfig>): AgentTool[];
@@ -8,11 +8,12 @@ import { init_session_repository } from "../../storage/sqlite/session-repository
8
8
  import { listConnectorInstances } from "../../connectors/instances.js";
9
9
  import { connectorPrincipalForSession } from "../../connectors/principal.js";
10
10
  import { parseExternalToolRef } from "./refs.js";
11
+ import { setXopcToolMetadata } from "../embedded/tool-metadata.js";
11
12
  import { getStoreConnectorInstallPlan, parseStoreConnectorCandidateRef, searchStoreConnectorInstallCandidates } from "../../capabilities/store-connector.js";
12
13
  import { connectionCandidates, resolveConnectionCandidate } from "../../connectors/connection-candidates.js";
13
- import { parsePluginMcpCandidateRef, resolvePluginMcpConnectionCandidate } from "../../extensions/agent-plugins/connection.js";
14
14
  import { ExternalToolService } from "./service.js";
15
15
  import { EXTERNAL_TOOL_SOURCES } from "./types.js";
16
+ import { bindExternalToolRegistry } from "./tool-registry.js";
16
17
  import { Type } from "@sinclair/typebox";
17
18
  //#region src/agent/external-tools/gateway-tools.ts
18
19
  init_connector_repository();
@@ -60,17 +61,28 @@ function textResult(value, details = {}) {
60
61
  details
61
62
  };
62
63
  }
63
- function createExternalToolGatewayTools(providers, getContext, getConfig) {
64
+ function createExternalToolGatewayTools(providers, getContext, getConfig, getExecutionConversationId, nativeSources = [], executorConfig) {
64
65
  const service = new ExternalToolService(providers);
66
+ const legacySources = EXTERNAL_TOOL_SOURCES.filter((source) => !nativeSources.includes(source));
67
+ const assertLegacyRef = (ref) => {
68
+ if (nativeSources.some((source) => ref.startsWith(`${source}:`))) throw new Error("Use tool_search to load this native tool, then call it directly.");
69
+ };
65
70
  const searchTool = {
66
71
  name: EXTERNAL_TOOL_NAMES.search,
67
72
  label: "🔎 External Tool Search",
68
- description: `Search external tools from these sources: ${EXTERNAL_TOOL_SOURCES.join(", ")}. CLI connectors include Feishu/Lark, WeCom and WPS 365. Omit sources unless intentionally restricting the search; do not guess a source list. Use concise English capability keywords, e.g. "wecom doc.search". Returns executable tools, connection candidates, or reviewed Store install candidates. Call xopc_tool_describe before executing a tool. When no executable tool exists but a connection or install candidate is returned, use xopc_require_connection instead of falling back to browser automation. If a source-filtered search finds no relevant tools, retry without sources before concluding a capability is unavailable.`,
73
+ description: `Search external tools from these sources: ${legacySources.join(", ")}.${nativeSources.length ? ` Use tool_search for native ${nativeSources.join(", ")} tools.` : ""} CLI connectors include Feishu/Lark, WeCom and WPS 365. Omit sources unless intentionally restricting the search; do not guess a source list. Use concise English capability keywords, e.g. "wecom doc.search". Returns executable tools, connection candidates, or reviewed Store install candidates. Call xopc_tool_describe before executing a tool. When no executable tool exists but a connection or install candidate is returned, use xopc_require_connection instead of falling back to browser automation. If a source-filtered search finds no relevant tools, retry without sources before concluding a capability is unavailable.`,
69
74
  parameters: ToolSearchSchema,
70
75
  async execute(_toolCallId, params) {
71
76
  const selectedSources = new Set(params.sources ?? []);
72
77
  const excludedSources = selectedSources.size ? EXTERNAL_TOOL_SOURCES.filter((source) => !selectedSources.has(source)) : [];
73
- const result = await service.search(params);
78
+ if (params.sources?.length && params.sources.every((source) => nativeSources.includes(source))) return textResult({
79
+ tools: [],
80
+ instruction: "Use tool_search for native tools."
81
+ });
82
+ const result = await service.search({
83
+ ...params,
84
+ sources: (params.sources?.length ? params.sources : legacySources).filter((source) => !nativeSources.includes(source))
85
+ });
74
86
  const candidates = [...result.connectionCandidates, ...connectionCandidates(params.query)].filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index);
75
87
  let installCandidates = [];
76
88
  let installCatalogError;
@@ -101,6 +113,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
101
113
  description: "Load exact contracts for up to three external tools returned by xopc_tool_search.",
102
114
  parameters: ToolDescribeSchema,
103
115
  async execute(_toolCallId, params) {
116
+ params.toolRefs.forEach(assertLegacyRef);
104
117
  const result = await service.describe(params.toolRefs);
105
118
  return textResult({
106
119
  ...result,
@@ -114,7 +127,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
114
127
  description: "Execute one external tool using its exact reference, contract revision, and validated arguments.",
115
128
  parameters: ToolExecuteSchema,
116
129
  async execute(toolCallId, params, signal, onUpdate) {
117
- const conversationId = getContext?.()?.conversationId;
130
+ const conversationId = getExecutionConversationId?.() ?? getContext?.()?.conversationId;
118
131
  const request = conversationId ? personalRequestForExecution(conversationId) : void 0;
119
132
  if (!request && conversationId && isXopcDatabaseOpen() && getSessionMetadata(conversationId)?.customData?.personalReadRequestId) throw new Error("Personal request is no longer active");
120
133
  if (request) {
@@ -161,6 +174,17 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
161
174
  };
162
175
  }
163
176
  };
177
+ const nativeExecute = executeTool.execute.bind(executeTool);
178
+ executeTool.execute = async (id, params, signal, update) => {
179
+ assertLegacyRef(params.toolRef);
180
+ return nativeExecute(id, params, signal, update);
181
+ };
182
+ bindExternalToolRegistry(executeTool, {
183
+ service,
184
+ nativeSources,
185
+ execute: nativeExecute,
186
+ executorConfig
187
+ });
164
188
  const requireSchema = Type.Object({
165
189
  requirements: Type.Array(Type.Object({
166
190
  candidateRef: Type.String(),
@@ -203,13 +227,11 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
203
227
  if (!principal.isLocalOwner) throw new Error("Connection recovery is available in the owner chat.");
204
228
  const selected = connectionBindings(context.conversationId);
205
229
  if (params.requirements.every((item) => {
206
- const pluginTarget = parsePluginMcpCandidateRef(item.candidateRef);
207
230
  return selected.some((need) => {
208
231
  if (need.target.type === "connector") return need.target.connectorId === item.candidateRef && Boolean(need.connectionId) && (!item.accountId || item.accountId === need.accountId) && (!item.accountSelector || item.accountSelector === need.accountSelector) && listConnectorConnections({
209
232
  principalId: principal.principalId,
210
233
  connectorId: need.target.connectorId
211
234
  }).some((connection) => connection.id === need.connectionId && connection.status === "active");
212
- if (need.target.type === "plugin-mcp") return Boolean(pluginTarget && need.target.pluginId === pluginTarget.pluginId && need.target.serverName === pluginTarget.serverName && need.connectionId === need.target.serverId);
213
235
  const storeTarget = parseStoreConnectorCandidateRef(item.candidateRef);
214
236
  return Boolean(storeTarget && need.target.packageName === storeTarget.packageName && need.target.version === storeTarget.version && need.connectionId);
215
237
  });
@@ -242,7 +264,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
242
264
  },
243
265
  label: plan.definition.displayName,
244
266
  capabilities: plan.definition.capabilities
245
- } : resolvePluginMcpConnectionCandidate(item.candidateRef) ?? resolveConnectionCandidate(item.candidateRef);
267
+ } : resolveConnectionCandidate(item.candidateRef);
246
268
  if (item.accountId && need.target.type !== "connector") throw new Error("This install candidate does not support account selection.");
247
269
  if (item.accountId && need.target.type === "connector" && !listConnectorConnections({
248
270
  principalId: principal.principalId,
@@ -267,24 +289,25 @@ function createExternalToolGatewayTools(providers, getContext, getConfig) {
267
289
  maxLength: 4e3
268
290
  }))
269
291
  });
292
+ const reviseTool = {
293
+ name: EXTERNAL_TOOL_NAMES.updateConnectionObjective,
294
+ label: "Update waiting objective",
295
+ parameters: reviseSchema,
296
+ description: "Use when the user supplements or explicitly cancels the objective waiting for a connection. Update with the complete revised objective including the requested time range. For unrelated work leave the waiting objective unchanged. Cancellation does not disconnect the account.",
297
+ async execute(_id, params) {
298
+ const context = getContext?.();
299
+ if (!context) throw new Error("No active conversation.");
300
+ if (params.action === "update" && !params.objective) throw new Error("The revised objective is required.");
301
+ reviseCurrentConnectionObjective(context.conversationId, params.action === "update" ? params.objective : void 0);
302
+ return textResult({ status: params.action === "update" ? "updated" : "cancelled" });
303
+ }
304
+ };
270
305
  return [
271
306
  searchTool,
272
307
  describeTool,
273
308
  executeTool,
274
- requireTool,
275
- {
276
- name: EXTERNAL_TOOL_NAMES.updateConnectionObjective,
277
- label: "Update waiting objective",
278
- parameters: reviseSchema,
279
- description: "Use when the user supplements or explicitly cancels the objective waiting for a connection. Update with the complete revised objective including the requested time range. For unrelated work leave the waiting objective unchanged. Cancellation does not disconnect the account.",
280
- async execute(_id, params) {
281
- const context = getContext?.();
282
- if (!context) throw new Error("No active conversation.");
283
- if (params.action === "update" && !params.objective) throw new Error("The revised objective is required.");
284
- reviseCurrentConnectionObjective(context.conversationId, params.action === "update" ? params.objective : void 0);
285
- return textResult({ status: params.action === "update" ? "updated" : "cancelled" });
286
- }
287
- }
309
+ setXopcToolMetadata(requireTool, { exposure: "model-only" }),
310
+ setXopcToolMetadata(reviseTool, { exposure: "model-only" })
288
311
  ];
289
312
  }
290
313
  //#endregion
@@ -1,28 +1,24 @@
1
1
  import { resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
2
+ import { getEmbeddedExecutionSession } from "../embedded/execution-context.js";
3
+ import { parseExternalToolRef } from "./refs.js";
2
4
  import { CliToolProvider } from "./cliProvider.js";
3
5
  import { ComposioToolProvider } from "./composio-provider.js";
4
6
  import { ExtensionToolProvider } from "./extension-provider.js";
5
7
  import { ExternalToolService } from "./service.js";
8
+ import { getExternalToolRegistry } from "./tool-registry.js";
6
9
  import { EXTERNAL_TOOL_NAMES, createExternalToolGatewayTools } from "./gateway-tools.js";
7
- import { McpToolProvider } from "./mcp-provider.js";
8
10
  import { MemoryToolProvider } from "./memory-provider.js";
9
11
  import { EndpointToolProvider } from "./endpoint-provider.js";
10
12
  import { withExternalReadPolicy } from "./read-policy.js";
11
13
  //#region src/agent/external-tools/index.ts
12
14
  function createDefaultExternalToolGatewayTools(deps) {
15
+ const getConversationId = () => getEmbeddedExecutionSession() ?? deps.getCurrentContext()?.conversationId;
13
16
  const providers = [
14
17
  new CliToolProvider({
15
18
  getConfig: deps.getConfig,
16
19
  getCurrentContext: deps.getCurrentContext,
17
20
  agentId: deps.agentId
18
21
  }),
19
- new McpToolProvider({
20
- workspace: deps.workspace,
21
- getConfig: deps.getConfig,
22
- getConversationId: () => deps.getCurrentContext()?.conversationId,
23
- agentId: deps.agentId,
24
- hookRunner: deps.hookRunner
25
- }),
26
22
  new ComposioToolProvider({
27
23
  getConfig: deps.getConfig,
28
24
  getCurrentContext: deps.getCurrentContext,
@@ -32,14 +28,14 @@ function createDefaultExternalToolGatewayTools(deps) {
32
28
  new ExtensionToolProvider({
33
29
  registry: deps.extensionRegistry,
34
30
  disabledTools: deps.disabledTools,
35
- getConversationId: () => deps.getCurrentContext()?.conversationId,
31
+ getConversationId,
36
32
  hookRunner: deps.hookRunner,
37
33
  toolExecutorConfig: deps.toolExecutorConfig
38
34
  }),
39
35
  new MemoryToolProvider({
40
36
  getMemoryManager: deps.getMemoryManager,
41
37
  disabledTools: deps.disabledTools,
42
- getConversationId: () => deps.getCurrentContext()?.conversationId,
38
+ getConversationId,
43
39
  canAccess: deps.canAccessMemory,
44
40
  hookRunner: deps.hookRunner,
45
41
  toolExecutorConfig: deps.toolExecutorConfig
@@ -47,13 +43,49 @@ function createDefaultExternalToolGatewayTools(deps) {
47
43
  ];
48
44
  if (deps.endpointTools) providers.push(new EndpointToolProvider({
49
45
  runtime: deps.endpointTools,
50
- getCurrentContext: deps.getCurrentContext
46
+ getCurrentContext: () => {
47
+ const conversationId = getConversationId();
48
+ if (!conversationId) return null;
49
+ const context = deps.getCurrentContext();
50
+ return context?.conversationId === conversationId ? context : {
51
+ conversationId,
52
+ channel: "internal",
53
+ chatId: conversationId,
54
+ origin: {
55
+ type: "system",
56
+ source: "internal"
57
+ }
58
+ };
59
+ }
51
60
  }));
52
- return createExternalToolGatewayTools(providers.map((provider) => withExternalReadPolicy(provider, (toolRef) => {
61
+ const tools = createExternalToolGatewayTools(providers.map((provider) => withExternalReadPolicy(provider, (toolRef) => {
53
62
  if (!deps.getConfig()) return void 0;
54
- const conversationId = deps.getCurrentContext()?.conversationId;
63
+ const conversationId = getConversationId();
55
64
  return (conversationId ? resolveEffectiveAgentConfigForSession(conversationId) : deps.agentId ? resolveEffectiveAgentConfigForAgent(deps.agentId) : resolveEffectiveAgentConfigForSession(void 0)).config.tools[toolRef];
56
- })), deps.getCurrentContext, deps.getConfig);
65
+ })), deps.getCurrentContext, deps.getConfig, getConversationId, [
66
+ "endpoint",
67
+ "extension",
68
+ "memory"
69
+ ], deps.toolExecutorConfig);
70
+ const registry = getExternalToolRegistry(tools);
71
+ if (registry && deps.endpointTools) {
72
+ const endpoints = deps.endpointTools;
73
+ registry.subscribeInvalidation = (conversationId, ref, listener) => {
74
+ const parsed = parseExternalToolRef(ref, "endpoint");
75
+ if (!parsed) return () => {};
76
+ const releaseEndpoint = endpoints.registry.onChange((id) => {
77
+ if (id === parsed?.namespace) listener();
78
+ });
79
+ const releaseBinding = endpoints.bindings.onChange((id) => {
80
+ if (id === conversationId) listener();
81
+ });
82
+ return () => {
83
+ releaseEndpoint();
84
+ releaseBinding();
85
+ };
86
+ };
87
+ }
88
+ return tools;
57
89
  }
58
90
  //#endregion
59
91
  export { EXTERNAL_TOOL_NAMES, ExternalToolService, createDefaultExternalToolGatewayTools };
@@ -1,5 +1,6 @@
1
1
  import { externalToolRef, parseExternalToolRef } from "./refs.js";
2
2
  import { executeToolWithProtection } from "../tools/executor.js";
3
+ import { getXopcToolMetadata } from "../embedded/tool-metadata.js";
3
4
  //#region src/agent/external-tools/memory-provider.ts
4
5
  function toolSummary(tool) {
5
6
  return tool.description || tool.label || tool.name;
@@ -22,6 +23,8 @@ var MemoryToolProvider = class {
22
23
  const resolved = this.resolve(toolRef);
23
24
  if (!resolved) return void 0;
24
25
  const summary = toolSummary(resolved.tool);
26
+ const metadata = getXopcToolMetadata(resolved.tool);
27
+ if (metadata?.exposure === "hidden") return void 0;
25
28
  return {
26
29
  toolRef,
27
30
  source: this.source,
@@ -29,7 +32,10 @@ var MemoryToolProvider = class {
29
32
  title: resolved.tool.label || resolved.tool.name,
30
33
  summary,
31
34
  description: summary,
32
- inputSchema: resolved.tool.parameters
35
+ inputSchema: resolved.tool.parameters,
36
+ outputSchema: metadata?.outputSchema,
37
+ annotations: metadata?.annotations,
38
+ exposure: metadata?.exposure
33
39
  };
34
40
  }
35
41
  async execute(toolRef, args, _approvalId, context) {
@@ -41,6 +47,7 @@ var MemoryToolProvider = class {
41
47
  if (!hook.allowed) throw new Error(hook.reason ?? "Memory provider tool call blocked by policy hook.");
42
48
  executionArgs = hook.params ?? args;
43
49
  }
50
+ context.validateArguments?.(executionArgs);
44
51
  return executeToolWithProtection(resolved.tool, context.toolCallId, executionArgs, context.signal, context.onUpdate, this.deps.toolExecutorConfig);
45
52
  }
46
53
  entries() {
@@ -4,6 +4,7 @@ function withExternalReadPolicy(provider, getPolicy) {
4
4
  return {
5
5
  source: provider.source,
6
6
  search: (query) => provider.search(query),
7
+ ...provider.connectionCandidates ? { connectionCandidates: provider.connectionCandidates.bind(provider) } : {},
7
8
  describe: async (ref) => {
8
9
  const descriptor = await provider.describe(ref);
9
10
  if (!descriptor) return void 0;
@@ -11,7 +12,7 @@ function withExternalReadPolicy(provider, getPolicy) {
11
12
  if (policy?.mode === "deny") return void 0;
12
13
  return {
13
14
  ...descriptor,
14
- batchRead: policy?.readOnly ?? descriptor.batchRead
15
+ batchRead: provider.source === "endpoint" ? descriptor.batchRead === true && policy?.readOnly !== false : policy?.readOnly ?? descriptor.batchRead
15
16
  };
16
17
  },
17
18
  execute: (ref, args, approval, context) => provider.execute(ref, args, approval, context)
@@ -4,6 +4,8 @@ export declare class ExternalToolService {
4
4
  private readonly providerBySource;
5
5
  private readonly ajv;
6
6
  constructor(providers: ExternalToolProvider[]);
7
+ /** Materialize an authorized local directory without keyword ranking or model round trips. */
8
+ catalog(sources: readonly ExternalToolSource[]): Promise<VersionedExternalToolDescriptor[]>;
7
9
  search(params: {
8
10
  query: string;
9
11
  sources?: ExternalToolSource[];
@@ -28,7 +28,11 @@ function descriptorRevision(descriptor) {
28
28
  toolRef: descriptor.toolRef,
29
29
  description: descriptor.description,
30
30
  inputSchema: descriptor.inputSchema,
31
- batchRead: descriptor.batchRead === true
31
+ outputSchema: descriptor.outputSchema,
32
+ annotations: descriptor.annotations,
33
+ batchRead: descriptor.batchRead === true,
34
+ contractRevision: descriptor.contractRevision,
35
+ exposure: descriptor.exposure
32
36
  })).digest("hex").slice(0, 16);
33
37
  }
34
38
  function versionDescriptor(descriptor) {
@@ -48,6 +52,17 @@ var ExternalToolService = class {
48
52
  constructor(providers) {
49
53
  this.providerBySource = new Map(providers.map((provider) => [provider.source, provider]));
50
54
  }
55
+ /** Materialize an authorized local directory without keyword ranking or model round trips. */
56
+ async catalog(sources) {
57
+ const descriptors = [];
58
+ for (const source of sources) {
59
+ const provider = this.providerBySource.get(source);
60
+ if (!provider) continue;
61
+ const refs = [...new Set((await provider.search("")).map((hit) => hit.toolRef))];
62
+ for (const ref of refs) descriptors.push(...(await this.describe([ref])).tools);
63
+ }
64
+ return descriptors;
65
+ }
51
66
  async search(params) {
52
67
  const selected = params.sources?.length ? params.sources.map((source) => this.providerBySource.get(source)).filter((provider) => provider !== void 0) : [...this.providerBySource.values()];
53
68
  const settled = await Promise.allSettled(selected.map(async (provider) => ({
@@ -132,8 +147,15 @@ var ExternalToolService = class {
132
147
  } catch (error) {
133
148
  throw new Error(`Tool contract is invalid: ${params.toolRef}`, { cause: error });
134
149
  }
135
- if (!validate(args)) throw new Error(`Arguments do not match ${params.toolRef}: ${this.ajv.errorsText(validate.errors)}`);
136
- return provider.execute(params.toolRef, args, params.approvalId, params.context);
150
+ const validateArguments = (input) => {
151
+ if (!validate(input)) throw new Error(`Arguments do not match ${params.toolRef}: ${this.ajv.errorsText(validate.errors)}`);
152
+ };
153
+ validateArguments(args);
154
+ return provider.execute(params.toolRef, args, params.approvalId, {
155
+ ...params.context,
156
+ contractRevision: current.contractRevision,
157
+ validateArguments
158
+ });
137
159
  }
138
160
  providerForRef(toolRef) {
139
161
  const separator = toolRef.indexOf(":");