@xopcai/xopc 0.0.205 → 0.0.207

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 (208) hide show
  1. package/README.md +7 -7
  2. package/README.zh-CN.md +7 -7
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-DJBadfSX.js → activity-store-BmpM0zwM.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Br6C32BX.js → agent-avatar-dicebear-DhK5wi6_.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-Bc3Lc-n2.js +68 -0
  8. package/dist/gateway/static/root/assets/{api-B5O7fKXa.js → api-CzaAcDOn.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-Le1vJ1OO.js → app-management-settings-panel-Dqj5G_cd.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-CZlAU60t.js → appearance-settings-Bm1uLGMi.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-BKtwU47-.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-CRzXRXPE.js → archive-plugin-CgnzBplN.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-CYAAQ6Qi.js → attachment-load-Cuybcmhn.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-page-ilGeRLDN.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-CVR5cUmS.js → binary-plugins-D6BBx6Ps.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-CFe74rWi.js → block-editor-Dk1c3Spa.js} +46 -46
  17. package/dist/gateway/static/root/assets/browser-settings-page-BCu8AZbs.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bd68yluo.js → browser-workflow-inputs-DvfIzCgV.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-B0uiDLga.js → browser-workflows-page-DZScuPlF.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-BbWQBtTe.js +7 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-BerPMp6f.js → capability-presets-api-hoA8R_J1.js} +1 -1
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BTVU46Yn.js +3 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-D2d21_XA.js → channel-recipient-api-BS8I65NT.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-BEQsC9a9.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-DRwbgtOT.js +1 -0
  26. package/dist/gateway/static/root/assets/chat-terminal-dock-BIPhWBDI.js +36 -0
  27. package/dist/gateway/static/root/assets/chat-terminal-dock-uQUnjRtf.css +1 -0
  28. package/dist/gateway/static/root/assets/{connectors-api-Bq_vUzxP.js → connectors-api-B_78jmvM.js} +1 -1
  29. package/dist/gateway/static/root/assets/connectors-page-w_3kpqbc.js +2 -0
  30. package/dist/gateway/static/root/assets/{cron-expression-DZBxmKGR.js → cron-expression-BBheaBIr.js} +1 -1
  31. package/dist/gateway/static/root/assets/{date-picker-BNHd7HT7.js → date-picker-CDwj7UrT.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-D1kJBknt.js → dependency-picker-Dnrc2qZe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-Di75oHkC.js → desktop-pet-Bj_vUjXp.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-D6tD1uym.js → desktop-pet-settings-uiCwJJk4.js} +1 -1
  35. package/dist/gateway/static/root/assets/directory-picker-path-field-D0zUQ-TO.js +1 -0
  36. package/dist/gateway/static/root/assets/{extension-debug-page-D91_S7NQ.js → extension-debug-page-_GZ4y2da.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-DHzmmr_N.js → extension-page-scR96Edg.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-settings-page-BpJNtePi.js → extension-settings-page-CILsAwxx.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-api-BAzLYTKZ.js → gateway-config-api-984O_4wM.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-VVcfd3sG.js → gateway-config-swr-D4hvsdJA.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-settings-C5-aKkTp.js → gateway-settings-aF4eQHo3.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-qAX_T2t2.js → gateway-startup-retry-Deo5-O87.js} +1 -1
  43. package/dist/gateway/static/root/assets/heartbeat-settings-D5DrFWH6.js +1 -0
  44. package/dist/gateway/static/root/assets/home-page-DiMWxngC.js +3 -0
  45. package/dist/gateway/static/root/assets/index-DzKLVgY-.js +85 -0
  46. package/dist/gateway/static/root/assets/index-wR5jX-lw.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fpNjXnJK.js → keyboard-shortcuts-settings-DGmOlNcB.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-De8vuwu1.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-DBpQIfNd.js → local-apps-page-CzS2sCxg.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-CbPVxonP.js → locale-store-C7xtkP3D.js} +1 -1
  51. package/dist/gateway/static/root/assets/logs-page-BI9stsVO.js +2 -0
  52. package/dist/gateway/static/root/assets/{management-settings-CiK7Xkvi.js → management-settings-Cpxs43JB.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-DVgpcOze.js → markdown-split-CQvFHxUa.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-view-Dl-0_9JR.js → markdown-view-BRwrSbwM.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-DMj1lW-n.js → media-plugins-Bs9MsiaM.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-Dxk5Rzj_.js +3 -0
  57. package/dist/gateway/static/root/assets/{notes-page-DvX1sTlf.js → notes-page-Dux_g6aZ.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CGafcgJ8.js +4 -0
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-DvsLigha.js → preview-open-alternatives-fvhtN4Y2.js} +1 -1
  60. package/dist/gateway/static/root/assets/{product-open-page-DbCraAI3.js → product-open-page-f_jbg-9N.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-C6mNsjYr.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-D1G6VIxR.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-CIez6X0x.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DzuUglQo.js → runtime-tools-settings-panel-zapSiJrv.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-plDnazVj.js → schema-form-CFyz8y5v.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-6irxQjHb.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-CRb0QTG2.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-BwAxX_7e.js → settings-form-section-DCiK4TIq.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-B3OiTnF9.js → settings-loading-skeleton-DFUJEv4G.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-DvIWXBvp.js → settings-page-Cnp9Bdd0.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-DThKKjLV.js → setup-status-panel-BFMGTGBO.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-CFnoGHJb.js → share-preview-page-DA8nA4cz.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CaKfvJzQ.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-BOBUcYr5.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-B38fY22S.js → skills-page-BJJACxzz.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-vLIlk1c3.js → skills-page.utils--1-vOg3V.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DRV2wljT.js → system-settings-panel-DY0lIaXY.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-Ciuwe7AG.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Bc_eRUev.js → theme-store-DoyRfkoi.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-DTu23D9J.js → use-autosave-DzIR5Lxf.js} +1 -1
  81. package/dist/gateway/static/root/assets/{user-context-page-DCwqzN03.js → user-context-page-yf18T_BZ.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-CVDMesWc.js → voice-api-key-field-B7MZS8tS.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-cyt93k0V.js → work-discovery-overlay-zyX6yxxF.js} +1 -1
  84. package/dist/gateway/static/root/assets/work-discovery-page-2e5J0sIp.js +1 -0
  85. package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cj1vPWRM.js +3 -0
  86. package/dist/gateway/static/root/assets/workflows-page-D37zWlWY.js +5 -0
  87. package/dist/gateway/static/root/assets/{working-directory-picker-modal-CYWdZUJ5.js → working-directory-picker-modal-Bm7cox3y.js} +1 -1
  88. package/dist/gateway/static/root/index.html +10 -10
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +11 -0
  91. package/dist/src/agent/agent-manager.js +36 -6
  92. package/dist/src/agent/embedded/transcript-runtime.d.ts +2 -1
  93. package/dist/src/agent/embedded/transcript-runtime.js +38 -4
  94. package/dist/src/agent/inbound/inbound-loop.d.ts +1 -1
  95. package/dist/src/agent/memory/compaction-ledger.d.ts +11 -0
  96. package/dist/src/agent/memory/compaction-ledger.js +108 -0
  97. package/dist/src/agent/memory/compaction-serializer.d.ts +2 -0
  98. package/dist/src/agent/memory/compaction-serializer.js +52 -0
  99. package/dist/src/agent/memory/compaction-source-planner.d.ts +20 -0
  100. package/dist/src/agent/memory/compaction-source-planner.js +67 -0
  101. package/dist/src/agent/memory/compaction.d.ts +11 -5
  102. package/dist/src/agent/memory/compaction.js +245 -153
  103. package/dist/src/agent/prompt/sections/behavior.js +1 -1
  104. package/dist/src/agent/prompt/sections/memory-skills.js +4 -2
  105. package/dist/src/agent/prompt/sections/tooling.js +2 -0
  106. package/dist/src/agent/service.d.ts +4 -1
  107. package/dist/src/agent/service.js +12 -0
  108. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  109. package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
  110. package/dist/src/agent/tools/factory.js +5 -0
  111. package/dist/src/agent/tools/index.d.ts +1 -0
  112. package/dist/src/agent/tools/index.js +2 -1
  113. package/dist/src/agent/tools/session-recall-tool.d.ts +7 -0
  114. package/dist/src/agent/tools/session-recall-tool.js +82 -0
  115. package/dist/src/agent/tools/xopc-use-tool.js +6 -2
  116. package/dist/src/automations/api/routes.js +8 -0
  117. package/dist/src/automations/domain/index.js +2 -2
  118. package/dist/src/automations/domain/types.d.ts +17 -12
  119. package/dist/src/automations/domain/validation.d.ts +30 -32
  120. package/dist/src/automations/domain/validation.js +8 -10
  121. package/dist/src/automations/draft/automation-draft-prompt.js +9 -5
  122. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -8
  123. package/dist/src/automations/draft/automation-draft-validator.js +3 -3
  124. package/dist/src/automations/index.js +2 -2
  125. package/dist/src/automations/service/action-executor.js +13 -4
  126. package/dist/src/automations/service/automation-service.d.ts +5 -1
  127. package/dist/src/automations/service/automation-service.js +19 -12
  128. package/dist/src/automations/storage/automation-repository.js +8 -4
  129. package/dist/src/automations/storage/automation-run-repository.d.ts +5 -0
  130. package/dist/src/automations/storage/automation-run-repository.js +24 -8
  131. package/dist/src/automations/storage/index.js +2 -2
  132. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  133. package/dist/src/config/agent-profile.js +1 -1
  134. package/dist/src/config/schema.d.ts +1 -0
  135. package/dist/src/gateway/agents-admin.js +1 -1
  136. package/dist/src/gateway/automation-agent-session.d.ts +4 -0
  137. package/dist/src/gateway/automation-agent-session.js +40 -0
  138. package/dist/src/gateway/dreaming-automation-reconciler.js +3 -2
  139. package/dist/src/gateway/heartbeat/service.js +1 -1
  140. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  141. package/dist/src/gateway/hono/routes/commands-skills.js +36 -2
  142. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  143. package/dist/src/gateway/service/marketplace-service.d.ts +4 -1
  144. package/dist/src/gateway/service/marketplace-service.js +9 -0
  145. package/dist/src/gateway/service/run-gateway-agent.js +3 -3
  146. package/dist/src/gateway/service.js +19 -2
  147. package/dist/src/heartbeat/index.js +1 -1
  148. package/dist/src/mobile/notification-service.js +7 -4
  149. package/dist/src/session/compaction-types.d.ts +30 -0
  150. package/dist/src/session/compaction-types.js +35 -0
  151. package/dist/src/session/manager.d.ts +3 -0
  152. package/dist/src/session/session-context-for-llm.d.ts +4 -2
  153. package/dist/src/session/session-context-for-llm.js +2 -1
  154. package/dist/src/session/store.d.ts +10 -1
  155. package/dist/src/session/store.js +55 -23
  156. package/dist/src/session/types.d.ts +3 -2
  157. package/dist/src/storage/sqlite/index.d.ts +1 -1
  158. package/dist/src/storage/sqlite/index.js +2 -2
  159. package/dist/src/storage/sqlite/migrations/121_automation_inbox.sql +24 -0
  160. package/dist/src/storage/sqlite/migrations/122_automation_session_projects.sql +18 -0
  161. package/dist/src/storage/sqlite/migrations/123_remove_v2_compaction_boundaries.sql +25 -0
  162. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  163. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  164. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  165. package/dist/src/storage/sqlite/schema.js +1 -1
  166. package/dist/src/storage/sqlite/transcript-repository.d.ts +24 -1
  167. package/dist/src/storage/sqlite/transcript-repository.js +78 -29
  168. package/dist/src/user-context/config.d.ts +4 -0
  169. package/dist/src/user-context/config.js +2 -0
  170. package/package.json +4 -3
  171. package/skills/THIRD_PARTY_NOTICES.md +1 -1
  172. package/skills/engineering/define-task/SKILL.md +48 -0
  173. package/skills/engineering/define-task/references/task-contract-rubric.md +15 -0
  174. package/dist/gateway/static/root/assets/agents-DnFIy8Ye.js +0 -68
  175. package/dist/gateway/static/root/assets/apps-page-CONlVc-f.js +0 -1
  176. package/dist/gateway/static/root/assets/automations-page-DuG69tIj.js +0 -6
  177. package/dist/gateway/static/root/assets/browser-settings-page-Cvt-8fqE.js +0 -8
  178. package/dist/gateway/static/root/assets/capabilities-settings-panel-yk3QkGBP.js +0 -7
  179. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJjVOCJY.js +0 -3
  180. package/dist/gateway/static/root/assets/channels-settings-CaNnYUQo.js +0 -1
  181. package/dist/gateway/static/root/assets/channels-status-swr-CZ5P9jbB.js +0 -1
  182. package/dist/gateway/static/root/assets/connectors-page-DTpCnOsQ.js +0 -2
  183. package/dist/gateway/static/root/assets/directory-picker-path-field-Ly0TUflq.js +0 -1
  184. package/dist/gateway/static/root/assets/heartbeat-settings-CMZr1_Op.js +0 -1
  185. package/dist/gateway/static/root/assets/home-page-CBG9Bk-1.js +0 -3
  186. package/dist/gateway/static/root/assets/index-BBw9QL0p.js +0 -85
  187. package/dist/gateway/static/root/assets/index-Dm-cvIpl.css +0 -2
  188. package/dist/gateway/static/root/assets/local-app-workbench-page-Bi_0Sknt.js +0 -2
  189. package/dist/gateway/static/root/assets/logs-page-BmXcJCKz.js +0 -2
  190. package/dist/gateway/static/root/assets/messages-9zCa8KkW.js +0 -3
  191. package/dist/gateway/static/root/assets/notes-workbench-CMyosgjY.js +0 -4
  192. package/dist/gateway/static/root/assets/project-detail-page-DkS-kbpj.js +0 -1
  193. package/dist/gateway/static/root/assets/projects-page-B3NxP6S4.js +0 -1
  194. package/dist/gateway/static/root/assets/remote-access-hub-DwhrMhjl.js +0 -1
  195. package/dist/gateway/static/root/assets/sessions-page-BOfXXmBL.js +0 -1
  196. package/dist/gateway/static/root/assets/settings-advanced-gate-sPrZfZVR.js +0 -1
  197. package/dist/gateway/static/root/assets/shares-settings-Dvl13Udt.js +0 -1
  198. package/dist/gateway/static/root/assets/skill-reload-api-D9elkZOz.js +0 -1
  199. package/dist/gateway/static/root/assets/task-detail-page-Xd8PlB24.js +0 -1
  200. package/dist/gateway/static/root/assets/work-discovery-page--DTi90d5.js +0 -1
  201. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DrdcfX_N.js +0 -3
  202. package/dist/gateway/static/root/assets/workflows-page-DXyButkm.js +0 -5
  203. package/dist/src/agent/memory/compaction-planner.d.ts +0 -16
  204. package/dist/src/agent/memory/compaction-planner.js +0 -168
  205. package/dist/src/agent/memory/summary-generator.d.ts +0 -46
  206. package/dist/src/agent/memory/summary-generator.js +0 -229
  207. package/skills/engineering/define-goal/SKILL.md +0 -41
  208. package/skills/engineering/define-goal/references/objective-rubric.md +0 -12
@@ -1 +1 @@
1
- export declare const xopcUseManual = "# XOPC Use Tool Manual\n\n## Purpose\n\n`xopc_use` operates first-class XOPC product objects without editing SQLite or product files directly.\nLoad this manual before a non-trivial mutation.\n\n```json\n{\n \"mode\": \"project | automation | note | task | task_run | local_app | settings\",\n \"command\": \"...\",\n \"args\": {},\n \"dryRun\": false\n}\n```\n\nSend one object command per call. Inspect the returned JSON `ok` field; a tool call can\ncomplete successfully while the product command returns `ok: false`.\n\n## Object routing\n\n| Object | Tool |\n| --- | --- |\n| Project, milestone, project update | `xopc_use` mode `project` |\n| Automation | `xopc_use` mode `automation` |\n| Task intent and lifecycle | `xopc_use` mode `task` |\n| Task execution attempt, receipt, events and waits | `xopc_use` mode `task_run` |\n| Note | `xopc_use` mode `note` |\n| Local app | `xopc_use` mode `local_app` |\n| Settings jump target | `xopc_use` mode `settings` |\n| Workflow run | dedicated `workflow` tool; pass `taskId` to link it to a Task |\n| Session, memory, skill, connected app or workspace file | its dedicated tool |\n\nDo not emulate Workflow APIs through `xopc_use`. A Task is durable intent;\na TaskRun is one execution attempt; a WorkflowRun is a procedure execution and may belong\nto a TaskRun. Never treat these three objects as interchangeable.\n\n## Reliable protocol\n\n1. Use `list` then `get` when an id is unknown.\n2. Read the current `version` before a Task mutation.\n3. Use `dryRun: true` for broad Project changes or uncertain mutations.\n4. Mutate once with the exact id and current concurrency token.\n5. Verify the returned object and preserve any \u201COpen in xopc\u201D delivery link.\n6. On a conflict, read again and reconsider the operation; do not blindly retry.\n\nTimestamps are Unix epoch milliseconds. Array fields are arrays of strings. Omission\npreserves a patchable field; an empty array intentionally clears it. Prefer explicit\n`projectId`, `taskId`, `runId`, `noteId`, and `localAppId` fields over `id`.\n\n## Projects\n\nCommands: `list`, `get`, `create`, `update`, `resolve_workspace`,\n`list_milestones`, `create_milestone`, `update_milestone`, `list_updates`,\nand `create_update`.\n\nProject statuses: `planned`, `active`, `paused`, `completed`, `cancelled`,\n`archived`. Health values: `unknown`, `on_track`, `at_risk`, `off_track`.\n\nA Project defines a bounded goal. Its durable planning fields are `outcome`,\n`successCriteria`, `scope`, `nonGoals`, `ownerId`, `targetAt`, and `health`.\nUse `brief` for a concise description and `instructions` for durable operating guidance.\n\n### Create\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"AI Product Research\",\n \"outcome\": \"Choose a validated product direction\",\n \"successCriteria\": [\"Ten customer interviews\", \"Decision recorded\"],\n \"scope\": { \"market\": \"developer tools\" },\n \"nonGoals\": [\"Build the production product\"],\n \"health\": \"on_track\",\n \"targetAt\": 1760000000000,\n \"workspaceRoot\": \"/path/to/repo\"\n }\n}\n```\n\n### Update\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"status\": \"active\",\n \"health\": \"at_risk\",\n \"successCriteria\": [\"Ten interviews\", \"Evidence-backed decision\"]\n }\n}\n```\n\n### Resolve a workspace\n\nUse `autoCreate: false` for lookup. Set it to true only when creating a Project is authorized.\n\n```json\n{ \"mode\": \"project\", \"command\": \"resolve_workspace\", \"args\": { \"workspacePath\": \"/path/to/repo\", \"autoCreate\": false } }\n```\n\n### Milestones\n\nMilestone statuses: `planned`, `active`, `completed`, `cancelled`.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_milestone\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"title\": \"Finish discovery\",\n \"status\": \"active\",\n \"targetAt\": 1760000000000,\n \"sortOrder\": 10\n }\n}\n```\n\nUse `list_milestones` with `projectId`. Use `update_milestone` with both\n`projectId` and `milestoneId`. Milestone deletion is intentionally not exposed.\n\n### Immutable project updates\n\nProject updates are append-only progress snapshots. They also update Project health.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"health\": \"on_track\",\n \"summary\": \"Discovery is complete\",\n \"progress\": [\"Interviewed ten users\"],\n \"risks\": [\"Pricing remains unvalidated\"],\n \"nextSteps\": [\"Run pricing tests\"]\n }\n}\n```\n\nUse `list_updates` with `projectId` and optional `limit`. Updates cannot be edited.\n\n## Automations\n\nCommands: `list`, `get`, `create`, `update`, `delete`, `run`, `pause`,\n`resume`, and `history`.\n\nAutomation `create` automatically uses the current session Project when `projectId` is\nomitted. An explicit `projectId` takes precedence and is validated before mutation. Use an\nexplicit id when creating for a Project other than the current session Project.\n\n### Create in the current Project\n\n`trigger` and `action` use the same shapes as the Automation product API.\n\n```json\n{\n \"mode\": \"automation\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"Daily project review\",\n \"trigger\": { \"kind\": \"schedule\", \"schedule\": { \"kind\": \"cron\", \"expr\": \"0 9 * * 1-5\", \"tz\": \"Asia/Shanghai\" } },\n \"action\": { \"kind\": \"agent\", \"instruction\": \"Review the current project and summarize risks.\" }\n }\n}\n```\n\nTo override the inherited Project, add `\"projectId\": \"project_id\"` to `args`.\nThe create payload may also be nested under `args.automation`; top-level `args.projectId`\nhas precedence.\n\n### List and history\n\n`list` and unqualified `history` inherit the current session Project. Pass an explicit\n`projectId` to query another Project. Pass `automationId` to `history` for one Automation.\n\n### Update and operate\n\nUse `automationId` for `get`, `update`, `delete`, `run`, `pause`, and `resume`.\nFor `update`, patch fields may be direct args or nested under `args.patch`. Supplying a new\n`projectId` reassigns the Automation after validating the target Project.\n\n## Tasks\n\nCommands: `list`, `get`, `create`, `update_dependencies`, `add_context`,\n`remove_context`, and `command`.\n\nTask phases are `backlog`, `ready`, `active`, `review`, and `closed`.\nOperational state is projected separately as `idle`, `queued`, `running`, `waiting`,\n`verifying`, `succeeded`, `failed`, or `cancelled`. Never send either value as a\nfree-form status update.\n\n`task.get` returns the Task, its projected `model`, dependencies, dependents, context,\nauthority grants, TaskRuns, receipts, and waits.\nThe projected model is the correct source for current operational state and attention items.\n\n### Capture or start\n\n`createMode` defaults to `capture`, which creates a backlog Task without executing it.\nUse `start` only when immediate execution is intended.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"create\",\n \"args\": {\n \"objective\": \"Complete the customer research report\",\n \"projectId\": \"project_id\",\n \"createMode\": \"capture\",\n \"priority\": \"high\",\n \"expectedOutputs\": [\"Research report\"],\n \"acceptanceCriteria\": [\"Sources are cited\"],\n \"constraints\": [\"Do not contact customers without approval\"],\n \"dependsOnTaskIds\": []\n }\n}\n```\n\n### Dependencies\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"update_dependencies\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"dependsOnTaskIds\": [\"dependency_task_id\"]\n }\n}\n```\n\n### Context links\n\nUse `add_context` to link a document, file, URL, session, memory, Task, artifact, or source\nas `input`, `reference`, `constraint`, `deliverable`, or `evidence` context.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"add_context\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"targetKind\": \"file\",\n \"targetId\": \"/path/to/spec.md\",\n \"role\": \"input\",\n \"title\": \"Product specification\",\n \"pinned\": true,\n \"retrievalPolicy\": {},\n \"metadata\": {}\n }\n}\n```\n\nUse `remove_context` with `taskId` and the exact `edgeId` returned by `task.get`.\nDo not add authority grants through this tool; an Agent must not authorize itself.\n\n### Typed lifecycle commands\n\nEvery command requires `taskId`, the Task's current `expectedVersion`, a `type`, and\ntype-specific fields inside `commandArgs`.\n\nSupported command types:\n\n- `mark_ready`\n- `start`: `{ \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" } }`\n- `request_review`\n- `close`: `{ \"resolution\": \"done | cancelled | duplicate | wont_do\" }`\n- `reopen`: `{ \"phase\": \"ready | active\" }`\n- `add_wait`: `{ \"wait\": { \"kind\": \"dependency | approval | input | schedule | external | paused\", \"reason\": \"...\", \"condition\": {} } }`\n- `resolve_wait`: `{ \"waitId\": \"wait_id\", \"resolution\": {} }`\n- `delegate`: `{ \"agentId\": \"agent_id\" }`\n- `revise_contract`: `{ \"contract\": { ...complete contract... } }`\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"command\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"type\": \"start\",\n \"commandArgs\": {\n \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" }\n }\n }\n}\n```\n\nContract revision is replacement, not a patch. Read the Task and preserve all contract fields\nthe user did not ask to change. Resolve a wait through `resolve_wait`; do not directly mutate\na TaskRun or manufacture a phase transition.\n\n## TaskRuns\n\nTaskRun inspection is read-only except for explicit cancellation. Other execution state is\ncontrolled by Task commands and the runtime coordinator.\n\n### List attempts for a Task\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"list\", \"args\": { \"taskId\": \"task_id\", \"limit\": 20 } }\n```\n\nThe result contains run attempts, finalized receipts, and active waits.\n\n### Inspect one attempt\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"get\", \"args\": { \"runId\": \"run_id\" } }\n```\n\nThe result contains the TaskRun, its receipt when terminal, ordered events, and active Task waits.\n\n### Cancel an attempt\n\nRead the run first, then pass its current version. Cancellation creates a terminal receipt.\n\n```json\n{\n \"mode\": \"task_run\",\n \"command\": \"cancel\",\n \"args\": { \"runId\": \"run_id\", \"expectedVersion\": 2, \"reason\": \"User cancelled execution\" }\n}\n```\n\nDo not guess commands such as retry, force-complete, heartbeat, or transition; they are not Agent APIs.\n\n## Notes\n\nCommands: `list`, `get`, `create`, `append`, `preview_edit`, and `update`.\nUse Notes for durable prose and reference material, not as a Task substitute. Prefer `append`\nwhen preserving user content. Use `preview_edit` before a canonical rewrite.\n\n```json\n{ \"mode\": \"note\", \"command\": \"create\", \"args\": { \"title\": \"Decision\", \"markdown\": \"...\", \"projectId\": \"project_id\" } }\n```\n\n```json\n{ \"mode\": \"note\", \"command\": \"append\", \"args\": { \"noteId\": \"note_id\", \"heading\": \"AI synthesis\", \"content\": \"...\" } }\n```\n\n## Local apps and settings\n\nLocal app commands are `list`, `get`, `create`, and `validate`. Installation,\nactivation, rollback, and uninstall remain product runtime operations.\n\nSettings supports only `open` and returns an exact product jump target without changing config.\n\n## Error recovery\n\n| Result | Recovery |\n| --- | --- |\n| service unavailable | Stop retrying and report the unavailable capability. |\n| not found | Re-list in the intended scope; do not invent another id. |\n| conflict | Read the current object and reassess using its latest version. |\n| waiting | Inspect the Task projection and TaskRun waits; resolve only the real blocker. |\n| invalid command or state | Read the object and use only a documented transition. |\n| unsupported operation | Use the dedicated tool or product UI; never write storage directly. |\n\n## Deliberate boundaries\n\n- Project deletion and milestone deletion are not Agent APIs.\n- TaskRun mutation is internal to execution coordination except for optimistic cancellation.\n- Project updates are immutable.\n- Workflow and Automation operations remain in their dedicated tools.\n- Only the documented Task and TaskRun commands are valid; do not infer hidden aliases.\n";
1
+ export declare const xopcUseManual = "# XOPC Use Tool Manual\n\n## Purpose\n\n`xopc_use` operates first-class XOPC product objects without editing SQLite or product files directly.\nLoad this manual before a non-trivial mutation.\n\n```json\n{\n \"mode\": \"project | automation | note | task | task_run | local_app | settings\",\n \"command\": \"...\",\n \"args\": {},\n \"dryRun\": false\n}\n```\n\nSend one object command per call. Inspect the returned JSON `ok` field; a tool call can\ncomplete successfully while the product command returns `ok: false`.\n\n## Object routing\n\n| Object | Tool |\n| --- | --- |\n| Project, milestone, project update | `xopc_use` mode `project` |\n| Automation | `xopc_use` mode `automation` |\n| Task intent and lifecycle | `xopc_use` mode `task` |\n| Task execution attempt, receipt, events and waits | `xopc_use` mode `task_run` |\n| Note | `xopc_use` mode `note` |\n| Local app | `xopc_use` mode `local_app` |\n| Settings jump target | `xopc_use` mode `settings` |\n| Workflow run | dedicated `workflow` tool; pass `taskId` to link it to a Task |\n| Session, memory, skill, connected app or workspace file | its dedicated tool |\n\nDo not emulate Workflow APIs through `xopc_use`. A Task is durable intent;\na TaskRun is one execution attempt; a WorkflowRun is a procedure execution and may belong\nto a TaskRun. Never treat these three objects as interchangeable.\n\n## Reliable protocol\n\n1. Use `list` then `get` when an id is unknown.\n2. Read the current `version` before a Task mutation.\n3. Use `dryRun: true` for broad Project changes or uncertain mutations.\n4. Mutate once with the exact id and current concurrency token.\n5. Verify the returned object and preserve any \u201COpen in xopc\u201D delivery link.\n6. On a conflict, read again and reconsider the operation; do not blindly retry.\n\nTimestamps are Unix epoch milliseconds. Array fields are arrays of strings. Omission\npreserves a patchable field; an empty array intentionally clears it. Prefer explicit\n`projectId`, `taskId`, `runId`, `noteId`, and `localAppId` fields over `id`.\n\n## Projects\n\nCommands: `list`, `get`, `create`, `update`, `resolve_workspace`,\n`list_milestones`, `create_milestone`, `update_milestone`, `list_updates`,\nand `create_update`.\n\nProject statuses: `planned`, `active`, `paused`, `completed`, `cancelled`,\n`archived`. Health values: `unknown`, `on_track`, `at_risk`, `off_track`.\n\nA Project defines bounded shared context for related work. Its durable planning fields are `outcome`,\n`successCriteria`, `scope`, `nonGoals`, `ownerId`, `targetAt`, and `health`.\nUse `brief` for a concise description and `instructions` for durable operating guidance.\n\n### Create\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"AI Product Research\",\n \"outcome\": \"Choose a validated product direction\",\n \"successCriteria\": [\"Ten customer interviews\", \"Decision recorded\"],\n \"scope\": { \"market\": \"developer tools\" },\n \"nonGoals\": [\"Build the production product\"],\n \"health\": \"on_track\",\n \"targetAt\": 1760000000000,\n \"workspaceRoot\": \"/path/to/repo\"\n }\n}\n```\n\n### Update\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"status\": \"active\",\n \"health\": \"at_risk\",\n \"successCriteria\": [\"Ten interviews\", \"Evidence-backed decision\"]\n }\n}\n```\n\n### Resolve a workspace\n\nUse `autoCreate: false` for lookup. Set it to true only when creating a Project is authorized.\n\n```json\n{ \"mode\": \"project\", \"command\": \"resolve_workspace\", \"args\": { \"workspacePath\": \"/path/to/repo\", \"autoCreate\": false } }\n```\n\n### Milestones\n\nMilestone statuses: `planned`, `active`, `completed`, `cancelled`.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_milestone\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"title\": \"Finish discovery\",\n \"status\": \"active\",\n \"targetAt\": 1760000000000,\n \"sortOrder\": 10\n }\n}\n```\n\nUse `list_milestones` with `projectId`. Use `update_milestone` with both\n`projectId` and `milestoneId`. Milestone deletion is intentionally not exposed.\n\n### Immutable project updates\n\nProject updates are append-only progress snapshots. They also update Project health.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"health\": \"on_track\",\n \"summary\": \"Discovery is complete\",\n \"progress\": [\"Interviewed ten users\"],\n \"risks\": [\"Pricing remains unvalidated\"],\n \"nextSteps\": [\"Run pricing tests\"]\n }\n}\n```\n\nUse `list_updates` with `projectId` and optional `limit`. Updates cannot be edited.\n\n## Automations\n\nCommands: `list`, `get`, `create`, `update`, `delete`, `run`, `pause`,\n`resume`, and `history`.\n\nAutomation `create` automatically uses the current session Project when `projectId` is\nomitted. An explicit `projectId` takes precedence and is validated before mutation. Use an\nexplicit id when creating for a Project other than the current session Project.\n\n### Create in the current Project\n\n`trigger` and `action` use the same shapes as the Automation product API.\n\n```json\n{\n \"mode\": \"automation\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"Daily project review\",\n \"trigger\": { \"kind\": \"schedule\", \"schedule\": { \"kind\": \"cron\", \"expr\": \"0 9 * * 1-5\", \"tz\": \"Asia/Shanghai\" } },\n \"action\": { \"kind\": \"agent\", \"instruction\": \"Review the current project and summarize risks.\" }\n }\n}\n```\n\nTo override the inherited Project, add `\"projectId\": \"project_id\"` to `args`.\nThe create payload may also be nested under `args.automation`; top-level `args.projectId`\nhas precedence.\n\n### List and history\n\n`list` and unqualified `history` inherit the current session Project. Pass an explicit\n`projectId` to query another Project. Pass `automationId` to `history` for one Automation.\n\n### Update and operate\n\nUse `automationId` for `get`, `update`, `delete`, `run`, `pause`, and `resume`.\nFor `update`, patch fields may be direct args or nested under `args.patch`. Supplying a new\n`projectId` reassigns the Automation after validating the target Project.\n\n## Tasks\n\nCommands: `list`, `get`, `create`, `update_dependencies`, `add_context`,\n`remove_context`, and `command`.\n\nTask phases are `backlog`, `ready`, `active`, `review`, and `closed`.\nOperational state is projected separately as `idle`, `queued`, `running`, `waiting`,\n`verifying`, `succeeded`, `failed`, or `cancelled`. Never send either value as a\nfree-form status update.\n\n`task.get` returns the Task, its projected `model`, dependencies, dependents, context,\nauthority grants, TaskRuns, receipts, and waits.\nThe projected model is the correct source for current operational state and attention items.\n\n### Capture or start\n\n`createMode` defaults to `capture`, which creates a backlog Task without executing it.\nUse `start` only when immediate execution is intended.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"create\",\n \"args\": {\n \"objective\": \"Complete the customer research report\",\n \"projectId\": \"project_id\",\n \"createMode\": \"capture\",\n \"priority\": \"high\",\n \"expectedOutputs\": [\"Research report\"],\n \"acceptanceCriteria\": [\"Sources are cited\"],\n \"constraints\": [\"Do not contact customers without approval\"],\n \"dependsOnTaskIds\": []\n }\n}\n```\n\n### Dependencies\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"update_dependencies\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"dependsOnTaskIds\": [\"dependency_task_id\"]\n }\n}\n```\n\n### Context links\n\nUse `add_context` to link a document, file, URL, session, memory, Task, artifact, or source\nas `input`, `reference`, `constraint`, `deliverable`, or `evidence` context.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"add_context\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"targetKind\": \"file\",\n \"targetId\": \"/path/to/spec.md\",\n \"role\": \"input\",\n \"title\": \"Product specification\",\n \"pinned\": true,\n \"retrievalPolicy\": {},\n \"metadata\": {}\n }\n}\n```\n\nUse `remove_context` with `taskId` and the exact `edgeId` returned by `task.get`.\nDo not add authority grants through this tool; an Agent must not authorize itself.\n\n### Typed lifecycle commands\n\nEvery command requires `taskId`, the Task's current `expectedVersion`, a `type`, and\ntype-specific fields inside `commandArgs`.\n\nSupported command types:\n\n- `mark_ready`\n- `start`: `{ \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" } }`\n- `request_review`\n- `close`: `{ \"resolution\": \"done | cancelled | duplicate | wont_do\" }`\n- `reopen`: `{ \"phase\": \"ready | active\" }`\n- `add_wait`: `{ \"wait\": { \"kind\": \"dependency | approval | input | schedule | external | paused\", \"reason\": \"...\", \"condition\": {} } }`\n- `resolve_wait`: `{ \"waitId\": \"wait_id\", \"resolution\": {} }`\n- `delegate`: `{ \"agentId\": \"agent_id\" }`\n- `revise_contract`: `{ \"contract\": { ...complete contract... } }`\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"command\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"type\": \"start\",\n \"commandArgs\": {\n \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" }\n }\n }\n}\n```\n\nContract revision is replacement, not a patch. Read the Task and preserve all contract fields\nthe user did not ask to change. Resolve a wait through `resolve_wait`; do not directly mutate\na TaskRun or manufacture a phase transition.\n\n## TaskRuns\n\nTaskRun inspection is read-only except for explicit cancellation. Other execution state is\ncontrolled by Task commands and the runtime coordinator.\n\n### List attempts for a Task\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"list\", \"args\": { \"taskId\": \"task_id\", \"limit\": 20 } }\n```\n\nThe result contains run attempts, finalized receipts, and active waits.\n\n### Inspect one attempt\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"get\", \"args\": { \"runId\": \"run_id\" } }\n```\n\nThe result contains the TaskRun, its receipt when terminal, ordered events, and active Task waits.\n\n### Cancel an attempt\n\nRead the run first, then pass its current version. Cancellation creates a terminal receipt.\n\n```json\n{\n \"mode\": \"task_run\",\n \"command\": \"cancel\",\n \"args\": { \"runId\": \"run_id\", \"expectedVersion\": 2, \"reason\": \"User cancelled execution\" }\n}\n```\n\nDo not guess commands such as retry, force-complete, heartbeat, or transition; they are not Agent APIs.\n\n## Notes\n\nCommands: `list`, `get`, `create`, `append`, `preview_edit`, and `update`.\nUse Notes for durable prose and reference material, not as a Task substitute. Prefer `append`\nwhen preserving user content. Use `preview_edit` before a canonical rewrite.\n\n```json\n{ \"mode\": \"note\", \"command\": \"create\", \"args\": { \"title\": \"Decision\", \"markdown\": \"...\", \"projectId\": \"project_id\" } }\n```\n\n```json\n{ \"mode\": \"note\", \"command\": \"append\", \"args\": { \"noteId\": \"note_id\", \"heading\": \"AI synthesis\", \"content\": \"...\" } }\n```\n\n## Local apps and settings\n\nLocal app commands are `list`, `get`, `create`, and `validate`. Installation,\nactivation, rollback, and uninstall remain product runtime operations.\n\nSettings supports only `open` and returns an exact product jump target without changing config.\n\n## Error recovery\n\n| Result | Recovery |\n| --- | --- |\n| service unavailable | Stop retrying and report the unavailable capability. |\n| not found | Re-list in the intended scope; do not invent another id. |\n| conflict | Read the current object and reassess using its latest version. |\n| waiting | Inspect the Task projection and TaskRun waits; resolve only the real blocker. |\n| invalid command or state | Read the object and use only a documented transition. |\n| unsupported operation | Use the dedicated tool or product UI; never write storage directly. |\n\n## Deliberate boundaries\n\n- Project deletion and milestone deletion are not Agent APIs.\n- TaskRun mutation is internal to execution coordination except for optimistic cancellation.\n- Project updates are immutable.\n- Workflow and Automation operations remain in their dedicated tools.\n- Only the documented Task and TaskRun commands are valid; do not infer hidden aliases.\n";
@@ -58,7 +58,7 @@ and \`create_update\`.
58
58
  Project statuses: \`planned\`, \`active\`, \`paused\`, \`completed\`, \`cancelled\`,
59
59
  \`archived\`. Health values: \`unknown\`, \`on_track\`, \`at_risk\`, \`off_track\`.
60
60
 
61
- A Project defines a bounded goal. Its durable planning fields are \`outcome\`,
61
+ A Project defines bounded shared context for related work. Its durable planning fields are \`outcome\`,
62
62
  \`successCriteria\`, \`scope\`, \`nonGoals\`, \`ownerId\`, \`targetAt\`, and \`health\`.
63
63
  Use \`brief\` for a concise description and \`instructions\` for durable operating guidance.
64
64
 
@@ -15,6 +15,7 @@ import { createExecCommandTool } from "./exec-command.js";
15
15
  import { createApplyPatchTool } from "./apply-patch.js";
16
16
  import { createMemoryGetTool, createMemorySearchTool } from "./memory-tool.js";
17
17
  import { createSessionSearchTool } from "./session-search-tool.js";
18
+ import { createSessionRecallTool } from "./session-recall-tool.js";
18
19
  import { createGrepTool } from "./grep.js";
19
20
  import { createFindTool } from "./find.js";
20
21
  import { createWebFetchTool, createWebSearchTool } from "./web.js";
@@ -299,6 +300,10 @@ var AgentToolsFactory = class {
299
300
  ...this.deps.getCurrentContext?.()?.sessionKey ? { sessionKey: this.deps.getCurrentContext().sessionKey } : {}
300
301
  })
301
302
  })] : [],
303
+ ...this.deps.getSessionStore ? [createSessionRecallTool({
304
+ getSessionStore: this.deps.getSessionStore,
305
+ getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey
306
+ })] : [],
302
307
  ...this.deps.getSessionStore && getPrimary ? [createSessionSearchTool({
303
308
  getSessionStore: this.deps.getSessionStore,
304
309
  getPrimaryModel: getPrimary,
@@ -7,6 +7,7 @@ export { createExecCommandTool, type ExecCommandDetails, type ExecCommandUpdateD
7
7
  export { createApplyPatchTool, type AppliedPatchChange, type ApplyPatchDetails, } from './apply-patch.js';
8
8
  export { createMemorySearchTool, createMemoryGetTool, type MemoryToolOptions, } from './memory-tool.js';
9
9
  export { createSessionSearchTool } from './session-search-tool.js';
10
+ export { createSessionRecallTool, type SessionRecallToolDeps } from './session-recall-tool.js';
10
11
  export { grepTool, createGrepTool, type GrepToolInput, type GrepToolDetails, } from './grep.js';
11
12
  export { findTool, createFindTool, type FindToolInput, type FindToolDetails, } from './find.js';
12
13
  export { createWebSearchTool, createWebFetchTool } from './web.js';
@@ -9,6 +9,7 @@ import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToL
9
9
  import { createApplyPatchTool } from "./apply-patch.js";
10
10
  import { createMemoryGetTool, createMemorySearchTool } from "./memory-tool.js";
11
11
  import { createSessionSearchTool } from "./session-search-tool.js";
12
+ import { createSessionRecallTool } from "./session-recall-tool.js";
12
13
  import { createGrepTool, grepTool } from "./grep.js";
13
14
  import { createFindTool, findTool } from "./find.js";
14
15
  import { createWebFetchTool, createWebSearchTool } from "./web.js";
@@ -41,4 +42,4 @@ import { createManagedJobTool } from "./managed-job-tool.js";
41
42
  import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
42
43
  import { createImageTool } from "./image-tool.js";
43
44
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
44
- export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCreateShareTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createManagedJobTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
45
+ export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCreateShareTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createManagedJobTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -0,0 +1,7 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ import type { SessionStore } from '../../session/store.js';
3
+ export interface SessionRecallToolDeps {
4
+ getSessionStore: () => SessionStore;
5
+ getCurrentSessionKey: () => string | undefined;
6
+ }
7
+ export declare function createSessionRecallTool(deps: SessionRecallToolDeps): AgentTool;
@@ -0,0 +1,82 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ //#region src/agent/tools/session-recall-tool.ts
3
+ const SessionRecallSchema = Type.Object({
4
+ query: Type.String({
5
+ minLength: 1,
6
+ maxLength: 500,
7
+ description: "Keywords, an exact phrase, path, URL, ID, date, or name to find in this session."
8
+ }),
9
+ limit: Type.Optional(Type.Integer({
10
+ minimum: 1,
11
+ maximum: 20,
12
+ default: 8
13
+ })),
14
+ beforeSeq: Type.Optional(Type.Integer({
15
+ minimum: 1,
16
+ description: "Return matches older than this transcript sequence number."
17
+ })),
18
+ maxCharsPerResult: Type.Optional(Type.Integer({
19
+ minimum: 500,
20
+ maximum: 2e4,
21
+ default: 6e3
22
+ }))
23
+ });
24
+ function excerpt(content, query, maxChars) {
25
+ if (content.length <= maxChars) return content;
26
+ const matchAt = content.toLowerCase().indexOf(query.toLowerCase());
27
+ const center = matchAt >= 0 ? matchAt + Math.floor(query.length / 2) : Math.floor(content.length / 2);
28
+ const start = Math.max(0, Math.min(content.length - maxChars, center - Math.floor(maxChars / 2)));
29
+ const end = Math.min(content.length, start + maxChars);
30
+ return `${start > 0 ? "…\n" : ""}${content.slice(start, end)}${end < content.length ? "\n…" : ""}`;
31
+ }
32
+ function createSessionRecallTool(deps) {
33
+ return {
34
+ name: "session_recall",
35
+ label: "Session recall",
36
+ description: "Search the authoritative raw transcript of the current session, including turns older than context compaction. Use when a continuation summary lacks an exact fact, quote, path, URL, ID, date, decision, or tool outcome. This tool cannot access other sessions.",
37
+ parameters: SessionRecallSchema,
38
+ supportsParallel: true,
39
+ idempotent: true,
40
+ async execute(_toolCallId, params) {
41
+ const input = params;
42
+ const sessionKey = deps.getCurrentSessionKey();
43
+ if (!sessionKey) return {
44
+ content: [{
45
+ type: "text",
46
+ text: "session_recall is unavailable outside an active session."
47
+ }],
48
+ details: { error: "missing_session" }
49
+ };
50
+ const query = input.query.trim();
51
+ const limit = Math.min(20, Math.max(1, input.limit ?? 8));
52
+ const maxChars = Math.min(2e4, Math.max(500, input.maxCharsPerResult ?? 6e3));
53
+ const results = deps.getSessionStore().recallSession(sessionKey, query, {
54
+ limit,
55
+ ...input.beforeSeq ? { beforeSeq: input.beforeSeq } : {}
56
+ }).map((match) => ({
57
+ seq: match.seq,
58
+ entryId: match.entryId,
59
+ role: match.role,
60
+ createdAt: new Date(match.createdAt).toISOString(),
61
+ content: excerpt(match.content, query, maxChars)
62
+ }));
63
+ const nextBeforeSeq = results.length === limit ? Math.min(...results.map((result) => result.seq)) : void 0;
64
+ const payload = {
65
+ success: true,
66
+ query,
67
+ results,
68
+ count: results.length,
69
+ ...nextBeforeSeq ? { nextBeforeSeq } : {}
70
+ };
71
+ return {
72
+ content: [{
73
+ type: "text",
74
+ text: JSON.stringify(payload, null, 2)
75
+ }],
76
+ details: payload
77
+ };
78
+ }
79
+ };
80
+ }
81
+ //#endregion
82
+ export { createSessionRecallTool };
@@ -747,7 +747,9 @@ async function handleAutomation(command, args, deps, dryRun) {
747
747
  "trigger",
748
748
  "action",
749
749
  "safety",
750
- "afterRun",
750
+ "conversationMode",
751
+ "notificationPolicy",
752
+ "completionWebhookUrl",
751
753
  "reliability",
752
754
  "state"
753
755
  ]),
@@ -781,7 +783,9 @@ async function handleAutomation(command, args, deps, dryRun) {
781
783
  "trigger",
782
784
  "action",
783
785
  "safety",
784
- "afterRun",
786
+ "conversationMode",
787
+ "notificationPolicy",
788
+ "completionWebhookUrl",
785
789
  "reliability",
786
790
  "state"
787
791
  ]));
@@ -115,6 +115,14 @@ function registerAutomationRoutes(authenticated, deps) {
115
115
  const events = await service.automationServiceInstance.listRunEvents(runId);
116
116
  return c.json({ events });
117
117
  });
118
+ authenticated.post("/api/automation-runs/:runId/read", async (c) => {
119
+ if (!await service.automationServiceInstance.markRunRead(c.req.param("runId"))) return c.json({ error: "Run not found" }, 404);
120
+ return c.json({ marked: true });
121
+ });
122
+ authenticated.post("/api/automation-runs/read-all", async (c) => {
123
+ const count = await service.automationServiceInstance.markAllRunsRead({ projectId: c.req.query("projectId") });
124
+ return c.json({ count });
125
+ });
118
126
  authenticated.post("/api/automation-runs/:runId/rerun", async (c) => {
119
127
  try {
120
128
  const run = await service.automationServiceInstance.rerunFromRun(c.req.param("runId"));
@@ -1,4 +1,4 @@
1
1
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./defaults.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./schedule.js";
3
- import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
4
- export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
3
+ import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
4
+ export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
@@ -55,14 +55,8 @@ export type AutomationAction = {
55
55
  taskId: string;
56
56
  command: TaskCommand;
57
57
  };
58
- export type AutomationAfterRun = {
59
- kind: 'none';
60
- } | {
61
- kind: 'saveToSession';
62
- } | {
63
- kind: 'webhook';
64
- url: string;
65
- };
58
+ export type AutomationConversationMode = 'new_session' | 'continuous';
59
+ export type AutomationNotificationPolicy = 'attention' | 'all' | 'none';
66
60
  export interface AutomationReliability {
67
61
  /** Overall run deadline. `timeoutSeconds` remains a read-only legacy fallback. */
68
62
  executionTimeoutSeconds?: number;
@@ -71,7 +65,7 @@ export interface AutomationReliability {
71
65
  maxConcurrentRuns?: number;
72
66
  disableAfterConsecutiveFailures?: number;
73
67
  }
74
- export type AutomationRunPhase = 'queued' | 'action' | 'after_run' | 'cancelling' | 'completed';
68
+ export type AutomationRunPhase = 'queued' | 'action' | 'completion_hook' | 'cancelling' | 'completed';
75
69
  export interface AutomationRunTermination {
76
70
  reason: 'completed' | 'failed' | 'user_cancelled' | 'deadline_exceeded';
77
71
  component?: 'automation' | 'agent_turn' | 'tool' | 'mcp' | 'process';
@@ -99,7 +93,9 @@ export interface Automation {
99
93
  trigger: AutomationTrigger;
100
94
  action: AutomationAction;
101
95
  safety?: AutomationSafetyPolicy;
102
- afterRun?: AutomationAfterRun;
96
+ conversationMode: AutomationConversationMode;
97
+ notificationPolicy: AutomationNotificationPolicy;
98
+ completionWebhookUrl?: string;
103
99
  reliability?: AutomationReliability;
104
100
  state: AutomationState;
105
101
  createdAtMs: number;
@@ -133,8 +129,9 @@ export interface AutomationRun {
133
129
  leaseExpiresAtMs?: number;
134
130
  attemptNumber?: number;
135
131
  rootRunId?: string;
132
+ readAtMs?: number;
136
133
  }
137
- export type AutomationRunEventType = 'run.queued' | 'run.started' | 'run.deadline_resolved' | 'run.cancel_requested' | 'run.cancel_confirmed' | 'run.cancellation_unconfirmed' | 'run.recovered' | 'action.started' | 'action.retry_scheduled' | 'action.completed' | 'action.failed' | 'after_run.started' | 'after_run.completed' | 'after_run.failed' | 'run.completed';
134
+ export type AutomationRunEventType = 'run.queued' | 'run.started' | 'run.deadline_resolved' | 'run.cancel_requested' | 'run.cancel_confirmed' | 'run.cancellation_unconfirmed' | 'run.recovered' | 'action.started' | 'action.retry_scheduled' | 'action.completed' | 'action.failed' | 'completion_hook.started' | 'completion_hook.completed' | 'completion_hook.failed' | 'run.completed';
138
135
  export interface AutomationRunEvent {
139
136
  id: string;
140
137
  runId: string;
@@ -165,6 +162,14 @@ export interface AutomationMetrics {
165
162
  runAtMs: number;
166
163
  };
167
164
  }
165
+ export interface PrepareAutomationAgentSessionInput {
166
+ sessionKey: string;
167
+ projectId?: string;
168
+ agentId: string;
169
+ peerId: string;
170
+ automationId: string;
171
+ runId: string;
172
+ }
168
173
  export interface AutomationDeps {
169
174
  agentService?: {
170
175
  sessionConfig?: {
@@ -181,7 +186,7 @@ export interface AutomationDeps {
181
186
  getModelForSession?: (sessionKey: string) => string | undefined;
182
187
  };
183
188
  getDefaultAgentId?: () => string;
184
- getProjectWorkspaceRoot?: (projectId: string) => string | undefined;
189
+ prepareAgentSession?: (input: PrepareAutomationAgentSessionInput) => Promise<void>;
185
190
  workflowRunService?: WorkflowRunServiceLike;
186
191
  browserRecipeService?: {
187
192
  runAndWait(recipeId: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<{
@@ -152,14 +152,6 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
152
152
  }, z.core.$strip>;
153
153
  }, z.core.$strip>], "type">;
154
154
  }, z.core.$strict>], "kind">;
155
- export declare const AutomationAfterRunSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
156
- kind: z.ZodLiteral<"none">;
157
- }, z.core.$strict>, z.ZodObject<{
158
- kind: z.ZodLiteral<"saveToSession">;
159
- }, z.core.$strict>, z.ZodObject<{
160
- kind: z.ZodLiteral<"webhook">;
161
- url: z.ZodString;
162
- }, z.core.$strict>], "kind">;
163
155
  export declare const AutomationReliabilitySchema: z.ZodObject<{
164
156
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
165
157
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -344,14 +336,16 @@ export declare const AutomationSchema: z.ZodObject<{
344
336
  auto_apply: "auto_apply";
345
337
  }>;
346
338
  }, z.core.$strict>>;
347
- afterRun: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
348
- kind: z.ZodLiteral<"none">;
349
- }, z.core.$strict>, z.ZodObject<{
350
- kind: z.ZodLiteral<"saveToSession">;
351
- }, z.core.$strict>, z.ZodObject<{
352
- kind: z.ZodLiteral<"webhook">;
353
- url: z.ZodString;
354
- }, z.core.$strict>], "kind">>;
339
+ conversationMode: z.ZodDefault<z.ZodEnum<{
340
+ new_session: "new_session";
341
+ continuous: "continuous";
342
+ }>>;
343
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
344
+ none: "none";
345
+ all: "all";
346
+ attention: "attention";
347
+ }>>;
348
+ completionWebhookUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
355
349
  reliability: z.ZodOptional<z.ZodObject<{
356
350
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
357
351
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -530,14 +524,6 @@ export declare const CreateAutomationSchema: z.ZodObject<{
530
524
  source: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
531
525
  payloadMatch: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
532
526
  }, z.core.$strict>], "kind">;
533
- afterRun: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
534
- kind: z.ZodLiteral<"none">;
535
- }, z.core.$strict>, z.ZodObject<{
536
- kind: z.ZodLiteral<"saveToSession">;
537
- }, z.core.$strict>, z.ZodObject<{
538
- kind: z.ZodLiteral<"webhook">;
539
- url: z.ZodString;
540
- }, z.core.$strict>], "kind">>;
541
527
  reliability: z.ZodOptional<z.ZodObject<{
542
528
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
543
529
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -545,6 +531,16 @@ export declare const CreateAutomationSchema: z.ZodObject<{
545
531
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
546
532
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
547
533
  }, z.core.$strict>>;
534
+ conversationMode: z.ZodDefault<z.ZodEnum<{
535
+ new_session: "new_session";
536
+ continuous: "continuous";
537
+ }>>;
538
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
539
+ none: "none";
540
+ all: "all";
541
+ attention: "attention";
542
+ }>>;
543
+ completionWebhookUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
548
544
  id: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
549
545
  enabled: z.ZodOptional<z.ZodBoolean>;
550
546
  state: z.ZodOptional<z.ZodObject<{
@@ -733,14 +729,6 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
733
729
  lastError: z.ZodOptional<z.ZodString>;
734
730
  consecutiveFailures: z.ZodOptional<z.ZodNumber>;
735
731
  }, z.core.$strict>>>;
736
- afterRun: z.ZodOptional<z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
737
- kind: z.ZodLiteral<"none">;
738
- }, z.core.$strict>, z.ZodObject<{
739
- kind: z.ZodLiteral<"saveToSession">;
740
- }, z.core.$strict>, z.ZodObject<{
741
- kind: z.ZodLiteral<"webhook">;
742
- url: z.ZodString;
743
- }, z.core.$strict>], "kind">>>;
744
732
  reliability: z.ZodOptional<z.ZodOptional<z.ZodObject<{
745
733
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
746
734
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -748,6 +736,16 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
748
736
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
749
737
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
750
738
  }, z.core.$strict>>>;
739
+ conversationMode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
740
+ new_session: "new_session";
741
+ continuous: "continuous";
742
+ }>>>;
743
+ notificationPolicy: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
744
+ none: "none";
745
+ all: "all";
746
+ attention: "attention";
747
+ }>>>;
748
+ completionWebhookUrl: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodString>>>;
751
749
  }, z.core.$strict>;
752
750
  export type CreateAutomationInput = z.infer<typeof CreateAutomationSchema>;
753
751
  export type UpdateAutomationInput = z.infer<typeof UpdateAutomationSchema>;
@@ -94,14 +94,6 @@ const AutomationActionSchema = z.discriminatedUnion("kind", [
94
94
  command: TaskCommandSchema
95
95
  }).strict()
96
96
  ]);
97
- const AutomationAfterRunSchema = z.discriminatedUnion("kind", [
98
- z.object({ kind: z.literal("none") }).strict(),
99
- z.object({ kind: z.literal("saveToSession") }).strict(),
100
- z.object({
101
- kind: z.literal("webhook"),
102
- url: nonEmptyString.max(2e3)
103
- }).strict()
104
- ]);
105
97
  const AutomationReliabilitySchema = z.object({
106
98
  executionTimeoutSeconds: z.number().int().min(1).max(86400).optional(),
107
99
  timeoutSeconds: z.number().int().min(1).max(86400).optional(),
@@ -139,7 +131,13 @@ const AutomationSchema = z.object({
139
131
  trigger: AutomationTriggerSchema,
140
132
  action: AutomationActionSchema,
141
133
  safety: AutomationSafetyPolicySchema.optional(),
142
- afterRun: AutomationAfterRunSchema.optional(),
134
+ conversationMode: z.enum(["new_session", "continuous"]).default("new_session"),
135
+ notificationPolicy: z.enum([
136
+ "attention",
137
+ "all",
138
+ "none"
139
+ ]).default("attention"),
140
+ completionWebhookUrl: optionalTrimmedString(2e3),
143
141
  reliability: AutomationReliabilitySchema.optional(),
144
142
  state: AutomationStateSchema.default({}),
145
143
  createdAtMs: z.number().int().nonnegative(),
@@ -162,4 +160,4 @@ const UpdateAutomationSchema = AutomationSchema.omit({
162
160
  updatedAtMs: true
163
161
  }).partial().refine((data) => Object.keys(data).length > 0, { message: "At least one field must be provided" });
164
162
  //#endregion
165
- export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
163
+ export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
@@ -10,8 +10,9 @@ JSON shape:
10
10
  "trigger": { "kind": "manual" },
11
11
  "action": { "kind": "agent", "instruction": "clear instruction for the agent" },
12
12
  "safety": { "mode": "suggest_only" },
13
- "afterRun": { "kind": "none" },
14
- "reliability": { "timeoutSeconds": 300, "disableAfterConsecutiveFailures": 3 }
13
+ "conversationMode": "new_session",
14
+ "notificationPolicy": "attention",
15
+ "reliability": { "executionTimeoutSeconds": 300, "disableAfterConsecutiveFailures": 3 }
15
16
  },
16
17
  "explanation": "Short explanation",
17
18
  "assumptions": ["..."],
@@ -49,8 +50,9 @@ Rules:
49
50
  - Default to safety { "mode": "suggest_only" } unless the user explicitly asks for fully automatic execution.
50
51
  - Do not invent destructive actions. For deletion, external sending, or irreversible changes, include a risk and make the instruction ask for confirmation.
51
52
  - Use cron for daily/weekly schedules. Use standard 5-field cron.
52
- - Keep timeoutSeconds between 60 and 1800.
53
- - afterRun should usually be { "kind": "none" }.
53
+ - Keep executionTimeoutSeconds between 60 and 1800.
54
+ - Use conversationMode "new_session" unless the user explicitly wants each run to continue the same conversation.
55
+ - Use notificationPolicy "attention" unless the user explicitly requests every-run notifications or no notifications.
54
56
  - Language for user-facing copy: ${params.language ?? "en"}.
55
57
 
56
58
  User request:
@@ -82,7 +84,9 @@ JSON shape:
82
84
  "trigger": "optional complete trigger object",
83
85
  "action": "optional complete action object",
84
86
  "safety": "optional complete safety object",
85
- "afterRun": "optional complete afterRun object",
87
+ "conversationMode": "optional new_session or continuous",
88
+ "notificationPolicy": "optional attention, all, or none",
89
+ "completionWebhookUrl": "optional HTTPS URL",
86
90
  "reliability": "optional complete reliability object",
87
91
  "enabled": true
88
92
  },
@@ -11,6 +11,8 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
11
11
  draftId: `${string}-${string}-${string}-${string}-${string}`;
12
12
  automation: {
13
13
  name: string;
14
+ conversationMode: "new_session" | "continuous";
15
+ notificationPolicy: "none" | "all" | "attention";
14
16
  projectId?: string;
15
17
  action?: {
16
18
  kind: "agent";
@@ -130,14 +132,6 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
130
132
  source?: string;
131
133
  payloadMatch?: Record<string, string | number | boolean>;
132
134
  };
133
- afterRun?: {
134
- kind: "none";
135
- } | {
136
- kind: "saveToSession";
137
- } | {
138
- kind: "webhook";
139
- url: string;
140
- };
141
135
  reliability?: {
142
136
  executionTimeoutSeconds?: number;
143
137
  timeoutSeconds?: number;
@@ -145,6 +139,7 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
145
139
  maxConcurrentRuns?: number;
146
140
  disableAfterConsecutiveFailures?: number;
147
141
  };
142
+ completionWebhookUrl?: string;
148
143
  id?: string;
149
144
  enabled?: boolean;
150
145
  state?: {
@@ -54,8 +54,8 @@ function simulateAutomation(input) {
54
54
  const triggerSummary = summarizeTrigger(automation.trigger);
55
55
  const actionSummary = summarizeAction(automation.action);
56
56
  if (automation.action.kind === "agent" && /delete|remove|send|post|publish|付款|删除|发送|发布/i.test(automation.action.instruction)) requiredConfirmations.push("Agent instruction may perform an external or destructive action.");
57
- if (automation.afterRun?.kind === "webhook") {
58
- safetyNotes.push("After-run webhook will call an external URL after each run.");
57
+ if (automation.completionWebhookUrl) {
58
+ safetyNotes.push("The completion webhook will call an external URL after each run.");
59
59
  requiredConfirmations.push("External webhook call should be reviewed before publishing.");
60
60
  }
61
61
  const safetyMode = automation.safety?.mode ?? "auto_apply";
@@ -96,7 +96,7 @@ function summarizeAction(action) {
96
96
  }
97
97
  function repairPatchNeedsApproval(patch) {
98
98
  if (patch.safety?.mode === "auto_apply") return true;
99
- if (patch.afterRun?.kind === "webhook") return true;
99
+ if (patch.completionWebhookUrl) return true;
100
100
  if (patch.trigger?.kind === "webhook") return true;
101
101
  if (patch.action?.kind === "agent") return /delete|remove|send|post|publish|付款|删除|发送|发布/i.test(patch.action.instruction);
102
102
  return false;
@@ -1,9 +1,9 @@
1
1
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./domain/defaults.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./domain/schedule.js";
3
- import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
3
+ import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
4
4
  import "./domain/index.js";
5
5
  import { AutomationActionExecutor } from "./service/action-executor.js";
6
6
  import { AutomationAlreadyRunningError, AutomationService } from "./service/automation-service.js";
7
7
  import "./service/index.js";
8
8
  import { onAutomationProductEvent, publishAutomationProductEvent } from "./product-events.js";
9
- export { AutomationActionExecutor, AutomationActionSchema, AutomationAfterRunSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };
9
+ export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };
@@ -157,19 +157,28 @@ var AutomationActionExecutor = class {
157
157
  status: "failed",
158
158
  error: "Agent service is not available"
159
159
  };
160
+ const agentId = normalizeAgentId(action.agentId || this.deps.getDefaultAgentId?.() || "main");
161
+ const peerId = automation.conversationMode === "continuous" ? automation.id : `${automation.id}-${crypto.randomUUID().slice(0, 8)}`;
160
162
  const sessionKey = buildSessionKey({
161
- agentId: normalizeAgentId(action.agentId || this.deps.getDefaultAgentId?.() || "main"),
163
+ agentId,
162
164
  source: "automation",
163
165
  accountId: "default",
164
166
  peerKind: "dm",
165
- peerId: `${automation.id}-${crypto.randomUUID().slice(0, 8)}`
167
+ peerId
166
168
  });
167
- const effectiveWorkingDirectory = action.workingDirectory ?? (automation.projectId ? this.deps.getProjectWorkspaceRoot?.(automation.projectId) : void 0);
168
169
  await hooks.onRunPatch?.({
169
170
  sessionKey,
170
171
  currentPhase: "action"
171
172
  });
172
- await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(sessionKey, effectiveWorkingDirectory);
173
+ await this.deps.prepareAgentSession?.({
174
+ sessionKey,
175
+ projectId: automation.projectId,
176
+ agentId,
177
+ peerId,
178
+ automationId: automation.id,
179
+ runId: run.id
180
+ });
181
+ await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(sessionKey, automation.projectId ? void 0 : action.workingDirectory);
173
182
  if (agentService.sessionConfig?.applyAutomationModelOverride) {
174
183
  if (!await agentService.sessionConfig.applyAutomationModelOverride(sessionKey, action.model) && action.model) log.warn({
175
184
  automationId: automation.id,