@xopcai/xopc 0.0.187 → 0.0.189

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 (385) hide show
  1. package/README.md +1 -1
  2. package/dist/browser-ext/manifest.json +1 -1
  3. package/dist/extensions/demo-memory/src/index.js +1 -0
  4. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -3
  5. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +0 -2
  6. package/dist/extensions/telegram/src/draft-stream.d.ts +0 -4
  7. package/dist/extensions/telegram/src/draft-stream.js +1 -53
  8. package/dist/extensions/telegram/xopc.extension.json +1 -1
  9. package/dist/gateway/static/root/assets/{activity-store-WlR2zEvA.js → activity-store-DTFKTPs8.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-RedDszrG.js → agent-avatar-dicebear-DqO25Qe5.js} +1 -1
  11. package/dist/gateway/static/root/assets/agents-BvdqdER9.js +2 -0
  12. package/dist/gateway/static/root/assets/{api-tVOllncq.js → api-DWeXfwVU.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-C9hKBzaF.js → app-management-settings-panel-BRpV8PXG.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-5cQvq7hd.js → appearance-settings-3ntKM9nQ.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-nKLsfy6C.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-Ct-shK4n.js → archive-plugin-Df7Ycj_7.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-CpPj3m-q.js → attachment-load-UHgfZYtj.js} +1 -1
  18. package/dist/gateway/static/root/assets/automations-page-Dh5bdZiN.js +6 -0
  19. package/dist/gateway/static/root/assets/{binary-plugins-BpSXZBle.js → binary-plugins-BJah99wE.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-B8hR2tXc.js → block-editor-DNlY5KqF.js} +46 -46
  21. package/dist/gateway/static/root/assets/browser-settings-page-CRJ_nAuh.js +8 -0
  22. package/dist/gateway/static/root/assets/{browser-workflow-inputs-D_LAXUrh.js → browser-workflow-inputs-vyUfdzAd.js} +1 -1
  23. package/dist/gateway/static/root/assets/{browser-workflows-page-CPAs7-6s.js → browser-workflows-page-C1cKZjx-.js} +2 -2
  24. package/dist/gateway/static/root/assets/capabilities-settings-panel-DeQR5BZt.js +7 -0
  25. package/dist/gateway/static/root/assets/{capability-presets-api-CKklVY2p.js → capability-presets-api-D7tkhDMv.js} +1 -1
  26. package/dist/gateway/static/root/assets/capability-presets-settings-panel-D7uK3q1p.js +1 -0
  27. package/dist/gateway/static/root/assets/{channel-recipient-api-WWN-nbFL.js → channel-recipient-api-BGG2kpJB.js} +1 -1
  28. package/dist/gateway/static/root/assets/channels-settings-Bw6Dniyq.js +1 -0
  29. package/dist/gateway/static/root/assets/channels-status-swr-BrUTz4uU.js +1 -0
  30. package/dist/gateway/static/root/assets/{connector-logo-CdNkVFdB.js → connector-logo-8YU53RUT.js} +1 -1
  31. package/dist/gateway/static/root/assets/connectors-page-k9tMiOL5.js +2 -0
  32. package/dist/gateway/static/root/assets/{desktop-pet-Bm_IEAf3.js → desktop-pet-BUuBEJuP.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-C0Ve04-G.js → desktop-pet-settings-BGfVIJM3.js} +1 -1
  34. package/dist/gateway/static/root/assets/{directory-picker-path-field-B2cvhvAI.js → directory-picker-path-field-DrQFfHH_.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-debug-page-DNashgGu.js → extension-debug-page-CEnIFOX-.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-page-Bvo-5htX.js → extension-page-CCqHbexs.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-settings-page-BBESdISV.js → extension-settings-page-DEZw_7zN.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-api-ClQvokMo.js → gateway-config-api-CgUE2Ii1.js} +1 -1
  39. package/dist/gateway/static/root/assets/gateway-settings-Dg8qCiIp.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-startup-retry-CntXJF6W.js → gateway-startup-retry-DxhKNiCF.js} +1 -1
  41. package/dist/gateway/static/root/assets/{heartbeat-settings-CWKcZuvc.js → heartbeat-settings-27tRzDEo.js} +1 -1
  42. package/dist/gateway/static/root/assets/home-page-VA511kMr.js +3 -0
  43. package/dist/gateway/static/root/assets/{image-generation-api-DjSAQwGy.js → image-generation-api-DCFdc-HD.js} +1 -1
  44. package/dist/gateway/static/root/assets/index-BvR-i-m6.js +216 -0
  45. package/dist/gateway/static/root/assets/index-zybP34zk.css +1 -0
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ahKHpjoW.js → keyboard-shortcuts-settings-Bf2VLtXW.js} +1 -1
  47. package/dist/gateway/static/root/assets/local-app-workbench-page-CaJq4-wV.js +2 -0
  48. package/dist/gateway/static/root/assets/{local-apps-page-B6GKdgza.js → local-apps-page-Ca1RuI13.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-Bff30u5V.js → locale-store-DUW5YE3R.js} +1 -1
  50. package/dist/gateway/static/root/assets/logs-page-BLTCg69e.js +2 -0
  51. package/dist/gateway/static/root/assets/management-settings-B3Eop1zn.js +1 -0
  52. package/dist/gateway/static/root/assets/{markdown-split-BeNMJm_i.js → markdown-split-BGOYjgnM.js} +1 -1
  53. package/dist/gateway/static/root/assets/{media-plugins-Bdzrj_-6.js → media-plugins-CT0txyM4.js} +1 -1
  54. package/dist/gateway/static/root/assets/messages-CMjnbdbn.js +3 -0
  55. package/dist/gateway/static/root/assets/{notes-page-MYIi-9S9.js → notes-page-DfKgAe78.js} +1 -1
  56. package/dist/gateway/static/root/assets/notes-workbench-Bp1w9UM1.js +4 -0
  57. package/dist/gateway/static/root/assets/{page-tabs-3t88bbGx.js → page-tabs-DNrbCgmC.js} +1 -1
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-Cf_BWbeE.js → preview-open-alternatives-BTqViDOR.js} +1 -1
  59. package/dist/gateway/static/root/assets/product-delivery-tRr-7IxY.js +1 -0
  60. package/dist/gateway/static/root/assets/{product-open-page-CKq73c98.js → product-open-page-C_2L4_Iu.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-CZmbPDQN.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-D5pzqfm5.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-CC-XhVGI.js +1 -0
  64. package/dist/gateway/static/root/assets/{schema-form-NqOm-OG1.js → schema-form-BFLfkDGG.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schemas-C6onAggk.js → schemas-zIBW3wiV.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-B2eTLVDV.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-CRuZ_bl0.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-DYAS8p8z.js → settings-form-section-C4GXGeA4.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-DZFhxihA.js → settings-loading-skeleton-C9a-EbTZ.js} +1 -1
  70. package/dist/gateway/static/root/assets/settings-page-DI9qDH5x.js +1 -0
  71. package/dist/gateway/static/root/assets/{settings-page-layout-DfFfkdED.js → settings-page-layout-D-LWQdI5.js} +1 -1
  72. package/dist/gateway/static/root/assets/setup-status-panel-CJwmPvgs.js +1 -0
  73. package/dist/gateway/static/root/assets/{share-preview-page-CYtrQaZN.js → share-preview-page-BKSMG9r5.js} +1 -1
  74. package/dist/gateway/static/root/assets/shares-settings-YzSDS4G_.js +1 -0
  75. package/dist/gateway/static/root/assets/skill-reload-api-CwOo8zZk.js +1 -0
  76. package/dist/gateway/static/root/assets/skills-page-xd1cgSGN.js +2 -0
  77. package/dist/gateway/static/root/assets/{skills-page.utils-BBXirAjc.js → skills-page.utils-zsz2HIlZ.js} +1 -1
  78. package/dist/gateway/static/root/assets/{system-settings-panel-DLf5YvFl.js → system-settings-panel-IWNDBI1O.js} +1 -1
  79. package/dist/gateway/static/root/assets/{task-detail-page-DFGkuYfl.js → task-detail-page-CgtK02kP.js} +1 -1
  80. package/dist/gateway/static/root/assets/{theme-store-y7e_tvYi.js → theme-store-BkJe7UDo.js} +1 -1
  81. package/dist/gateway/static/root/assets/time-picker-CstQ___Y.js +1 -0
  82. package/dist/gateway/static/root/assets/{typed-models-lib-DR12j_dr.js → typed-models-lib-C07LGthO.js} +1 -1
  83. package/dist/gateway/static/root/assets/{use-save-bar-registration-BsvcJgZl.js → use-save-bar-registration-CQYE0l6z.js} +1 -1
  84. package/dist/gateway/static/root/assets/user-context-page-BnQAWS_B.js +1 -0
  85. package/dist/gateway/static/root/assets/{voice-api-key-field-DKADXFWD.js → voice-api-key-field-Boue1D46.js} +1 -1
  86. package/dist/gateway/static/root/assets/{work-discovery-overlay-BC1nExf8.js → work-discovery-overlay-bbmvCmc8.js} +1 -1
  87. package/dist/gateway/static/root/assets/work-discovery-page-CAszL1y8.js +1 -0
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C8X5W-8k.js → workflow-run-setup-panel-DlHv-GZC.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-DxGzo3-x.js +11 -0
  90. package/dist/gateway/static/root/index.html +9 -9
  91. package/dist/package.js +1 -1
  92. package/dist/packages/endpoint-tools-protocol/src/index.js +184 -0
  93. package/dist/packages/gateway-contract/src/tool-activity.js +223 -0
  94. package/dist/packages/realtime-client/src/index.js +199 -0
  95. package/dist/packages/realtime-protocol/src/index.js +83 -0
  96. package/dist/src/agent/agent-manager.d.ts +1 -0
  97. package/dist/src/agent/agent-manager.js +3 -8
  98. package/dist/src/agent/background-review/prompts.d.ts +1 -1
  99. package/dist/src/agent/background-review/prompts.js +3 -1
  100. package/dist/src/agent/background-review/run-background-review.d.ts +2 -0
  101. package/dist/src/agent/background-review/run-background-review.js +5 -2
  102. package/dist/src/agent/client-error-format.d.ts +1 -1
  103. package/dist/src/agent/client-error-format.js +1 -1
  104. package/dist/src/agent/code-intelligence/binary.js +1 -1
  105. package/dist/src/agent/embedded/run-for-session.d.ts +0 -2
  106. package/dist/src/agent/embedded/run-for-session.js +99 -112
  107. package/dist/src/agent/external-tools/composio-provider.d.ts +29 -0
  108. package/dist/src/agent/external-tools/composio-provider.js +307 -0
  109. package/dist/src/agent/external-tools/endpoint-provider.d.ts +17 -0
  110. package/dist/src/agent/external-tools/endpoint-provider.js +93 -0
  111. package/dist/src/agent/external-tools/extension-provider.d.ts +20 -0
  112. package/dist/src/agent/external-tools/extension-provider.js +68 -0
  113. package/dist/src/agent/external-tools/gateway-tools.d.ts +8 -0
  114. package/dist/src/agent/external-tools/gateway-tools.js +89 -0
  115. package/dist/src/agent/external-tools/index.d.ts +23 -0
  116. package/dist/src/agent/external-tools/index.js +46 -0
  117. package/dist/src/agent/external-tools/mcp-provider.d.ts +29 -0
  118. package/dist/src/agent/external-tools/mcp-provider.js +118 -0
  119. package/dist/src/agent/external-tools/memory-provider.d.ts +21 -0
  120. package/dist/src/agent/external-tools/memory-provider.js +56 -0
  121. package/dist/src/agent/external-tools/refs.d.ts +5 -0
  122. package/dist/src/agent/external-tools/refs.js +18 -0
  123. package/dist/src/agent/external-tools/service.d.ts +26 -0
  124. package/dist/src/agent/external-tools/service.js +117 -0
  125. package/dist/src/agent/external-tools/types.d.ts +35 -0
  126. package/dist/src/agent/external-tools/types.js +10 -0
  127. package/dist/src/agent/inbound/inbound-loop.d.ts +0 -2
  128. package/dist/src/agent/inbound/inbound-loop.js +4 -3
  129. package/dist/src/agent/inbound/turn-dispatcher.d.ts +9 -8
  130. package/dist/src/agent/inbound/turn-dispatcher.js +13 -11
  131. package/dist/src/agent/mcp/{bundle-mcp-materialize.d.ts → bundle-mcp-gateway.d.ts} +1 -19
  132. package/dist/src/agent/mcp/bundle-mcp-gateway.js +60 -0
  133. package/dist/src/agent/mcp/bundle-mcp-names.d.ts +0 -8
  134. package/dist/src/agent/mcp/bundle-mcp-names.js +2 -29
  135. package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +4 -7
  136. package/dist/src/agent/mcp/bundle-mcp-policy.js +6 -20
  137. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
  138. package/dist/src/agent/mcp/bundle-mcp-tools.d.ts +1 -2
  139. package/dist/src/agent/mcp/bundle-mcp-tools.js +1 -2
  140. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +0 -5
  141. package/dist/src/agent/mcp/index.d.ts +0 -2
  142. package/dist/src/agent/mcp/index.js +2 -5
  143. package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
  144. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  145. package/dist/src/agent/memory/context/planner.d.ts +1 -0
  146. package/dist/src/agent/memory/context/planner.js +22 -7
  147. package/dist/src/agent/memory/manager.d.ts +4 -1
  148. package/dist/src/agent/memory/manager.js +5 -2
  149. package/dist/src/agent/memory/types.d.ts +2 -0
  150. package/dist/src/agent/messaging/command-handler.d.ts +2 -2
  151. package/dist/src/agent/messaging/command-handler.js +3 -3
  152. package/dist/src/agent/messaging/stream-manager.d.ts +2 -14
  153. package/dist/src/agent/messaging/stream-manager.js +0 -12
  154. package/dist/src/agent/orchestration/agent-event-handler.d.ts +1 -3
  155. package/dist/src/agent/orchestration/agent-event-handler.js +0 -36
  156. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -5
  157. package/dist/src/agent/orchestration/agent-orchestrator.js +0 -5
  158. package/dist/src/agent/prompt/sections/behavior.js +6 -4
  159. package/dist/src/agent/service/async-queue.d.ts +1 -1
  160. package/dist/src/agent/service/async-queue.js +1 -1
  161. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
  162. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  163. package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -1
  164. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  165. package/dist/src/agent/service/process-direct-streaming.d.ts +7 -5
  166. package/dist/src/agent/service/process-direct-streaming.js +5 -5
  167. package/dist/src/agent/service.d.ts +1 -4
  168. package/dist/src/agent/service.js +6 -32
  169. package/dist/src/agent/service.types.d.ts +2 -3
  170. package/dist/src/agent/session/index.d.ts +1 -1
  171. package/dist/src/agent/session/session-context.d.ts +2 -0
  172. package/dist/src/agent/session/session-context.js +4 -0
  173. package/dist/src/agent/session/session-state-bag.d.ts +4 -4
  174. package/dist/src/agent/session/session-state-bag.js +1 -1
  175. package/dist/src/agent/skills/hub-pull.js +1 -1
  176. package/dist/src/agent/starter-agents.js +2 -2
  177. package/dist/src/agent/streaming/reasoning-visibility.d.ts +6 -0
  178. package/dist/src/agent/streaming/{reasoning-visibility-sse.js → reasoning-visibility.js} +3 -6
  179. package/dist/src/agent/tools/delegate-tool.js +5 -1
  180. package/dist/src/agent/tools/executor.js +1 -1
  181. package/dist/src/agent/tools/factory.d.ts +6 -1
  182. package/dist/src/agent/tools/factory.js +17 -22
  183. package/dist/src/agent/tools/index.d.ts +0 -1
  184. package/dist/src/agent/tools/index.js +1 -2
  185. package/dist/src/agent/workflow/workflow-child-tools.js +7 -1
  186. package/dist/src/automations/domain/types.d.ts +2 -1
  187. package/dist/src/automations/domain/validation.d.ts +1 -1
  188. package/dist/src/automations/service/action-executor.js +4 -1
  189. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  190. package/dist/src/channels/channel-domain.d.ts +0 -4
  191. package/dist/src/channels/pairing/pairing-challenge.d.ts +1 -1
  192. package/dist/src/channels/pairing/pairing-challenge.js +1 -1
  193. package/dist/src/channels/plugin-types.d.ts +0 -2
  194. package/dist/src/cli/commands/agent/stream-renderer.js +4 -1
  195. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  196. package/dist/src/config/rules.js +0 -5
  197. package/dist/src/config/schema.d.ts +3 -5
  198. package/dist/src/config/schema.js +0 -3
  199. package/dist/src/config/web-patch.js +0 -1
  200. package/dist/src/connectors/health.js +1 -1
  201. package/dist/src/endpoint-tools/auth.d.ts +20 -0
  202. package/dist/src/endpoint-tools/auth.js +51 -0
  203. package/dist/src/endpoint-tools/index.d.ts +5 -0
  204. package/dist/src/endpoint-tools/index.js +6 -0
  205. package/dist/src/endpoint-tools/invocation-service.d.ts +68 -0
  206. package/dist/src/endpoint-tools/invocation-service.js +190 -0
  207. package/dist/src/endpoint-tools/policy.d.ts +10 -0
  208. package/dist/src/endpoint-tools/policy.js +18 -0
  209. package/dist/src/endpoint-tools/registry.d.ts +45 -0
  210. package/dist/src/endpoint-tools/registry.js +121 -0
  211. package/dist/src/endpoint-tools/runtime.d.ts +23 -0
  212. package/dist/src/endpoint-tools/runtime.js +86 -0
  213. package/dist/src/endpoint-tools/upload-service.d.ts +41 -0
  214. package/dist/src/endpoint-tools/upload-service.js +103 -0
  215. package/dist/src/extensions/extension-registry-impl.d.ts +3 -1
  216. package/dist/src/extensions/extension-registry-impl.js +7 -1
  217. package/dist/src/extensions/loader.js +1 -1
  218. package/dist/src/extensions/types/core.d.ts +2 -1
  219. package/dist/src/extensions/types/hooks.d.ts +1 -1
  220. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  221. package/dist/src/gateway/agent-builtin-tools.js +5 -2
  222. package/dist/src/gateway/chat-stream/mapper.js +16 -1
  223. package/dist/src/gateway/chat-stream/protocol.d.ts +4 -1
  224. package/dist/src/gateway/clarify-bridge.d.ts +5 -4
  225. package/dist/src/gateway/clarify-bridge.js +3 -4
  226. package/dist/src/gateway/file-reference-errors.d.ts +6 -0
  227. package/dist/src/gateway/file-reference-errors.js +21 -0
  228. package/dist/src/gateway/heartbeat/service.js +5 -2
  229. package/dist/src/gateway/hono/app.js +1 -5
  230. package/dist/src/gateway/hono/index.d.ts +0 -1
  231. package/dist/src/gateway/hono/index.js +1 -2
  232. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -2
  233. package/dist/src/gateway/hono/lib/config-payload.js +1 -2
  234. package/dist/src/gateway/hono/middleware/auth.js +3 -5
  235. package/dist/src/gateway/hono/routes/agent-stream.js +49 -6
  236. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +2 -2
  237. package/dist/src/gateway/hono/routes/config-patch/gateway.js +0 -19
  238. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  239. package/dist/src/gateway/hono/routes/deps.d.ts +0 -2
  240. package/dist/src/gateway/hono/routes/endpoint-tools.d.ts +3 -0
  241. package/dist/src/gateway/hono/routes/endpoint-tools.js +196 -0
  242. package/dist/src/gateway/hono/routes/index.js +4 -0
  243. package/dist/src/gateway/hono/routes/logs.js +0 -4
  244. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  245. package/dist/src/gateway/hono/routes/projects.js +34 -13
  246. package/dist/src/gateway/hono/routes/public-gateway.js +2 -2
  247. package/dist/src/gateway/hono/routes/realtime.d.ts +3 -0
  248. package/dist/src/gateway/hono/routes/realtime.js +35 -0
  249. package/dist/src/gateway/hono/routes/workspace.js +34 -13
  250. package/dist/src/gateway/hono/routes/you.d.ts +0 -9
  251. package/dist/src/gateway/hono/routes/you.js +81 -128
  252. package/dist/src/gateway/index.d.ts +1 -1
  253. package/dist/src/gateway/index.js +1 -2
  254. package/dist/src/gateway/protocol.d.ts +1 -7
  255. package/dist/src/gateway/security/index.js +1 -1
  256. package/dist/src/gateway/security/operator-scopes.js +1 -1
  257. package/dist/src/gateway/server.js +4 -4
  258. package/dist/src/gateway/service/agent-runner.d.ts +11 -9
  259. package/dist/src/gateway/service/agent-runner.js +18 -18
  260. package/dist/src/gateway/service/config-coordinator.d.ts +2 -2
  261. package/dist/src/gateway/service/config-coordinator.js +1 -1
  262. package/dist/src/gateway/service/run-gateway-agent.d.ts +4 -3
  263. package/dist/src/gateway/service/run-gateway-agent.js +17 -14
  264. package/dist/src/gateway/service/session-input-coordinator.d.ts +3 -0
  265. package/dist/src/gateway/service/session-input-coordinator.js +4 -2
  266. package/dist/src/gateway/service/types.d.ts +0 -5
  267. package/dist/src/gateway/service.d.ts +7 -6
  268. package/dist/src/gateway/service.js +39 -22
  269. package/dist/src/heartbeat/index.js +1 -1
  270. package/dist/src/mcp/channel-bridge.d.ts +6 -9
  271. package/dist/src/mcp/channel-bridge.js +48 -76
  272. package/dist/src/mcp/channel-server.js +2 -6
  273. package/dist/src/realtime/broker.d.ts +30 -0
  274. package/dist/src/realtime/broker.js +97 -0
  275. package/dist/src/realtime/runtime.d.ts +20 -0
  276. package/dist/src/realtime/runtime.js +258 -0
  277. package/dist/src/realtime/tickets.d.ts +15 -0
  278. package/dist/src/realtime/tickets.js +38 -0
  279. package/dist/src/realtime/writer.d.ts +15 -0
  280. package/dist/src/realtime/writer.js +78 -0
  281. package/dist/src/share/share-config.js +0 -1
  282. package/dist/src/share/share-zip.js +1 -1
  283. package/dist/src/share/site-share-config.js +0 -1
  284. package/dist/src/storage/sqlite/endpoint-principal-repository.d.ts +17 -0
  285. package/dist/src/storage/sqlite/endpoint-principal-repository.js +54 -0
  286. package/dist/src/storage/sqlite/endpoint-tool-invocation-repository.d.ts +25 -0
  287. package/dist/src/storage/sqlite/endpoint-tool-invocation-repository.js +42 -0
  288. package/dist/src/storage/sqlite/index.d.ts +2 -0
  289. package/dist/src/storage/sqlite/index.js +3 -1
  290. package/dist/src/storage/sqlite/memory-records-repository.js +3 -1
  291. package/dist/src/storage/sqlite/migrations/108_repair_user_memory_provider.sql +18 -0
  292. package/dist/src/storage/sqlite/migrations/109_endpoint_principals.sql +14 -0
  293. package/dist/src/storage/sqlite/migrations/110_session_input_origin.sql +43 -0
  294. package/dist/src/storage/sqlite/migrations/111_endpoint_tool_invocations.sql +18 -0
  295. package/dist/src/storage/sqlite/migrations/112_endpoint_instance_bindings.sql +8 -0
  296. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  297. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  298. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  299. package/dist/src/storage/sqlite/schema.js +1 -1
  300. package/dist/src/storage/sqlite/session-input-repository.d.ts +3 -0
  301. package/dist/src/storage/sqlite/session-input-repository.js +5 -3
  302. package/dist/src/tasks/home-query-service.d.ts +1 -1
  303. package/dist/src/tui/backends/embedded-backend.js +5 -2
  304. package/dist/src/tui/backends/{gateway-sse-backend.d.ts → gateway-realtime-backend.d.ts} +13 -10
  305. package/dist/src/tui/backends/{gateway-sse-backend.js → gateway-realtime-backend.js} +114 -151
  306. package/dist/src/tui/tool-summary.d.ts +1 -2
  307. package/dist/src/tui/tool-summary.js +2 -18
  308. package/dist/src/tui/tui-agent-events.d.ts +0 -1
  309. package/dist/src/tui/tui-agent-events.js +2 -15
  310. package/dist/src/tui/tui-backend.d.ts +4 -4
  311. package/dist/src/tui/tui-run-state.js +0 -4
  312. package/dist/src/tui/tui-types.d.ts +2 -9
  313. package/dist/src/tui/tui-types.js +0 -1
  314. package/dist/src/tui/tui.js +5 -5
  315. package/dist/src/tunnel/frpc-binary.js +1 -1
  316. package/dist/src/tunnel/gateway-lifecycle.d.ts +1 -1
  317. package/dist/src/tunnel/gateway-lifecycle.js +1 -1
  318. package/dist/src/user-context/actionableInsights.d.ts +14 -0
  319. package/dist/src/user-context/actionableInsights.js +34 -0
  320. package/dist/src/user-context/manual-understanding.js +6 -1
  321. package/dist/src/user-context/projection.d.ts +2 -1
  322. package/dist/src/user-context/projection.js +2 -1
  323. package/dist/src/user-context/understandingQuality.d.ts +5 -0
  324. package/dist/src/user-context/understandingQuality.js +44 -0
  325. package/dist/src/utils/logger/log-stream.d.ts +3 -10
  326. package/dist/src/utils/logger/log-stream.js +2 -73
  327. package/dist/src/utils/logger/pino-record.d.ts +1 -1
  328. package/dist/src/utils/logger/streams.js +1 -1
  329. package/dist/src/voice/local/model-files.js +1 -1
  330. package/dist/src/work-discovery/service.js +1 -1
  331. package/package.json +6 -3
  332. package/dist/gateway/static/root/assets/agents-Df9mTa-K.js +0 -2
  333. package/dist/gateway/static/root/assets/apps-page-Bd3tN-k2.js +0 -1
  334. package/dist/gateway/static/root/assets/automations-page-w6K9GZQ7.js +0 -6
  335. package/dist/gateway/static/root/assets/browser-settings-page-jb5Hf-hm.js +0 -8
  336. package/dist/gateway/static/root/assets/capabilities-settings-panel-BjUe4raq.js +0 -7
  337. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DiWIMYRr.js +0 -1
  338. package/dist/gateway/static/root/assets/channels-settings-D8IkjMuX.js +0 -1
  339. package/dist/gateway/static/root/assets/channels-status-swr-CySs1GQX.js +0 -1
  340. package/dist/gateway/static/root/assets/connectors-page-BT2ahw52.js +0 -2
  341. package/dist/gateway/static/root/assets/gateway-settings-CIRs2QVy.js +0 -1
  342. package/dist/gateway/static/root/assets/home-page-C59f8UJw.js +0 -3
  343. package/dist/gateway/static/root/assets/index-D-YfWVyS.css +0 -1
  344. package/dist/gateway/static/root/assets/index-vi5KlR5_.js +0 -222
  345. package/dist/gateway/static/root/assets/local-app-workbench-page-DRB4UQBE.js +0 -2
  346. package/dist/gateway/static/root/assets/logs-page-CNp4XiBN.js +0 -7
  347. package/dist/gateway/static/root/assets/messages-CPxz48hr.js +0 -3
  348. package/dist/gateway/static/root/assets/notes-workbench-DqSkeDXX.js +0 -4
  349. package/dist/gateway/static/root/assets/product-delivery-C8JbSj5Y.js +0 -1
  350. package/dist/gateway/static/root/assets/project-detail-page-BrbHs4Wp.js +0 -1
  351. package/dist/gateway/static/root/assets/projects-page-B80rtkj6.js +0 -1
  352. package/dist/gateway/static/root/assets/remote-access-hub-_Q3GEznb.js +0 -1
  353. package/dist/gateway/static/root/assets/sessions-page-55dJOUVg.js +0 -1
  354. package/dist/gateway/static/root/assets/settings-advanced-gate-CSFCZj14.js +0 -1
  355. package/dist/gateway/static/root/assets/settings-page-BSIiMLi-.js +0 -1
  356. package/dist/gateway/static/root/assets/setup-status-panel-q_yE6-H1.js +0 -1
  357. package/dist/gateway/static/root/assets/shares-settings-gYkRX9Ik.js +0 -1
  358. package/dist/gateway/static/root/assets/skill-reload-api-BoNBMKW6.js +0 -1
  359. package/dist/gateway/static/root/assets/skills-page-GZHKDFSb.js +0 -2
  360. package/dist/gateway/static/root/assets/time-picker-5sHEZ5w5.js +0 -1
  361. package/dist/gateway/static/root/assets/user-context-page-q5dr8JFG.js +0 -1
  362. package/dist/gateway/static/root/assets/work-discovery-page-fNvSg40M.js +0 -1
  363. package/dist/gateway/static/root/assets/workflows-page-YJBKmPYK.js +0 -11
  364. package/dist/src/agent/feedback/feedback-coordinator.d.ts +0 -73
  365. package/dist/src/agent/feedback/feedback-coordinator.js +0 -156
  366. package/dist/src/agent/feedback/index.d.ts +0 -4
  367. package/dist/src/agent/feedback/index.js +0 -2
  368. package/dist/src/agent/lifecycle/progress.d.ts +0 -90
  369. package/dist/src/agent/lifecycle/progress.js +0 -339
  370. package/dist/src/agent/mcp/bundle-mcp-materialize.js +0 -183
  371. package/dist/src/agent/mcp/mcp-tool-meta.d.ts +0 -8
  372. package/dist/src/agent/mcp/mcp-tool-meta.js +0 -13
  373. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.d.ts +0 -14
  374. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js +0 -48
  375. package/dist/src/agent/streaming/reasoning-visibility-sse.d.ts +0 -15
  376. package/dist/src/agent/tools/composio-tool.d.ts +0 -21
  377. package/dist/src/agent/tools/composio-tool.js +0 -261
  378. package/dist/src/gateway/agent-run-relay.d.ts +0 -19
  379. package/dist/src/gateway/agent-run-relay.js +0 -169
  380. package/dist/src/gateway/hono/sse.d.ts +0 -53
  381. package/dist/src/gateway/hono/sse.js +0 -207
  382. package/dist/src/gateway/service/sse-hub.d.ts +0 -10
  383. package/dist/src/gateway/service/sse-hub.js +0 -53
  384. package/dist/src/tui/sse-consumer.d.ts +0 -15
  385. package/dist/src/tui/sse-consumer.js +0 -73
@@ -10,19 +10,15 @@ init_loader();
10
10
  init_package_version();
11
11
  async function createXopcChannelMcpServer(opts = {}) {
12
12
  const cfg = opts.config ?? loadConfig();
13
- const claudeChannelMode = opts.claudeChannelMode ?? "auto";
14
- const capabilities = getChannelMcpCapabilities(claudeChannelMode);
13
+ const capabilities = getChannelMcpCapabilities(opts.claudeChannelMode ?? "auto");
15
14
  const server = new McpServer({
16
15
  name: "xopc",
17
16
  version: PACKAGE_VERSION
18
17
  }, capabilities ? { capabilities } : void 0);
19
18
  const bridge = new XopcChannelBridge(cfg, {
20
19
  gatewayUrl: opts.gatewayUrl,
21
- gatewayCredential: opts.gatewayCredential,
22
- claudeChannelMode,
23
- verbose: opts.verbose ?? false
20
+ gatewayCredential: opts.gatewayCredential
24
21
  });
25
- bridge.setServer(server);
26
22
  server.server.setNotificationHandler(ClaudePermissionRequestSchema, async ({ params }) => {
27
23
  await bridge.handleClaudePermissionRequest({
28
24
  requestId: params.request_id,
@@ -0,0 +1,30 @@
1
+ import { type ServerRealtimeMessage } from '@xopcai/realtime-protocol';
2
+ export type RealtimeEvent = Extract<ServerRealtimeMessage, {
3
+ kind: 'realtime.event';
4
+ }>;
5
+ export type RealtimeGap = Extract<ServerRealtimeMessage, {
6
+ kind: 'realtime.gap';
7
+ }>;
8
+ export type RealtimeDelivery = RealtimeEvent | RealtimeGap;
9
+ export interface RealtimeTopicPolicy {
10
+ replayCapacity: number;
11
+ }
12
+ export type RealtimeTopicPolicyResolver = (topic: string) => RealtimeTopicPolicy;
13
+ export interface RealtimeSubscriptionHandle {
14
+ initial: RealtimeDelivery[];
15
+ unsubscribe: () => void;
16
+ }
17
+ export declare function defaultRealtimeTopicPolicy(topic: string): RealtimeTopicPolicy;
18
+ export declare class RealtimeBroker {
19
+ private readonly resolvePolicy;
20
+ private readonly onListenerError;
21
+ private readonly topics;
22
+ constructor(resolvePolicy?: RealtimeTopicPolicyResolver, onListenerError?: (error: unknown, topic: string) => void);
23
+ publish(topic: string, event: string, data: unknown, now?: number): RealtimeEvent;
24
+ subscribe(topic: string, afterSeq: number | undefined, listener: (event: RealtimeEvent) => void): RealtimeSubscriptionHandle;
25
+ removeTopic(topic: string): void;
26
+ currentSequence(topic: string): number;
27
+ hasTopic(topic: string): boolean;
28
+ private replayFrom;
29
+ private ensureTopic;
30
+ }
@@ -0,0 +1,97 @@
1
+ import { realtimeEventNameSchema, realtimeTopicSchema } from "../../packages/realtime-protocol/src/index.js";
2
+ import crypto from "node:crypto";
3
+ //#region src/realtime/broker.ts
4
+ const DEFAULT_TOPIC_POLICY = { replayCapacity: 0 };
5
+ function defaultRealtimeTopicPolicy(topic) {
6
+ if (topic.startsWith("run:")) return { replayCapacity: 8e3 };
7
+ if (topic.startsWith("session:")) return { replayCapacity: 200 };
8
+ if (topic === "logs") return { replayCapacity: 500 };
9
+ if (topic === "gateway" || topic === "sessions") return { replayCapacity: 1e3 };
10
+ return DEFAULT_TOPIC_POLICY;
11
+ }
12
+ var RealtimeBroker = class {
13
+ topics = /* @__PURE__ */ new Map();
14
+ constructor(resolvePolicy = defaultRealtimeTopicPolicy, onListenerError = () => {}) {
15
+ this.resolvePolicy = resolvePolicy;
16
+ this.onListenerError = onListenerError;
17
+ }
18
+ publish(topic, event, data, now = Date.now()) {
19
+ realtimeTopicSchema.parse(topic);
20
+ realtimeEventNameSchema.parse(event);
21
+ const state = this.ensureTopic(topic);
22
+ const message = {
23
+ protocolVersion: 1,
24
+ messageId: crypto.randomUUID(),
25
+ kind: "realtime.event",
26
+ sentAt: now,
27
+ payload: {
28
+ topic,
29
+ seq: state.nextSeq++,
30
+ event,
31
+ data
32
+ }
33
+ };
34
+ const capacity = this.resolvePolicy(topic).replayCapacity;
35
+ if (capacity > 0) {
36
+ state.events.push(message);
37
+ if (state.events.length > capacity) state.events.splice(0, state.events.length - capacity);
38
+ }
39
+ for (const listener of state.listeners) try {
40
+ listener(message);
41
+ } catch (error) {
42
+ this.onListenerError(error, topic);
43
+ }
44
+ return message;
45
+ }
46
+ subscribe(topic, afterSeq, listener) {
47
+ realtimeTopicSchema.parse(topic);
48
+ const state = this.ensureTopic(topic);
49
+ state.listeners.add(listener);
50
+ return {
51
+ initial: afterSeq === void 0 ? [] : this.replayFrom(topic, state, afterSeq),
52
+ unsubscribe: () => {
53
+ state.listeners.delete(listener);
54
+ }
55
+ };
56
+ }
57
+ removeTopic(topic) {
58
+ this.topics.delete(topic);
59
+ }
60
+ currentSequence(topic) {
61
+ return (this.topics.get(topic)?.nextSeq ?? 1) - 1;
62
+ }
63
+ hasTopic(topic) {
64
+ return this.topics.has(topic);
65
+ }
66
+ replayFrom(topic, state, afterSeq) {
67
+ const currentSeq = state.nextSeq - 1;
68
+ if (currentSeq <= afterSeq) return [];
69
+ const earliestSeq = state.events[0]?.payload.seq;
70
+ if (earliestSeq === void 0 || afterSeq + 1 < earliestSeq) return [{
71
+ protocolVersion: 1,
72
+ messageId: crypto.randomUUID(),
73
+ kind: "realtime.gap",
74
+ sentAt: Date.now(),
75
+ payload: {
76
+ topic,
77
+ requestedSeq: afterSeq,
78
+ earliestSeq: earliestSeq ?? currentSeq + 1
79
+ }
80
+ }, ...state.events];
81
+ return state.events.filter((event) => event.payload.seq > afterSeq);
82
+ }
83
+ ensureTopic(topic) {
84
+ let state = this.topics.get(topic);
85
+ if (!state) {
86
+ state = {
87
+ nextSeq: 1,
88
+ events: [],
89
+ listeners: /* @__PURE__ */ new Set()
90
+ };
91
+ this.topics.set(topic, state);
92
+ }
93
+ return state;
94
+ }
95
+ };
96
+ //#endregion
97
+ export { RealtimeBroker, defaultRealtimeTopicPolicy };
@@ -0,0 +1,20 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import type { Socket } from 'node:net';
3
+ import type { EndpointToolRuntime } from '../endpoint-tools/runtime.js';
4
+ import { RealtimeBroker } from './broker.js';
5
+ import { RealtimeTicketStore } from './tickets.js';
6
+ export declare class RealtimeRuntime {
7
+ private readonly endpointTools?;
8
+ readonly broker: RealtimeBroker;
9
+ readonly tickets: RealtimeTicketStore;
10
+ private readonly preauthBudget;
11
+ private readonly wss;
12
+ private readonly topicCleanupTimers;
13
+ private closed;
14
+ constructor(endpointTools?: EndpointToolRuntime);
15
+ handleUpgrade(req: IncomingMessage, socket: Socket, head: Buffer): boolean;
16
+ close(): void;
17
+ completeTopic(topic: string, ttlMs?: number): void;
18
+ private handleConnection;
19
+ private rawDataToText;
20
+ }
@@ -0,0 +1,258 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { REALTIME_HEARTBEAT_INTERVAL_MS, REALTIME_HEARTBEAT_TIMEOUT_MS, REALTIME_HELLO_TIMEOUT_MS, REALTIME_MAX_CLIENT_FRAME_BYTES, parseClientRealtimeJsonFrame, parseClientRealtimeMessage } from "../../packages/realtime-protocol/src/index.js";
4
+ import { createPreauthConnectionBudget } from "../gateway/security/preauth-connection-budget.js";
5
+ import { RealtimeBroker } from "./broker.js";
6
+ import { RealtimeTicketStore } from "./tickets.js";
7
+ import { RealtimeSocketWriter } from "./writer.js";
8
+ import { createRequire } from "node:module";
9
+ import crypto from "node:crypto";
10
+ //#region src/realtime/runtime.ts
11
+ init_logger();
12
+ const log = createLogger("Realtime");
13
+ const { WebSocketServer } = createRequire(import.meta.url)("ws");
14
+ const REALTIME_WS_PATH = "/api/realtime/v1/ws";
15
+ const MAX_MESSAGE_CLOCK_SKEW_MS = 6e4;
16
+ const MAX_SUBSCRIPTIONS = 100;
17
+ const MAX_CONNECTIONS = 100;
18
+ function serverMessage(kind, payload) {
19
+ return {
20
+ protocolVersion: 1,
21
+ messageId: crypto.randomUUID(),
22
+ kind,
23
+ sentAt: Date.now(),
24
+ payload
25
+ };
26
+ }
27
+ function isAuthorizedTopic(topic) {
28
+ return topic === "gateway" || topic === "sessions" || topic === "logs" || topic.startsWith("session:") && topic.length > 8 || topic.startsWith("run:") && topic.length > 4 || topic.startsWith("workflow:") && topic.length > 9;
29
+ }
30
+ var RealtimeRuntime = class {
31
+ broker = new RealtimeBroker(void 0, (error, topic) => {
32
+ log.warn({
33
+ err: error,
34
+ topic
35
+ }, "Realtime subscriber failed");
36
+ });
37
+ tickets = new RealtimeTicketStore();
38
+ preauthBudget = createPreauthConnectionBudget();
39
+ wss = new WebSocketServer({
40
+ noServer: true,
41
+ maxPayload: REALTIME_MAX_CLIENT_FRAME_BYTES,
42
+ perMessageDeflate: false
43
+ });
44
+ topicCleanupTimers = /* @__PURE__ */ new Map();
45
+ closed = false;
46
+ constructor(endpointTools) {
47
+ this.endpointTools = endpointTools;
48
+ this.wss.on("connection", (socket, request) => this.handleConnection(socket, request));
49
+ this.wss.on("error", (err) => log.error({ err }, "Realtime WebSocket server failed"));
50
+ }
51
+ handleUpgrade(req, socket, head) {
52
+ if (new URL(req.url ?? "/", "http://gateway.local").pathname !== REALTIME_WS_PATH) return false;
53
+ if (this.closed) {
54
+ socket.destroy();
55
+ return true;
56
+ }
57
+ if (this.wss.clients.size >= MAX_CONNECTIONS) {
58
+ socket.destroy();
59
+ return true;
60
+ }
61
+ const clientIp = req.socket.remoteAddress;
62
+ if (!this.preauthBudget.acquire(clientIp)) {
63
+ socket.destroy();
64
+ return true;
65
+ }
66
+ try {
67
+ this.wss.handleUpgrade(req, socket, head, (ws) => {
68
+ this.wss.emit("connection", ws, req);
69
+ });
70
+ } catch (error) {
71
+ this.preauthBudget.release(clientIp);
72
+ throw error;
73
+ }
74
+ return true;
75
+ }
76
+ close() {
77
+ if (this.closed) return;
78
+ this.closed = true;
79
+ for (const client of this.wss.clients) client.close(1001, "Gateway stopping");
80
+ for (const timer of this.topicCleanupTimers.values()) clearTimeout(timer);
81
+ this.topicCleanupTimers.clear();
82
+ this.wss.close();
83
+ }
84
+ completeTopic(topic, ttlMs = 5 * 6e4) {
85
+ const existing = this.topicCleanupTimers.get(topic);
86
+ if (existing) clearTimeout(existing);
87
+ this.topicCleanupTimers.set(topic, setTimeout(() => {
88
+ this.topicCleanupTimers.delete(topic);
89
+ this.broker.removeTopic(topic);
90
+ }, ttlMs));
91
+ }
92
+ handleConnection(socket, request) {
93
+ const clientIp = request.socket.remoteAddress;
94
+ const writer = new RealtimeSocketWriter(socket);
95
+ const subscriptions = /* @__PURE__ */ new Map();
96
+ let authenticated = false;
97
+ let lastSeenAt = Date.now();
98
+ let connectionId;
99
+ let endpointId;
100
+ let budgetHeld = true;
101
+ const releaseBudget = () => {
102
+ if (!budgetHeld) return;
103
+ budgetHeld = false;
104
+ this.preauthBudget.release(clientIp);
105
+ };
106
+ const helloTimer = setTimeout(() => socket.close(4401, "Realtime hello timeout"), REALTIME_HELLO_TIMEOUT_MS);
107
+ const heartbeatTimer = setInterval(() => {
108
+ if (Date.now() - lastSeenAt > 45e3) socket.close(4408, "Realtime heartbeat timeout");
109
+ }, REALTIME_HEARTBEAT_INTERVAL_MS);
110
+ const sendError = (code, message) => {
111
+ writer.enqueue(serverMessage("realtime.error", {
112
+ code,
113
+ message
114
+ }), "critical");
115
+ };
116
+ const subscribe = (requested) => {
117
+ const authorized = requested.filter((item) => {
118
+ if (isAuthorizedTopic(item.topic)) return true;
119
+ sendError("FORBIDDEN_TOPIC", `Topic is not available: ${item.topic}`);
120
+ return false;
121
+ });
122
+ if (new Set([...subscriptions.keys(), ...authorized.map((item) => item.topic)]).size > MAX_SUBSCRIPTIONS) {
123
+ sendError("TOO_MANY_SUBSCRIPTIONS", `At most ${MAX_SUBSCRIPTIONS} topics may be subscribed`);
124
+ return false;
125
+ }
126
+ for (const item of authorized) {
127
+ if (item.topic.startsWith("run:") && item.afterSeq !== void 0 && !this.broker.hasTopic(item.topic)) {
128
+ writer.enqueue(serverMessage("realtime.gap", {
129
+ topic: item.topic,
130
+ requestedSeq: item.afterSeq,
131
+ earliestSeq: 1
132
+ }));
133
+ continue;
134
+ }
135
+ subscriptions.get(item.topic)?.unsubscribe();
136
+ const handle = this.broker.subscribe(item.topic, item.afterSeq, (event) => {
137
+ writer.enqueue(event);
138
+ });
139
+ subscriptions.set(item.topic, handle);
140
+ for (const message of handle.initial) writer.enqueue(message);
141
+ }
142
+ return true;
143
+ };
144
+ socket.on("message", (data, isBinary) => {
145
+ if (isBinary) {
146
+ socket.close(4400, "Binary realtime frames are not supported");
147
+ return;
148
+ }
149
+ let message;
150
+ try {
151
+ message = parseClientRealtimeMessage(parseClientRealtimeJsonFrame(this.rawDataToText(data)));
152
+ if (Math.abs(Date.now() - message.sentAt) > MAX_MESSAGE_CLOCK_SKEW_MS) throw new Error("Realtime message timestamp is outside the allowed window");
153
+ } catch (error) {
154
+ log.warn({ err: error }, "Realtime client sent an invalid frame");
155
+ socket.close(4400, "Invalid realtime protocol frame");
156
+ return;
157
+ }
158
+ lastSeenAt = Date.now();
159
+ if (!authenticated) {
160
+ if (message.kind !== "realtime.hello") {
161
+ socket.close(4401, "First realtime message must be hello");
162
+ return;
163
+ }
164
+ const claim = this.tickets.consume(message.payload.ticket, message.payload.clientId, message.payload.clientKind);
165
+ if (!claim) {
166
+ socket.close(4401, "Realtime authentication failed");
167
+ return;
168
+ }
169
+ authenticated = true;
170
+ connectionId = crypto.randomUUID();
171
+ let endpointReady;
172
+ if (message.payload.endpoint) {
173
+ if (!this.endpointTools || message.payload.endpoint.kind !== message.payload.clientKind) {
174
+ socket.close(4401, "Realtime endpoint identity is invalid");
175
+ return;
176
+ }
177
+ const transport = {
178
+ get readyState() {
179
+ return socket.readyState;
180
+ },
181
+ send: (data) => {
182
+ writer.enqueue(serverMessage("endpoint.message", JSON.parse(data)), "critical");
183
+ },
184
+ close: (code, reason) => socket.close(code, reason)
185
+ };
186
+ try {
187
+ const registration = this.endpointTools.connect(message.payload.endpoint, connectionId, transport);
188
+ endpointId = message.payload.endpoint.endpointId;
189
+ endpointReady = {
190
+ endpointId,
191
+ turnToken: registration.turnToken
192
+ };
193
+ } catch (error) {
194
+ log.warn({
195
+ err: error,
196
+ principalId: message.payload.endpoint.principalId
197
+ }, "Realtime endpoint authentication failed");
198
+ socket.close(4401, "Realtime endpoint authentication failed");
199
+ return;
200
+ }
201
+ }
202
+ clearTimeout(helloTimer);
203
+ releaseBudget();
204
+ writer.enqueue(serverMessage("realtime.ready", {
205
+ connectionId,
206
+ heartbeatIntervalMs: REALTIME_HEARTBEAT_INTERVAL_MS,
207
+ heartbeatTimeoutMs: REALTIME_HEARTBEAT_TIMEOUT_MS,
208
+ ...endpointReady ? { endpoint: endpointReady } : {}
209
+ }), "critical");
210
+ subscribe(message.payload.subscriptions);
211
+ log.info({
212
+ connectionId,
213
+ clientId: claim.clientId,
214
+ clientKind: claim.clientKind
215
+ }, "Realtime client connected");
216
+ return;
217
+ }
218
+ if (message.kind === "realtime.hello") socket.close(4400, "Realtime hello may only be sent once");
219
+ else if (message.kind === "realtime.subscribe") subscribe(message.payload.subscriptions);
220
+ else if (message.kind === "realtime.unsubscribe") for (const topic of message.payload.topics) {
221
+ subscriptions.get(topic)?.unsubscribe();
222
+ subscriptions.delete(topic);
223
+ }
224
+ else if (message.kind === "realtime.ping") {
225
+ if (endpointId && connectionId) this.endpointTools?.touch(endpointId, connectionId);
226
+ writer.enqueue(serverMessage("realtime.pong", {}), "critical");
227
+ } else if (!endpointId || !connectionId || !this.endpointTools) sendError("ENDPOINT_NOT_REGISTERED", "Endpoint messages require an endpoint identity");
228
+ else try {
229
+ this.endpointTools.handleMessage(endpointId, connectionId, message.payload);
230
+ } catch (error) {
231
+ log.warn({
232
+ err: error,
233
+ endpointId,
234
+ connectionId
235
+ }, "Realtime endpoint message failed");
236
+ socket.close(4400, "Invalid endpoint message");
237
+ }
238
+ });
239
+ socket.on("close", () => {
240
+ clearTimeout(helloTimer);
241
+ clearInterval(heartbeatTimer);
242
+ releaseBudget();
243
+ writer.close();
244
+ for (const handle of subscriptions.values()) handle.unsubscribe();
245
+ subscriptions.clear();
246
+ if (endpointId && connectionId) this.endpointTools?.remove(endpointId, connectionId);
247
+ if (connectionId) log.info({ connectionId }, "Realtime client disconnected");
248
+ });
249
+ }
250
+ rawDataToText(data) {
251
+ if (typeof data === "string") return data;
252
+ if (Array.isArray(data)) return Buffer.concat(data).toString("utf8");
253
+ if (data instanceof ArrayBuffer) return Buffer.from(data).toString("utf8");
254
+ return data.toString("utf8");
255
+ }
256
+ };
257
+ //#endregion
258
+ export { RealtimeRuntime };
@@ -0,0 +1,15 @@
1
+ import type { RealtimeClientKind } from '@xopcai/realtime-protocol';
2
+ export interface RealtimeTicketClaim {
3
+ clientId: string;
4
+ clientKind: RealtimeClientKind;
5
+ expiresAt: number;
6
+ }
7
+ export interface IssuedRealtimeTicket extends RealtimeTicketClaim {
8
+ ticket: string;
9
+ }
10
+ export declare class RealtimeTicketStore {
11
+ private readonly claims;
12
+ issue(clientId: string, clientKind: RealtimeClientKind, now?: number): IssuedRealtimeTicket;
13
+ consume(ticket: string, clientId: string, clientKind: RealtimeClientKind, now?: number): RealtimeTicketClaim | undefined;
14
+ private prune;
15
+ }
@@ -0,0 +1,38 @@
1
+ import crypto from "node:crypto";
2
+ //#region src/realtime/tickets.ts
3
+ const TICKET_TTL_MS = 3e4;
4
+ const MAX_OUTSTANDING_TICKETS = 1e3;
5
+ function ticketKey(ticket) {
6
+ return crypto.createHash("sha256").update(ticket).digest("hex");
7
+ }
8
+ var RealtimeTicketStore = class {
9
+ claims = /* @__PURE__ */ new Map();
10
+ issue(clientId, clientKind, now = Date.now()) {
11
+ this.prune(now);
12
+ if (this.claims.size >= MAX_OUTSTANDING_TICKETS) throw new Error("Too many outstanding realtime tickets");
13
+ const ticket = crypto.randomBytes(32).toString("base64url");
14
+ const claim = {
15
+ clientId,
16
+ clientKind,
17
+ expiresAt: now + TICKET_TTL_MS
18
+ };
19
+ this.claims.set(ticketKey(ticket), claim);
20
+ return {
21
+ ticket,
22
+ ...claim
23
+ };
24
+ }
25
+ consume(ticket, clientId, clientKind, now = Date.now()) {
26
+ const key = ticketKey(ticket);
27
+ const claim = this.claims.get(key);
28
+ this.claims.delete(key);
29
+ if (!claim || claim.expiresAt < now) return void 0;
30
+ if (claim.clientId !== clientId || claim.clientKind !== clientKind) return void 0;
31
+ return claim;
32
+ }
33
+ prune(now) {
34
+ for (const [key, claim] of this.claims) if (claim.expiresAt < now) this.claims.delete(key);
35
+ }
36
+ };
37
+ //#endregion
38
+ export { RealtimeTicketStore };
@@ -0,0 +1,15 @@
1
+ import type { ServerRealtimeMessage } from '@xopcai/realtime-protocol';
2
+ import type { WebSocket } from 'ws';
3
+ export declare class RealtimeSocketWriter {
4
+ private readonly socket;
5
+ private readonly critical;
6
+ private readonly normal;
7
+ private queuedBytes;
8
+ private sending;
9
+ private closed;
10
+ private retryTimer?;
11
+ constructor(socket: WebSocket);
12
+ enqueue(message: ServerRealtimeMessage, priority?: 'critical' | 'normal'): boolean;
13
+ close(): void;
14
+ private flush;
15
+ }
@@ -0,0 +1,78 @@
1
+ //#region src/realtime/writer.ts
2
+ const SOFT_BUFFERED_BYTES = 512 * 1024;
3
+ const HARD_BUFFERED_BYTES = 4 * 1024 * 1024;
4
+ const MAX_QUEUED_BYTES = 2 * 1024 * 1024;
5
+ var RealtimeSocketWriter = class {
6
+ critical = [];
7
+ normal = [];
8
+ queuedBytes = 0;
9
+ sending = false;
10
+ closed = false;
11
+ retryTimer;
12
+ constructor(socket) {
13
+ this.socket = socket;
14
+ }
15
+ enqueue(message, priority = "normal") {
16
+ if (this.closed || this.socket.readyState !== 1) return false;
17
+ let data;
18
+ try {
19
+ data = JSON.stringify(message);
20
+ } catch {
21
+ this.socket.close(1011, "Realtime message serialization failed");
22
+ this.close();
23
+ return false;
24
+ }
25
+ const item = {
26
+ data,
27
+ bytes: Buffer.byteLength(data)
28
+ };
29
+ if (this.queuedBytes + item.bytes > MAX_QUEUED_BYTES) {
30
+ this.socket.close(4413, "Realtime client is too slow");
31
+ this.close();
32
+ return false;
33
+ }
34
+ this.queuedBytes += item.bytes;
35
+ (priority === "critical" ? this.critical : this.normal).push(item);
36
+ this.flush();
37
+ return true;
38
+ }
39
+ close() {
40
+ if (this.closed) return;
41
+ this.closed = true;
42
+ if (this.retryTimer) clearTimeout(this.retryTimer);
43
+ this.retryTimer = void 0;
44
+ this.critical.length = 0;
45
+ this.normal.length = 0;
46
+ this.queuedBytes = 0;
47
+ }
48
+ flush() {
49
+ if (this.closed || this.sending || this.socket.readyState !== 1) return;
50
+ if (this.socket.bufferedAmount > HARD_BUFFERED_BYTES) {
51
+ this.socket.close(4413, "Realtime client is too slow");
52
+ this.close();
53
+ return;
54
+ }
55
+ if (this.socket.bufferedAmount > SOFT_BUFFERED_BYTES) {
56
+ if (!this.retryTimer) this.retryTimer = setTimeout(() => {
57
+ this.retryTimer = void 0;
58
+ this.flush();
59
+ }, 10);
60
+ return;
61
+ }
62
+ const item = this.critical.shift() ?? this.normal.shift();
63
+ if (!item) return;
64
+ this.sending = true;
65
+ this.socket.send(item.data, (error) => {
66
+ this.sending = false;
67
+ this.queuedBytes -= item.bytes;
68
+ if (error) {
69
+ this.socket.close(1011, "Realtime delivery failed");
70
+ this.close();
71
+ return;
72
+ }
73
+ this.flush();
74
+ });
75
+ }
76
+ };
77
+ //#endregion
78
+ export { RealtimeSocketWriter };
@@ -85,7 +85,6 @@ function mergeShareConfigPatch(config, patch) {
85
85
  intervalMs: 18e5,
86
86
  includeSystemPromptSection: false
87
87
  },
88
- maxSseConnections: 100,
89
88
  corsOrigins: []
90
89
  };
91
90
  const current = resolveShareConfig(config.gateway.share);
@@ -2,8 +2,8 @@ import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
2
2
  import { relative, resolve } from "node:path";
3
3
  import { createReadStream } from "node:fs";
4
4
  import { lstat, readdir, realpath, stat } from "node:fs/promises";
5
- import { pipeline } from "node:stream/promises";
6
5
  import { Readable, Transform } from "node:stream";
6
+ import { pipeline } from "node:stream/promises";
7
7
  import { crc32, createDeflateRaw } from "node:zlib";
8
8
  //#region src/share/share-zip.ts
9
9
  const SIG_LOCAL = 67324752;
@@ -73,7 +73,6 @@ function mergeSiteShareConfigPatch(config, patch) {
73
73
  intervalMs: 18e5,
74
74
  includeSystemPromptSection: false
75
75
  },
76
- maxSseConnections: 100,
77
76
  corsOrigins: []
78
77
  };
79
78
  const cfg = config.gateway;
@@ -0,0 +1,17 @@
1
+ import type { EndpointKind } from '@xopcai/endpoint-tools-protocol';
2
+ export interface EndpointPrincipal {
3
+ id: string;
4
+ kind: EndpointKind;
5
+ displayName: string;
6
+ platform: string;
7
+ publicKey: string;
8
+ createdAt: number;
9
+ lastSeenAt?: number;
10
+ revokedAt?: number;
11
+ }
12
+ export declare function createEndpointPrincipal(principal: Omit<EndpointPrincipal, 'createdAt' | 'lastSeenAt' | 'revokedAt'>): EndpointPrincipal;
13
+ export declare function getEndpointPrincipal(id: string): EndpointPrincipal | undefined;
14
+ export declare function listEndpointPrincipals(): EndpointPrincipal[];
15
+ export declare function touchEndpointPrincipal(id: string, seenAt?: number): void;
16
+ export declare function bindEndpointPrincipal(endpointId: string, principalId: string, boundAt?: number): boolean;
17
+ export declare function revokeEndpointPrincipal(id: string, revokedAt?: number): boolean;
@@ -0,0 +1,54 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ //#region src/storage/sqlite/endpoint-principal-repository.ts
3
+ function fromRow(row) {
4
+ return {
5
+ id: row.id,
6
+ kind: row.kind,
7
+ displayName: row.display_name,
8
+ platform: row.platform,
9
+ publicKey: row.public_key,
10
+ createdAt: row.created_at,
11
+ ...row.last_seen_at === null ? {} : { lastSeenAt: row.last_seen_at },
12
+ ...row.revoked_at === null ? {} : { revokedAt: row.revoked_at }
13
+ };
14
+ }
15
+ function createEndpointPrincipal(principal) {
16
+ const createdAt = Date.now();
17
+ runSqliteWriteTransaction((db) => {
18
+ db.prepare(`
19
+ INSERT INTO endpoint_principals (
20
+ id, kind, display_name, platform, public_key, created_at
21
+ ) VALUES (?, ?, ?, ?, ?, ?)
22
+ `).run(principal.id, principal.kind, principal.displayName, principal.platform, principal.publicKey, createdAt);
23
+ });
24
+ return {
25
+ ...principal,
26
+ createdAt
27
+ };
28
+ }
29
+ function getEndpointPrincipal(id) {
30
+ const row = getSqliteDatabase().prepare("SELECT * FROM endpoint_principals WHERE id = ?").get(id);
31
+ return row ? fromRow(row) : void 0;
32
+ }
33
+ function listEndpointPrincipals() {
34
+ return getSqliteDatabase().prepare("SELECT * FROM endpoint_principals ORDER BY created_at DESC").all().map(fromRow);
35
+ }
36
+ function touchEndpointPrincipal(id, seenAt = Date.now()) {
37
+ getSqliteDatabase().prepare("UPDATE endpoint_principals SET last_seen_at = ? WHERE id = ? AND revoked_at IS NULL").run(seenAt, id);
38
+ }
39
+ function bindEndpointPrincipal(endpointId, principalId, boundAt = Date.now()) {
40
+ return runSqliteWriteTransaction((db) => {
41
+ db.prepare(`
42
+ INSERT OR IGNORE INTO endpoint_instance_bindings (endpoint_id, principal_id, bound_at)
43
+ VALUES (?, ?, ?)
44
+ `).run(endpointId, principalId, boundAt);
45
+ return db.prepare(`
46
+ SELECT principal_id FROM endpoint_instance_bindings WHERE endpoint_id = ?
47
+ `).get(endpointId)?.principal_id === principalId;
48
+ });
49
+ }
50
+ function revokeEndpointPrincipal(id, revokedAt = Date.now()) {
51
+ return getSqliteDatabase().prepare("UPDATE endpoint_principals SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL").run(revokedAt, id).changes > 0;
52
+ }
53
+ //#endregion
54
+ export { bindEndpointPrincipal, createEndpointPrincipal, getEndpointPrincipal, listEndpointPrincipals, revokeEndpointPrincipal, touchEndpointPrincipal };