@xopcai/xopc 0.0.384 → 0.0.386

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 (280) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BSel9yf8.js → agent-avatar-dicebear-D-86VOlb.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DgHMyhuY.js → agent-defaults-settings-panel-SmeUVHY8.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-BosuN4dO.js → agent-plugin-dialog-BVT3wXq5.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-B-pw5RKI.js → agents-D7rLQFhX.js} +3 -3
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DuOqKkfH.js → app-management-settings-panel-CUR7n5iP.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-8JF9rXFr.js → appearance-settings-BCotSGep.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-Cuclpk0A.js → apps-page-hk0bo9LT.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automations-page-D7NwNy2I.js → automations-page-CqxuUwox.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-workspace-CSxW4wX0.js → automations-workspace-11_Z69pr.js} +1 -1
  12. package/dist/gateway/static/root/assets/{block-editor-Dnb7CH_l.js → block-editor-eldB84Mj.js} +1 -1
  13. package/dist/gateway/static/root/assets/{browser-automations-page-GBgDe21o.js → browser-automations-page-D4TaUPYT.js} +1 -1
  14. package/dist/gateway/static/root/assets/{browser-settings-page-B2FXaO3n.js → browser-settings-page-BXRlxeGV.js} +1 -1
  15. package/dist/gateway/static/root/assets/{capabilities-XFwwUNU3.js → capabilities-BkKgImWi.js} +1 -1
  16. package/dist/gateway/static/root/assets/{capabilities-2Do3eKMM.js → capabilities-DVj9n65C.js} +1 -1
  17. package/dist/gateway/static/root/assets/{capabilities-page-f2-MquJn.js → capabilities-page-CyYlueEd.js} +2 -2
  18. package/dist/gateway/static/root/assets/{capabilities-settings-panel-D9F0mw16.js → capabilities-settings-panel-uVEgfvo0.js} +1 -1
  19. package/dist/gateway/static/root/assets/{capability-header-actions-DVRxJPQP.js → capability-header-actions-BXv0xu56.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-CnDm5T1t.js → channels-fNb3SOzm.js} +1 -1
  21. package/dist/gateway/static/root/assets/{chat-terminal-dock-BxSCDbK7.js → chat-terminal-dock-CnLtparQ.js} +1 -1
  22. package/dist/gateway/static/root/assets/{computer-settings-page-DVAB-kQw.js → computer-settings-page-xM0AnOlP.js} +1 -1
  23. package/dist/gateway/static/root/assets/{connector-service-page-D2EeLXei.js → connector-service-page-CdG2WUb6.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-DK9n4hgZ.js → connectors-page-BRd08GH6.js} +1 -1
  25. package/dist/gateway/static/root/assets/constants-CpWu0oHS.js +1 -0
  26. package/dist/gateway/static/root/assets/{date-picker-Cl9KfFj8.js → date-picker-DIBbE-O8.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-Ei6aX5WM.js → dependency-picker-DDD8zokD.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-4Evl4RKX.js → desktop-pet-KlF390Xn.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-DAD_OWcX.js → desktop-pet-settings-CgqQMKDC.js} +1 -1
  30. package/dist/gateway/static/root/assets/{device-pairing-wizard-BA21epMn.js → device-pairing-wizard-BR6isfG2.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-B_Zb5nNR.js → directory-picker-path-field-vPQsW05P.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-DtHNy4TE.js → extension-debug-page-ZHLPrLbH.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-8gWSThWP.js → extension-page-DJ42KFRN.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-provider-nbgU7xBS.js → extension-provider-6IcsyNaV.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-CunUbB09.js → extension-settings-page-D7-5v0V4.js} +1 -1
  36. package/dist/gateway/static/root/assets/{fallback-models-BSAfzXby.js → fallback-models-DnYn7qOV.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-settings-CN-2229W.js → gateway-settings-Bwe3JWX-.js} +1 -1
  38. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DktBCtHF.js → highlighted-body-KQOG7T2V-DefTxF3q.js} +1 -1
  39. package/dist/gateway/static/root/assets/{home-page-CUJcNW3H.js → home-page-BtSy2hRV.js} +1 -1
  40. package/dist/gateway/static/root/assets/{imports-page-DQm1MNNC.js → imports-page-CTdBYZib.js} +1 -1
  41. package/dist/gateway/static/root/assets/{index-BPNL54bv.js → index-B08iR7fT.js} +10 -10
  42. package/dist/gateway/static/root/assets/index-DBRwvWzm.css +1 -0
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DaC5YjuJ.js → keyboard-shortcuts-settings-CXKp57O_.js} +1 -1
  44. package/dist/gateway/static/root/assets/{local-app-workbench-page-DwQyyo7a.js → local-app-workbench-page-DzD_OzGY.js} +1 -1
  45. package/dist/gateway/static/root/assets/{local-apps-page-CpZhivpf.js → local-apps-page-B0E0vttg.js} +1 -1
  46. package/dist/gateway/static/root/assets/{logs-page-Db43nh1M.js → logs-page-eL4fYcMl.js} +1 -1
  47. package/dist/gateway/static/root/assets/{management-settings-DrKejBEZ.js → management-settings-DSpjodMC.js} +1 -1
  48. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-BTrk2wWv.js +1 -0
  49. package/dist/gateway/static/root/assets/{note-detail-panel-a8NSwmmW.js → note-detail-panel-CsY5tQp5.js} +3 -3
  50. package/dist/gateway/static/root/assets/{notes-page-BKRke43F.js → notes-page-D09LjNoj.js} +1 -1
  51. package/dist/gateway/static/root/assets/{page-context-capture-button-DUaMkmxv.js → page-context-capture-button-DO-aP3D9.js} +1 -1
  52. package/dist/gateway/static/root/assets/{personal-page-BqF-HHw1.js → personal-page-E8F2aGNB.js} +1 -1
  53. package/dist/gateway/static/root/assets/{product-open-page-GrhtTQIz.js → product-open-page-aUoA-uPw.js} +1 -1
  54. package/dist/gateway/static/root/assets/{product-preview-content-zdP7gN0y.js → product-preview-content-B-cz-pIV.js} +1 -1
  55. package/dist/gateway/static/root/assets/{project-detail-page-9Vd_AqDW.js → project-detail-page-WhefAh8E.js} +1 -1
  56. package/dist/gateway/static/root/assets/{projects-page-DGunhjoM.js → projects-page-CyqAs0tO.js} +1 -1
  57. package/dist/gateway/static/root/assets/{remote-access-hub-BoRsF3Lx.js → remote-access-hub-BwhRGL6m.js} +1 -1
  58. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-W0HDm--J.js → runtime-tools-settings-panel-o26dmPNq.js} +1 -1
  59. package/dist/gateway/static/root/assets/{scenes-page-CYsFOfVJ.js → scenes-page-D_e19kv_.js} +1 -1
  60. package/dist/gateway/static/root/assets/{schema-form-CBxEbBQq.js → schema-form-DLLdqUC3.js} +1 -1
  61. package/dist/gateway/static/root/assets/{send-session-input-BCAF-Ikt.js → send-session-input-2I-nFJcE.js} +1 -1
  62. package/dist/gateway/static/root/assets/session-manager-Co5ozD0l.js +16 -0
  63. package/dist/gateway/static/root/assets/{sessions-page-Dthfx_vc.js → sessions-page-DX6INsiS.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-C4_gW1vw.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-page-CFs-WP_2.js → settings-page-Bc_zxxRu.js} +1 -1
  66. package/dist/gateway/static/root/assets/{setup-status-panel-D2-9fXYL.js → setup-status-panel-FpF_cPPr.js} +1 -1
  67. package/dist/gateway/static/root/assets/{share-preview-page-nJ2FWAEP.js → share-preview-page-BOCcPBqQ.js} +1 -1
  68. package/dist/gateway/static/root/assets/{shares-settings-DTb88RHD.js → shares-settings-CInxjxgJ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{skill-api-DJ8UBsxq.js → skill-api-Bjd8WAA4.js} +1 -1
  70. package/dist/gateway/static/root/assets/{skills-page-DjbBOikT.js → skills-page-8CKS3Oo2.js} +1 -1
  71. package/dist/gateway/static/root/assets/{system-settings-panel-Dt5GkLhM.js → system-settings-panel-BgQdsrNw.js} +1 -1
  72. package/dist/gateway/static/root/assets/task-detail-page-BnG5ehZ6.js +2 -0
  73. package/dist/gateway/static/root/assets/task-expandable-content-BCuc70Vc.js +1 -0
  74. package/dist/gateway/static/root/assets/{tasks-DJIeIk9C.js → tasks-PuIUgF9L.js} +1 -1
  75. package/dist/gateway/static/root/assets/{tunnel-api-JHttXi63.js → tunnel-api-CY7MoDGf.js} +1 -1
  76. package/dist/gateway/static/root/assets/{usage-page-B3rUa0fW.js → usage-page-s8Sv_PIG.js} +1 -1
  77. package/dist/gateway/static/root/assets/{use-composer-attachments-BFP3k6oC.js → use-composer-attachments-D0S2iZF4.js} +1 -1
  78. package/dist/gateway/static/root/assets/{use-file-preview-expanded-B1BiTQNS.js → use-file-preview-expanded-BElqELib.js} +1 -1
  79. package/dist/gateway/static/root/assets/{user-model-page-Cq1VSsZw.js → user-model-page-CyWrEtHY.js} +1 -1
  80. package/dist/gateway/static/root/assets/{work-discovery-overlay-BAtG_JHv.js → work-discovery-overlay-DmZXLs1v.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cw12NFgx.js → workflow-run-setup-panel-BdLOzHm4.js} +1 -1
  82. package/dist/gateway/static/root/assets/{workflows-page-kR5ouOuM.js → workflows-page-Cx3I3AV5.js} +1 -1
  83. package/dist/gateway/static/root/assets/{workspace-api-Xr3wz8T3.js → workspace-api-Du7-xJ0q.js} +2 -2
  84. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-BTBVKpSg.js → xopc-cloud-account-card-D8B136vW.js} +1 -1
  85. package/dist/gateway/static/root/index.html +12 -12
  86. package/dist/package.js +1 -1
  87. package/dist/packages/gateway-contract/src/index.js +2 -0
  88. package/dist/packages/gateway-contract/src/task-research-result.js +89 -0
  89. package/dist/packages/gateway-contract/src/tasks.js +7 -1
  90. package/dist/packages/gateway-contract/src/turn-outcome.js +3 -0
  91. package/dist/src/agent/child-agent-factory.d.ts +4 -1
  92. package/dist/src/agent/child-agent-factory.js +91 -11
  93. package/dist/src/agent/context/connection-objective-context.d.ts +1 -0
  94. package/dist/src/agent/context/connection-objective-context.js +33 -0
  95. package/dist/src/agent/data-acquisition/service.js +41 -6
  96. package/dist/src/agent/data-acquisition/types.d.ts +2 -0
  97. package/dist/src/agent/embedded/agent-profile-context.d.ts +7 -0
  98. package/dist/src/agent/embedded/agent-profile-context.js +92 -0
  99. package/dist/src/agent/embedded/execution-tool-policy.d.ts +1 -1
  100. package/dist/src/agent/embedded/execution-tool-policy.js +3 -2
  101. package/dist/src/agent/embedded/run-for-session.js +37 -14
  102. package/dist/src/agent/embedded/run-turn.js +123 -26
  103. package/dist/src/agent/embedded/runs.d.ts +9 -2
  104. package/dist/src/agent/embedded/runs.js +30 -7
  105. package/dist/src/agent/embedded/session-runner.js +14 -3
  106. package/dist/src/agent/embedded/types.d.ts +6 -1
  107. package/dist/src/agent/external-tools/cliProvider.d.ts +1 -0
  108. package/dist/src/agent/external-tools/cliProvider.js +1 -0
  109. package/dist/src/agent/external-tools/composio-provider.js +2 -0
  110. package/dist/src/agent/external-tools/gateway-tools.js +15 -5
  111. package/dist/src/agent/external-tools/service.d.ts +1 -0
  112. package/dist/src/agent/external-tools/service.js +3 -1
  113. package/dist/src/agent/external-tools/types.d.ts +4 -0
  114. package/dist/src/agent/orchestration/agent-run-supervisor.js +2 -1
  115. package/dist/src/agent/orchestration/agent-turn-policy.d.ts +1 -0
  116. package/dist/src/agent/orchestration/agent-turn-policy.js +5 -1
  117. package/dist/src/agent/orchestration/delegation-budget.d.ts +7 -1
  118. package/dist/src/agent/orchestration/delegation-budget.js +19 -10
  119. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
  120. package/dist/src/agent/orchestration/llm-turn-retry.js +15 -5
  121. package/dist/src/agent/orchestration/research-checkpoint.d.ts +56 -0
  122. package/dist/src/agent/orchestration/research-checkpoint.js +64 -0
  123. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +3 -1
  124. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +15 -2
  125. package/dist/src/agent/orchestration/run-termination.d.ts +12 -0
  126. package/dist/src/agent/orchestration/run-termination.js +24 -0
  127. package/dist/src/agent/orchestration/turn-recovery.d.ts +9 -0
  128. package/dist/src/agent/orchestration/turn-recovery.js +45 -0
  129. package/dist/src/agent/prompt/sections/agent-identity.js +12 -7
  130. package/dist/src/agent/prompt/sections/messaging-runtime.js +1 -1
  131. package/dist/src/agent/prompt/sections/project-context.js +1 -1
  132. package/dist/src/agent/prompt/sections/response-language.d.ts +1 -1
  133. package/dist/src/agent/prompt/sections/response-language.js +6 -2
  134. package/dist/src/agent/prompt/subagent-context.js +1 -1
  135. package/dist/src/agent/prompt/system-prompt.js +4 -6
  136. package/dist/src/agent/service/direct-turn-helpers.js +6 -5
  137. package/dist/src/agent/service/process-direct-streaming.js +7 -1
  138. package/dist/src/agent/tasks/task-judge-service.js +30 -10
  139. package/dist/src/agent/tools/apply-patch.js +1 -1
  140. package/dist/src/agent/tools/delegate-tool.js +216 -121
  141. package/dist/src/agent/tools/delegation-policy.js +13 -1
  142. package/dist/src/agent/tools/factory.js +12 -1
  143. package/dist/src/agent/tools/index.d.ts +2 -0
  144. package/dist/src/agent/tools/index.js +3 -1
  145. package/dist/src/agent/tools/language-diagnostics.js +1 -1
  146. package/dist/src/agent/tools/personal-request-result-tool.js +20 -3
  147. package/dist/src/agent/tools/personal-request-tool.js +165 -23
  148. package/dist/src/agent/tools/personal-task-tool.d.ts +6 -3
  149. package/dist/src/agent/tools/personal-task-tool.js +146 -23
  150. package/dist/src/agent/tools/publish-artifacts.js +1 -1
  151. package/dist/src/agent/tools/research-checkpoint-tool.d.ts +3 -0
  152. package/dist/src/agent/tools/research-checkpoint-tool.js +28 -0
  153. package/dist/src/agent/tools/review-workspace.js +1 -1
  154. package/dist/src/agent/tools/search/cache.d.ts +20 -0
  155. package/dist/src/agent/tools/search/cache.js +19 -0
  156. package/dist/src/agent/tools/search/errors.d.ts +19 -0
  157. package/dist/src/agent/tools/search/errors.js +69 -0
  158. package/dist/src/agent/tools/search/providers/bing-api.js +2 -1
  159. package/dist/src/agent/tools/search/providers/bing-html.js +2 -1
  160. package/dist/src/agent/tools/search/providers/brave.js +2 -1
  161. package/dist/src/agent/tools/search/providers/duckduckgo-html.js +2 -1
  162. package/dist/src/agent/tools/search/providers/searxng.js +2 -1
  163. package/dist/src/agent/tools/search/providers/tavily.js +2 -1
  164. package/dist/src/agent/tools/search/providers/xopc-cloud.d.ts +1 -0
  165. package/dist/src/agent/tools/search/providers/xopc-cloud.js +7 -2
  166. package/dist/src/agent/tools/search/registry.d.ts +21 -5
  167. package/dist/src/agent/tools/search/registry.js +252 -25
  168. package/dist/src/agent/tools/search/types.d.ts +25 -0
  169. package/dist/src/agent/tools/task-collaboration-tool.d.ts +16 -0
  170. package/dist/src/agent/tools/task-collaboration-tool.js +153 -0
  171. package/dist/src/agent/tools/task-result-tool.d.ts +2 -0
  172. package/dist/src/agent/tools/task-result-tool.js +73 -0
  173. package/dist/src/agent/tools/web.d.ts +16 -2
  174. package/dist/src/agent/tools/web.js +74 -29
  175. package/dist/src/agent/tools/xopc-use-tool.js +3 -3
  176. package/dist/src/automations/capabilities/write.d.ts +4 -4
  177. package/dist/src/automations/domain/validation.d.ts +8 -8
  178. package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
  179. package/dist/src/browser/automations/schema.d.ts +2 -2
  180. package/dist/src/browser/automations/service.d.ts +2 -2
  181. package/dist/src/cli/commands/channels.js +1 -1
  182. package/dist/src/cli/commands/connectors.js +1 -1
  183. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  184. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  185. package/dist/src/cli/commands/models.js +1 -1
  186. package/dist/src/cli/commands/onboard.js +1 -1
  187. package/dist/src/config/index.js +2 -2
  188. package/dist/src/config/schema.d.ts +1 -0
  189. package/dist/src/config/schema.js +4 -1
  190. package/dist/src/connectors/connection-recovery-service.d.ts +9 -1
  191. package/dist/src/connectors/connection-recovery-service.js +213 -33
  192. package/dist/src/discussions/action-tasks.d.ts +2 -2
  193. package/dist/src/extensions/sdk/index.js +1 -1
  194. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  195. package/dist/src/gateway/hono/routes/connection-waits.js +3 -1
  196. package/dist/src/gateway/hono/routes/projects.js +1 -1
  197. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +16 -0
  198. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  199. package/dist/src/gateway/service/agent-runner.d.ts +2 -0
  200. package/dist/src/gateway/service/agent-runner.js +30 -17
  201. package/dist/src/gateway/service/run-gateway-agent.js +21 -6
  202. package/dist/src/gateway/service/session-input-coordinator.d.ts +10 -1
  203. package/dist/src/gateway/service/session-input-coordinator.js +216 -27
  204. package/dist/src/gateway/service.d.ts +1 -0
  205. package/dist/src/gateway/service.js +6 -4
  206. package/dist/src/gateway/session-context-summary.js +1 -1
  207. package/dist/src/personal-agent/prompts.js +10 -3
  208. package/dist/src/personal-agent/reply-composer.d.ts +1 -0
  209. package/dist/src/personal-agent/reply-composer.js +91 -19
  210. package/dist/src/personal-agent/reply-style.d.ts +1 -1
  211. package/dist/src/personal-agent/reply-style.js +1 -0
  212. package/dist/src/personal-agent/repository.d.ts +1 -1
  213. package/dist/src/personal-agent/repository.js +1 -1
  214. package/dist/src/personal-agent/request-access.d.ts +3 -0
  215. package/dist/src/personal-agent/request-access.js +31 -0
  216. package/dist/src/personal-agent/request-delivery.js +9 -4
  217. package/dist/src/personal-agent/request-repository.d.ts +3 -0
  218. package/dist/src/personal-agent/request-service.d.ts +6 -0
  219. package/dist/src/personal-agent/request-service.js +121 -25
  220. package/dist/src/personal-agent/result-file-links.d.ts +3 -0
  221. package/dist/src/personal-agent/result-file-links.js +21 -0
  222. package/dist/src/personal-agent/task-cancel.js +85 -35
  223. package/dist/src/providers/model-response.js +13 -2
  224. package/dist/src/scenes/taskFollowUp/service.d.ts +15 -5
  225. package/dist/src/session/session-context-for-llm.js +2 -2
  226. package/dist/src/session/store.d.ts +3 -1
  227. package/dist/src/session/store.js +30 -7
  228. package/dist/src/storage/sqlite/connection-wait-repository.d.ts +7 -2
  229. package/dist/src/storage/sqlite/connection-wait-repository.js +124 -20
  230. package/dist/src/storage/sqlite/index.d.ts +1 -0
  231. package/dist/src/storage/sqlite/index.js +3 -1
  232. package/dist/src/storage/sqlite/migrations/250_research_checkpoints.sql +15 -0
  233. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  234. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  235. package/dist/src/storage/sqlite/research-checkpoint-repository.d.ts +24 -0
  236. package/dist/src/storage/sqlite/research-checkpoint-repository.js +91 -0
  237. package/dist/src/storage/sqlite/schema.js +1 -1
  238. package/dist/src/storage/sqlite/session-creation-repository.js +3 -2
  239. package/dist/src/storage/sqlite/session-input-repository.d.ts +16 -0
  240. package/dist/src/storage/sqlite/session-input-repository.js +41 -7
  241. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -0
  242. package/dist/src/storage/sqlite/transcript-repository.js +25 -1
  243. package/dist/src/tasks/capabilities/management.d.ts +2 -2
  244. package/dist/src/tasks/capabilities/relations.d.ts +7 -7
  245. package/dist/src/tasks/capabilities/write.d.ts +2 -2
  246. package/dist/src/tasks/index.js +1 -1
  247. package/dist/src/tasks/task-allocation-service.d.ts +2 -0
  248. package/dist/src/tasks/task-allocation-service.js +43 -2
  249. package/dist/src/tasks/task-application-service.js +3 -3
  250. package/dist/src/tasks/task-collaboration-delivery.js +4 -1
  251. package/dist/src/tasks/task-collaboration-repository.d.ts +3 -0
  252. package/dist/src/tasks/task-collaboration-repository.js +11 -1
  253. package/dist/src/tasks/task-context-assembler.js +19 -6
  254. package/dist/src/tasks/task-continuation.d.ts +6 -0
  255. package/dist/src/tasks/task-continuation.js +33 -0
  256. package/dist/src/tasks/task-contract-planner.d.ts +1 -0
  257. package/dist/src/tasks/task-contract-planner.js +22 -15
  258. package/dist/src/tasks/task-main-update-delivery.js +13 -8
  259. package/dist/src/tasks/task-model-call.d.ts +7 -0
  260. package/dist/src/tasks/task-model-call.js +35 -0
  261. package/dist/src/tasks/task-read-model-projector.js +1 -1
  262. package/dist/src/tasks/task-research-repair.d.ts +19 -0
  263. package/dist/src/tasks/task-research-repair.js +75 -0
  264. package/dist/src/tasks/task-research-result.d.ts +85 -0
  265. package/dist/src/tasks/task-research-result.js +394 -0
  266. package/dist/src/tasks/task-result-delivery-repository.js +13 -2
  267. package/dist/src/tasks/task-result-delivery-service.js +1 -1
  268. package/dist/src/tasks/task-run-coordinator.d.ts +1 -0
  269. package/dist/src/tasks/task-run-coordinator.js +80 -11
  270. package/dist/src/tasks/task-run-dispatcher.js +12 -0
  271. package/dist/src/tasks/task-run-repository.d.ts +13 -0
  272. package/dist/src/tasks/task-run-repository.js +120 -2
  273. package/package.json +7 -3
  274. package/dist/gateway/static/root/assets/constants-Dy8Gw0sF.js +0 -1
  275. package/dist/gateway/static/root/assets/index-yseLAt9D.css +0 -1
  276. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-C4VzqE9z.js +0 -1
  277. package/dist/gateway/static/root/assets/session-manager-_yy4bxhT.js +0 -16
  278. package/dist/gateway/static/root/assets/settings-advanced-gate-O_0Lk38S.js +0 -1
  279. package/dist/gateway/static/root/assets/task-detail-page-88EShcbs.js +0 -2
  280. package/dist/gateway/static/root/assets/task-expandable-content-CF6Bj-Qa.js +0 -1
@@ -14,6 +14,8 @@ import type { AgentSourceContext, TurnContextRef } from '../../agent/source-cont
14
14
  import { SessionInputCoordinator, type ReplaceLatestTurnInput, type SubmitSessionInput } from './session-input-coordinator.js';
15
15
  export interface GatewayAgentRunnerOptions {
16
16
  validateConnectionResume?: (input: import('../../storage/sqlite/session-input-repository.js').SessionInput) => Promise<boolean>;
17
+ continueConnection?: (wait: import('@xopcai/gateway-contract').ConnectionWait, idempotencyKey: string) => Promise<void>;
18
+ cancelConnection?: (wait: import('@xopcai/gateway-contract').ConnectionWait) => void;
17
19
  bus: MessageBus;
18
20
  sessionIndex: SessionIndex;
19
21
  /** Resolved lazily — the runner is constructed before AgentService exists. */
@@ -6,9 +6,11 @@ import { TaskRepository, init_task_repository } from "../../tasks/task-repositor
6
6
  import { createClarificationWait, getClarification, getClarificationSnapshot, init_clarification_wait_repository, resolveClarification, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
7
7
  import { init_connection_wait_repository, onConnectionWaitChanged } from "../../storage/sqlite/connection-wait-repository.js";
8
8
  import { init_sqlite } from "../../storage/sqlite/index.js";
9
+ import { AgentRunCancelledError } from "../../agent/orchestration/run-termination.js";
9
10
  import { isPersonalConversation } from "../../personal-agent/repository.js";
10
11
  import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
11
12
  import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
13
+ import { reserveEmbeddedRunCancellation } from "../../agent/embedded/runs.js";
12
14
  import { TaskApplicationService } from "../../tasks/task-application-service.js";
13
15
  import { EphemeralClarificationWaiter } from "../ephemeral-clarification-waiter.js";
14
16
  import { describeActiveExecution } from "./active-execution.js";
@@ -65,10 +67,12 @@ var GatewayAgentRunner = class {
65
67
  });
66
68
  this.inputs = new SessionInputCoordinator({
67
69
  beforeExecute: opts.validateConnectionResume,
70
+ continueConnection: opts.continueConnection,
71
+ cancelConnection: opts.cancelConnection,
68
72
  prioritizeInput: (input) => (input.origin.type !== "system" || input.origin.source === "cli") && isPersonalConversation(input.conversationId),
69
- interrupt: async (conversationId, runId) => {
73
+ interrupt: async (conversationId, runId, reason) => {
70
74
  const execution = this.activeExecutionBySession.get(conversationId);
71
- if (execution && execution.kind !== "chat") return;
75
+ if (reason !== "connection_cancel" && execution && execution.kind !== "chat") return;
72
76
  await this.abortAgentRun(runId);
73
77
  },
74
78
  sessionExists: async (conversationId) => Boolean(await opts.sessionIndex.getSessionMetadata(conversationId)),
@@ -187,29 +191,38 @@ var GatewayAgentRunner = class {
187
191
  }
188
192
  async *runAgent(message, channel, chatId, origin, attachments, thinking, runOptions) {
189
193
  const trackedRunId = runOptions?.runId;
194
+ const cancellation = channel === "webchat" && trackedRunId ? reserveEmbeddedRunCancellation({
195
+ conversationId: chatId,
196
+ runId: trackedRunId
197
+ }) : void 0;
190
198
  if (trackedRunId) {
199
+ if (channel === "webchat" && !this.runAbortControllers.has(trackedRunId)) this.runAbortControllers.set(trackedRunId, new AbortController());
191
200
  let resolve = () => {};
192
201
  this.runCompletions.set(trackedRunId, new Promise((done) => {
193
202
  resolve = done;
194
203
  }));
195
204
  this.resolveRunCompletions.set(trackedRunId, resolve);
196
205
  }
197
- const iter = runGatewayAgent({
198
- config: this.opts.getConfig(),
199
- agentService: this.opts.getAgentService(),
200
- bus: this.opts.bus,
201
- runAbortControllers: this.runAbortControllers,
202
- activeWebchatRunBySession: this.activeWebchatRunBySession,
203
- activeExecutionBySession: this.activeExecutionBySession,
204
- sessionIndex: this.opts.sessionIndex,
205
- emit: this.opts.emit,
206
- publishRealtime: this.opts.publishRealtime,
207
- completeRealtimeTopic: this.opts.completeRealtimeTopic
208
- }, message, channel, chatId, origin, attachments, thinking, runOptions);
209
206
  try {
210
- return yield* iter;
207
+ return yield* runGatewayAgent({
208
+ config: this.opts.getConfig(),
209
+ agentService: this.opts.getAgentService(),
210
+ bus: this.opts.bus,
211
+ runAbortControllers: this.runAbortControllers,
212
+ activeWebchatRunBySession: this.activeWebchatRunBySession,
213
+ activeExecutionBySession: this.activeExecutionBySession,
214
+ sessionIndex: this.opts.sessionIndex,
215
+ emit: this.opts.emit,
216
+ publishRealtime: this.opts.publishRealtime,
217
+ completeRealtimeTopic: this.opts.completeRealtimeTopic
218
+ }, message, channel, chatId, origin, attachments, thinking, cancellation ? {
219
+ ...runOptions,
220
+ signal: runOptions?.signal ? AbortSignal.any([runOptions.signal, cancellation.signal]) : cancellation.signal
221
+ } : runOptions);
211
222
  } finally {
223
+ cancellation?.release();
212
224
  if (trackedRunId) {
225
+ this.runAbortControllers.delete(trackedRunId);
213
226
  this.resolveRunCompletions.get(trackedRunId)?.();
214
227
  this.resolveRunCompletions.delete(trackedRunId);
215
228
  this.runCompletions.delete(trackedRunId);
@@ -258,9 +271,9 @@ var GatewayAgentRunner = class {
258
271
  data: { runId }
259
272
  }).catch(() => {});
260
273
  }
261
- c.abort();
274
+ c.abort(new AgentRunCancelledError());
262
275
  const { abortEmbeddedRun } = await import("../../agent/embedded/runs.js");
263
- await Promise.all(keysToMark.map((conversationId) => abortEmbeddedRun(conversationId).catch(() => false)));
276
+ await Promise.all(keysToMark.map((conversationId) => abortEmbeddedRun(conversationId, "user_cancelled", runId).catch(() => false)));
264
277
  await completion;
265
278
  return {
266
279
  aborted: true,
@@ -4,12 +4,14 @@ import { init_logger } from "../../utils/logger.js";
4
4
  import { parseTurnOutcome } from "../../../packages/gateway-contract/src/turn-outcome.js";
5
5
  import { init_src } from "../../../packages/gateway-contract/src/index.js";
6
6
  import { init_session_input_repository, listTaskUpdateTriggers } from "../../storage/sqlite/session-input-repository.js";
7
+ import { TaskRunRepository, init_task_run_repository } from "../../tasks/task-run-repository.js";
7
8
  import { init_clarification_wait_repository, isClarificationSuspended } from "../../storage/sqlite/clarification-wait-repository.js";
8
9
  import { updateInteractionStateFromMessage } from "../../storage/sqlite/interaction-state-repository.js";
9
10
  import { getConnectionResumeInput, init_connection_wait_repository, isConnectionSuspended } from "../../storage/sqlite/connection-wait-repository.js";
10
11
  import { init_sqlite } from "../../storage/sqlite/index.js";
11
12
  import { getConversationRouting } from "../../storage/sqlite/conversation-repository.js";
12
13
  import { init_session_key } from "../../routing/session-key.js";
14
+ import { resolveAgentTurnTimeoutMs } from "../../agent/orchestration/run-agent-turn-with-timeout.js";
13
15
  import { isPersonalConversation } from "../../personal-agent/repository.js";
14
16
  import { resolveExecutionContext } from "../../tasks/execution-context.js";
15
17
  import { TaskRunCoordinator } from "../../tasks/task-run-coordinator.js";
@@ -29,6 +31,7 @@ init_clarification_wait_repository();
29
31
  init_src();
30
32
  init_logger();
31
33
  init_session_key();
34
+ init_task_run_repository();
32
35
  init_sqlite();
33
36
  init_session_input_repository();
34
37
  const log = createLogger("Gateway:Service");
@@ -64,7 +67,15 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
64
67
  if (!meta) throw new Error("Session not found; submit a start input command first");
65
68
  webchatTranscriptId = meta?.transcriptId;
66
69
  webchatMetadata = meta;
67
- runAbortControllers.set(runId, new AbortController());
70
+ if (!runAbortControllers.has(runId)) runAbortControllers.set(runId, new AbortController());
71
+ if (runAbortControllers.get(runId).signal.aborted || runOptions?.signal?.aborted || runOptions?.taskRunId && new TaskRunRepository().get(runOptions.taskRunId)?.status === "cancelled") {
72
+ runAbortControllers.delete(runId);
73
+ completeRealtimeTopic(`run:${runId}`);
74
+ return {
75
+ status: "aborted",
76
+ summary: "Interrupted before startup"
77
+ };
78
+ }
68
79
  }
69
80
  const streamConversationId = webchatConversationId ?? chatId;
70
81
  if (webchatConversationId) {
@@ -89,7 +100,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
89
100
  taskRun = TaskRunCoordinator.start({
90
101
  runId: runOptions?.taskRunId ?? runId,
91
102
  context: executionContext,
92
- fallbackObjective: message
103
+ fallbackObjective: message,
104
+ timeoutMs: executionContext.taskId ? resolveAgentTurnTimeoutMs(deps.config, webchatConversationId) : void 0
93
105
  });
94
106
  }
95
107
  const mapper = new ChatStreamMapper({
@@ -156,6 +168,7 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
156
168
  const prepared = await agentService.prepareInboundAttachments(conversationId, cappedAttachments);
157
169
  const runAbort = runAbortControllers.get(runId);
158
170
  if (!runAbort) throw new Error("run abort controller missing for webchat");
171
+ if (runOptions?.taskRunId && new TaskRunRepository().get(runOptions.taskRunId)?.status === "cancelled") runAbort.abort();
159
172
  const mergedSignal = runOptions?.signal ? AbortSignal.any([runOptions.signal, runAbort.signal]) : runAbort.signal;
160
173
  agentService.beginInboundTurn(conversationId);
161
174
  if (!activeWebchatRunBySession.has(conversationId)) {
@@ -192,6 +205,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
192
205
  });
193
206
  const mappedEvents = (async function* () {
194
207
  for await (const event of eventStream) {
208
+ if (event.type === "error") streamError ??= String(event.content ?? event.message ?? "Agent run failed");
209
+ if (event.type === "turn_outcome" && parseTurnOutcome(event.outcome)?.status === "failed") streamError = parseTurnOutcome(event.outcome)?.summary ?? streamError ?? "Agent run failed";
195
210
  if (event.type === "turn_outcome" && parseTurnOutcome(event.outcome)?.summary === "aborted") embeddedAborted = true;
196
211
  yield* mapper.map(event);
197
212
  }
@@ -201,16 +216,16 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
201
216
  const clarificationSuspended = isClarificationSuspended(conversationId, runId);
202
217
  const suspended = connectionSuspended || clarificationSuspended;
203
218
  const cancelled = mergedSignal.aborted || embeddedAborted;
204
- const endStatus = cancelled ? "cancelled" : suspended ? "suspended" : "success";
205
- const endSummary = cancelled ? "Interrupted" : connectionSuspended ? "Waiting for connection" : clarificationSuspended ? "Waiting for user input" : "Message processed successfully";
206
- taskRunStatus = cancelled ? "cancelled" : "succeeded";
219
+ const endStatus = cancelled ? "cancelled" : suspended ? "suspended" : streamError ? "error" : "success";
220
+ const endSummary = cancelled ? "Interrupted" : connectionSuspended ? "Waiting for connection" : clarificationSuspended ? "Waiting for user input" : streamError ?? "Message processed successfully";
221
+ taskRunStatus = cancelled ? "cancelled" : streamError ? "failed" : "succeeded";
207
222
  terminalStatus = endStatus;
208
223
  taskRunSummary = endSummary;
209
224
  yield* emitAndYield(mapper.end(endStatus, endSummary));
210
225
  completeRealtimeTopic(`run:${runId}`);
211
226
  runTopicCompleted = true;
212
227
  return {
213
- status: cancelled ? "aborted" : suspended ? "suspended" : "ok",
228
+ status: cancelled ? "aborted" : suspended ? "suspended" : streamError ? "error" : "ok",
214
229
  summary: endSummary
215
230
  };
216
231
  } catch (error) {
@@ -1,4 +1,5 @@
1
1
  import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
+ import type { ConnectionWait } from '@xopcai/gateway-contract';
2
3
  import { type SessionInput } from '../../storage/sqlite/session-input-repository.js';
3
4
  import type { UserTurnAttachment } from '../user-turn-input.js';
4
5
  import { type AgentSourceContext, type TurnContextRef } from '../../agent/source-context/types.js';
@@ -26,12 +27,15 @@ export declare class SessionInputCoordinator {
26
27
  private readonly resumeAfter;
27
28
  private readonly draining;
28
29
  private readonly submissionTails;
30
+ private readonly pendingConnectionStops;
29
31
  constructor(deps: {
30
32
  prioritizeInput?: (input: SubmitSessionInput) => boolean;
31
- interrupt?: (conversationId: string, runId: string) => Promise<void>;
33
+ interrupt?: (conversationId: string, runId: string, reason?: 'connection_cancel') => Promise<void>;
32
34
  coalesceWindowMs?: number;
33
35
  onInputReceived?: (conversationId: string) => void;
34
36
  beforeExecute?: (input: SessionInput) => Promise<boolean>;
37
+ continueConnection?: (wait: ConnectionWait, idempotencyKey: string) => Promise<void>;
38
+ cancelConnection?: (wait: ConnectionWait) => void;
35
39
  sessionExists: (conversationId: string) => Promise<boolean>;
36
40
  execute: (input: {
37
41
  inputReceivedAtMs?: number;
@@ -54,7 +58,9 @@ export declare class SessionInputCoordinator {
54
58
  });
55
59
  isAcceptingInput(conversationId: string): boolean;
56
60
  snapshot(conversationId: string): SessionInputState;
61
+ private connectionTarget;
57
62
  prepareInput(input: SubmitSessionInput): Promise<{
63
+ payload?: import("../../storage/sqlite/session-input-repository.js").SessionInputPayload;
58
64
  status: "queued";
59
65
  requestedDelivery: SessionInputDelivery;
60
66
  effectiveDelivery: "next";
@@ -98,6 +104,9 @@ export declare class SessionInputCoordinator {
98
104
  }>;
99
105
  private submitLocked;
100
106
  drain(conversationId: string): Promise<void>;
107
+ private requestConnectionStop;
108
+ private completeConnectionCancellation;
109
+ private executeConnectionControl;
101
110
  update(conversationId: string, id: string, body: {
102
111
  version: number;
103
112
  content?: string;
@@ -1,10 +1,16 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
4
+ import { init_session_instance_repository, readCurrentTranscriptId } from "../../storage/sqlite/session-instance-repository.js";
3
5
  import { SessionInstanceChangedError, cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, findSessionInputByRunId, finishSessionInputRun, getSessionInputById, getSessionInputState, init_session_input_repository, insertSessionInput, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus } from "../../storage/sqlite/session-input-repository.js";
4
- import { consumeClarificationResume, init_clarification_wait_repository, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
6
+ import { TaskRunRepository, init_task_run_repository } from "../../tasks/task-run-repository.js";
7
+ import { consumeClarificationResume, getActiveClarification, init_clarification_wait_repository, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
5
8
  import { replaceLatestSessionTurnAndQueueInput, validateLatestSessionTurnTarget } from "../../storage/sqlite/session-turn-replace-repository.js";
6
- import { cancelConnectionObjective, consumeConnectionResume, init_connection_wait_repository, invalidateConnectionResumeIntent, publishConnectionWait } from "../../storage/sqlite/connection-wait-repository.js";
9
+ import { cancelConnectionObjective, consumeConnectionResume, getActiveConnectionWait, getConnectionWait, hasPendingConnectionMessages, init_connection_wait_repository, interruptedConnectionMessage, publishConnectionWait, reconcileConnectionWaits } from "../../storage/sqlite/connection-wait-repository.js";
10
+ import { appendTranscriptEntry, init_transcript_repository } from "../../storage/sqlite/transcript-repository.js";
7
11
  import { init_sqlite } from "../../storage/sqlite/index.js";
12
+ import { emitSessionTranscriptUpdate } from "../../session/transcript-events.js";
13
+ import { TaskApplicationService } from "../../tasks/task-application-service.js";
8
14
  import { summarizeSourceContext } from "../../agent/source-context/types.js";
9
15
  import { injectSourceContextsIntoUserMessage } from "../../agent/source-context/injector.js";
10
16
  import { deleteMediaUrisNoLongerReferenced } from "../../media/session-references.js";
@@ -14,11 +20,37 @@ import { isDeepStrictEqual } from "node:util";
14
20
  //#region src/gateway/service/session-input-coordinator.ts
15
21
  init_session_input_repository();
16
22
  init_connection_wait_repository();
23
+ init_transaction();
24
+ init_transcript_repository();
25
+ init_session_instance_repository();
17
26
  init_clarification_wait_repository();
18
27
  init_sqlite();
19
28
  init_logger();
29
+ init_task_run_repository();
20
30
  const log = createLogger("SessionInputCoordinator");
21
31
  const MAX_PENDING_INPUTS = 10;
32
+ function connectionControl(input, wait) {
33
+ if (input.attachments?.length || input.contextRefs?.length || input.sourceContexts?.some((source) => source.kind !== "device_context") || input.origin.type === "system" && input.origin.source !== "cli") return void 0;
34
+ const text = input.content.trim().toLowerCase().replace(/[。.!!??]+$/u, "").trim();
35
+ if (/^(?:继续|继续看下|继续看看|继续这个目标|继续原目标|continue|resume)$/u.test(text)) {
36
+ if (text !== "继续原目标" && (hasPendingConnectionMessages(wait) || getActiveClarification(wait.conversationId))) return void 0;
37
+ return "continue";
38
+ }
39
+ if (/^(?:取消这个目标|取消原目标|取消当前目标|cancel this objective|cancel the original objective)$/u.test(text)) return "cancel";
40
+ }
41
+ function connectionInputPayload(wait, control) {
42
+ if (!wait) return void 0;
43
+ if (control) return {
44
+ waitId: wait.id,
45
+ objectiveRevision: wait.objectiveRevision,
46
+ connectionAction: control
47
+ };
48
+ if (wait.status !== "closed") return {
49
+ waitId: wait.id,
50
+ objectiveRevision: wait.objectiveRevision,
51
+ connectionBarrier: true
52
+ };
53
+ }
22
54
  function sameAppContext(input, existing) {
23
55
  const identity = (sources) => sources?.filter((source) => source.kind === "app_context").map((source) => ({
24
56
  snapshot: source.appContext,
@@ -52,6 +84,7 @@ var SessionInputCoordinator = class {
52
84
  resumeAfter = /* @__PURE__ */ new Map();
53
85
  draining = /* @__PURE__ */ new Set();
54
86
  submissionTails = /* @__PURE__ */ new Map();
87
+ pendingConnectionStops = /* @__PURE__ */ new Set();
55
88
  constructor(deps) {
56
89
  this.deps = deps;
57
90
  }
@@ -61,9 +94,15 @@ var SessionInputCoordinator = class {
61
94
  snapshot(conversationId) {
62
95
  return getSessionInputState(conversationId);
63
96
  }
97
+ connectionTarget(conversationId, runtime = this.snapshot(conversationId)) {
98
+ const active = runtime.activeInputId ? getSessionInputById(conversationId, runtime.activeInputId) : void 0;
99
+ return getActiveConnectionWait(conversationId) ?? (active?.kind === "connection_resume" && active.payload ? getConnectionWait(active.payload.waitId) : void 0);
100
+ }
64
101
  async prepareInput(input) {
65
102
  const attachments = await this.deps.prepareAttachments(input.conversationId, input.attachments);
66
103
  const contexts = fitSourceContextsToBudget([...await this.deps.prepareContexts(input.conversationId, input.contextRefs) ?? [], ...input.sourceContexts ?? []]);
104
+ const wait = this.connectionTarget(input.conversationId);
105
+ const payload = connectionInputPayload(wait, wait?.principalId === "local-owner" ? connectionControl(input, wait) : void 0);
67
106
  return {
68
107
  status: "queued",
69
108
  requestedDelivery: input.delivery,
@@ -71,10 +110,11 @@ var SessionInputCoordinator = class {
71
110
  content: input.content.trim(),
72
111
  attachments,
73
112
  contextRefs: contexts.map(summarizeSourceContext),
74
- interruptRequested: input.interrupt !== false && this.deps.prioritizeInput?.(input) === true,
113
+ interruptRequested: !wait && input.interrupt !== false && this.deps.prioritizeInput?.(input) === true,
75
114
  contextSnapshots: contexts,
76
115
  thinking: input.thinking,
77
- origin: input.origin
116
+ origin: input.origin,
117
+ ...payload ? { payload } : {}
78
118
  };
79
119
  }
80
120
  async dispatchAcceptedInput(conversationId, inputId) {
@@ -84,6 +124,11 @@ var SessionInputCoordinator = class {
84
124
  const row = getSessionInputById(conversationId, inputId);
85
125
  const state = this.snapshot(input.conversationId);
86
126
  if (!row || row.status !== "queued") return;
127
+ if (row.payload?.connectionAction === "cancel") this.completeConnectionCancellation(row);
128
+ if (row.payload?.connectionAction || this.connectionTarget(row.conversationId, state)) {
129
+ this.requestConnectionStop(row);
130
+ return;
131
+ }
87
132
  if (row.interruptRequested) {
88
133
  this.prioritizeAcceptedInput(row, state);
89
134
  return;
@@ -158,6 +203,7 @@ var SessionInputCoordinator = class {
158
203
  const remaining = (this.pendingSubmissions.get(conversationId) ?? 1) - 1;
159
204
  if (remaining) this.pendingSubmissions.set(conversationId, remaining);
160
205
  else this.pendingSubmissions.delete(conversationId);
206
+ this.drain(conversationId);
161
207
  }
162
208
  }
163
209
  async submit(input) {
@@ -303,27 +349,36 @@ var SessionInputCoordinator = class {
303
349
  };
304
350
  }
305
351
  const runtime = this.snapshot(conversationId);
306
- const priority = input.interrupt !== false && this.deps.prioritizeInput?.(input) === true;
307
- const canSteer = !priority && input.delivery === "steer" && runtime.activeRunId !== void 0 && !attachments?.length && canSteerContexts(runtime, input.origin, sourceContexts);
352
+ const wait = this.connectionTarget(conversationId, runtime);
353
+ const control = wait?.principalId === "local-owner" ? connectionControl(input, wait) : void 0;
354
+ const payload = connectionInputPayload(wait, control);
355
+ const priority = !wait && input.interrupt !== false && this.deps.prioritizeInput?.(input) === true;
356
+ const canSteer = !wait && !priority && input.delivery === "steer" && runtime.activeRunId !== void 0 && !attachments?.length && canSteerContexts(runtime, input.origin, sourceContexts);
308
357
  const effectiveDelivery = canSteer ? "steer" : "next";
309
- const row = insertSessionInput({
310
- expectedTranscriptId: input.expectedTranscriptId,
311
- id: crypto.randomUUID(),
312
- conversationId,
313
- clientMessageId,
314
- requestedDelivery: input.delivery,
315
- interruptRequested: priority,
316
- effectiveDelivery,
317
- status: canSteer ? "injecting" : "queued",
318
- content,
319
- attachments,
320
- contextRefs: sourceContexts?.map(summarizeSourceContext),
321
- contextSnapshots: sourceContexts,
322
- thinking: input.thinking,
323
- origin: input.origin,
324
- targetRunId: canSteer ? runtime.activeRunId : void 0
358
+ const row = runSqliteWriteTransaction(() => {
359
+ const row = insertSessionInput({
360
+ expectedTranscriptId: input.expectedTranscriptId ?? (payload ? wait?.transcriptId : void 0),
361
+ id: crypto.randomUUID(),
362
+ conversationId,
363
+ clientMessageId,
364
+ requestedDelivery: input.delivery,
365
+ interruptRequested: priority,
366
+ effectiveDelivery,
367
+ status: canSteer ? "injecting" : "queued",
368
+ content,
369
+ attachments,
370
+ contextRefs: sourceContexts?.map(summarizeSourceContext),
371
+ contextSnapshots: sourceContexts,
372
+ thinking: input.thinking,
373
+ origin: input.origin,
374
+ targetRunId: canSteer ? runtime.activeRunId : void 0,
375
+ ...payload ? { payload } : {}
376
+ });
377
+ if (control === "cancel") cancelConnectionObjective(conversationId, wait?.id, wait?.objectiveRevision);
378
+ return row;
325
379
  });
326
- invalidateConnectionResumeIntent(conversationId);
380
+ if (control === "cancel") this.completeConnectionCancellation(row);
381
+ this.requestConnectionStop(row);
327
382
  supersedeActiveClarification(conversationId);
328
383
  if (priority) {
329
384
  this.prioritizeAcceptedInput(row, runtime);
@@ -364,6 +419,7 @@ var SessionInputCoordinator = class {
364
419
  this.draining.add(conversationId);
365
420
  try {
366
421
  while (true) {
422
+ if (this.isAcceptingInput(conversationId)) return;
367
423
  const delay = (this.resumeAfter.get(conversationId) ?? 0) - Date.now();
368
424
  if (delay > 0) {
369
425
  await new Promise((resolve) => setTimeout(resolve, delay));
@@ -375,7 +431,15 @@ var SessionInputCoordinator = class {
375
431
  if (!input) return;
376
432
  let allowed;
377
433
  try {
378
- allowed = (!this.deps.beforeExecute || await this.deps.beforeExecute(input)) && consumeConnectionResume(input) && consumeClarificationResume(input);
434
+ allowed = !this.deps.beforeExecute || await this.deps.beforeExecute(input);
435
+ const wait = input.kind === "connection_resume" && input.payload ? getConnectionWait(input.payload.waitId) : void 0;
436
+ if (allowed && wait?.status === "queued" && wait.queuedInputId === input.id && (this.isAcceptingInput(conversationId) || hasPendingConnectionMessages(wait, true))) {
437
+ finishSessionInputRun(conversationId, runId, "interrupted");
438
+ setSessionInputStatus(input.id, "queued");
439
+ this.publish(conversationId);
440
+ continue;
441
+ }
442
+ allowed = allowed && consumeConnectionResume(input) && consumeClarificationResume(input);
379
443
  } catch (err) {
380
444
  log.warn({
381
445
  err,
@@ -384,6 +448,7 @@ var SessionInputCoordinator = class {
384
448
  inputId: input.id
385
449
  }, "Session input preflight failed");
386
450
  finishSessionInputRun(conversationId, runId, "failed", "Input preflight failed");
451
+ if (input.kind === "connection_resume") reconcileConnectionWaits();
387
452
  this.publish(conversationId);
388
453
  continue;
389
454
  }
@@ -396,7 +461,7 @@ var SessionInputCoordinator = class {
396
461
  this.publish(conversationId);
397
462
  let result;
398
463
  try {
399
- result = await this.deps.execute({
464
+ result = input.payload?.connectionAction ? await this.executeConnectionControl(input) : await this.deps.execute({
400
465
  inputReceivedAtMs: input.createdAtMs,
401
466
  runId,
402
467
  taskRunId: input.taskRunId,
@@ -419,7 +484,37 @@ var SessionInputCoordinator = class {
419
484
  inputId: input.id
420
485
  }, "Session input execution failed");
421
486
  }
422
- const terminal = result.status === "suspended" ? "suspended" : result.status === "ok" ? "completed" : result.status === "aborted" ? "cancelled" : "failed";
487
+ const cancelledWait = input.kind === "connection_resume" && input.payload ? getConnectionWait(input.payload.waitId) : void 0;
488
+ const cancelled = cancelledWait?.resolution === "cancelled" && cancelledWait.objectiveRevision === input.payload?.objectiveRevision;
489
+ if (cancelled && input.taskRunId) {
490
+ const run = new TaskRunRepository().get(input.taskRunId);
491
+ if (run && [
492
+ "queued",
493
+ "running",
494
+ "waiting",
495
+ "verifying"
496
+ ].includes(run.status)) new TaskApplicationService().completeRun({
497
+ runId: run.id,
498
+ expectedRunVersion: run.version,
499
+ actor: { kind: "user" },
500
+ terminalCode: "cancelled_by_user",
501
+ suppressAttention: true,
502
+ receipt: {
503
+ status: "cancelled",
504
+ summary: "Connection objective cancelled",
505
+ changes: [],
506
+ evidence: [],
507
+ verification: {
508
+ status: "unverified",
509
+ checks: []
510
+ },
511
+ remainingWork: [],
512
+ needsUser: false,
513
+ completionVerdict: "not_achieved"
514
+ }
515
+ });
516
+ }
517
+ const terminal = cancelled ? "cancelled" : result.status === "suspended" ? "suspended" : result.status === "ok" ? "completed" : result.status === "aborted" ? "cancelled" : "failed";
423
518
  finishSessionInputRun(conversationId, runId, terminal, terminal === "failed" ? result.summary : void 0);
424
519
  this.publish(conversationId);
425
520
  }
@@ -427,6 +522,94 @@ var SessionInputCoordinator = class {
427
522
  this.draining.delete(conversationId);
428
523
  }
429
524
  }
525
+ requestConnectionStop(input) {
526
+ const target = input.payload;
527
+ if (target?.connectionAction !== "cancel" || !this.deps.interrupt) return;
528
+ const wait = getConnectionWait(target.waitId);
529
+ if (!wait || wait.resolution !== "cancelled" || wait.objectiveRevision !== target.objectiveRevision || wait.transcriptId !== input.expectedTranscriptId) return;
530
+ const runtime = this.snapshot(input.conversationId);
531
+ const active = runtime.activeInputId ? getSessionInputById(input.conversationId, runtime.activeInputId) : void 0;
532
+ if (!runtime.activeRunId || active?.kind !== "connection_resume" || !active.payload) return;
533
+ const sameVersion = active.payload.waitId === target.waitId && active.payload.objectiveRevision === target.objectiveRevision;
534
+ const parent = getConnectionWait(active.payload.waitId);
535
+ const sameExecution = wait.originInputId === active.id && parent?.objectiveId === wait.objectiveId;
536
+ if (!sameVersion && !sameExecution || this.pendingConnectionStops.has(runtime.activeRunId)) return;
537
+ const runId = runtime.activeRunId;
538
+ this.pendingConnectionStops.add(runId);
539
+ this.deps.emit("session.input-interrupt", {
540
+ conversationId: input.conversationId,
541
+ runId,
542
+ inputId: input.id
543
+ });
544
+ this.deps.interrupt(input.conversationId, runId, "connection_cancel").catch((err) => {
545
+ log.warn({
546
+ err,
547
+ conversationId: input.conversationId,
548
+ runId
549
+ }, "Connection cancellation saved; execution stop was not confirmed");
550
+ }).finally(() => {
551
+ this.pendingConnectionStops.delete(runId);
552
+ });
553
+ }
554
+ completeConnectionCancellation(input) {
555
+ const wait = input.payload ? getConnectionWait(input.payload.waitId) : void 0;
556
+ if (wait?.objectiveRevision !== input.payload?.objectiveRevision || wait?.resolution !== "cancelled") return;
557
+ try {
558
+ this.deps.cancelConnection?.(wait);
559
+ } catch (err) {
560
+ log.warn({
561
+ err,
562
+ conversationId: input.conversationId,
563
+ waitId: wait.id
564
+ }, "Connection cancellation saved; domain cleanup will retry with its control");
565
+ }
566
+ }
567
+ async executeConnectionControl(input) {
568
+ const target = input.payload;
569
+ if (!target?.connectionAction) throw new Error("Connection control is required");
570
+ let wait = getConnectionWait(target.waitId);
571
+ if (target.connectionAction === "cancel" && wait?.objectiveRevision === target.objectiveRevision) this.deps.cancelConnection?.(wait);
572
+ if (target.connectionAction === "continue" && wait?.objectiveRevision === target.objectiveRevision) try {
573
+ await this.deps.continueConnection?.(wait, `connection-control:${input.id}`);
574
+ } catch (err) {
575
+ log.warn({
576
+ err,
577
+ conversationId: input.conversationId,
578
+ waitId: target.waitId
579
+ }, "Connection control preserved for current status feedback");
580
+ }
581
+ wait = getConnectionWait(target.waitId);
582
+ const zh = /[\u3400-\u9fff]/u.test(input.content);
583
+ const summary = !wait || wait.objectiveRevision !== target.objectiveRevision ? zh ? "原目标已发生变化,请查看当前目标状态。" : "The original objective changed. Check the current objective status." : target.connectionAction === "cancel" ? zh ? "已取消原目标。" : "The original objective was cancelled." : interruptedConnectionMessage(wait) ? zh ? "原目标已保留。请重新发送重启时中断的补充要求,或移除中断的消息后继续。" : "The original objective is saved. Resend the interrupted message or remove it before continuing." : wait.resolution === "cancelled" ? zh ? "原目标已取消。" : "The original objective was cancelled." : wait.status === "closed" ? zh ? "原目标已交给执行流程,无需重复继续。" : "The original objective has already been handed to execution. No additional continuation is needed." : wait.status === "queued" ? zh ? "原目标已准备好,正在等待执行,无需重复继续。" : "The original objective is queued. No additional continuation is needed." : wait.intent ? zh ? "原目标已保留,完成连接和能力检查后会自动继续。" : "The original objective is saved and will continue automatically after connection and capability checks." : zh ? "原目标已保留,请查看连接操作区完成所需操作。" : "The original objective is saved. Complete the required action in the connection panel.";
584
+ const persisted = runSqliteWriteTransaction(() => {
585
+ const runtime = this.snapshot(input.conversationId);
586
+ if (runtime.activeInputId !== input.id || runtime.activeRunId !== input.runId || readCurrentTranscriptId(getSqliteDatabase(), input.conversationId) !== input.expectedTranscriptId) return false;
587
+ appendTranscriptEntry(input.conversationId, {
588
+ role: "user",
589
+ content: input.content,
590
+ timestamp: input.createdAtMs
591
+ });
592
+ appendTranscriptEntry(input.conversationId, {
593
+ role: "custom",
594
+ customType: "connection_control_status",
595
+ content: summary,
596
+ details: {
597
+ inputId: input.id,
598
+ waitId: target.waitId,
599
+ objectiveRevision: target.objectiveRevision
600
+ },
601
+ display: true,
602
+ timestamp: Date.now()
603
+ });
604
+ finishSessionInputRun(input.conversationId, input.runId, "completed");
605
+ return true;
606
+ });
607
+ if (persisted) emitSessionTranscriptUpdate({ conversationId: input.conversationId });
608
+ return {
609
+ status: persisted ? "ok" : "aborted",
610
+ summary: persisted ? summary : ""
611
+ };
612
+ }
430
613
  async update(conversationId, id, body) {
431
614
  const attachments = body.attachments === void 0 ? void 0 : await this.deps.prepareAttachments(conversationId, body.attachments);
432
615
  let sourceContexts;
@@ -463,6 +646,10 @@ var SessionInputCoordinator = class {
463
646
  }
464
647
  remove(conversationId, id, version) {
465
648
  const ok = cancelQueuedSessionInput(conversationId, id, version);
649
+ if (ok) {
650
+ publishConnectionWait(conversationId);
651
+ this.drain(conversationId);
652
+ }
466
653
  return {
467
654
  ok,
468
655
  state: ok ? this.publish(conversationId) : this.snapshot(conversationId)
@@ -478,7 +665,9 @@ var SessionInputCoordinator = class {
478
665
  }
479
666
  }
480
667
  recover() {
481
- for (const conversationId of recoverSessionInputState()) {
668
+ const interrupted = recoverSessionInputState();
669
+ new TaskRunRepository().reconcileCancelledRuns();
670
+ for (const conversationId of new Set([...interrupted, ...reconcileConnectionWaits(true)])) {
482
671
  this.publish(conversationId);
483
672
  this.drain(conversationId);
484
673
  }
@@ -155,6 +155,7 @@ export declare class GatewayService {
155
155
  }>;
156
156
  withSessionInputSubmission<T>(conversationId: string, operation: () => Promise<T>): Promise<T>;
157
157
  prepareSessionCommandInput(input: Parameters<GatewayAgentRunner['inputs']['prepareInput']>[0]): Promise<{
158
+ payload?: import("../storage/sqlite/session-input-repository.js").SessionInputPayload;
158
159
  status: "queued";
159
160
  requestedDelivery: import("../storage/sqlite/session-input-repository.js").SessionInputDelivery;
160
161
  effectiveDelivery: "next";
@@ -44,6 +44,7 @@ import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
44
44
  import { ProjectService } from "../projects/project-service.js";
45
45
  import { resolveProjectAgentId } from "../projects/project-agent.js";
46
46
  import "../projects/index.js";
47
+ import { onTaskResultQueued } from "../tasks/task-result-delivery-repository.js";
47
48
  import { runMemoryMaintenance } from "../memory-maintenance/service.js";
48
49
  import "../memory-maintenance/index.js";
49
50
  import { RealtimeExtensionBrowserProvider } from "../browser/providers/realtime-extension.js";
@@ -52,7 +53,6 @@ import { buildNoteAgentContext } from "../notes/agent-context.js";
52
53
  import { NotesStore } from "../notes/store.js";
53
54
  import { NotesService } from "../notes/service.js";
54
55
  import { LocalAppService } from "../local-apps/service.js";
55
- import { onTaskResultQueued } from "../tasks/task-result-delivery-repository.js";
56
56
  import { TaskApplicationService } from "../tasks/task-application-service.js";
57
57
  import { AutomationService } from "../automations/service/automation-service.js";
58
58
  import { TaskSignalService } from "../tasks/task-signal-service.js";
@@ -73,12 +73,12 @@ import "../infra/bus/index.js";
73
73
  import { collectMediaUrisFromMessages, deleteMediaUris } from "../media/session-references.js";
74
74
  import { AgentService } from "../agent/service.js";
75
75
  import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
76
- import { ChatPreviewService } from "../chat-previews/service.js";
77
- import "../chat-previews/index.js";
78
- import "../config/index.js";
79
76
  import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
80
77
  import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
81
78
  import { ChannelManager } from "../channels/manager.js";
79
+ import { ChatPreviewService } from "../chat-previews/service.js";
80
+ import "../chat-previews/index.js";
81
+ import "../config/index.js";
82
82
  import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
83
83
  import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
84
84
  import "../knowledge/index.js";
@@ -515,6 +515,8 @@ var GatewayService = class {
515
515
  });
516
516
  this.chatPreviews = new ChatPreviewService({ localApps: this.localApps });
517
517
  this.agentRunner = new GatewayAgentRunner({
518
+ continueConnection: (wait, idempotencyKey) => this.connectionRecovery.continueObjective(wait, idempotencyKey),
519
+ cancelConnection: (wait) => this.connectionRecovery.cancelObjective(wait),
518
520
  validateConnectionResume: async (input) => {
519
521
  for (const source of input.contextSnapshots ?? []) if (source.kind === "app_context") await checkAppContextAccess(source, this.appContextDispatcher(), this.auth);
520
522
  return this.connectionRecovery.preflight(input);