@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
@@ -0,0 +1,69 @@
1
+ import { type LocationRequest, type TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
+ import type { DeviceGrantAuditEvent } from '../storage/sqlite/device-grant-audit-repository.js';
3
+ import type { EndpointRegistry } from './registry.js';
4
+ export interface DeviceGrantLease {
5
+ signal: AbortSignal;
6
+ complete: () => void;
7
+ }
8
+ interface DeviceGrant {
9
+ id: string;
10
+ conversationId: string;
11
+ requestorPrincipalId: string;
12
+ targetEndpointId: string;
13
+ targetPrincipalId: string;
14
+ arguments: LocationRequest;
15
+ connectionId: string;
16
+ toolName: string;
17
+ argumentsDigest: string;
18
+ expiresAt: number;
19
+ state: 'ready' | 'running';
20
+ controller: AbortController;
21
+ }
22
+ /** Deliberately non-durable: restart, expiry, disconnect or revoke invalidates single-call consent. */
23
+ export declare class DeviceGrantService {
24
+ private readonly registry;
25
+ private readonly now;
26
+ private readonly audit?;
27
+ private readonly grants;
28
+ constructor(registry: EndpointRegistry, now?: () => number, audit?: (event: DeviceGrantAuditEvent) => void);
29
+ issue(input: {
30
+ conversationId: string;
31
+ requestorPrincipalId: string;
32
+ targetEndpointId: string;
33
+ toolName: string;
34
+ arguments: Record<string, unknown>;
35
+ }): {
36
+ id: string;
37
+ conversationId: string;
38
+ requestorPrincipalId: string;
39
+ targetEndpointId: string;
40
+ targetPrincipalId: string;
41
+ arguments: LocationRequest;
42
+ connectionId: string;
43
+ toolName: string;
44
+ expiresAt: number;
45
+ state: "ready" | "running";
46
+ };
47
+ private requestor;
48
+ candidates(conversationId: string, origin: TurnOrigin): DeviceGrant[];
49
+ find(conversationId: string, origin: TurnOrigin, endpointId: string, toolName: string): DeviceGrant;
50
+ reserve(id: string, args: Record<string, unknown>): DeviceGrantLease;
51
+ list(): {
52
+ id: string;
53
+ conversationId: string;
54
+ requestorPrincipalId: string;
55
+ targetEndpointId: string;
56
+ targetPrincipalId: string;
57
+ arguments: LocationRequest;
58
+ connectionId: string;
59
+ toolName: string;
60
+ expiresAt: number;
61
+ state: "ready" | "running";
62
+ }[];
63
+ revoke(id: string, reason?: 'consumed' | 'revoked' | 'expired'): boolean;
64
+ revokeEndpoint(endpointId: string, principalId?: string): void;
65
+ close(): void;
66
+ private prune;
67
+ private summary;
68
+ }
69
+ export {};
@@ -0,0 +1,113 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { locationRequestSchema } from "../../packages/endpoint-tools-protocol/src/location.js";
4
+ import { canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
5
+ import { createHash, randomUUID } from "node:crypto";
6
+ //#region src/endpoint-tools/grant-service.ts
7
+ init_src();
8
+ init_logger();
9
+ const grantLog = createLogger("DeviceGrants");
10
+ const digest = (args) => createHash("sha256").update(canonicalJson(args)).digest("hex");
11
+ /** Deliberately non-durable: restart, expiry, disconnect or revoke invalidates single-call consent. */
12
+ var DeviceGrantService = class {
13
+ grants = /* @__PURE__ */ new Map();
14
+ constructor(registry, now = Date.now, audit) {
15
+ this.registry = registry;
16
+ this.now = now;
17
+ this.audit = audit;
18
+ }
19
+ issue(input) {
20
+ this.prune();
21
+ if (this.grants.size >= 100) throw new Error("Too many outstanding device authorizations");
22
+ const target = this.registry.get(input.targetEndpointId);
23
+ if (!target || target.availability !== "foreground" || !this.registry.list().some((endpoint) => endpoint.principalId === input.requestorPrincipalId)) throw new Error("Device is offline");
24
+ if (!/^(mobile|web|desktop)\.device\.get_location$/.test(input.toolName) || !this.registry.getTool(target.endpointId, input.toolName)) throw new Error("Unsupported device authorization");
25
+ const args = locationRequestSchema.parse(input.arguments);
26
+ for (const grant of this.grants.values()) if (grant.conversationId === input.conversationId && grant.requestorPrincipalId === input.requestorPrincipalId && grant.toolName === input.toolName) this.revoke(grant.id);
27
+ const grant = {
28
+ conversationId: input.conversationId,
29
+ requestorPrincipalId: input.requestorPrincipalId,
30
+ targetEndpointId: input.targetEndpointId,
31
+ toolName: input.toolName,
32
+ arguments: args,
33
+ id: randomUUID(),
34
+ targetPrincipalId: target.principalId,
35
+ connectionId: target.connectionId,
36
+ argumentsDigest: digest(args),
37
+ expiresAt: this.now() + 6e4,
38
+ state: "ready",
39
+ controller: new AbortController()
40
+ };
41
+ this.audit?.({
42
+ ...grant,
43
+ event: "issued"
44
+ });
45
+ this.grants.set(grant.id, grant);
46
+ const timer = setTimeout(() => this.revoke(grant.id, "expired"), 6e4);
47
+ timer.unref();
48
+ grant.controller.signal.addEventListener("abort", () => clearTimeout(timer), { once: true });
49
+ return this.summary(grant);
50
+ }
51
+ requestor(origin) {
52
+ return origin.type === "endpoint" ? this.registry.get(origin.endpointId)?.principalId : void 0;
53
+ }
54
+ candidates(conversationId, origin) {
55
+ this.prune();
56
+ const principal = this.requestor(origin);
57
+ return [...this.grants.values()].filter((grant) => grant.state === "ready" && grant.conversationId === conversationId && grant.requestorPrincipalId === principal);
58
+ }
59
+ find(conversationId, origin, endpointId, toolName) {
60
+ return this.candidates(conversationId, origin).find((grant) => grant.targetEndpointId === endpointId && grant.toolName === toolName);
61
+ }
62
+ reserve(id, args) {
63
+ this.prune();
64
+ const grant = this.grants.get(id);
65
+ if (!grant || grant.state !== "ready" || grant.argumentsDigest !== digest(args)) throw new Error("Device authorization expired, consumed or outside its scope");
66
+ this.audit?.({
67
+ ...grant,
68
+ event: "reserved"
69
+ });
70
+ grant.state = "running";
71
+ return {
72
+ signal: grant.controller.signal,
73
+ complete: () => this.revoke(id, "consumed")
74
+ };
75
+ }
76
+ list() {
77
+ this.prune();
78
+ return [...this.grants.values()].map((grant) => this.summary(grant));
79
+ }
80
+ revoke(id, reason = "revoked") {
81
+ const grant = this.grants.get(id);
82
+ if (!grant) return false;
83
+ this.grants.delete(id);
84
+ grant.controller.abort();
85
+ try {
86
+ this.audit?.({
87
+ ...grant,
88
+ event: reason
89
+ });
90
+ } catch (err) {
91
+ grantLog.error({
92
+ err,
93
+ grantId: id
94
+ }, "Device grant invalidated but audit write failed");
95
+ }
96
+ return true;
97
+ }
98
+ revokeEndpoint(endpointId, principalId = this.registry.get(endpointId)?.principalId) {
99
+ for (const grant of this.grants.values()) if (grant.targetEndpointId === endpointId || grant.requestorPrincipalId === principalId) this.revoke(grant.id);
100
+ }
101
+ close() {
102
+ for (const id of this.grants.keys()) this.revoke(id);
103
+ }
104
+ prune() {
105
+ for (const grant of this.grants.values()) if (grant.expiresAt <= this.now() || this.registry.get(grant.targetEndpointId)?.connectionId !== grant.connectionId || !this.registry.list().some((endpoint) => endpoint.principalId === grant.requestorPrincipalId)) this.revoke(grant.id, grant.expiresAt <= this.now() ? "expired" : "revoked");
106
+ }
107
+ summary(grant) {
108
+ const { controller: _controller, argumentsDigest: _digest, ...summary } = grant;
109
+ return summary;
110
+ }
111
+ };
112
+ //#endregion
113
+ export { DeviceGrantService };
@@ -1,6 +1,6 @@
1
- import { EndpointBindingService } from "./binding-service.js";
2
1
  import { EndpointToolPolicy, EndpointToolPolicyError } from "./policy.js";
3
2
  import { EndpointInvocationService, EndpointToolExecutionError } from "./invocation-service.js";
3
+ import { EndpointBindingService } from "./binding-service.js";
4
4
  import { EndpointRegistry, endpointToolRevision } from "./registry.js";
5
5
  import { ENDPOINT_UPLOAD_MAX_BYTES, EndpointUploadError, EndpointUploadService } from "./upload-service.js";
6
6
  import { EndpointToolRuntime } from "./runtime.js";
@@ -33,6 +33,9 @@ var EndpointInvocationService = class {
33
33
  const tool = this.registry.getTool(params.endpointId, params.toolName);
34
34
  if (!tool) return Promise.reject(this.error("TOOL_NOT_FOUND", "Endpoint tool is unavailable"));
35
35
  if (tool.revision !== params.descriptorRevision) return Promise.reject(this.error("TOOL_REVISION_MISMATCH", "Endpoint tool contract changed"));
36
+ if (params.toolName.endsWith(".device.get_location")) {
37
+ if (!this.ajv.compile(tool.descriptor.inputSchema)(params.arguments)) return Promise.reject(this.error("INVALID_ARGUMENTS", "Invalid location task request"));
38
+ }
36
39
  let confirmationRequired;
37
40
  try {
38
41
  confirmationRequired = this.policy.evaluate(tool.descriptor, endpoint.availability).confirmationRequired;
@@ -113,6 +116,7 @@ var EndpointInvocationService = class {
113
116
  clearTimeout(pending.receiptTimer);
114
117
  return;
115
118
  case "tool.progress":
119
+ if (pending.toolName.endsWith(".device.get_location")) return;
116
120
  if (pending.state !== "running") return;
117
121
  pending.onProgress?.({
118
122
  ...message.payload.message === void 0 ? {} : { message: message.payload.message },
@@ -126,7 +130,7 @@ var EndpointInvocationService = class {
126
130
  if (!validate(message.payload.content)) throw new Error(`Endpoint result does not match its contract: ${this.ajv.errorsText(validate.errors)}`);
127
131
  this.options.uploads?.validateAndClose(invocationId, message.payload.content);
128
132
  } catch (error) {
129
- this.fail(invocationId, this.error("PROTOCOL_ERROR", error instanceof Error ? error.message : String(error)));
133
+ this.fail(invocationId, this.error("PROTOCOL_ERROR", pending.toolName.endsWith(".device.get_location") ? "Invalid location result" : error instanceof Error ? error.message : String(error)));
130
134
  return;
131
135
  }
132
136
  this.succeed(invocationId, {
@@ -135,7 +139,7 @@ var EndpointInvocationService = class {
135
139
  });
136
140
  return;
137
141
  case "tool.error":
138
- this.fail(invocationId, this.error(message.payload.code, message.payload.message));
142
+ this.fail(invocationId, this.error(message.payload.code, pending.toolName.endsWith(".device.get_location") ? `Location request failed: ${message.payload.code}` : message.payload.message));
139
143
  return;
140
144
  case "tool.cancelled": this.fail(invocationId, this.error("TOOL_CANCELLED", "Endpoint cancelled the tool call"));
141
145
  }
@@ -0,0 +1,22 @@
1
+ import { type EndpointToolContent } from '@xopcai/endpoint-tools-protocol';
2
+ /** Sensitive samples never leave this processor as model, stream or persistence content. */
3
+ export declare function processLocationTask(args: Record<string, unknown>, content: EndpointToolContent[], source: {
4
+ endpointId: string;
5
+ principalId: string;
6
+ }, signal?: AbortSignal, request?: typeof fetch, now?: () => number): Promise<{
7
+ version: number;
8
+ source: {
9
+ endpointId: string;
10
+ principalId: string;
11
+ };
12
+ capturedAt: number;
13
+ receivedAt: number;
14
+ validUntil: number;
15
+ cached: boolean;
16
+ retention: string;
17
+ purpose: "weather" | "nearby";
18
+ precision: string;
19
+ accuracyMeters: number;
20
+ status: string;
21
+ data: Record<string, unknown>;
22
+ }>;
@@ -0,0 +1,114 @@
1
+ import { locationRequestSchema, locationSampleSchema } from "../../packages/endpoint-tools-protocol/src/location.js";
2
+ import { init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
3
+ //#region src/endpoint-tools/location-task.ts
4
+ init_src();
5
+ const WEATHER_URL = "https://api.open-meteo.com/v1/forecast";
6
+ const PLACES_URL = "https://overpass-api.de/api/interpreter";
7
+ const CATEGORY_FILTER = {
8
+ restaurant: "amenity=restaurant",
9
+ cafe: "amenity=cafe",
10
+ pharmacy: "amenity=pharmacy",
11
+ park: "leisure=park"
12
+ };
13
+ /** Sensitive samples never leave this processor as model, stream or persistence content. */
14
+ async function processLocationTask(args, content, source, signal, request = fetch, now = Date.now) {
15
+ const input = locationRequestSchema.parse(args);
16
+ if (content.length !== 1 || content[0].type !== "json") throw new Error("Invalid location sample");
17
+ const sample = locationSampleSchema.parse(content[0].value);
18
+ if (sample.capturedAt < now() - 3e4 || sample.capturedAt > now() + 6e4) throw new Error("Location sample expired or has an invalid clock");
19
+ const approximate = input.precision === "approximate" || sample.precision === "approximate";
20
+ const latitude = approximate ? Math.round(sample.latitude * 50) / 50 : sample.latitude;
21
+ const longitude = approximate ? Math.round(sample.longitude * 50) / 50 : sample.longitude;
22
+ const scopedSignal = AbortSignal.any([signal ?? new AbortController().signal, AbortSignal.timeout(15e3)]);
23
+ const readResponse = async (response) => {
24
+ if (!response.ok || response.redirected) throw new Error("Location lookup service is unavailable");
25
+ const reader = response.body?.getReader();
26
+ if (!reader) throw new Error("Location lookup service returned no data");
27
+ let bytes = 0;
28
+ const chunks = [];
29
+ try {
30
+ while (true) {
31
+ const part = await reader.read();
32
+ if (part.done) break;
33
+ bytes += part.value.length;
34
+ if (bytes > 512e3) throw new Error("Location lookup response is too large");
35
+ chunks.push(part.value);
36
+ }
37
+ } finally {
38
+ await reader.cancel().catch(() => {});
39
+ }
40
+ const joined = new Uint8Array(bytes);
41
+ let offset = 0;
42
+ for (const chunk of chunks) {
43
+ joined.set(chunk, offset);
44
+ offset += chunk.length;
45
+ }
46
+ return JSON.parse(new TextDecoder().decode(joined));
47
+ };
48
+ let data;
49
+ try {
50
+ scopedSignal.throwIfAborted();
51
+ if (input.purpose === "weather") {
52
+ const url = new URL(WEATHER_URL);
53
+ url.searchParams.set("latitude", String(latitude));
54
+ url.searchParams.set("longitude", String(longitude));
55
+ url.searchParams.set("current", "temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m");
56
+ const current = (await readResponse(await request(url, {
57
+ signal: scopedSignal,
58
+ redirect: "error"
59
+ }))).current ?? {};
60
+ if (typeof current.temperature_2m !== "number" || !Number.isFinite(current.temperature_2m)) throw new Error("Invalid weather response");
61
+ const numeric = (key, min, max) => typeof current[key] === "number" && Number.isFinite(current[key]) && current[key] >= min && current[key] <= max ? current[key] : null;
62
+ data = {
63
+ provider: "Open-Meteo",
64
+ sourceUrl: "https://open-meteo.com/",
65
+ temperatureCelsius: numeric("temperature_2m", -100, 100),
66
+ humidityPercent: numeric("relative_humidity_2m", 0, 100),
67
+ weatherCode: numeric("weather_code", 0, 99),
68
+ windSpeedKmh: numeric("wind_speed_10m", 0, 500)
69
+ };
70
+ } else {
71
+ const query = `[out:json][timeout:10];nwr(around:2000,${latitude},${longitude})[${CATEGORY_FILTER[input.category]}];out tags 10;`;
72
+ const response = await readResponse(await request(PLACES_URL, {
73
+ method: "POST",
74
+ signal: scopedSignal,
75
+ redirect: "error",
76
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
77
+ body: new URLSearchParams({ data: query })
78
+ }));
79
+ if (!Array.isArray(response.elements)) throw new Error("Invalid nearby service result");
80
+ const text = (value) => typeof value === "string" ? value.slice(0, 160).replaceAll(String(sample.latitude), "[location]").replaceAll(String(sample.longitude), "[location]") : "";
81
+ data = {
82
+ provider: "OpenStreetMap",
83
+ sourceUrl: "https://www.openstreetmap.org/",
84
+ category: input.category,
85
+ radiusMeters: 2e3,
86
+ places: response.elements.slice(0, 10).map((element) => ({
87
+ name: text(element.tags?.name),
88
+ street: text(element.tags?.["addr:street"]),
89
+ houseNumber: text(element.tags?.["addr:housenumber"])
90
+ })).filter((place) => place.name.length > 0)
91
+ };
92
+ }
93
+ } catch {
94
+ throw new Error(scopedSignal.aborted ? "Location lookup cancelled or timed out" : "Location lookup service is unavailable");
95
+ }
96
+ scopedSignal.throwIfAborted();
97
+ if (sample.capturedAt < now() - 3e4) throw new Error("Location sample expired during lookup");
98
+ return {
99
+ version: 1,
100
+ source,
101
+ capturedAt: sample.capturedAt,
102
+ receivedAt: now(),
103
+ validUntil: Math.min(sample.capturedAt, now()) + 3e4,
104
+ cached: false,
105
+ retention: "summary",
106
+ purpose: input.purpose,
107
+ precision: approximate ? "approximate" : "precise",
108
+ accuracyMeters: approximate ? Math.max(3e3, sample.accuracyMeters) : sample.accuracyMeters,
109
+ status: "ok",
110
+ data
111
+ };
112
+ }
113
+ //#endregion
114
+ export { processLocationTask };
@@ -1,4 +1,6 @@
1
- import { ENDPOINT_CONTACT_LIST_OUTPUT_SCHEMA, ENDPOINT_CONTACT_OUTPUT_SCHEMA, ENDPOINT_FILE_OUTPUT_SCHEMA, ENDPOINT_TEXT_OUTPUT_SCHEMA, canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
1
+ import { BRIDGE_LIST_OUTPUT_SCHEMA, BRIDGE_READ_INPUT_SCHEMA, BRIDGE_READ_OUTPUT_SCHEMA } from "../../packages/endpoint-tools-protocol/src/bridge.js";
2
+ import { LOCATION_INPUT_SCHEMA, LOCATION_OUTPUT_SCHEMA } from "../../packages/endpoint-tools-protocol/src/location.js";
3
+ import { DEVICE_EMPTY_INPUT_SCHEMA, DEVICE_POWER_OUTPUT_SCHEMA, DEVICE_STATE_OUTPUT_SCHEMA, ENDPOINT_CONTACT_LIST_OUTPUT_SCHEMA, ENDPOINT_CONTACT_OUTPUT_SCHEMA, ENDPOINT_FILE_OUTPUT_SCHEMA, ENDPOINT_TEXT_OUTPUT_SCHEMA, canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
2
4
  import { COMPUTER_INPUT_SCHEMA, COMPUTER_OUTPUT_SCHEMA, init_src as init_src$1 } from "../../packages/computer-control-contract/src/index.js";
3
5
  import { BROWSER_CONTROL_ENDPOINT_DESCRIPTOR, BROWSER_CONTROL_ENDPOINT_INPUT_SCHEMA, BROWSER_CONTROL_ENDPOINT_OUTPUT_SCHEMA, BROWSER_RECORDING_ENDPOINT_DESCRIPTOR, BROWSER_RECORDING_ENDPOINT_INPUT_SCHEMA } from "../../packages/browser-control-contract/src/index.js";
4
6
  import Ajv2020 from "ajv/dist/2020.js";
@@ -17,6 +19,19 @@ function contract(policyId, outputSchema, resultKinds, permissions, legacyPolicy
17
19
  };
18
20
  }
19
21
  const POLICY_BY_TOOL = {
22
+ ...Object.fromEntries([
23
+ "mobile",
24
+ "desktop",
25
+ "web",
26
+ "browser"
27
+ ].flatMap((kind) => [[`${kind}.device.get_state`, contract("public.background-read", DEVICE_STATE_OUTPUT_SCHEMA, ["json"], [], [], DEVICE_EMPTY_INPUT_SCHEMA)], [`${kind}.device.get_power`, contract("public.background-read", DEVICE_POWER_OUTPUT_SCHEMA, ["json"], [], [], DEVICE_EMPTY_INPUT_SCHEMA)]])),
28
+ ...Object.fromEntries([
29
+ "mobile",
30
+ "desktop",
31
+ "web"
32
+ ].map((kind) => [`${kind}.device.get_location`, contract("personal.foreground-read", LOCATION_OUTPUT_SCHEMA, ["json"], ["location-read-once"], [], LOCATION_INPUT_SCHEMA)])),
33
+ "desktop.bridge.list_resources": contract("public.background-read", BRIDGE_LIST_OUTPUT_SCHEMA, ["json"], [], [], DEVICE_EMPTY_INPUT_SCHEMA),
34
+ "desktop.bridge.read_sensor": contract("public.background-read", BRIDGE_READ_OUTPUT_SCHEMA, ["json"], [], [], BRIDGE_READ_INPUT_SCHEMA),
20
35
  "desktop.computer.control": contract("computer.session-scoped", COMPUTER_OUTPUT_SCHEMA, ["json", "file"], ["computer-control"], [], COMPUTER_INPUT_SCHEMA),
21
36
  "web.file.pick": contract("personal.foreground-read", ENDPOINT_FILE_OUTPUT_SCHEMA, ["file"], ["file-read"]),
22
37
  "web.file.download": contract("user.foreground-write", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], ["file-download"]),
@@ -29,6 +29,8 @@ export declare function endpointToolRevision(descriptor: EndpointToolDescriptor)
29
29
  export declare class EndpointRegistry {
30
30
  private readonly policy;
31
31
  private readonly connectionByEndpointId;
32
+ private readonly changeListeners;
33
+ onChange(listener: (endpointId: string) => void): () => void;
32
34
  constructor(policy?: EndpointToolPolicy);
33
35
  register(hello: EndpointHelloPayload, connectionId: string, transport: EndpointTransport, now?: number): EndpointRegistration;
34
36
  remove(endpointId: string, connectionId: string): boolean;
@@ -22,6 +22,13 @@ function snapshot(connection) {
22
22
  }
23
23
  var EndpointRegistry = class {
24
24
  connectionByEndpointId = /* @__PURE__ */ new Map();
25
+ changeListeners = /* @__PURE__ */ new Set();
26
+ onChange(listener) {
27
+ this.changeListeners.add(listener);
28
+ return () => {
29
+ this.changeListeners.delete(listener);
30
+ };
31
+ }
25
32
  constructor(policy = new EndpointToolPolicy()) {
26
33
  this.policy = policy;
27
34
  }
@@ -54,6 +61,7 @@ var EndpointRegistry = class {
54
61
  toolByName
55
62
  };
56
63
  this.connectionByEndpointId.set(connection.endpointId, connection);
64
+ for (const listener of this.changeListeners) listener(connection.endpointId);
57
65
  return {
58
66
  connection: snapshot(connection),
59
67
  turnToken: connection.turnToken
@@ -63,6 +71,7 @@ var EndpointRegistry = class {
63
71
  const connection = this.connectionByEndpointId.get(endpointId);
64
72
  if (!connection || connection.connectionId !== connectionId) return false;
65
73
  this.connectionByEndpointId.delete(endpointId);
74
+ for (const listener of this.changeListeners) listener(endpointId);
66
75
  return true;
67
76
  }
68
77
  heartbeat(endpointId, connectionId, availability, now = Date.now()) {
@@ -0,0 +1,15 @@
1
+ import type { EndpointToolContent } from '@xopcai/endpoint-tools-protocol';
2
+ /** Only fixed bounded state contracts are retained; personal tools use their existing policies. */
3
+ export declare function projectDeviceReading(toolName: string, endpointId: string, principalId: string, content: EndpointToolContent[], receivedAt?: number, args?: Record<string, unknown>): {
4
+ version: number;
5
+ source: {
6
+ resourceId?: unknown;
7
+ endpointId: string;
8
+ principalId: string;
9
+ };
10
+ capturedAt: number;
11
+ receivedAt: number;
12
+ validUntil: number;
13
+ cached: boolean;
14
+ data: object;
15
+ };
@@ -0,0 +1,31 @@
1
+ //#region src/endpoint-tools/result-projector.ts
2
+ /** Only fixed bounded state contracts are retained; personal tools use their existing policies. */
3
+ function projectDeviceReading(toolName, endpointId, principalId, content, receivedAt = Date.now(), args) {
4
+ const sensor = toolName === "desktop.bridge.read_sensor";
5
+ if (!sensor && !/^(mobile|desktop|web|browser)\.device\.get_(state|power)$/.test(toolName)) return void 0;
6
+ const item = content[0];
7
+ if (item?.type !== "json" || !item.value || typeof item.value !== "object") throw new Error("Invalid device reading");
8
+ if (sensor) {
9
+ const reading = item.value;
10
+ if (reading.resourceId !== args?.resourceId) throw new Error("Bridge returned a different resource");
11
+ const expectedUnit = reading.measurement === "humidity" ? "percent" : "celsius";
12
+ if (reading.unit !== expectedUnit || reading.measurement === "humidity" && reading.value !== null && (typeof reading.value !== "number" || reading.value < 0 || reading.value > 100)) throw new Error("Invalid Bridge measurement");
13
+ }
14
+ const capturedAt = item.value.capturedAt;
15
+ if (typeof capturedAt !== "number" || !Number.isSafeInteger(capturedAt) || capturedAt > receivedAt + 6e4 || capturedAt < receivedAt - 3e4) throw new Error("Device sample is stale or has an invalid clock");
16
+ return {
17
+ version: 1,
18
+ source: {
19
+ endpointId,
20
+ principalId,
21
+ ...sensor ? { resourceId: item.value.resourceId } : {}
22
+ },
23
+ capturedAt,
24
+ receivedAt,
25
+ validUntil: Math.min(receivedAt, capturedAt) + 3e4,
26
+ cached: false,
27
+ data: item.value
28
+ };
29
+ }
30
+ //#endregion
31
+ export { projectDeviceReading };
@@ -1,11 +1,13 @@
1
1
  import { type ClientEndpointMessage, type EndpointHelloPayload } from '@xopcai/endpoint-tools-protocol';
2
2
  import { type EndpointAuthenticatorDeps } from './auth.js';
3
+ import { DeviceGrantService } from './grant-service.js';
3
4
  import { EndpointBindingService } from './binding-service.js';
4
5
  import { EndpointInvocationService, type EndpointInvocationAuditSink } from './invocation-service.js';
5
6
  import { EndpointRegistry, type EndpointRegistration, type EndpointTransport } from './registry.js';
6
7
  import { EndpointUploadService } from './upload-service.js';
7
8
  export declare class EndpointToolRuntime {
8
9
  readonly registry: EndpointRegistry;
10
+ readonly grants: DeviceGrantService;
9
11
  readonly invocations: EndpointInvocationService;
10
12
  readonly uploads: EndpointUploadService;
11
13
  readonly bindings: EndpointBindingService;
@@ -7,10 +7,12 @@ import { bindEndpointPrincipal, getEndpointPrincipal, touchEndpointPrincipal } f
7
7
  import { finishEndpointToolInvocationAudit, startEndpointToolInvocationAudit } from "../storage/sqlite/endpoint-tool-invocation-repository.js";
8
8
  import { init_sqlite } from "../storage/sqlite/index.js";
9
9
  import { init_paths } from "../config/paths.js";
10
- import { EndpointAuthenticator } from "./auth.js";
11
- import { EndpointBindingService } from "./binding-service.js";
12
10
  import { EndpointToolPolicy } from "./policy.js";
13
11
  import { EndpointInvocationService } from "./invocation-service.js";
12
+ import { EndpointAuthenticator } from "./auth.js";
13
+ import { EndpointBindingService } from "./binding-service.js";
14
+ import { DeviceGrantService } from "./grant-service.js";
15
+ import { recordDeviceGrantEvent } from "../storage/sqlite/device-grant-audit-repository.js";
14
16
  import { EndpointRegistry } from "./registry.js";
15
17
  import { EndpointUploadService } from "./upload-service.js";
16
18
  import { join } from "node:path";
@@ -22,6 +24,7 @@ const log = createLogger("EndpointTools");
22
24
  const MAX_MESSAGE_CLOCK_SKEW_MS = 6e4;
23
25
  var EndpointToolRuntime = class {
24
26
  registry;
27
+ grants;
25
28
  invocations;
26
29
  uploads;
27
30
  bindings;
@@ -30,6 +33,7 @@ var EndpointToolRuntime = class {
30
33
  constructor(options = {}) {
31
34
  const policy = new EndpointToolPolicy();
32
35
  this.registry = new EndpointRegistry(policy);
36
+ this.grants = new DeviceGrantService(this.registry, Date.now, recordDeviceGrantEvent);
33
37
  this.bindings = new EndpointBindingService(this.registry, {
34
38
  get: getEndpointSessionBinding,
35
39
  set: setEndpointSessionBinding,
@@ -53,6 +57,11 @@ var EndpointToolRuntime = class {
53
57
  connect(hello, connectionId, transport) {
54
58
  if (this.closed) throw new Error("Endpoint runtime is closed");
55
59
  this.authenticator.authenticate(hello);
60
+ const previous = this.registry.get(hello.endpointId);
61
+ if (previous) {
62
+ this.grants.revokeEndpoint(previous.endpointId, previous.principalId);
63
+ this.invocations.failEndpoint(previous.endpointId);
64
+ }
56
65
  const registration = this.registry.register(hello, connectionId, transport);
57
66
  log.info({
58
67
  endpointId: hello.endpointId,
@@ -75,7 +84,9 @@ var EndpointToolRuntime = class {
75
84
  if (endpoint?.connectionId === connectionId) this.registry.heartbeat(endpointId, connectionId, endpoint.availability);
76
85
  }
77
86
  remove(endpointId, connectionId) {
87
+ const principalId = this.registry.get(endpointId)?.principalId;
78
88
  if (!this.registry.remove(endpointId, connectionId)) return;
89
+ this.grants.revokeEndpoint(endpointId, principalId);
79
90
  this.invocations.failEndpoint(endpointId);
80
91
  deleteBrowserTabBindingsByEndpoint(endpointId);
81
92
  log.info({
@@ -84,11 +95,13 @@ var EndpointToolRuntime = class {
84
95
  }, "Endpoint disconnected");
85
96
  }
86
97
  disconnect(endpointId, reason) {
98
+ this.grants.revokeEndpoint(endpointId);
87
99
  this.registry.disconnect(endpointId, 4003, reason);
88
100
  }
89
101
  close() {
90
102
  if (this.closed) return;
91
103
  this.closed = true;
104
+ this.grants.close();
92
105
  this.invocations.close();
93
106
  this.uploads.close();
94
107
  this.registry.closeAll();
@@ -0,0 +1,12 @@
1
+ import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
+ import type { DeviceGrantService } from './grant-service.js';
3
+ import type { EndpointBindingService } from './binding-service.js';
4
+ import type { EndpointRegistry } from './registry.js';
5
+ export declare class DeviceTargetResolver {
6
+ private readonly registry;
7
+ private readonly bindings;
8
+ private readonly grants?;
9
+ constructor(registry: EndpointRegistry, bindings: EndpointBindingService, grants?: DeviceGrantService);
10
+ candidates(conversationId: string, origin: TurnOrigin): import("./registry.js").EndpointConnectionSnapshot[];
11
+ resolve(conversationId: string, origin: TurnOrigin, endpointId: string, toolName: string): import("./registry.js").EndpointConnectionSnapshot;
12
+ }
@@ -0,0 +1,27 @@
1
+ import { deviceCapabilityTarget } from "./capability-catalog.js";
2
+ //#region src/endpoint-tools/target-resolver.ts
3
+ var DeviceTargetResolver = class {
4
+ constructor(registry, bindings, grants) {
5
+ this.registry = registry;
6
+ this.bindings = bindings;
7
+ this.grants = grants;
8
+ }
9
+ candidates(conversationId, origin) {
10
+ const source = origin.type === "endpoint" ? this.registry.get(origin.endpointId) : void 0;
11
+ const execution = this.bindings.get(conversationId) ? this.bindings.resolve(conversationId) : source;
12
+ const authorized = (this.grants?.candidates(conversationId, origin) ?? []).map((grant) => this.registry.get(grant.targetEndpointId));
13
+ return [...new Map([
14
+ source,
15
+ execution,
16
+ ...authorized
17
+ ].filter((endpoint) => endpoint !== void 0).map((endpoint) => [endpoint.endpointId, endpoint])).values()];
18
+ }
19
+ resolve(conversationId, origin, endpointId, toolName) {
20
+ const grant = this.grants?.find(conversationId, origin, endpointId, toolName);
21
+ if (grant) return this.registry.get(grant.targetEndpointId);
22
+ const binding = this.bindings.get(conversationId);
23
+ return (deviceCapabilityTarget(toolName) === "turn_origin" ? origin.type === "endpoint" ? origin.endpointId : void 0 : binding?.endpointId ?? (origin.type === "endpoint" ? origin.endpointId : void 0)) === endpointId ? this.registry.get(endpointId) : void 0;
24
+ }
25
+ };
26
+ //#endregion
27
+ export { DeviceTargetResolver };
@@ -0,0 +1,6 @@
1
+ import type { EndpointContext } from '@xopcai/gateway-contract';
2
+ import type { AgentSourceContext } from '../agent/source-context/types.js';
3
+ import type { GatewayPrincipal } from '../gateway/security/gateway-principal.js';
4
+ import type { EndpointConnectionSnapshot, EndpointRegistry } from './registry.js';
5
+ export declare function endpointClaimBelongsToPrincipal(registry: EndpointRegistry, endpointId: string, principal: GatewayPrincipal): boolean;
6
+ export declare function deviceTurnSourceContext(endpoint: EndpointConnectionSnapshot, environment?: EndpointContext): AgentSourceContext;
@@ -0,0 +1,29 @@
1
+ import { getEndpointDeviceSettings } from "../storage/sqlite/endpoint-device-settings-repository.js";
2
+ import { createHash } from "node:crypto";
3
+ //#region src/endpoint-tools/turn-context.ts
4
+ function endpointClaimBelongsToPrincipal(registry, endpointId, principal) {
5
+ const endpoint = registry.get(endpointId);
6
+ return Boolean(endpoint && (principal.kind === "owner" || principal.kind === "device" && endpoint.principalId === principal.deviceId));
7
+ }
8
+ function deviceTurnSourceContext(endpoint, environment) {
9
+ const name = getEndpointDeviceSettings(endpoint.principalId)?.nickname ?? endpoint.displayName;
10
+ const snapshot = {
11
+ endpointId: endpoint.endpointId,
12
+ principalId: endpoint.principalId,
13
+ name: name.slice(0, 80),
14
+ platform: endpoint.platform.slice(0, 40),
15
+ kind: endpoint.kind,
16
+ ...environment ? { environment } : {}
17
+ };
18
+ const text = JSON.stringify(snapshot).replaceAll("<", "\\u003c").replaceAll(">", "\\u003e");
19
+ return {
20
+ kind: "device_context",
21
+ sourceId: endpoint.endpointId,
22
+ version: createHash("sha256").update(text).digest("hex"),
23
+ title: name.slice(0, 80),
24
+ text,
25
+ capturedAt: environment?.capturedAt ?? Date.now()
26
+ };
27
+ }
28
+ //#endregion
29
+ export { deviceTurnSourceContext, endpointClaimBelongsToPrincipal };
@@ -4,9 +4,7 @@ import { type PluginServer } from './validation.js';
4
4
  declare const bindingSchema: z.ZodObject<{
5
5
  serverName: z.ZodString;
6
6
  mode: z.ZodEnum<{
7
- none: "none";
8
7
  auto: "auto";
9
- oauth: "oauth";
10
8
  "api-key": "api-key";
11
9
  }>;
12
10
  identityScope: z.ZodLiteral<"owner">;