@xopcai/xopc 0.0.385 → 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 (243) 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-Cb9eaXxR.js → agent-avatar-dicebear-D-86VOlb.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DEV-xtgm.js → agent-defaults-settings-panel-SmeUVHY8.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-DXKc3Luj.js → agent-plugin-dialog-BVT3wXq5.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-DcNxwpJQ.js → agents-D7rLQFhX.js} +3 -3
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-X5i0Tz7_.js → app-management-settings-panel-CUR7n5iP.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CmHHzquT.js → appearance-settings-BCotSGep.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-ChFA4Zp0.js → apps-page-hk0bo9LT.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automations-page-BFqsIqOI.js → automations-page-CqxuUwox.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-workspace-Blfak-fT.js → automations-workspace-11_Z69pr.js} +1 -1
  12. package/dist/gateway/static/root/assets/{block-editor-CpOLG3Co.js → block-editor-eldB84Mj.js} +1 -1
  13. package/dist/gateway/static/root/assets/{browser-automations-page-BSbTJ9j2.js → browser-automations-page-D4TaUPYT.js} +1 -1
  14. package/dist/gateway/static/root/assets/{browser-settings-page-BUlILJrB.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-CeRdkwRf.js → capabilities-page-CyYlueEd.js} +2 -2
  18. package/dist/gateway/static/root/assets/{capabilities-settings-panel-S-cKsGja.js → capabilities-settings-panel-uVEgfvo0.js} +1 -1
  19. package/dist/gateway/static/root/assets/{capability-header-actions-6w8pQhnn.js → capability-header-actions-BXv0xu56.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-DfNTGBmp.js → channels-fNb3SOzm.js} +1 -1
  21. package/dist/gateway/static/root/assets/{chat-terminal-dock-DnoQHpDc.js → chat-terminal-dock-CnLtparQ.js} +1 -1
  22. package/dist/gateway/static/root/assets/{computer-settings-page-7yliE7sG.js → computer-settings-page-xM0AnOlP.js} +1 -1
  23. package/dist/gateway/static/root/assets/{connector-service-page-DOLAUFSW.js → connector-service-page-CdG2WUb6.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-DAsn97XG.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-DNDqr4Fk.js → date-picker-DIBbE-O8.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-B5oG7RgE.js → dependency-picker-DDD8zokD.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-K7kUCX1O.js → desktop-pet-KlF390Xn.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-KgOAuqSh.js → desktop-pet-settings-CgqQMKDC.js} +1 -1
  30. package/dist/gateway/static/root/assets/{device-pairing-wizard-DvqniZDm.js → device-pairing-wizard-BR6isfG2.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-BmOguLDl.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-DSSuMQxp.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-DSd__mNd.js → extension-settings-page-D7-5v0V4.js} +1 -1
  36. package/dist/gateway/static/root/assets/{fallback-models-D7bjbiwZ.js → fallback-models-DnYn7qOV.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-settings-hSXGWumL.js → gateway-settings-Bwe3JWX-.js} +1 -1
  38. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-C7xJwE61.js → highlighted-body-KQOG7T2V-DefTxF3q.js} +1 -1
  39. package/dist/gateway/static/root/assets/{home-page-DJNmlMfH.js → home-page-BtSy2hRV.js} +1 -1
  40. package/dist/gateway/static/root/assets/{imports-page-BufZPzGE.js → imports-page-CTdBYZib.js} +1 -1
  41. package/dist/gateway/static/root/assets/{index-K8SXDtxr.js → index-B08iR7fT.js} +9 -9
  42. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8pPP5RF.js → keyboard-shortcuts-settings-CXKp57O_.js} +1 -1
  43. package/dist/gateway/static/root/assets/{local-app-workbench-page-zEtvE7pJ.js → local-app-workbench-page-DzD_OzGY.js} +1 -1
  44. package/dist/gateway/static/root/assets/{local-apps-page-Bli7e_eg.js → local-apps-page-B0E0vttg.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-BimZk3R4.js → logs-page-eL4fYcMl.js} +1 -1
  46. package/dist/gateway/static/root/assets/{management-settings-5Y4COyU9.js → management-settings-DSpjodMC.js} +1 -1
  47. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-BTrk2wWv.js +1 -0
  48. package/dist/gateway/static/root/assets/{note-detail-panel-KLDPLVg7.js → note-detail-panel-CsY5tQp5.js} +3 -3
  49. package/dist/gateway/static/root/assets/{notes-page-DST0oPXD.js → notes-page-D09LjNoj.js} +1 -1
  50. package/dist/gateway/static/root/assets/{page-context-capture-button-Bmed83-6.js → page-context-capture-button-DO-aP3D9.js} +1 -1
  51. package/dist/gateway/static/root/assets/{personal-page-BG4Ystrm.js → personal-page-E8F2aGNB.js} +1 -1
  52. package/dist/gateway/static/root/assets/{product-open-page-CXkYP9xE.js → product-open-page-aUoA-uPw.js} +1 -1
  53. package/dist/gateway/static/root/assets/{product-preview-content-DjmupQSq.js → product-preview-content-B-cz-pIV.js} +1 -1
  54. package/dist/gateway/static/root/assets/{project-detail-page-CzBmV0P6.js → project-detail-page-WhefAh8E.js} +1 -1
  55. package/dist/gateway/static/root/assets/{projects-page-DByqe5Em.js → projects-page-CyqAs0tO.js} +1 -1
  56. package/dist/gateway/static/root/assets/{remote-access-hub-DTjj-odF.js → remote-access-hub-BwhRGL6m.js} +1 -1
  57. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-B_ptn3T8.js → runtime-tools-settings-panel-o26dmPNq.js} +1 -1
  58. package/dist/gateway/static/root/assets/{scenes-page-wkua4l5y.js → scenes-page-D_e19kv_.js} +1 -1
  59. package/dist/gateway/static/root/assets/{schema-form-VvOSM84Y.js → schema-form-DLLdqUC3.js} +1 -1
  60. package/dist/gateway/static/root/assets/{send-session-input-BCAF-Ikt.js → send-session-input-2I-nFJcE.js} +1 -1
  61. package/dist/gateway/static/root/assets/session-manager-Co5ozD0l.js +16 -0
  62. package/dist/gateway/static/root/assets/{sessions-page-D06XwYAT.js → sessions-page-DX6INsiS.js} +1 -1
  63. package/dist/gateway/static/root/assets/settings-advanced-gate-C4_gW1vw.js +1 -0
  64. package/dist/gateway/static/root/assets/{settings-page-C-6BJdb1.js → settings-page-Bc_zxxRu.js} +1 -1
  65. package/dist/gateway/static/root/assets/{setup-status-panel-L0JSG0K-.js → setup-status-panel-FpF_cPPr.js} +1 -1
  66. package/dist/gateway/static/root/assets/{share-preview-page-nJ2FWAEP.js → share-preview-page-BOCcPBqQ.js} +1 -1
  67. package/dist/gateway/static/root/assets/{shares-settings-BbgAUM3v.js → shares-settings-CInxjxgJ.js} +1 -1
  68. package/dist/gateway/static/root/assets/{skill-api-BFU1tPyw.js → skill-api-Bjd8WAA4.js} +1 -1
  69. package/dist/gateway/static/root/assets/{skills-page-DZw6el4o.js → skills-page-8CKS3Oo2.js} +1 -1
  70. package/dist/gateway/static/root/assets/{system-settings-panel-DshSGWNg.js → system-settings-panel-BgQdsrNw.js} +1 -1
  71. package/dist/gateway/static/root/assets/task-detail-page-BnG5ehZ6.js +2 -0
  72. package/dist/gateway/static/root/assets/task-expandable-content-BCuc70Vc.js +1 -0
  73. package/dist/gateway/static/root/assets/{tasks-DJIeIk9C.js → tasks-PuIUgF9L.js} +1 -1
  74. package/dist/gateway/static/root/assets/{tunnel-api-DFDXwWnU.js → tunnel-api-CY7MoDGf.js} +1 -1
  75. package/dist/gateway/static/root/assets/{usage-page-2RJLg54s.js → usage-page-s8Sv_PIG.js} +1 -1
  76. package/dist/gateway/static/root/assets/{use-composer-attachments-BFP3k6oC.js → use-composer-attachments-D0S2iZF4.js} +1 -1
  77. package/dist/gateway/static/root/assets/{use-file-preview-expanded-B1BiTQNS.js → use-file-preview-expanded-BElqELib.js} +1 -1
  78. package/dist/gateway/static/root/assets/{user-model-page-y1gjGYPI.js → user-model-page-CyWrEtHY.js} +1 -1
  79. package/dist/gateway/static/root/assets/{work-discovery-overlay-Ch-KfpCF.js → work-discovery-overlay-DmZXLs1v.js} +1 -1
  80. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CTu297Hc.js → workflow-run-setup-panel-BdLOzHm4.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflows-page-CRZXG_rm.js → workflows-page-Cx3I3AV5.js} +1 -1
  82. package/dist/gateway/static/root/assets/{workspace-api-Xr3wz8T3.js → workspace-api-Du7-xJ0q.js} +2 -2
  83. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-hEfjVjnc.js → xopc-cloud-account-card-D8B136vW.js} +1 -1
  84. package/dist/gateway/static/root/index.html +11 -11
  85. package/dist/package.js +1 -1
  86. package/dist/packages/gateway-contract/src/index.js +2 -0
  87. package/dist/packages/gateway-contract/src/task-research-result.js +89 -0
  88. package/dist/packages/gateway-contract/src/tasks.js +7 -1
  89. package/dist/packages/gateway-contract/src/turn-outcome.js +3 -0
  90. package/dist/src/agent/child-agent-factory.d.ts +4 -1
  91. package/dist/src/agent/child-agent-factory.js +86 -12
  92. package/dist/src/agent/context/connection-objective-context.d.ts +1 -0
  93. package/dist/src/agent/context/connection-objective-context.js +33 -0
  94. package/dist/src/agent/data-acquisition/service.js +41 -6
  95. package/dist/src/agent/data-acquisition/types.d.ts +2 -0
  96. package/dist/src/agent/embedded/agent-profile-context.d.ts +7 -0
  97. package/dist/src/agent/embedded/agent-profile-context.js +92 -0
  98. package/dist/src/agent/embedded/run-for-session.js +5 -2
  99. package/dist/src/agent/embedded/run-turn.js +19 -6
  100. package/dist/src/agent/embedded/runs.d.ts +9 -2
  101. package/dist/src/agent/embedded/runs.js +30 -7
  102. package/dist/src/agent/embedded/session-runner.js +5 -2
  103. package/dist/src/agent/embedded/types.d.ts +4 -0
  104. package/dist/src/agent/external-tools/gateway-tools.js +7 -3
  105. package/dist/src/agent/orchestration/agent-run-supervisor.js +2 -1
  106. package/dist/src/agent/orchestration/agent-turn-policy.js +5 -1
  107. package/dist/src/agent/orchestration/delegation-budget.d.ts +7 -1
  108. package/dist/src/agent/orchestration/delegation-budget.js +17 -9
  109. package/dist/src/agent/orchestration/research-checkpoint.d.ts +56 -0
  110. package/dist/src/agent/orchestration/research-checkpoint.js +64 -0
  111. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +3 -1
  112. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +15 -2
  113. package/dist/src/agent/orchestration/run-termination.d.ts +12 -0
  114. package/dist/src/agent/orchestration/run-termination.js +24 -0
  115. package/dist/src/agent/orchestration/turn-recovery.d.ts +4 -1
  116. package/dist/src/agent/orchestration/turn-recovery.js +19 -3
  117. package/dist/src/agent/prompt/sections/agent-identity.js +12 -7
  118. package/dist/src/agent/prompt/sections/messaging-runtime.js +1 -1
  119. package/dist/src/agent/prompt/sections/project-context.js +1 -1
  120. package/dist/src/agent/prompt/sections/response-language.d.ts +1 -1
  121. package/dist/src/agent/prompt/sections/response-language.js +6 -2
  122. package/dist/src/agent/prompt/subagent-context.js +1 -1
  123. package/dist/src/agent/prompt/system-prompt.js +4 -6
  124. package/dist/src/agent/tasks/task-judge-service.js +3 -1
  125. package/dist/src/agent/tools/apply-patch.js +1 -1
  126. package/dist/src/agent/tools/delegate-tool.js +216 -121
  127. package/dist/src/agent/tools/delegation-policy.js +13 -1
  128. package/dist/src/agent/tools/factory.js +2 -0
  129. package/dist/src/agent/tools/index.d.ts +1 -0
  130. package/dist/src/agent/tools/index.js +2 -1
  131. package/dist/src/agent/tools/language-diagnostics.js +1 -1
  132. package/dist/src/agent/tools/personal-request-tool.js +8 -13
  133. package/dist/src/agent/tools/personal-task-tool.d.ts +1 -2
  134. package/dist/src/agent/tools/personal-task-tool.js +9 -8
  135. package/dist/src/agent/tools/publish-artifacts.js +1 -1
  136. package/dist/src/agent/tools/research-checkpoint-tool.d.ts +3 -0
  137. package/dist/src/agent/tools/research-checkpoint-tool.js +28 -0
  138. package/dist/src/agent/tools/review-workspace.js +1 -1
  139. package/dist/src/agent/tools/search/cache.d.ts +20 -0
  140. package/dist/src/agent/tools/search/cache.js +19 -0
  141. package/dist/src/agent/tools/search/errors.d.ts +19 -0
  142. package/dist/src/agent/tools/search/errors.js +69 -0
  143. package/dist/src/agent/tools/search/providers/bing-api.js +2 -1
  144. package/dist/src/agent/tools/search/providers/bing-html.js +2 -1
  145. package/dist/src/agent/tools/search/providers/brave.js +2 -1
  146. package/dist/src/agent/tools/search/providers/duckduckgo-html.js +2 -1
  147. package/dist/src/agent/tools/search/providers/searxng.js +2 -1
  148. package/dist/src/agent/tools/search/providers/tavily.js +2 -1
  149. package/dist/src/agent/tools/search/providers/xopc-cloud.d.ts +1 -0
  150. package/dist/src/agent/tools/search/providers/xopc-cloud.js +7 -2
  151. package/dist/src/agent/tools/search/registry.d.ts +21 -5
  152. package/dist/src/agent/tools/search/registry.js +252 -25
  153. package/dist/src/agent/tools/search/types.d.ts +25 -0
  154. package/dist/src/agent/tools/task-result-tool.d.ts +2 -0
  155. package/dist/src/agent/tools/task-result-tool.js +73 -0
  156. package/dist/src/agent/tools/web.d.ts +16 -2
  157. package/dist/src/agent/tools/web.js +74 -29
  158. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  159. package/dist/src/automations/capabilities/write.d.ts +4 -4
  160. package/dist/src/automations/domain/validation.d.ts +8 -8
  161. package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
  162. package/dist/src/browser/automations/schema.d.ts +2 -2
  163. package/dist/src/browser/automations/service.d.ts +2 -2
  164. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  165. package/dist/src/config/index.js +2 -2
  166. package/dist/src/config/schema.d.ts +1 -0
  167. package/dist/src/config/schema.js +4 -1
  168. package/dist/src/connectors/connection-recovery-service.d.ts +3 -1
  169. package/dist/src/connectors/connection-recovery-service.js +66 -5
  170. package/dist/src/discussions/action-tasks.d.ts +2 -2
  171. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  172. package/dist/src/gateway/hono/routes/projects.js +1 -1
  173. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +16 -0
  174. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  175. package/dist/src/gateway/service/agent-runner.d.ts +2 -0
  176. package/dist/src/gateway/service/agent-runner.js +30 -17
  177. package/dist/src/gateway/service/run-gateway-agent.js +12 -1
  178. package/dist/src/gateway/service/session-input-coordinator.d.ts +10 -1
  179. package/dist/src/gateway/service/session-input-coordinator.js +213 -26
  180. package/dist/src/gateway/service.d.ts +1 -0
  181. package/dist/src/gateway/service.js +9 -7
  182. package/dist/src/gateway/session-context-summary.js +1 -1
  183. package/dist/src/personal-agent/prompts.js +4 -1
  184. package/dist/src/personal-agent/reply-composer.d.ts +1 -0
  185. package/dist/src/personal-agent/reply-composer.js +70 -12
  186. package/dist/src/personal-agent/reply-style.d.ts +1 -1
  187. package/dist/src/personal-agent/reply-style.js +1 -0
  188. package/dist/src/personal-agent/repository.d.ts +1 -1
  189. package/dist/src/personal-agent/repository.js +1 -1
  190. package/dist/src/personal-agent/request-repository.d.ts +2 -0
  191. package/dist/src/personal-agent/request-service.d.ts +4 -0
  192. package/dist/src/personal-agent/request-service.js +90 -19
  193. package/dist/src/personal-agent/result-file-links.d.ts +3 -0
  194. package/dist/src/personal-agent/result-file-links.js +21 -0
  195. package/dist/src/personal-agent/task-cancel.js +85 -35
  196. package/dist/src/scenes/taskFollowUp/service.d.ts +15 -5
  197. package/dist/src/session/session-context-for-llm.js +2 -2
  198. package/dist/src/session/store.d.ts +3 -1
  199. package/dist/src/session/store.js +13 -3
  200. package/dist/src/storage/sqlite/connection-wait-repository.d.ts +5 -2
  201. package/dist/src/storage/sqlite/connection-wait-repository.js +42 -17
  202. package/dist/src/storage/sqlite/index.d.ts +1 -0
  203. package/dist/src/storage/sqlite/index.js +3 -1
  204. package/dist/src/storage/sqlite/migrations/250_research_checkpoints.sql +15 -0
  205. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  206. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  207. package/dist/src/storage/sqlite/research-checkpoint-repository.d.ts +24 -0
  208. package/dist/src/storage/sqlite/research-checkpoint-repository.js +91 -0
  209. package/dist/src/storage/sqlite/schema.js +1 -1
  210. package/dist/src/storage/sqlite/session-creation-repository.js +3 -2
  211. package/dist/src/storage/sqlite/session-input-repository.d.ts +16 -0
  212. package/dist/src/storage/sqlite/session-input-repository.js +41 -7
  213. package/dist/src/tasks/capabilities/management.d.ts +2 -2
  214. package/dist/src/tasks/capabilities/relations.d.ts +7 -7
  215. package/dist/src/tasks/capabilities/write.d.ts +2 -2
  216. package/dist/src/tasks/index.js +1 -1
  217. package/dist/src/tasks/task-allocation-service.d.ts +2 -0
  218. package/dist/src/tasks/task-allocation-service.js +43 -2
  219. package/dist/src/tasks/task-application-service.js +2 -2
  220. package/dist/src/tasks/task-context-assembler.js +6 -1
  221. package/dist/src/tasks/task-continuation.d.ts +1 -0
  222. package/dist/src/tasks/task-continuation.js +1 -0
  223. package/dist/src/tasks/task-contract-planner.d.ts +1 -0
  224. package/dist/src/tasks/task-contract-planner.js +22 -15
  225. package/dist/src/tasks/task-model-call.d.ts +7 -0
  226. package/dist/src/tasks/task-model-call.js +35 -0
  227. package/dist/src/tasks/task-research-repair.d.ts +19 -0
  228. package/dist/src/tasks/task-research-repair.js +75 -0
  229. package/dist/src/tasks/task-research-result.d.ts +85 -0
  230. package/dist/src/tasks/task-research-result.js +394 -0
  231. package/dist/src/tasks/task-result-delivery-repository.js +13 -2
  232. package/dist/src/tasks/task-result-delivery-service.js +1 -1
  233. package/dist/src/tasks/task-run-coordinator.js +69 -15
  234. package/dist/src/tasks/task-run-dispatcher.js +1 -0
  235. package/dist/src/tasks/task-run-repository.d.ts +5 -0
  236. package/dist/src/tasks/task-run-repository.js +88 -1
  237. package/package.json +9 -5
  238. package/dist/gateway/static/root/assets/constants-Dy8Gw0sF.js +0 -1
  239. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-DBRj4-1-.js +0 -1
  240. package/dist/gateway/static/root/assets/session-manager-_yy4bxhT.js +0 -16
  241. package/dist/gateway/static/root/assets/settings-advanced-gate-DoAHy1wj.js +0 -1
  242. package/dist/gateway/static/root/assets/task-detail-page-CfZhq4XZ.js +0 -2
  243. package/dist/gateway/static/root/assets/task-expandable-content-CF6Bj-Qa.js +0 -1
@@ -1,4 +1,4 @@
1
1
  export declare const PREVIOUS_PERSONAL_REPLY_STYLE_RULES: readonly ["Make the first sentence useful on its own. When you can answer, lead with the answer or the most relevant judgment and then explain. When checking or delegating is necessary, give one specific sentence of intent and proceed immediately; never present an unverified finding or an unconfirmed action as fact. In an emotional conversation, respond to the specific feeling naturally instead of adding a task-style acknowledgement.", "Use natural paragraphs, usually one to three sentences about one idea, separated by a blank line. A simple question may need only one sentence. Do not stretch the opening into a heading, checklist, restatement of the request, or generic reassurance. Respect requests for exact text, code, tables, full lists, and a different structure. Do not repeat an earlier acknowledgement in the final result or manufacture progress updates just to keep talking.", "Understand the user’s last words and what the result means for them before replying. Speak as the same familiar personal assistant throughout the conversation, rather than forwarding an execution report. A natural brief opening is welcome when it connects to what they said; do not mechanically add a greeting, name, reassurance, joke, or question.", "Use a conversational rhythm and concrete language. Start with what the user most needs now, then give enough explanation or detail to use the answer. Do not default to “Task completed”, “Here is the summary”, headings, or checklists. Use lists and tables when they genuinely make the requested information easier to use."];
2
2
  export declare const PREVIOUS_PERSONAL_REPLY_EXAMPLES = "Examples of presentation, only when the evidence supports the facts:\nReport: \u201CQuery complete. Scanned 28 emails and found 3 important items.\u201D\nConversation: \u201CThree emails are worth looking at first. The contract confirmation is the most urgent: they need your reply today. I\u2019ve included the other two below.\u201D\nReport: \u201CTask failed: connector authorization expired.\u201D\nConversation: \u201CI couldn\u2019t finish checking the remaining emails because the connection expired. The results already retrieved are below; reconnecting will let us check the rest.\u201D\nThese are examples of rhythm, not facts or fixed templates. Match the user\u2019s language and preferences.";
3
- export declare const PERSONAL_REPLY_STYLE_RULES: readonly ["Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.", "Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.", "Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.", "Keep warmth and conversational rhythm specific to the moment. Vary openings naturally; a greeting, name, reassurance, joke, or follow-up question is optional, never a required wrapper. Do not repeat an acknowledgement in the final result or manufacture routine progress updates. Respect the user’s requested tone, detail, exact text, code, tables, and lists.", "Synthesis means understanding and organizing, not always shortening. Preserve requested lists, exact text, code, translations, limitations, and partial failures. Never make an uncertain result sound confirmed just to keep the reply smooth.", "Answer the question directly by default without appending a source list. Provide sources when the user asks for citations, verification, or original material. Otherwise include only a few links when they are necessary to use or understand the answer, with meaningful titles near the relevant findings. Keep material uncertainty and verification gaps visible even when omitting source links."];
3
+ export declare const PERSONAL_REPLY_STYLE_RULES: readonly ["Be concise by default: usually one short paragraph of one to three sentences, or a few brief items when necessary. Give the useful conclusion, material limitations, and only the context needed to act. Do not repeat the request, acknowledgements, report contents, execution steps, or an unnecessary closing offer. A narrow follow-up needs a narrow answer. Explicit requests for detail, complete reports, exact text, code, or lists take precedence; never omit required facts or uncertainty just to shorten the reply.", "Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.", "Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.", "Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.", "Keep warmth and conversational rhythm specific to the moment. Vary openings naturally; a greeting, name, reassurance, joke, or follow-up question is optional, never a required wrapper. Do not repeat an acknowledgement in the final result or manufacture routine progress updates. Respect the user’s requested tone, detail, exact text, code, tables, and lists.", "Synthesis means understanding and organizing, not always shortening. Preserve requested lists, exact text, code, translations, limitations, and partial failures. Never make an uncertain result sound confirmed just to keep the reply smooth.", "Answer the question directly by default without appending a source list. Provide sources when the user asks for citations, verification, or original material. Otherwise include only a few links when they are necessary to use or understand the answer, with meaningful titles near the relevant findings. Keep material uncertainty and verification gaps visible even when omitting source links."];
4
4
  export declare const PERSONAL_REPLY_EXAMPLES = "Conversation examples with hypothetical facts, only to demonstrate rhythm. Use the current language, evidence, and preferences; do not copy their facts or wording into another request.\n<examples>\n<example>\nContext: The user wants to chat about a verified news item concerning AI avatars and a popular human discussion forum.\nUser: \u7EE7\u7EED\u804A\u4E00\u804A AI \u76F8\u5173\u7684\u65B0\u95FB\u3002\nAssistant: AI \u5206\u8EAB\u90A3\u6761\u633A\u6709\u610F\u601D\uFF1A\u5927\u5BB6\u82B1\u94B1\u4F53\u9A8C\u865A\u62DF\u8001\u5E08\uFF0C\u6700\u540E\u6700\u7231\u7528\u7684\u5374\u662F\u540C\u5B66\u8BBA\u575B\u3002\u6280\u672F\u8D8A\u60F3\u590D\u523B\u4EBA\uFF0C\u8FD9\u4EF6\u4E8B\u53CD\u800C\u8D8A\u663E\u51FA\u771F\u4EBA\u4EA4\u6D41\u7684\u4EF7\u503C\u3002\n</example>\n<example>\nContext: The supplied records show publication dates of October 10\u201312 and one reference dated October 7.\nUser: \u8FD9\u4E9B\u65B0\u95FB\u4EC0\u4E48\u65F6\u5019\u7684\uFF1F\nAssistant: \u4E3B\u8981\u662F 10 \u6708 10\u201312 \u65E5\u7684\u62A5\u9053\u3002\u5176\u4E2D\u4E00\u6761\u5F15\u7528\u4E86 10 \u6708 7 \u65E5\u7684\u8D44\u6599\uFF0C\u62A5\u9053\u65E5\u671F\u548C\u539F\u59CB\u8D44\u6599\u7684\u65E5\u671F\u8981\u5206\u5F00\u770B\u3002\n</example>\n<example>\nContext: The assistant has finished answering; there is no pending question or requested continuation.\nUser: K.\nAssistant: \u55EF\u3002\n</example>\n<example>\nContext: The assistant offered to discuss why the human forum in the AI-avatar news item was popular; the user accepts that offer.\nUser: \u7EE7\u7EED\u3002\nAssistant: \u521A\u624D\u8BF4\u7684\u540C\u5B66\u8BBA\u575B\uFF0C\u5438\u5F15\u4EBA\u7684\u53EF\u80FD\u5C31\u662F\u80FD\u78B0\u5230\u6709\u76F8\u4F3C\u56F0\u60D1\u7684\u4EBA\u3002\u9664\u4E86\u62FF\u5230\u7B54\u6848\uFF0C\u5927\u5BB6\u4E5F\u60F3\u542C\u542C\u522B\u4EBA\u662F\u600E\u4E48\u8D70\u8FC7\u6765\u7684\u3002\n</example>\n<example>\nContext: Several recipients were discussed, and the recipient of an external message is unresolved.\nUser: \u53D1\u7ED9\u4ED6\u3002\nAssistant: \u4F60\u6307\u7684\u662F\u521A\u624D\u63D0\u5230\u7684\u54EA\u4E00\u4F4D\uFF1F\n</example>\n<example>\nUser: \u5148\u522B\u8BB2\u4E86\u3002\nAssistant: \u597D\uFF0C\u5148\u505C\u5728\u8FD9\u513F\u3002\n</example>\n<example>\nContext: A hypothetical report establishes reduced waiting, configurable preferences, and an outstanding need for real-conversation evaluation.\nUser: \u5E2E\u6211\u603B\u7ED3\u6210\u4E09\u70B9\u3002\nAssistant: 1. \u9996\u53E5\u7B49\u5F85\u7F29\u77ED\u4E86\u3002\n2. \u7528\u6237\u4ECD\u80FD\u8C03\u6574\u8868\u8FBE\u504F\u597D\u3002\n3. \u81EA\u7136\u5EA6\u8FD8\u9700\u8981\u771F\u5B9E\u5BF9\u8BDD\u9A8C\u8BC1\u3002\n</example>\n<example>\nContext: Some requested email results were retrieved, but authorization expired before the remaining items could be checked.\nAssistant: \u5DF2\u7ECF\u67E5\u5230\u7684\u51E0\u5C01\u90AE\u4EF6\u5728\u4E0B\u9762\u3002\u5269\u4E0B\u7684\u6682\u65F6\u6CA1\u67E5\u5B8C\uFF0C\u56E0\u4E3A\u8FDE\u63A5\u8FC7\u671F\u4E86\uFF1B\u91CD\u65B0\u8FDE\u63A5\u540E\u624D\u80FD\u63A5\u7740\u770B\u3002\n</example>\n</examples>";
@@ -12,6 +12,7 @@ Report: “Task failed: connector authorization expired.”
12
12
  Conversation: “I couldn’t finish checking the remaining emails because the connection expired. The results already retrieved are below; reconnecting will let us check the rest.”
13
13
  These are examples of rhythm, not facts or fixed templates. Match the user’s language and preferences.`;
14
14
  const PERSONAL_REPLY_STYLE_RULES = [
15
+ "Be concise by default: usually one short paragraph of one to three sentences, or a few brief items when necessary. Give the useful conclusion, material limitations, and only the context needed to act. Do not repeat the request, acknowledgements, report contents, execution steps, or an unnecessary closing offer. A narrow follow-up needs a narrow answer. Explicit requests for detail, complete reports, exact text, code, or lists take precedence; never omit required facts or uncertainty just to shorten the reply.",
15
16
  "Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.",
16
17
  "Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.",
17
18
  "Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.",
@@ -24,7 +24,7 @@ export declare const DEFAULT_PERSONAL_PREFERENCES: {
24
24
  readonly warmth: "balanced";
25
25
  readonly humor: "occasional";
26
26
  readonly supportMode: "untangle";
27
- readonly detailLevel: "balanced";
27
+ readonly detailLevel: "brief";
28
28
  readonly proactivity: "decisions";
29
29
  };
30
30
  export declare function personalAgentId(ownerId: string): string;
@@ -13,7 +13,7 @@ const DEFAULT_PERSONAL_PREFERENCES = {
13
13
  warmth: "balanced",
14
14
  humor: "occasional",
15
15
  supportMode: "untangle",
16
- detailLevel: "balanced",
16
+ detailLevel: "brief",
17
17
  proactivity: "decisions"
18
18
  };
19
19
  function personalAgentId(ownerId) {
@@ -12,6 +12,8 @@ export interface PersonalRequest {
12
12
  parameters: {
13
13
  brief?: string;
14
14
  allocate?: boolean;
15
+ taskRunId?: string;
16
+ cancellationCleanupCompleted?: boolean;
15
17
  timeRange?: {
16
18
  from: string;
17
19
  to: string;
@@ -17,5 +17,9 @@ export declare function resolvePersonalRequestConnection(wait: ConnectionWait, r
17
17
  /** A worker can request access recovery without requiring a new main-chat turn. */
18
18
  export declare function requirePersonalWorkerConnection(conversationId: string): PersonalRequest;
19
19
  export declare function personalRequestSnapshot(request: PersonalRequest): PersonalRequest;
20
+ /** Dispatch only the request's bound execution; SDK acknowledgement must not block input. */
21
+ export declare function stopPersonalRequestExecution(request: PersonalRequest): {
22
+ executionStopConfirmed: boolean;
23
+ };
20
24
  export declare function cancelPersonalRequest(request: PersonalRequest): PersonalRequest;
21
25
  export declare function publishPersonalRequest(request: PersonalRequest): void;
@@ -1,3 +1,5 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
1
3
  import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
2
4
  import { TaskCreateRequestSchema } from "../../packages/gateway-contract/src/tasks.js";
3
5
  import { init_src } from "../../packages/gateway-contract/src/index.js";
@@ -15,12 +17,13 @@ import { canAccessConnectorAccount } from "../connectors/account-access.js";
15
17
  import { connectorPrincipalForSession } from "../connectors/principal.js";
16
18
  import { resolveConnectionCandidate } from "../connectors/connection-candidates.js";
17
19
  import { TaskCollaborationRepository } from "../tasks/task-collaboration-repository.js";
18
- import { TaskApplicationService } from "../tasks/task-application-service.js";
19
20
  import { defineTaskContract } from "../tasks/task-contract-definition.js";
21
+ import { abortEmbeddedRun } from "../agent/embedded/runs.js";
22
+ import { TaskApplicationService } from "../tasks/task-application-service.js";
23
+ import { PERSONAL_WORKER_RESULT_GUIDANCE } from "./communication.js";
20
24
  import { assessSpecialist } from "../agent-matching/service.js";
21
25
  import { AgentSelectionRepository, selectionRequestHash } from "../agent-matching/selection-repository.js";
22
26
  import { assertSpecialistEligible } from "../agent-matching/delegation-service.js";
23
- import { PERSONAL_WORKER_RESULT_GUIDANCE } from "./communication.js";
24
27
  import { personalCapabilities } from "./capability-service.js";
25
28
  import { createHash, randomUUID } from "node:crypto";
26
29
  //#region src/personal-agent/request-service.ts
@@ -34,6 +37,9 @@ init_task_repository();
34
37
  init_task_run_repository();
35
38
  init_connector_account_repository();
36
39
  init_connector_repository();
40
+ init_logger();
41
+ const log = createLogger("PersonalRequest");
42
+ const pendingStops = /* @__PURE__ */ new Set();
37
43
  function requestAssessment(request, accountId) {
38
44
  const principal = connectorPrincipalForSession(request.conversationId);
39
45
  const capability = personalCapabilities(request.conversationId, request.connectorId, accountId).find((item) => item.connectorId === request.connectorId);
@@ -294,7 +300,11 @@ function startPersonalRequest(request, accountId) {
294
300
  return updatePersonalRequest(request, {
295
301
  state: result.ok ? "queued" : "failed",
296
302
  accountId,
297
- taskId
303
+ taskId,
304
+ parameters: {
305
+ ...request.parameters,
306
+ taskRunId: result.ok ? result.runId : void 0
307
+ }
298
308
  });
299
309
  }
300
310
  /** Called inside the connection-resolution transaction; ordinary waits return undefined. */
@@ -407,7 +417,11 @@ function requirePersonalWorkerConnection(conversationId) {
407
417
  });
408
418
  return updatePersonalRequest(request, {
409
419
  state: "waiting_connection",
410
- connectionWaitId: result.waitId
420
+ connectionWaitId: result.waitId,
421
+ parameters: {
422
+ ...request.parameters,
423
+ taskRunId: run.id
424
+ }
411
425
  });
412
426
  });
413
427
  }
@@ -420,16 +434,58 @@ function personalRequestSnapshot(request) {
420
434
  state
421
435
  };
422
436
  }
423
- function cancelPersonalRequestTask(request) {
437
+ function personalRequestRunId(request) {
438
+ if (request.parameters.taskRunId) return request.parameters.taskRunId;
439
+ if (request.connectionWaitId) {
440
+ const wait = getSqliteDatabase().prepare(`SELECT task_run_id FROM task_waits
441
+ WHERE task_id = ? AND json_extract(condition_json, '$.connectionWaitId') = ? LIMIT 1`).get(request.taskId ?? null, request.connectionWaitId);
442
+ if (wait?.task_run_id) return wait.task_run_id;
443
+ }
444
+ const selected = new AgentSelectionRepository().find(request.conversationId, `personal-request-start:${request.requestId}`)?.taskRunId;
445
+ if (selected) return selected;
446
+ return (request.taskId ? getSqliteDatabase().prepare(`SELECT run_id FROM task_runs
447
+ WHERE task_id = ? AND parent_run_id IS NULL ORDER BY queued_at, rowid LIMIT 1`).get(request.taskId) : void 0)?.run_id;
448
+ }
449
+ /** Dispatch only the request's bound execution; SDK acknowledgement must not block input. */
450
+ function stopPersonalRequestExecution(request) {
451
+ if (request.state !== "cancelled") return { executionStopConfirmed: false };
452
+ const runId = personalRequestRunId(request);
453
+ const run = runId ? new TaskRunRepository().get(runId) : void 0;
454
+ if (!run || !run.conversationId && !run.startedAt) return { executionStopConfirmed: true };
455
+ if (run.conversationId) {
456
+ const state = getSessionInputState(run.conversationId);
457
+ const input = state.activeInputId ? getSessionInputById(run.conversationId, state.activeInputId) : void 0;
458
+ if (state.activeRunId && input?.taskRunId === run.id && !pendingStops.has(state.activeRunId)) {
459
+ const executionId = state.activeRunId;
460
+ pendingStops.add(executionId);
461
+ abortEmbeddedRun(run.conversationId, "user_cancelled", executionId).catch((err) => {
462
+ log.warn({
463
+ err,
464
+ requestId: request.requestId,
465
+ runId,
466
+ executionId
467
+ }, "Request cancelled; execution stop was not confirmed");
468
+ }).finally(() => {
469
+ pendingStops.delete(executionId);
470
+ });
471
+ }
472
+ }
473
+ return { executionStopConfirmed: false };
474
+ }
475
+ function cancelPersonalRequestTask(request, runId = personalRequestRunId(request)) {
424
476
  if (!request.taskId) return;
425
477
  const runs = new TaskRunRepository();
426
- const run = runs.getActiveRoot(request.taskId);
478
+ const run = runId ? runs.get(runId) : void 0;
427
479
  if (!run) return;
428
- for (const wait of runs.listActiveWaits(request.taskId)) if (wait.condition.connectionWaitId === request.connectionWaitId) runs.resolveWait({
429
- waitId: wait.id,
430
- actor: { kind: "user" },
431
- resolution: { cancelled: true }
432
- });
480
+ if (![
481
+ "queued",
482
+ "running",
483
+ "waiting",
484
+ "verifying",
485
+ "cancelled"
486
+ ].includes(run.status)) return;
487
+ runs.resolveCancelledRunWaits(run.id, { kind: "user" });
488
+ if (run.status === "cancelled") return;
433
489
  if (!new TaskApplicationService().completeRun({
434
490
  runId: run.id,
435
491
  expectedRunVersion: run.version,
@@ -452,12 +508,17 @@ function cancelPersonalRequestTask(request) {
452
508
  }).ok) throw new Error("Task changed while cancelling");
453
509
  }
454
510
  function cancelPersonalRequest(request) {
455
- const snapshot = personalRequestSnapshot(request);
456
- if (request.state === "cancelled" || ["completed", "failed"].includes(snapshot.state)) return snapshot;
457
- return runSqliteWriteTransaction(() => {
458
- if (request.connectionWaitId) cancelConnectionObjective(request.conversationId);
459
- cancelPersonalRequestTask(request);
460
- if (request.taskId) {
511
+ const cancelled = runSqliteWriteTransaction(() => {
512
+ request = getPersonalRequest(request.requestId);
513
+ if (request.parameters.cancellationCleanupCompleted) return request;
514
+ const snapshot = personalRequestSnapshot(request);
515
+ if (["completed", "failed"].includes(snapshot.state)) return snapshot;
516
+ const active = request.taskId ? new TaskRunRepository().getActiveRoot(request.taskId) : void 0;
517
+ const runId = personalRequestRunId(request);
518
+ const replacementRun = active && runId && active.id !== runId;
519
+ if (request.connectionWaitId) cancelConnectionObjective(request.conversationId, request.connectionWaitId);
520
+ cancelPersonalRequestTask(request, runId);
521
+ if (request.taskId && !replacementRun) {
461
522
  const task = new TaskRepository().require(request.taskId);
462
523
  if (task.phase !== "closed") new TaskApplicationService().execute({
463
524
  taskId: task.id,
@@ -471,11 +532,21 @@ function cancelPersonalRequest(request) {
471
532
  });
472
533
  getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL WHERE task_id = ?").run(request.taskId);
473
534
  }
474
- return updatePersonalRequest(getPersonalRequest(request.requestId), { state: "cancelled" });
535
+ const current = getPersonalRequest(request.requestId);
536
+ return updatePersonalRequest(current, {
537
+ state: "cancelled",
538
+ parameters: {
539
+ ...current.parameters,
540
+ taskRunId: runId,
541
+ cancellationCleanupCompleted: true
542
+ }
543
+ });
475
544
  });
545
+ stopPersonalRequestExecution(cancelled);
546
+ return cancelled;
476
547
  }
477
548
  function publishPersonalRequest(request) {
478
549
  publishConnectionWait(request.conversationId);
479
550
  }
480
551
  //#endregion
481
- export { assertPersonalRequestTimeRange, cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest, requirePersonalWorkerConnection, resolvePersonalRequestConnection, submitPersonalRequest };
552
+ export { assertPersonalRequestTimeRange, cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest, requirePersonalWorkerConnection, resolvePersonalRequestConnection, stopPersonalRequestExecution, submitPersonalRequest };
@@ -0,0 +1,3 @@
1
+ /** Preserve literal code; remove actionable local file references from prose. */
2
+ export declare function sanitizePersonalResultFileLinks(text: string): string;
3
+ export declare function hasPersonalResultFileLinks(text: string): boolean;
@@ -0,0 +1,21 @@
1
+ //#region src/personal-agent/result-file-links.ts
2
+ /** File delivery belongs to structured artifacts, not model-authored host links. */
3
+ function localTarget(value) {
4
+ let target = value.trim().replace(/^<|>$/g, "").replace(/\\([\\/])/g, "$1");
5
+ try {
6
+ target = decodeURIComponent(target);
7
+ } catch {}
8
+ return /^(?:\/|\\\\|~\/|\.\.?\/|[a-z]:[\\/]|file:|media:|xopc:\/\/workspace\/file)/i.test(target) || /^[^\s:?#]+\.(?:md|pdf|docx?|xlsx?|csv|pptx?|zip|png|jpe?g|webp|mp[34]|wav)(?:[?#].*)?$/i.test(target);
9
+ }
10
+ function cleanSegment(text) {
11
+ return text.replace(/^\s*MEDIA\s*:\s*.*$/gim, "").replace(/!?\[([^\]\n]*)\]\(\s*(<[^>]+>|[^\s)]+)(?:\s+["'][^\n]*?["'])?\s*\)/g, (match, label, target) => localTarget(target) ? label : match).replace(/^\s*\[[^\]\n]+\]:\s*(<[^>]+>|\S+).*$/gm, (match, target) => localTarget(target) ? "" : match).replace(/<([^<>\n]+)>/g, (match, target) => localTarget(target) ? "" : match).replace(/\b(?:file:\/\/|media:\/\/|xopc:\/\/workspace\/file)[^\s<>"'`]+/gi, "").replace(/(?<![\w:/])(?:\/(?:Users|home|tmp|private|workspace|var)\/|[a-z]:[\\/])[^\s<>"'`]+/gi, "");
12
+ }
13
+ /** Preserve literal code; remove actionable local file references from prose. */
14
+ function sanitizePersonalResultFileLinks(text) {
15
+ return text.split(/(```[\s\S]*?```|~~~[\s\S]*?~~~|`[^`\n]+`)/g).map((part, index) => index % 2 ? part : cleanSegment(part)).join("").trim();
16
+ }
17
+ function hasPersonalResultFileLinks(text) {
18
+ return sanitizePersonalResultFileLinks(text) !== text.trim();
19
+ }
20
+ //#endregion
21
+ export { hasPersonalResultFileLinks, sanitizePersonalResultFileLinks };
@@ -1,49 +1,36 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
1
3
  import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
4
+ import { getSessionInputById, getSessionInputState, init_session_input_repository } from "../storage/sqlite/session-input-repository.js";
2
5
  import { TaskRepository, init_task_repository } from "../tasks/task-repository.js";
3
6
  import { TaskRunRepository, init_task_run_repository } from "../tasks/task-run-repository.js";
4
7
  import { TaskAllocationRepository } from "../tasks/task-allocation-repository.js";
5
8
  import { TaskOriginRepository } from "../tasks/task-origin-repository.js";
6
- import { abortEmbeddedRun } from "../agent/embedded/runs.js";
9
+ import { abortEmbeddedRun, getEmbeddedRunByConversationId } from "../agent/embedded/runs.js";
7
10
  import { TaskApplicationService } from "../tasks/task-application-service.js";
8
11
  //#region src/personal-agent/task-cancel.ts
9
12
  init_transaction();
10
13
  init_task_repository();
11
14
  init_task_run_repository();
12
- /** Close before aborting so a late router decision or receipt cannot restart the task. */
13
- async function cancelPersonalTask(taskId, conversationId, key) {
14
- if (!new TaskOriginRepository().owns(taskId, conversationId)) throw new Error("Task does not belong to this personal conversation");
15
+ init_session_input_repository();
16
+ init_logger();
17
+ const log = createLogger("PersonalTaskCancel");
18
+ const pendingStops = /* @__PURE__ */ new Set();
19
+ function finalizeCancellation(runId) {
15
20
  const runs = new TaskRunRepository();
16
- const { active, changed } = runSqliteWriteTransaction(() => {
17
- const task = new TaskRepository().require(taskId);
18
- const run = runs.getActiveRoot(taskId);
19
- if (task.phase !== "closed") {
20
- if (!new TaskApplicationService().execute({
21
- taskId,
22
- expectedVersion: task.version,
23
- idempotencyKey: `personal-cancel:${key}`,
24
- command: {
25
- type: "close",
26
- resolution: "cancelled"
27
- },
28
- actor: { kind: "user" }
29
- }).ok) throw new Error("Task changed while cancelling");
30
- } else if (task.resolution !== "cancelled") throw new Error("Task is already closed");
31
- getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL, updated_at = ? WHERE task_id = ? AND status != 'cancelled'").run(Date.now(), taskId);
32
- return {
33
- active: run,
34
- changed: task.phase !== "closed"
35
- };
36
- });
37
- const latest = active ?? runs.getLatestRoot(taskId);
38
- let executionStopConfirmed = !latest || !latest.conversationId && !latest.startedAt && ["queued", "cancelled"].includes(latest.status);
39
- if (active?.conversationId) {
40
- await abortEmbeddedRun(active.conversationId);
41
- executionStopConfirmed = false;
42
- }
43
- const current = active ? runs.get(active.id) : void 0;
44
- if (current && runs.getActiveRoot(taskId)?.id === current.id) new TaskApplicationService().completeRun({
45
- runId: current.id,
46
- expectedRunVersion: current.version,
21
+ const run = runId ? runs.get(runId) : void 0;
22
+ if (!run || ![
23
+ "queued",
24
+ "running",
25
+ "waiting",
26
+ "verifying",
27
+ "cancelled"
28
+ ].includes(run.status)) return;
29
+ runs.resolveCancelledRunWaits(run.id, { kind: "user" });
30
+ if (run.status === "cancelled") return;
31
+ if (!new TaskApplicationService().completeRun({
32
+ runId: run.id,
33
+ expectedRunVersion: run.version,
47
34
  actor: { kind: "user" },
48
35
  terminalCode: "cancelled_by_user",
49
36
  suppressAttention: true,
@@ -60,7 +47,70 @@ async function cancelPersonalTask(taskId, conversationId, key) {
60
47
  needsUser: false,
61
48
  completionVerdict: "not_achieved"
62
49
  }
50
+ }).ok) throw new Error("Task changed while cancelling");
51
+ }
52
+ /** Close before aborting so a late router decision or receipt cannot restart the task. */
53
+ async function cancelPersonalTask(taskId, conversationId, key) {
54
+ if (!new TaskOriginRepository().owns(taskId, conversationId)) throw new Error("Task does not belong to this personal conversation");
55
+ const runs = new TaskRunRepository();
56
+ const { active, changed, targetKnown } = runSqliteWriteTransaction(() => {
57
+ const previous = getSqliteDatabase().prepare(`SELECT subject_id, result_json FROM command_deduplication
58
+ WHERE idempotency_key = ?`).get(`personal-cancel:${key}`);
59
+ if (previous) {
60
+ if (previous.subject_id !== taskId) throw new Error("Cancellation key belongs to another Task");
61
+ const saved = JSON.parse(previous.result_json);
62
+ const active = saved.cancellationRunId ? runs.get(saved.cancellationRunId) : void 0;
63
+ finalizeCancellation(active?.id);
64
+ return {
65
+ active,
66
+ changed: false,
67
+ targetKnown: Object.hasOwn(saved, "cancellationRunId")
68
+ };
69
+ }
70
+ const task = new TaskRepository().require(taskId);
71
+ if (task.phase === "closed" && task.resolution !== "cancelled") throw new Error("Task is already closed");
72
+ const run = runs.getActiveRoot(taskId) ?? (task.phase === "closed" ? runs.getLatestRoot(taskId) : void 0);
73
+ if (!new TaskApplicationService().execute({
74
+ taskId,
75
+ expectedVersion: task.version,
76
+ idempotencyKey: `personal-cancel:${key}`,
77
+ command: {
78
+ type: "close",
79
+ resolution: "cancelled"
80
+ },
81
+ actor: { kind: "user" }
82
+ }).ok) throw new Error("Task changed while cancelling");
83
+ getSqliteDatabase().prepare(`UPDATE command_deduplication SET result_json = json_set(result_json, '$.cancellationRunId', ?)
84
+ WHERE idempotency_key = ?`).run(run?.id ?? null, `personal-cancel:${key}`);
85
+ getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL, updated_at = ? WHERE task_id = ? AND status != 'cancelled'").run(Date.now(), taskId);
86
+ finalizeCancellation(run?.id);
87
+ return {
88
+ active: run,
89
+ changed: task.phase !== "closed",
90
+ targetKnown: true
91
+ };
63
92
  });
93
+ let executionStopConfirmed = targetKnown && (!active || !active.conversationId && !active.startedAt && ["queued", "cancelled"].includes(active.status));
94
+ if (active?.conversationId) {
95
+ const state = getSessionInputState(active.conversationId);
96
+ const input = state.activeInputId ? getSessionInputById(active.conversationId, state.activeInputId) : void 0;
97
+ const embedded = getEmbeddedRunByConversationId(active.conversationId);
98
+ const executionId = input?.taskRunId === active.id ? state.activeRunId : embedded?.runId === active.id ? active.id : void 0;
99
+ if (executionId && !pendingStops.has(executionId)) {
100
+ pendingStops.add(executionId);
101
+ abortEmbeddedRun(active.conversationId, "user_cancelled", executionId).catch((err) => {
102
+ log.warn({
103
+ err,
104
+ taskId,
105
+ runId: active.id,
106
+ executionId
107
+ }, "Task cancelled; execution stop was not confirmed");
108
+ }).finally(() => {
109
+ pendingStops.delete(executionId);
110
+ });
111
+ }
112
+ executionStopConfirmed = false;
113
+ }
64
114
  if (changed && new TaskAllocationRepository().get(taskId)) {
65
115
  const zh = new TaskRepository().require(taskId).locale === "zh";
66
116
  runSqliteWriteTransaction(() => new TaskAllocationRepository().publish(taskId, zh ? "任务已取消。" : "Task cancelled."));
@@ -50,7 +50,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
50
50
  task: {
51
51
  id: string;
52
52
  title: string;
53
- phase: "backlog" | "ready" | "active" | "review" | "closed";
53
+ phase: "review" | "backlog" | "ready" | "active" | "closed";
54
54
  priority: "low" | "normal" | "high" | "critical";
55
55
  source: string;
56
56
  latestContractVersion: number;
@@ -170,6 +170,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
170
170
  criterion: string;
171
171
  status: "failed" | "passed" | "unverified";
172
172
  evidenceTitles: string[];
173
+ note?: string;
174
+ method?: "unverified" | "model_reviewed" | "tool_verified";
173
175
  }[];
174
176
  };
175
177
  remainingWork: string[];
@@ -201,7 +203,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
201
203
  task: {
202
204
  id: string;
203
205
  title: string;
204
- phase: "backlog" | "ready" | "active" | "review" | "closed";
206
+ phase: "review" | "backlog" | "ready" | "active" | "closed";
205
207
  priority: "low" | "normal" | "high" | "critical";
206
208
  source: string;
207
209
  latestContractVersion: number;
@@ -321,6 +323,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
321
323
  criterion: string;
322
324
  status: "failed" | "passed" | "unverified";
323
325
  evidenceTitles: string[];
326
+ note?: string;
327
+ method?: "unverified" | "model_reviewed" | "tool_verified";
324
328
  }[];
325
329
  };
326
330
  remainingWork: string[];
@@ -351,7 +355,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
351
355
  task: {
352
356
  id: string;
353
357
  title: string;
354
- phase: "backlog" | "ready" | "active" | "review" | "closed";
358
+ phase: "review" | "backlog" | "ready" | "active" | "closed";
355
359
  priority: "low" | "normal" | "high" | "critical";
356
360
  source: string;
357
361
  latestContractVersion: number;
@@ -471,6 +475,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
471
475
  criterion: string;
472
476
  status: "failed" | "passed" | "unverified";
473
477
  evidenceTitles: string[];
478
+ note?: string;
479
+ method?: "unverified" | "model_reviewed" | "tool_verified";
474
480
  }[];
475
481
  };
476
482
  remainingWork: string[];
@@ -527,7 +533,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
527
533
  task: {
528
534
  id: string;
529
535
  title: string;
530
- phase: "backlog" | "ready" | "active" | "review" | "closed";
536
+ phase: "review" | "backlog" | "ready" | "active" | "closed";
531
537
  priority: "low" | "normal" | "high" | "critical";
532
538
  source: string;
533
539
  latestContractVersion: number;
@@ -647,6 +653,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
647
653
  criterion: string;
648
654
  status: "failed" | "passed" | "unverified";
649
655
  evidenceTitles: string[];
656
+ note?: string;
657
+ method?: "unverified" | "model_reviewed" | "tool_verified";
650
658
  }[];
651
659
  };
652
660
  remainingWork: string[];
@@ -677,7 +685,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
677
685
  task: {
678
686
  id: string;
679
687
  title: string;
680
- phase: "backlog" | "ready" | "active" | "review" | "closed";
688
+ phase: "review" | "backlog" | "ready" | "active" | "closed";
681
689
  priority: "low" | "normal" | "high" | "critical";
682
690
  source: string;
683
691
  latestContractVersion: number;
@@ -797,6 +805,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
797
805
  criterion: string;
798
806
  status: "failed" | "passed" | "unverified";
799
807
  evidenceTitles: string[];
808
+ note?: string;
809
+ method?: "unverified" | "model_reviewed" | "tool_verified";
800
810
  }[];
801
811
  };
802
812
  remainingWork: string[];
@@ -297,7 +297,7 @@ function buildSessionContextForLlm(rows) {
297
297
  continue;
298
298
  }
299
299
  if (isTranscriptCustomMessageEntry(r)) {
300
- if (r.customType === "personal_request_status") continue;
300
+ if (r.customType === "personal_request_status" || r.customType === "connection_control_status") continue;
301
301
  if (r.customType === "personal_proactive_message") {
302
302
  const message = parsePersonalProactiveMessage(r.details);
303
303
  if (message) out.push({
@@ -350,7 +350,7 @@ function buildSessionDisplayMessages(rows) {
350
350
  const out = [];
351
351
  for (const r of rows) {
352
352
  if (isTranscriptCustomMessageEntry(r)) {
353
- if (r.customType === "personal_request_status") {
353
+ if (r.customType === "personal_request_status" || r.customType === "connection_control_status") {
354
354
  out.push({
355
355
  role: "assistant",
356
356
  content: [{
@@ -116,7 +116,9 @@ export declare class SessionStore {
116
116
  private buildSessionDetail;
117
117
  loadTranscriptRows(key: string): Promise<TranscriptStoredRow[]>;
118
118
  loadTranscriptHistoryRows(key: string): Promise<TranscriptStoredRow[]>;
119
- prepareModelFallback(key: string, rowsBeforeAttempt: readonly TranscriptStoredRow[]): Promise<ModelFallbackPreparation>;
119
+ prepareModelFallback(key: string, rowsBeforeAttempt: readonly TranscriptStoredRow[], options?: {
120
+ resumeTaskContinuation?: boolean;
121
+ }): Promise<ModelFallbackPreparation>;
120
122
  getMetadata(key: string): Promise<SessionMetadata | null>;
121
123
  resolveKeyByTranscriptId(transcriptId: string): Promise<string | null>;
122
124
  updateMetadata(key: string, updates: Partial<SessionMetadata>): Promise<void>;
@@ -15,7 +15,7 @@ import { init_sqlite } from "../storage/sqlite/index.js";
15
15
  import { init_agent_session_key, resolveAgentIdFromConversationId } from "../routing/agent-session-key.js";
16
16
  import { resolveUserContextSessionAccess } from "../user-context/access-policy.js";
17
17
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
18
- import { canResumeAfterModelFailure } from "../agent/orchestration/turn-recovery.js";
18
+ import { ACCEPTANCE_REPAIR_READ_TOOLS, canResumeAfterModelFailure } from "../agent/orchestration/turn-recovery.js";
19
19
  import { DurableState } from "../storage/sqlite/durable-state.js";
20
20
  import { transcriptRowsToClientHistory } from "./client-history.js";
21
21
  import { SessionCompactor } from "../agent/memory/compaction.js";
@@ -272,7 +272,7 @@ var SessionStore = class {
272
272
  requireXopcDatabase();
273
273
  return loadTranscriptHistoryRowsForSession(key);
274
274
  }
275
- async prepareModelFallback(key, rowsBeforeAttempt) {
275
+ async prepareModelFallback(key, rowsBeforeAttempt, options) {
276
276
  return this.runStoreMutation(async () => {
277
277
  requireXopcDatabase();
278
278
  const currentRows = loadTranscriptRowsForSession(key);
@@ -289,7 +289,17 @@ var SessionStore = class {
289
289
  "assistant",
290
290
  "toolResult"
291
291
  ].includes(String(row.role)));
292
- if (appendedRows.some((row) => isTranscriptMessageRole(row, "user")) && appendedRows.filter((row) => isTranscriptMessageRole(row, "user")).length === 1 && (isTranscriptMessageRole(tail, "user") || isTranscriptMessageRole(tail, "toolResult")) && canResumeAfterModelFailure(preparedRows) || appendedRows.length === 1 && isTranscriptMessageRole(appendedRows[0], "user") || removedError && appendedRows.length === 0 && isTranscriptMessageRole(preparedRows.at(-1), "user")) {
292
+ const onlyRecoveryMetadata = appendedRows.every((row) => "type" in row && row.type === "custom" && [
293
+ "coding_run_started",
294
+ "coding_verification",
295
+ "codemode-store",
296
+ "xopc-tool-discovery-state"
297
+ ].includes(String(row.customType)));
298
+ if (removedError && options?.resumeTaskContinuation && onlyRecoveryMetadata && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS })) {
299
+ archiveFailedModelAttempts(key, rowsBeforeAttempt.length);
300
+ return "prompt";
301
+ }
302
+ if (appendedRows.some((row) => isTranscriptMessageRole(row, "user")) && appendedRows.filter((row) => isTranscriptMessageRole(row, "user")).length === 1 && (isTranscriptMessageRole(tail, "user") || isTranscriptMessageRole(tail, "toolResult")) && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS }) || appendedRows.length === 1 && isTranscriptMessageRole(appendedRows[0], "user") || removedError && appendedRows.length === 0 && isTranscriptMessageRole(preparedRows.at(-1), "user") || removedError && onlyRecoveryMetadata && (isTranscriptMessageRole(tail, "user") || isTranscriptMessageRole(tail, "toolResult")) && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS })) {
293
303
  if (removedError) archiveFailedModelAttempts(key, rowsBeforeAttempt.length);
294
304
  return "resume";
295
305
  }
@@ -21,6 +21,9 @@ export declare function requireSessionConnection(input: {
21
21
  status: 'connection_required' | 'skipped' | 'objective_conflict';
22
22
  waitId?: string;
23
23
  };
24
+ /** Pending messages may revise the goal; controls cannot become a competing model execution. */
25
+ export declare function interruptedConnectionMessage(wait: ConnectionWait): SessionInput | undefined;
26
+ export declare function hasPendingConnectionMessages(wait: ConnectionWait, includeControls?: boolean): boolean;
24
27
  /** The input and the wait transition commit together, using the existing queue's unique key. */
25
28
  export declare function queueConnectionResolution(wait: ConnectionWait, resolution: 'continued' | 'skipped', resolvePersonal?: (wait: ConnectionWait, resolution: 'continued' | 'skipped') => unknown): ConnectionWait;
26
29
  export declare function consumeConnectionResume(input: SessionInput): boolean;
@@ -29,10 +32,10 @@ export declare function connectionBindings(conversationId: string): ConnectionNe
29
32
  export declare function connectorObjectiveScope(conversationId: string): string | undefined;
30
33
  export declare function bindObjectiveAccount(conversationId: string, connectorId: string, accountId: string): void;
31
34
  export declare function connectionBinding(conversationId: string, connectorId: string): string | undefined;
32
- /** New input wins over an outstanding auto-resume intent, including an already queued resume. */
35
+ /** Explicit objective changes invalidate an outstanding auto-resume intent. */
33
36
  export declare function invalidateConnectionResumeIntent(conversationId: string): void;
34
37
  export declare function reviseCurrentConnectionObjective(conversationId: string, summary: string | undefined): void;
35
- export declare function cancelConnectionObjective(conversationId: string): void;
38
+ export declare function cancelConnectionObjective(conversationId: string, expectedWaitId?: string, expectedObjectiveRevision?: number): void;
36
39
  export declare function getConnectionResumeInput(conversationId: string, runId: string): SessionInput | undefined;
37
40
  export declare function listConnectionWaitsToCheck(): ConnectionWait[];
38
41
  /** A queued wait has not crossed consumeConnectionResume's execution boundary. */