@xopcai/xopc 0.0.110 → 0.0.111

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 (301) hide show
  1. package/README.md +46 -4
  2. package/README.zh-CN.md +46 -4
  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/Combination-BzaXOLd9.js +41 -0
  6. package/dist/gateway/static/root/assets/agent-avatar-dicebear-zlx9l5Yp.js +1 -0
  7. package/dist/gateway/static/root/assets/agent-browser-settings-page-B-0zGjt8.js +6 -0
  8. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-Bz7JWjRM.js +1 -0
  9. package/dist/gateway/static/root/assets/agents-DwDnJlXT.js +71 -0
  10. package/dist/gateway/static/root/assets/app-management-settings-panel-DaQwdeCq.js +1 -0
  11. package/dist/gateway/static/root/assets/appearance-settings-D2zv6r3P.js +1 -0
  12. package/dist/gateway/static/root/assets/apps-page-BIppe_jj.js +1 -0
  13. package/dist/gateway/static/root/assets/archive-plugin-DEmu8eH7.js +1 -0
  14. package/dist/gateway/static/root/assets/attachment-load-B98lJoN5.js +2 -0
  15. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CybMSIoS.js → attachment-preview-renderer-DonnL2dL.js} +1 -1
  16. package/dist/gateway/static/root/assets/binary-plugins-CL9QKmyo.js +2 -0
  17. package/dist/gateway/static/root/assets/block-editor-BOAhMAhT.js +180 -0
  18. package/dist/gateway/static/root/assets/channels-settings-Br8iRnXp.js +1 -0
  19. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +1 -0
  20. package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +1 -0
  21. package/dist/gateway/static/root/assets/config-api-0o1WYdz2.js +3 -0
  22. package/dist/gateway/static/root/assets/connectors-settings-DDvHo9in.js +2 -0
  23. package/dist/gateway/static/root/assets/cron-api-Dj_UZKST.js +1 -0
  24. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +1 -0
  25. package/dist/gateway/static/root/assets/cron-page-Dv7GII9G.js +1 -0
  26. package/dist/gateway/static/root/assets/cron-schedule-picker-DH10KgD6.js +1 -0
  27. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
  28. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
  29. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
  30. package/dist/gateway/static/root/assets/dreaming-scene-BHMRVEUS.js +4585 -0
  31. package/dist/gateway/static/root/assets/dreaming-settings-L2rgZDQl.js +1 -0
  32. package/dist/gateway/static/root/assets/extension-debug-page-Cjx6pZVz.js +1 -0
  33. package/dist/gateway/static/root/assets/{extension-page-W1wiG38F.js → extension-page-BSPNL90V.js} +1 -1
  34. package/dist/gateway/static/root/assets/extension-settings-page-m_UQYkVc.js +1 -0
  35. package/dist/gateway/static/root/assets/fetch-Bs7in_4F.js +1 -0
  36. package/dist/gateway/static/root/assets/format-interval-label-CftJ5uXu.js +1 -0
  37. package/dist/gateway/static/root/assets/gateway-config-api-Clfck-hW.js +1 -0
  38. package/dist/gateway/static/root/assets/gateway-settings-CS177xni.js +1 -0
  39. package/dist/gateway/static/root/assets/gateway-startup-retry-BkjVJc38.js +1 -0
  40. package/dist/gateway/static/root/assets/goal-detail-page-kqJue0sE.js +1 -0
  41. package/dist/gateway/static/root/assets/goals-page-C0FujUB5.js +2 -0
  42. package/dist/gateway/static/root/assets/goals-settings-CJnzNSDo.js +1 -0
  43. package/dist/gateway/static/root/assets/heartbeat-config-api-Cp7CPuIn.js +1 -0
  44. package/dist/gateway/static/root/assets/heartbeat-settings-ifSI1Wbh.js +1 -0
  45. package/dist/gateway/static/root/assets/html-workspace-editor-CQLWDiwE.js +1 -0
  46. package/dist/gateway/static/root/assets/index-COkF54xv.js +121 -0
  47. package/dist/gateway/static/root/assets/index-DIaSNGEO.css +1 -0
  48. package/dist/gateway/static/root/assets/interval-presets-B29Ss_2y.js +2 -0
  49. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings--MI1rYl7.js +1 -0
  50. package/dist/gateway/static/root/assets/locale-store-DjbfSsfA.js +1 -0
  51. package/dist/gateway/static/root/assets/logs-page-BwrVNlyW.js +2 -0
  52. package/dist/gateway/static/root/assets/markdown-editor-AssmZFx4.js +2 -0
  53. package/dist/gateway/static/root/assets/markdown-split-B_oc9lJe.js +1 -0
  54. package/dist/gateway/static/root/assets/media-plugins-DLPvB5H3.js +1 -0
  55. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +134 -0
  56. package/dist/gateway/static/root/assets/messages-Csef1aW7.js +3 -0
  57. package/dist/gateway/static/root/assets/middleware-Pd0e8Igk.js +1 -0
  58. package/dist/gateway/static/root/assets/models-hub-panel-DHGiTIvf.js +2 -0
  59. package/dist/gateway/static/root/assets/note-detail-page-BM7zlDiT.js +2 -0
  60. package/dist/gateway/static/root/assets/note-image-lightbox-rSqAgOi9.js +1 -0
  61. package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +1 -0
  62. package/dist/gateway/static/root/assets/notes-page-C9ACGEty.js +1 -0
  63. package/dist/gateway/static/root/assets/preview-open-alternatives-Bw_N2oZi.js +1 -0
  64. package/dist/gateway/static/root/assets/remote-access-hub-BhcWIKuM.js +1 -0
  65. package/dist/gateway/static/root/assets/save-bar-controls-CNP2jmw0.js +1 -0
  66. package/dist/gateway/static/root/assets/schedule-field-BPAWui3P.js +1 -0
  67. package/dist/gateway/static/root/assets/schedule-summary-B-hdSRdR.js +1 -0
  68. package/dist/gateway/static/root/assets/schema-form-CDPzua9q.js +1 -0
  69. package/dist/gateway/static/root/assets/sessions-page-DzkpSDZr.js +1 -0
  70. package/dist/gateway/static/root/assets/settings-advanced-gate-BYS-rpzn.js +1 -0
  71. package/dist/gateway/static/root/assets/settings-collapsible-section-C9bff85B.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-form-section-BsrK7TBF.js +1 -0
  73. package/dist/gateway/static/root/assets/settings-page-DWK4Zo7s.js +1 -0
  74. package/dist/gateway/static/root/assets/setup-status-panel-DJiksNu4.js +1 -0
  75. package/dist/gateway/static/root/assets/share-preview-page-DnutoY_S.js +2 -0
  76. package/dist/gateway/static/root/assets/shares-settings-6oRgJMpn.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-CU9i0nJV.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-ERbdWENm.js +2 -0
  79. package/dist/gateway/static/root/assets/system-settings-panel-qP1JDtDd.js +1 -0
  80. package/dist/gateway/static/root/assets/theme-store-CD2wtgZV.js +1 -0
  81. package/dist/gateway/static/root/assets/use-agent-defaults-form-D3FGVLZb.js +1 -0
  82. package/dist/gateway/static/root/assets/use-blob-object-url-D4BFuzZB.js +1 -0
  83. package/dist/gateway/static/root/assets/use-channel-catalog-C4mg1hjD.js +1 -0
  84. package/dist/gateway/static/root/assets/use-settings-tab-guard-F6C0mpJt.js +1 -0
  85. package/dist/gateway/static/root/assets/vendor-codemirror-CNP1wPe7.js +45 -0
  86. package/dist/gateway/static/root/assets/voice-api-key-field-BnDDb6qO.js +1 -0
  87. package/dist/gateway/static/root/assets/voice-player-store-B2EwIhtY.js +1 -0
  88. package/dist/gateway/static/root/assets/{workflow-page.utils-EYg_xBQS.js → workflow-page.utils-CRB7WX9l.js} +1 -1
  89. package/dist/gateway/static/root/assets/workflows-page-2Fptr0je.js +18 -0
  90. package/dist/gateway/static/root/index.html +12 -10
  91. package/dist/package.js +1 -1
  92. package/dist/src/agent/goals/checklist-judge.d.ts +5 -0
  93. package/dist/src/agent/goals/checklist-judge.js +26 -2
  94. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  95. package/dist/src/agent/goals/evaluate-turn.d.ts +5 -1
  96. package/dist/src/agent/goals/evaluate-turn.js +29 -3
  97. package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
  98. package/dist/src/agent/goals/goal-locale.d.ts +0 -2
  99. package/dist/src/agent/goals/goal-locale.js +2 -15
  100. package/dist/src/agent/goals/goal-locale.js.map +1 -1
  101. package/dist/src/agent/goals/persistent-goal-service.d.ts +9 -0
  102. package/dist/src/agent/goals/persistent-goal-service.js +2 -1
  103. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  104. package/dist/src/agent/goals/post-turn.d.ts +7 -0
  105. package/dist/src/agent/goals/post-turn.js +68 -23
  106. package/dist/src/agent/goals/post-turn.js.map +1 -1
  107. package/dist/src/agent/goals/state.d.ts +0 -5
  108. package/dist/src/agent/goals/state.js +1 -96
  109. package/dist/src/agent/goals/state.js.map +1 -1
  110. package/dist/src/agent/messaging/command-handler.d.ts +4 -0
  111. package/dist/src/agent/messaging/command-handler.js +6 -2
  112. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  113. package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -0
  114. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  115. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  116. package/dist/src/agent/service/process-direct-streaming.js +10 -1
  117. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  118. package/dist/src/agent/service.js +20 -1
  119. package/dist/src/agent/service.js.map +1 -1
  120. package/dist/src/agent/service.types.d.ts +8 -0
  121. package/dist/src/agent/tools/cronjob-tool.d.ts +2 -0
  122. package/dist/src/agent/tools/cronjob-tool.js +27 -4
  123. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  124. package/dist/src/agent/tools/edit.d.ts +2 -0
  125. package/dist/src/agent/tools/edit.js +10 -0
  126. package/dist/src/agent/tools/edit.js.map +1 -1
  127. package/dist/src/agent/tools/factory.js +16 -3
  128. package/dist/src/agent/tools/factory.js.map +1 -1
  129. package/dist/src/agent/tools/goal-evidence-recorder.d.ts +6 -0
  130. package/dist/src/agent/tools/goal-evidence-recorder.js +34 -0
  131. package/dist/src/agent/tools/goal-evidence-recorder.js.map +1 -0
  132. package/dist/src/agent/tools/goal-tool.d.ts +19 -0
  133. package/dist/src/agent/tools/goal-tool.js +101 -0
  134. package/dist/src/agent/tools/goal-tool.js.map +1 -0
  135. package/dist/src/agent/tools/index.d.ts +1 -0
  136. package/dist/src/agent/tools/index.js +2 -1
  137. package/dist/src/agent/tools/shell.d.ts +2 -0
  138. package/dist/src/agent/tools/shell.js +17 -2
  139. package/dist/src/agent/tools/shell.js.map +1 -1
  140. package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
  141. package/dist/src/agent/tools/workflow-tool.js +10 -2
  142. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  143. package/dist/src/agent/tools/write.d.ts +2 -0
  144. package/dist/src/agent/tools/write.js +11 -0
  145. package/dist/src/agent/tools/write.js.map +1 -1
  146. package/dist/src/channels/attachments/inbound-persist.d.ts +7 -0
  147. package/dist/src/channels/attachments/inbound-persist.js +20 -2
  148. package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
  149. package/dist/src/chat-commands/builtins/goal.d.ts +1 -1
  150. package/dist/src/chat-commands/builtins/goal.js +55 -97
  151. package/dist/src/chat-commands/builtins/goal.js.map +1 -1
  152. package/dist/src/chat-commands/builtins/subgoal.d.ts +1 -1
  153. package/dist/src/chat-commands/builtins/subgoal.js +49 -108
  154. package/dist/src/chat-commands/builtins/subgoal.js.map +1 -1
  155. package/dist/src/chat-commands/builtins/workflow.js +132 -8
  156. package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
  157. package/dist/src/chat-commands/context.d.ts +3 -0
  158. package/dist/src/chat-commands/context.js +5 -0
  159. package/dist/src/chat-commands/context.js.map +1 -1
  160. package/dist/src/chat-commands/types.d.ts +5 -0
  161. package/dist/src/cli/command-catalog.js +43 -0
  162. package/dist/src/cli/command-catalog.js.map +1 -1
  163. package/dist/src/cli/command-loaders.js +1 -0
  164. package/dist/src/cli/command-loaders.js.map +1 -1
  165. package/dist/src/cli/command-manifest.js +4 -0
  166. package/dist/src/cli/command-manifest.js.map +1 -1
  167. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  168. package/dist/src/cli/commands/goal.d.ts +4 -0
  169. package/dist/src/cli/commands/goal.js +213 -0
  170. package/dist/src/cli/commands/goal.js.map +1 -0
  171. package/dist/src/cli/commands/onboard.js +11 -5
  172. package/dist/src/cli/commands/onboard.js.map +1 -1
  173. package/dist/src/config/index.js +2 -2
  174. package/dist/src/config/schema.d.ts +115 -0
  175. package/dist/src/config/schema.js +63 -4
  176. package/dist/src/config/schema.js.map +1 -1
  177. package/dist/src/config/web-patch.d.ts +14 -0
  178. package/dist/src/config/web-patch.js +45 -6
  179. package/dist/src/config/web-patch.js.map +1 -1
  180. package/dist/src/cron/executor.d.ts +2 -0
  181. package/dist/src/cron/executor.js +25 -0
  182. package/dist/src/cron/executor.js.map +1 -1
  183. package/dist/src/cron/job-content.js +1 -0
  184. package/dist/src/cron/job-content.js.map +1 -1
  185. package/dist/src/cron/types.d.ts +19 -1
  186. package/dist/src/cron/validation.d.ts +20 -0
  187. package/dist/src/cron/validation.js +7 -0
  188. package/dist/src/cron/validation.js.map +1 -1
  189. package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -0
  190. package/dist/src/gateway/hono/routes/goals.d.ts +1 -1
  191. package/dist/src/gateway/hono/routes/goals.js +670 -173
  192. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  193. package/dist/src/gateway/hono/routes/home.d.ts +5 -0
  194. package/dist/src/gateway/hono/routes/home.js +88 -3
  195. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  196. package/dist/src/gateway/hono/routes/notes.js +20 -14
  197. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  198. package/dist/src/gateway/hono/routes/workflows.js +6 -2
  199. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  200. package/dist/src/gateway/hono/sse.js.map +1 -1
  201. package/dist/src/gateway/service/agent-runner.d.ts +2 -0
  202. package/dist/src/gateway/service/agent-runner.js +6 -2
  203. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  204. package/dist/src/gateway/service/run-gateway-agent.d.ts +3 -0
  205. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  206. package/dist/src/gateway/service.d.ts +8 -0
  207. package/dist/src/gateway/service.js +69 -2
  208. package/dist/src/gateway/service.js.map +1 -1
  209. package/dist/src/goals/goal-notifications.d.ts +29 -0
  210. package/dist/src/goals/goal-notifications.js +154 -0
  211. package/dist/src/goals/goal-notifications.js.map +1 -0
  212. package/dist/src/goals/goal-queue-store.d.ts +16 -0
  213. package/dist/src/goals/goal-queue-store.js +131 -0
  214. package/dist/src/goals/goal-queue-store.js.map +1 -0
  215. package/dist/src/goals/goal-queue-types.d.ts +31 -0
  216. package/dist/src/goals/goal-queue-types.js +1 -0
  217. package/dist/src/goals/goal-runner.d.ts +17 -0
  218. package/dist/src/goals/goal-runner.js +127 -0
  219. package/dist/src/goals/goal-runner.js.map +1 -0
  220. package/dist/src/goals/goal-service.d.ts +77 -0
  221. package/dist/src/goals/goal-service.js +261 -0
  222. package/dist/src/goals/goal-service.js.map +1 -0
  223. package/dist/src/goals/goal-store.d.ts +38 -0
  224. package/dist/src/goals/goal-store.js +404 -0
  225. package/dist/src/goals/goal-store.js.map +1 -0
  226. package/dist/src/goals/goal-workflow-judge.d.ts +13 -0
  227. package/dist/src/goals/goal-workflow-judge.js +147 -0
  228. package/dist/src/goals/goal-workflow-judge.js.map +1 -0
  229. package/dist/src/goals/index.d.ts +10 -0
  230. package/dist/src/goals/index.js +7 -0
  231. package/dist/src/goals/types.d.ts +119 -0
  232. package/dist/src/goals/types.js +1 -0
  233. package/dist/src/storage/sqlite/migrations/006_add_goals.sql +108 -0
  234. package/dist/src/storage/sqlite/migrations/007_goal_run_judge_schema.sql +4 -0
  235. package/dist/src/storage/sqlite/migrations/008_goal_queue_workflow_runs.sql +53 -0
  236. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  237. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  238. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  239. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  240. package/dist/src/storage/sqlite/schema.js +1 -1
  241. package/dist/src/storage/sqlite/schema.sql +163 -0
  242. package/dist/src/utils/logger/stats.d.ts +1 -1
  243. package/dist/src/workflows/domain/run.d.ts +1 -0
  244. package/dist/src/workflows/domain/run.js.map +1 -1
  245. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  246. package/dist/src/workflows/service/workflow-run-service.js +5 -1
  247. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  248. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
  249. package/dist/src/workflows/service/workflow-session-bridge.js +7 -0
  250. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  251. package/dist/src/workflows/store/run-index-store.d.ts +8 -0
  252. package/dist/src/workflows/store/run-index-store.js +58 -0
  253. package/dist/src/workflows/store/run-index-store.js.map +1 -0
  254. package/dist/src/workflows/store/run-store.d.ts +2 -0
  255. package/dist/src/workflows/store/run-store.js +14 -21
  256. package/dist/src/workflows/store/run-store.js.map +1 -1
  257. package/package.json +9 -3
  258. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
  259. package/dist/gateway/static/root/assets/agents-CFFioJCI.js +0 -78
  260. package/dist/gateway/static/root/assets/apps-page-BYDmkbzG.js +0 -1
  261. package/dist/gateway/static/root/assets/channels-settings-CsbDaMvd.js +0 -1
  262. package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +0 -1
  263. package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +0 -1
  264. package/dist/gateway/static/root/assets/cron-page-Apk-7p4p.js +0 -1
  265. package/dist/gateway/static/root/assets/dist-DmGDgpy2.js +0 -1
  266. package/dist/gateway/static/root/assets/extension-debug-page-pxFC-tUa.js +0 -1
  267. package/dist/gateway/static/root/assets/extension-settings-page-COXSv6xP.js +0 -1
  268. package/dist/gateway/static/root/assets/fetch-CFdKBnE6.js +0 -1
  269. package/dist/gateway/static/root/assets/gateway-startup-retry-DdngdObI.js +0 -1
  270. package/dist/gateway/static/root/assets/heartbeat-config-api-DcmAMYmN.js +0 -1
  271. package/dist/gateway/static/root/assets/index-C_2yKRJX.js +0 -4845
  272. package/dist/gateway/static/root/assets/index-DI5_GsZt.css +0 -1
  273. package/dist/gateway/static/root/assets/logs-page-DvTWUOzd.js +0 -2
  274. package/dist/gateway/static/root/assets/note-detail-page-CZbdugWZ.js +0 -180
  275. package/dist/gateway/static/root/assets/note-time-RdyBZxj3.js +0 -1
  276. package/dist/gateway/static/root/assets/notes-page-mEAwy3e1.js +0 -1
  277. package/dist/gateway/static/root/assets/schema-form-DEvdni_r.js +0 -1
  278. package/dist/gateway/static/root/assets/sessions-page-BsgffzV4.js +0 -1
  279. package/dist/gateway/static/root/assets/settings-advanced-gate-t6v8Dwb8.js +0 -2
  280. package/dist/gateway/static/root/assets/settings-form-section-BoYYZmJG.js +0 -1
  281. package/dist/gateway/static/root/assets/settings-page-ClIthYF8.js +0 -3
  282. package/dist/gateway/static/root/assets/share-preview-page-Dd9et7KD.js +0 -2
  283. package/dist/gateway/static/root/assets/skills-page-DEXtxyfQ.js +0 -2
  284. package/dist/gateway/static/root/assets/theme-store-BZozwAeK.js +0 -1
  285. package/dist/gateway/static/root/assets/url-DQRqHuL-.js +0 -3
  286. package/dist/gateway/static/root/assets/vendor-codemirror-DYoKfS8f.js +0 -45
  287. package/dist/gateway/static/root/assets/voice-api-key-field-CNrKzQrf.js +0 -1
  288. package/dist/gateway/static/root/assets/workflows-page-EMZkzJNN.js +0 -18
  289. package/dist/src/agent/goals/checklist-user.d.ts +0 -24
  290. package/dist/src/agent/goals/checklist-user.js +0 -92
  291. package/dist/src/agent/goals/checklist-user.js.map +0 -1
  292. package/dist/src/agent/goals/goal-run-store.d.ts +0 -19
  293. package/dist/src/agent/goals/goal-run-store.js +0 -138
  294. package/dist/src/agent/goals/goal-run-store.js.map +0 -1
  295. package/dist/src/agent/goals/goal-run-types.d.ts +0 -28
  296. package/dist/src/agent/goals/goal-run-types.js +0 -6
  297. package/dist/src/agent/goals/goal-run-types.js.map +0 -1
  298. package/dist/src/agent/goals/patch-from-user-action.d.ts +0 -20
  299. package/dist/src/agent/goals/patch-from-user-action.js +0 -103
  300. package/dist/src/agent/goals/patch-from-user-action.js.map +0 -1
  301. /package/dist/gateway/static/root/assets/{note-detail-page-D4ZIVQbk.css → block-editor-D4ZIVQbk.css} +0 -0
@@ -1,224 +1,721 @@
1
- import { PERSISTENT_GOAL_CUSTOM_KEY, defaultMaxTurns, mergeCustomDataPatch, readPersistentGoal, serializePersistentGoal } from "../../../agent/goals/state.js";
2
- import { applyPersistentGoalUserAction } from "../../../agent/goals/patch-from-user-action.js";
3
- import { applyChecklistUserMutation } from "../../../agent/goals/checklist-user.js";
4
- import { mergePersistentGoalUiLocale, normalizeGoalUiLocale } from "../../../agent/goals/goal-locale.js";
5
- import { listGoalRuns } from "../../../agent/goals/goal-run-store.js";
1
+ import { buildSessionKey, init_session_key, sanitizeSegment } from "../../../routing/session-key.js";
2
+ import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
3
+ import { createWorkflowCatalog } from "../../../agent/workflow/catalog.js";
4
+ import { GoalService, normalizeGoalUiLocale } from "../../../goals/goal-service.js";
5
+ import "../../../goals/index.js";
6
6
  //#region src/gateway/hono/routes/goals.ts
7
- function isGoalAction(x) {
8
- return x === "pause" || x === "resume" || x === "clear" || x === "restart";
7
+ init_session_key();
8
+ init_resolve_route();
9
+ function parseLimit(raw, fallback = 50) {
10
+ if (!raw) return fallback;
11
+ const n = Number.parseInt(raw, 10);
12
+ return Number.isFinite(n) ? Math.min(500, Math.max(1, n)) : fallback;
9
13
  }
10
- /** Webchat persistent `/goal` REST API. */
14
+ function parseStatuses(raw) {
15
+ if (!raw?.trim()) return void 0;
16
+ const statuses = raw.split(",").map((s) => s.trim()).filter((s) => s === "active" || s === "paused" || s === "blocked" || s === "needs_input" || s === "done" || s === "archived");
17
+ return statuses.length ? statuses : void 0;
18
+ }
19
+ function parseBodyGoalStatus(raw) {
20
+ return raw === "active" || raw === "paused" || raw === "blocked" || raw === "needs_input" || raw === "done" || raw === "archived" ? raw : null;
21
+ }
22
+ function parsePriority(raw) {
23
+ return raw === "low" || raw === "normal" || raw === "high" ? raw : void 0;
24
+ }
25
+ const STOP_WORDS = new Set([
26
+ "a",
27
+ "an",
28
+ "and",
29
+ "are",
30
+ "as",
31
+ "for",
32
+ "in",
33
+ "is",
34
+ "of",
35
+ "on",
36
+ "or",
37
+ "the",
38
+ "to",
39
+ "with",
40
+ "一个",
41
+ "这个",
42
+ "需要",
43
+ "进行",
44
+ "推进"
45
+ ]);
46
+ function tokenizeForWorkflowMatch(text) {
47
+ return (text.toLowerCase().match(/[\p{L}\p{N}_-]+/gu) ?? []).map((token) => token.trim()).filter((token) => token.length >= 2 && !STOP_WORDS.has(token));
48
+ }
49
+ function goalSearchText(goal) {
50
+ return [
51
+ goal.title,
52
+ goal.description,
53
+ goal.nextAction,
54
+ goal.blockedReason,
55
+ ...goal.checklist.map((item) => `${item.text} ${item.evidenceSummary ?? ""}`)
56
+ ].filter(Boolean).join("\n");
57
+ }
58
+ function buildGoalWorkflowSuggestions(params) {
59
+ const goalTokens = new Set(tokenizeForWorkflowMatch(goalSearchText(params.goal)));
60
+ const runsByDefinition = /* @__PURE__ */ new Map();
61
+ for (const run of params.workflowRuns) {
62
+ const list = runsByDefinition.get(run.definitionId) ?? [];
63
+ list.push(run);
64
+ runsByDefinition.set(run.definitionId, list);
65
+ }
66
+ const suggestions = [];
67
+ for (const entry of createWorkflowCatalog().list()) {
68
+ const candidateText = [
69
+ entry.name,
70
+ entry.title,
71
+ entry.description,
72
+ entry.whenToUse,
73
+ ...entry.tags ?? []
74
+ ].filter(Boolean).join("\n");
75
+ const candidateTokens = new Set(tokenizeForWorkflowMatch(candidateText));
76
+ const matched = [...goalTokens].filter((token) => candidateTokens.has(token));
77
+ const relatedRuns = runsByDefinition.get(entry.name) ?? [];
78
+ const terminalRuns = relatedRuns.filter((run) => run.status !== "queued" && run.status !== "running");
79
+ const succeededRuns = terminalRuns.filter((run) => run.status === "succeeded");
80
+ const successRate = terminalRuns.length ? succeededRuns.length / terminalRuns.length : void 0;
81
+ const lastRun = relatedRuns.toSorted((left, right) => right.createdAtMs - left.createdAtMs)[0];
82
+ let score = matched.length * 8;
83
+ if (entry.tags?.some((tag) => goalTokens.has(tag.toLowerCase()))) score += 8;
84
+ if (entry.whenToUse && matched.length > 0) score += 4;
85
+ if (successRate != null) score += Math.round(successRate * 10);
86
+ if (lastRun?.status === "succeeded") score += 4;
87
+ if (lastRun?.status === "failed" || lastRun?.status === "timeout") score -= 3;
88
+ if (score <= 0) score = entry.source === "builtin" ? 1 : 0;
89
+ const reasons = [];
90
+ if (matched.length) reasons.push(`matches ${matched.slice(0, 4).join(", ")}`);
91
+ if (successRate != null) reasons.push(`${Math.round(successRate * 100)}% success rate`);
92
+ if (lastRun) reasons.push(`last run ${lastRun.status}`);
93
+ if (!reasons.length && entry.whenToUse) reasons.push("general workflow fit");
94
+ if (score > 0) suggestions.push({
95
+ definitionId: entry.name,
96
+ name: entry.name,
97
+ title: entry.title || entry.name,
98
+ description: entry.description,
99
+ score,
100
+ reasons,
101
+ tags: entry.tags ?? [],
102
+ successRate,
103
+ lastRunStatus: lastRun?.status
104
+ });
105
+ }
106
+ return suggestions.sort((left, right) => right.score - left.score || left.name.localeCompare(right.name)).slice(0, 5);
107
+ }
108
+ function buildGoalActivities(input) {
109
+ const activities = [];
110
+ for (const item of input.queue.filter((queueItem) => queueItem.goalId === input.goalId)) activities.push({
111
+ id: `queue:${item.id}`,
112
+ kind: "queue",
113
+ status: item.status,
114
+ title: "Goal queued",
115
+ summary: item.lastError || item.message || void 0,
116
+ createdAt: item.finishedAt ?? item.startedAt ?? item.nextRunAt ?? item.enqueuedAt,
117
+ link: item.sessionKey ? {
118
+ type: "chat",
119
+ value: item.sessionKey
120
+ } : void 0,
121
+ data: item
122
+ });
123
+ for (const run of input.runs) activities.push({
124
+ id: `goal_run:${run.id}`,
125
+ kind: "goal_run",
126
+ status: run.verdict ?? run.status,
127
+ title: "Goal run judged",
128
+ summary: run.reason || run.assistantPreview || run.nextAction,
129
+ createdAt: run.finishedAt ?? run.startedAt,
130
+ data: run
131
+ });
132
+ for (const run of input.workflowRuns) activities.push({
133
+ id: `workflow_run:${run.id}`,
134
+ kind: "workflow_run",
135
+ status: run.status,
136
+ title: run.title || run.definitionId,
137
+ summary: run.definitionId,
138
+ createdAt: run.completedAtMs ?? run.startedAtMs ?? run.createdAtMs,
139
+ link: {
140
+ type: "workflow_run",
141
+ value: run.id
142
+ },
143
+ data: run
144
+ });
145
+ for (const event of input.events) activities.push({
146
+ id: `event:${event.id}`,
147
+ kind: "event",
148
+ status: event.kind,
149
+ title: event.kind,
150
+ summary: event.message,
151
+ createdAt: event.createdAt,
152
+ data: event
153
+ });
154
+ for (const item of input.evidence) activities.push({
155
+ id: `evidence:${item.id}`,
156
+ kind: "evidence",
157
+ status: item.kind,
158
+ title: item.title,
159
+ summary: item.summary || item.uri,
160
+ createdAt: item.createdAt,
161
+ data: item
162
+ });
163
+ return activities.sort((left, right) => right.createdAt - left.createdAt).slice(0, input.limit);
164
+ }
165
+ function abortActiveWebchatRunForGoal(deps, goal) {
166
+ const sessionKey = goal.activeSessionKey?.trim();
167
+ if (!sessionKey) return {};
168
+ const runId = deps.service.getActiveWebchatRunId(sessionKey);
169
+ if (!runId) return {};
170
+ return {
171
+ abortedRunId: runId,
172
+ aborted: deps.service.abortAgentRun(runId)
173
+ };
174
+ }
175
+ /** First-class Goal API. Sessions are execution context; goals are durable product objects. */
11
176
  function registerGoalsRoutes(authenticated, deps) {
12
- const sm = deps.service.sessionIndexInstance;
177
+ const goals = new GoalService();
13
178
  const cfg = () => deps.service.currentConfig;
14
- authenticated.get("/api/goals/webchat", async (c) => {
179
+ const workflowRunService = deps.service.createWorkflowRunService();
180
+ authenticated.get("/api/goals/current", async (c) => {
15
181
  const sessionKey = c.req.query("sessionKey")?.trim();
16
182
  if (!sessionKey) return c.json({
17
183
  ok: false,
18
184
  error: "Missing sessionKey"
19
185
  }, 400);
20
- const uiLocale = normalizeGoalUiLocale(c.req.query("uiLocale"));
21
- let m = await sm.getSessionMetadata(sessionKey);
22
- if (uiLocale && m) {
23
- const merged = mergePersistentGoalUiLocale(m.customData, uiLocale);
24
- if (merged !== m.customData) {
25
- await sm.updateSessionMetadata(sessionKey, { customData: merged });
26
- m = await sm.getSessionMetadata(sessionKey);
27
- }
28
- }
29
- const goal = readPersistentGoal(m?.customData);
30
186
  return c.json({
31
187
  ok: true,
32
- sessionKey,
33
- persistentGoal: goal
188
+ goal: goals.getActiveForSession(sessionKey)
34
189
  });
35
190
  });
36
- authenticated.get("/api/goals/webchat/runs", async (c) => {
37
- const sessionKey = c.req.query("sessionKey")?.trim();
38
- if (!sessionKey) return c.json({
191
+ authenticated.get("/api/goals", async (c) => {
192
+ const status = parseStatuses(c.req.query("status"));
193
+ const agentId = c.req.query("agentId")?.trim() || void 0;
194
+ const sessionKey = c.req.query("sessionKey")?.trim() || void 0;
195
+ const limit = parseLimit(c.req.query("limit"));
196
+ const offsetRaw = c.req.query("offset")?.trim();
197
+ const offset = offsetRaw ? Math.max(0, Number.parseInt(offsetRaw, 10) || 0) : 0;
198
+ return c.json({
199
+ ok: true,
200
+ goals: goals.list({
201
+ status,
202
+ agentId,
203
+ sessionKey,
204
+ limit,
205
+ offset
206
+ })
207
+ });
208
+ });
209
+ authenticated.get("/api/goals/queue", async (c) => {
210
+ return c.json({
211
+ ok: true,
212
+ queue: deps.service.getGoalQueueSnapshot()
213
+ });
214
+ });
215
+ authenticated.post("/api/goals", async (c) => {
216
+ const body = await c.req.json().catch(() => ({}));
217
+ const title = typeof body.title === "string" ? body.title.trim() : "";
218
+ if (!title) return c.json({
39
219
  ok: false,
40
- error: "Missing sessionKey"
220
+ error: "Missing title"
41
221
  }, 400);
42
- const limitRaw = c.req.query("limit")?.trim();
43
- let limit = 50;
44
- if (limitRaw) {
45
- const n = Number.parseInt(limitRaw, 10);
46
- if (Number.isFinite(n)) limit = Math.min(500, Math.max(1, n));
47
- }
48
- const runs = await listGoalRuns(cfg(), sessionKey, { limit });
222
+ const sessionKey = typeof body.sessionKey === "string" && body.sessionKey.trim() ? body.sessionKey.trim() : void 0;
223
+ const agentId = typeof body.agentId === "string" && body.agentId.trim() ? body.agentId.trim() : sessionKey ? void 0 : getDefaultAgentId(cfg());
224
+ const maxTurns = typeof body.maxTurns === "number" && Number.isFinite(body.maxTurns) ? Math.max(1, Math.min(500, Math.floor(body.maxTurns))) : void 0;
225
+ const goal = goals.create({
226
+ title,
227
+ description: typeof body.description === "string" ? body.description : void 0,
228
+ sessionKey,
229
+ agentId,
230
+ priority: body.priority === "low" || body.priority === "high" ? body.priority : "normal",
231
+ deadlineAt: typeof body.deadlineAt === "number" && Number.isFinite(body.deadlineAt) ? body.deadlineAt : void 0,
232
+ judgeModelRef: typeof body.judgeModelRef === "string" ? body.judgeModelRef : void 0,
233
+ maxTurns,
234
+ uiLocale: normalizeGoalUiLocale(body.uiLocale),
235
+ source: body.source === "cli" || body.source === "cron" || body.source === "workflow" || body.source === "channel" || body.source === "api" ? body.source : "chat",
236
+ config: cfg()
237
+ });
238
+ if (sessionKey) deps.service.enqueueWebchatPersistentGoalKickoff(sessionKey, title);
239
+ return c.json({
240
+ ok: true,
241
+ goal: goals.get(goal.id)
242
+ });
243
+ });
244
+ authenticated.get("/api/goals/:goalId/workflow-runs", async (c) => {
245
+ const goalId = c.req.param("goalId");
246
+ const goal = goals.get(goalId);
247
+ if (!goal) return c.json({
248
+ ok: false,
249
+ error: "Goal not found"
250
+ }, 404);
251
+ const runs = await workflowRunService.createRunStore(goal.agentId || getDefaultAgentId(cfg())).listRunSummariesForGoal(goalId, parseLimit(c.req.query("limit")));
49
252
  return c.json({
50
253
  ok: true,
51
- sessionKey,
52
254
  runs
53
255
  });
54
256
  });
55
- authenticated.post("/api/goals/webchat", async (c) => {
257
+ authenticated.post("/api/goals/:goalId/workflows/run", async (c) => {
258
+ const goalId = c.req.param("goalId");
259
+ const goal = goals.get(goalId);
260
+ if (!goal) return c.json({
261
+ ok: false,
262
+ error: "Goal not found"
263
+ }, 404);
264
+ if (goal.status === "done" || goal.status === "archived") return c.json({
265
+ ok: false,
266
+ error: `Goal is ${goal.status}`
267
+ }, 409);
56
268
  const body = await c.req.json().catch(() => ({}));
57
- const sessionKey = typeof body.sessionKey === "string" ? body.sessionKey.trim() : "";
58
- if (!sessionKey) return c.json({
269
+ const definitionId = typeof body.definitionId === "string" ? body.definitionId.trim() : "";
270
+ if (!definitionId) return c.json({
59
271
  ok: false,
60
- error: "Missing sessionKey"
272
+ error: "Missing definitionId"
61
273
  }, 400);
62
- const goalsSlice = cfg().goals;
63
- const actionRaw = body.action ?? (body.clear === true ? "clear" : void 0);
64
- if (isGoalAction(actionRaw)) {
65
- const meta = await sm.getSessionMetadata(sessionKey);
66
- if (!meta) return c.json({
67
- ok: false,
68
- error: "Session not found"
69
- }, 404);
70
- const applied = applyPersistentGoalUserAction(meta.customData, actionRaw, goalsSlice);
71
- if (applied.kind === "error") return c.json({
72
- ok: false,
73
- error: applied.error
74
- }, 400);
75
- if (applied.kind === "noop") {
76
- const persistentGoal = readPersistentGoal(meta.customData);
77
- return c.json({
78
- ok: true,
79
- sessionKey,
80
- noop: true,
81
- message: applied.message,
82
- persistentGoal
83
- });
84
- }
85
- const uiLocale = normalizeGoalUiLocale(body.uiLocale);
86
- const customData = uiLocale != null ? mergePersistentGoalUiLocale(applied.customData, uiLocale) ?? applied.customData : applied.customData;
87
- await sm.updateSessionMetadata(sessionKey, { customData });
88
- const persistentGoal = readPersistentGoal((await sm.getSessionMetadata(sessionKey))?.customData);
89
- if (applied.kickoff) deps.service.enqueueWebchatPersistentGoalKickoff(sessionKey, applied.kickoff);
274
+ try {
275
+ createWorkflowCatalog().load(definitionId);
276
+ } catch {
90
277
  return c.json({
91
- ok: true,
92
- sessionKey,
93
- action: actionRaw,
94
- persistentGoal
95
- });
96
- }
97
- if (body.clear === true) {
98
- const meta = await sm.getSessionMetadata(sessionKey);
99
- if (!meta) return c.json({
100
278
  ok: false,
101
- error: "Session not found"
279
+ error: "Workflow definition not found"
102
280
  }, 404);
103
- const base = { ...meta.customData };
104
- delete base[PERSISTENT_GOAL_CUSTOM_KEY];
105
- await sm.updateSessionMetadata(sessionKey, { customData: base });
281
+ }
282
+ const result = await workflowRunService.startWorkflowRun({
283
+ agentId: goal.agentId || getDefaultAgentId(cfg()),
284
+ definitionId,
285
+ goalId,
286
+ goal: typeof body.goal === "string" && body.goal.trim() ? body.goal.trim() : goal.nextAction || goal.title,
287
+ input: body.input ?? {
288
+ goal: goal.title,
289
+ description: goal.description,
290
+ nextAction: goal.nextAction,
291
+ checklist: goal.checklist.map((item) => ({
292
+ text: item.text,
293
+ status: item.status,
294
+ evidenceSummary: item.evidenceSummary
295
+ }))
296
+ },
297
+ parentSessionKey: goal.activeSessionKey,
298
+ source: { kind: "webui" },
299
+ concurrency: typeof body.concurrency === "number" ? body.concurrency : void 0,
300
+ maxSubagents: typeof body.maxSubagents === "number" ? body.maxSubagents : void 0
301
+ });
302
+ if (result.ok === false) return c.json({
303
+ ok: false,
304
+ error: result.message,
305
+ code: result.code
306
+ }, result.httpStatus);
307
+ return c.json({
308
+ ok: true,
309
+ runId: result.runId,
310
+ sessionKey: result.sessionKey
311
+ }, 202);
312
+ });
313
+ authenticated.get("/api/goals/:goalId/activity", async (c) => {
314
+ const goalId = c.req.param("goalId");
315
+ const goal = goals.get(goalId);
316
+ if (!goal) return c.json({
317
+ ok: false,
318
+ error: "Goal not found"
319
+ }, 404);
320
+ const limit = parseLimit(c.req.query("limit"), 100);
321
+ const workflowRuns = await workflowRunService.createRunStore(goal.agentId || getDefaultAgentId(cfg())).listRunSummariesForGoal(goalId, limit);
322
+ const activities = buildGoalActivities({
323
+ goalId,
324
+ queue: deps.service.getGoalQueueSnapshot(),
325
+ runs: goals.listRuns(goalId, limit),
326
+ workflowRuns,
327
+ events: goals.listEvents(goalId, limit),
328
+ evidence: goals.listEvidence(goalId, limit),
329
+ limit
330
+ });
331
+ return c.json({
332
+ ok: true,
333
+ activities
334
+ });
335
+ });
336
+ authenticated.get("/api/goals/:goalId/workflow-suggestions", async (c) => {
337
+ const goalId = c.req.param("goalId");
338
+ const goal = goals.get(goalId);
339
+ if (!goal) return c.json({
340
+ ok: false,
341
+ error: "Goal not found"
342
+ }, 404);
343
+ const workflowRuns = await workflowRunService.createRunStore(goal.agentId || getDefaultAgentId(cfg())).listRunSummaries(500);
344
+ return c.json({
345
+ ok: true,
346
+ suggestions: buildGoalWorkflowSuggestions({
347
+ goal,
348
+ workflowRuns
349
+ })
350
+ });
351
+ });
352
+ authenticated.get("/api/goals/:goalId", async (c) => {
353
+ const goal = goals.get(c.req.param("goalId"));
354
+ if (!goal) return c.json({
355
+ ok: false,
356
+ error: "Goal not found"
357
+ }, 404);
358
+ return c.json({
359
+ ok: true,
360
+ goal
361
+ });
362
+ });
363
+ authenticated.patch("/api/goals/:goalId", async (c) => {
364
+ const goalId = c.req.param("goalId");
365
+ const body = await c.req.json().catch(() => ({}));
366
+ const status = parseBodyGoalStatus(body.status);
367
+ let goal = goals.get(goalId);
368
+ if (!goal) return c.json({
369
+ ok: false,
370
+ error: "Goal not found"
371
+ }, 404);
372
+ const patch = {};
373
+ if (typeof body.title === "string") patch.title = body.title;
374
+ if ("description" in body) patch.description = typeof body.description === "string" ? body.description : void 0;
375
+ const priority = parsePriority(body.priority);
376
+ if (priority) patch.priority = priority;
377
+ if ("deadlineAt" in body) patch.deadlineAt = typeof body.deadlineAt === "number" && Number.isFinite(body.deadlineAt) ? body.deadlineAt : void 0;
378
+ if (typeof body.maxTurns === "number" && Number.isFinite(body.maxTurns)) patch.maxTurns = body.maxTurns;
379
+ if ("judgeModelRef" in body) patch.judgeModelRef = typeof body.judgeModelRef === "string" ? body.judgeModelRef : void 0;
380
+ if ("nextAction" in body) patch.nextAction = typeof body.nextAction === "string" ? body.nextAction : void 0;
381
+ if ("blockedReason" in body) patch.blockedReason = typeof body.blockedReason === "string" ? body.blockedReason : void 0;
382
+ const locale = normalizeGoalUiLocale(body.uiLocale);
383
+ if (locale) patch.uiLocale = locale;
384
+ if (Object.keys(patch).length > 0) goal = goals.update(goalId, patch);
385
+ if (status) {
386
+ const previousStatus = goal?.status;
387
+ goal = goals.setStatus(goalId, status, { reason: typeof body.reason === "string" ? body.reason : void 0 });
388
+ const abortResult = goal && status === "archived" ? abortActiveWebchatRunForGoal(deps, goal) : {};
389
+ if (goal && previousStatus !== goal.status) deps.service.emit("goal.status.updated", {
390
+ goalId,
391
+ previousStatus,
392
+ status: goal.status,
393
+ goal
394
+ });
106
395
  return c.json({
107
396
  ok: true,
108
- sessionKey,
109
- cleared: true
397
+ goal,
398
+ ...abortResult
110
399
  });
111
400
  }
112
- const goalText = typeof body.goalText === "string" ? body.goalText.trim() : "";
113
- if (!goalText) return c.json({
401
+ return c.json({
402
+ ok: true,
403
+ goal
404
+ });
405
+ });
406
+ authenticated.post("/api/goals/:goalId/continue", async (c) => {
407
+ const goalId = c.req.param("goalId");
408
+ const body = await c.req.json().catch(() => ({}));
409
+ const goal = goals.get(goalId);
410
+ if (!goal) return c.json({
114
411
  ok: false,
115
- error: "Missing goalText (or set clear:true)"
116
- }, 400);
117
- const meta = await sm.getSessionMetadata(sessionKey);
118
- if (!meta) return c.json({
119
- ok: false,
120
- error: "Session not found"
121
- }, 404);
122
- const maxTurns = typeof body.maxTurns === "number" && Number.isFinite(body.maxTurns) ? Math.max(1, Math.min(500, Math.floor(body.maxTurns))) : defaultMaxTurns(cfg().goals);
123
- const judgeModelRef = typeof body.judgeModelRef === "string" && body.judgeModelRef.trim() ? body.judgeModelRef.trim() : typeof cfg().goals?.judgeModelRef === "string" ? cfg().goals.judgeModelRef.trim() : void 0;
124
- const uiLocale = normalizeGoalUiLocale(body.uiLocale);
125
- const next = {
126
- goal: goalText,
127
- status: "active",
128
- turnsUsed: 0,
129
- maxTurns,
130
- createdAt: Date.now(),
131
- lastTurnAt: 0,
132
- decomposed: false,
133
- consecutiveParseFailures: 0,
134
- ...judgeModelRef ? { judgeModelRef } : {},
135
- ...uiLocale ? { uiLocale } : {}
136
- };
137
- const customData = mergeCustomDataPatch({ ...meta.customData }, { [PERSISTENT_GOAL_CUSTOM_KEY]: serializePersistentGoal(next) });
138
- await sm.updateSessionMetadata(sessionKey, { customData });
139
- const persistentGoal = readPersistentGoal((await sm.getSessionMetadata(sessionKey))?.customData);
140
- deps.service.enqueueWebchatPersistentGoalKickoff(sessionKey, goalText);
412
+ error: "Goal not found"
413
+ }, 404);
414
+ let sessionKey = typeof body.sessionKey === "string" && body.sessionKey.trim() ? body.sessionKey.trim() : goal.activeSessionKey;
415
+ if (!sessionKey) {
416
+ sessionKey = buildSessionKey({
417
+ agentId: goal.agentId || getDefaultAgentId(cfg()),
418
+ source: "webchat",
419
+ accountId: "default",
420
+ peerKind: "direct",
421
+ peerId: `goal-${sanitizeSegment(goal.id) || Date.now()}`
422
+ });
423
+ await deps.service.sessionIndexInstance.saveMessages(sessionKey, []);
424
+ goals.attachSession(goalId, sessionKey);
425
+ }
426
+ const queued = deps.service.enqueueGoalRun(goalId, {
427
+ message: typeof body.message === "string" ? body.message : void 0,
428
+ maxRetries: typeof body.maxRetries === "number" && Number.isFinite(body.maxRetries) ? body.maxRetries : void 0,
429
+ source: "api"
430
+ });
431
+ const nextGoal = goals.get(goalId);
141
432
  return c.json({
142
433
  ok: true,
434
+ goal: nextGoal,
143
435
  sessionKey,
144
- persistentGoal
436
+ queued
437
+ });
438
+ });
439
+ authenticated.post("/api/goals/:goalId/enqueue", async (c) => {
440
+ const goalId = c.req.param("goalId");
441
+ const body = await c.req.json().catch(() => ({}));
442
+ if (!goals.get(goalId)) return c.json({
443
+ ok: false,
444
+ error: "Goal not found"
445
+ }, 404);
446
+ const item = deps.service.enqueueGoalRun(goalId, {
447
+ message: typeof body.message === "string" ? body.message : void 0,
448
+ maxRetries: typeof body.maxRetries === "number" && Number.isFinite(body.maxRetries) ? body.maxRetries : void 0,
449
+ source: "api"
450
+ });
451
+ return c.json({
452
+ ok: true,
453
+ item
454
+ });
455
+ });
456
+ authenticated.post("/api/goals/:goalId/pause", async (c) => {
457
+ const body = await c.req.json().catch(() => ({}));
458
+ const before = goals.get(c.req.param("goalId"));
459
+ const goal = goals.pause(c.req.param("goalId"), typeof body.reason === "string" && body.reason.trim() ? body.reason.trim() : "user-paused");
460
+ if (!goal) return c.json({
461
+ ok: false,
462
+ error: "Goal not found"
463
+ }, 404);
464
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
465
+ goalId: goal.id,
466
+ previousStatus: before?.status,
467
+ status: goal.status,
468
+ goal
469
+ });
470
+ return c.json({
471
+ ok: true,
472
+ goal
473
+ });
474
+ });
475
+ authenticated.post("/api/goals/:goalId/resume", async (c) => {
476
+ const before = goals.get(c.req.param("goalId"));
477
+ const goal = goals.resume(c.req.param("goalId"));
478
+ if (!goal) return c.json({
479
+ ok: false,
480
+ error: "Goal not found"
481
+ }, 404);
482
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
483
+ goalId: goal.id,
484
+ previousStatus: before?.status,
485
+ status: goal.status,
486
+ goal
487
+ });
488
+ return c.json({
489
+ ok: true,
490
+ goal
491
+ });
492
+ });
493
+ authenticated.post("/api/goals/:goalId/reopen", async (c) => {
494
+ const before = goals.get(c.req.param("goalId"));
495
+ const goal = goals.reopen(c.req.param("goalId"));
496
+ if (!goal) return c.json({
497
+ ok: false,
498
+ error: "Goal not found"
499
+ }, 404);
500
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
501
+ goalId: goal.id,
502
+ previousStatus: before?.status,
503
+ status: goal.status,
504
+ goal
505
+ });
506
+ return c.json({
507
+ ok: true,
508
+ goal
509
+ });
510
+ });
511
+ authenticated.post("/api/goals/:goalId/complete", async (c) => {
512
+ const before = goals.get(c.req.param("goalId"));
513
+ const goal = goals.complete(c.req.param("goalId"));
514
+ if (!goal) return c.json({
515
+ ok: false,
516
+ error: "Goal not found"
517
+ }, 404);
518
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
519
+ goalId: goal.id,
520
+ previousStatus: before?.status,
521
+ status: goal.status,
522
+ goal
523
+ });
524
+ return c.json({
525
+ ok: true,
526
+ goal
145
527
  });
146
528
  });
147
- /** Checklist CRUD for standing goals (`/subgoal` parity for webchat). */
148
- authenticated.post("/api/goals/webchat/checklist", async (c) => {
529
+ authenticated.post("/api/goals/:goalId/archive", async (c) => {
530
+ const before = goals.get(c.req.param("goalId"));
531
+ const goal = goals.archive(c.req.param("goalId"));
532
+ if (!goal) return c.json({
533
+ ok: false,
534
+ error: "Goal not found"
535
+ }, 404);
536
+ const abortResult = abortActiveWebchatRunForGoal(deps, goal);
537
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
538
+ goalId: goal.id,
539
+ previousStatus: before?.status,
540
+ status: goal.status,
541
+ goal
542
+ });
543
+ return c.json({
544
+ ok: true,
545
+ goal,
546
+ ...abortResult
547
+ });
548
+ });
549
+ authenticated.post("/api/goals/:goalId/unarchive", async (c) => {
550
+ const before = goals.get(c.req.param("goalId"));
551
+ const goal = goals.unarchive(c.req.param("goalId"));
552
+ if (!goal) return c.json({
553
+ ok: false,
554
+ error: "Goal not found"
555
+ }, 404);
556
+ if (before?.status !== goal.status) deps.service.emit("goal.status.updated", {
557
+ goalId: goal.id,
558
+ previousStatus: before?.status,
559
+ status: goal.status,
560
+ goal
561
+ });
562
+ return c.json({
563
+ ok: true,
564
+ goal
565
+ });
566
+ });
567
+ authenticated.post("/api/goals/:goalId/attach", async (c) => {
568
+ const goalId = c.req.param("goalId");
149
569
  const body = await c.req.json().catch(() => ({}));
150
570
  const sessionKey = typeof body.sessionKey === "string" ? body.sessionKey.trim() : "";
151
571
  if (!sessionKey) return c.json({
152
572
  ok: false,
153
573
  error: "Missing sessionKey"
154
574
  }, 400);
155
- const op = typeof body.op === "string" ? body.op.trim().toLowerCase() : "";
156
- const meta = await sm.getSessionMetadata(sessionKey);
157
- if (!meta) return c.json({
158
- ok: false,
159
- error: "Session not found"
160
- }, 404);
161
- let mutation = null;
162
- if (op === "reset") mutation = applyChecklistUserMutation(meta.customData, { type: "reset" });
163
- else if (op === "add") {
164
- const text = typeof body.text === "string" ? body.text : "";
165
- mutation = applyChecklistUserMutation(meta.customData, {
166
- type: "add",
167
- text
168
- });
169
- } else if (op === "remove") {
170
- const index = typeof body.index === "number" && Number.isFinite(body.index) ? Math.floor(body.index) : void 0;
171
- if (index === void 0 || index < 1) return c.json({
172
- ok: false,
173
- error: "Missing or invalid index (1-based)"
174
- }, 400);
175
- mutation = applyChecklistUserMutation(meta.customData, {
176
- type: "remove",
177
- index1Based: index
178
- });
179
- } else if (op === "mark") {
180
- const index = typeof body.index === "number" && Number.isFinite(body.index) ? Math.floor(body.index) : void 0;
181
- const status = typeof body.status === "string" ? body.status.trim().toLowerCase() : "";
182
- if (index === void 0 || index < 1) return c.json({
183
- ok: false,
184
- error: "Missing or invalid index (1-based)"
185
- }, 400);
186
- if (status !== "pending" && status !== "completed" && status !== "impossible") return c.json({
187
- ok: false,
188
- error: "status must be pending, completed, or impossible"
189
- }, 400);
190
- mutation = applyChecklistUserMutation(meta.customData, {
191
- type: "mark",
192
- index1Based: index,
193
- status
194
- });
195
- } else return c.json({
575
+ const goal = goals.attachSession(goalId, sessionKey);
576
+ if (!goal) return c.json({
196
577
  ok: false,
197
- error: "Invalid op (add|remove|mark|reset)"
578
+ error: "Goal not found"
579
+ }, 404);
580
+ return c.json({
581
+ ok: true,
582
+ goal
583
+ });
584
+ });
585
+ authenticated.post("/api/goals/:goalId/detach", async (c) => {
586
+ const goal = goals.update(c.req.param("goalId"), { activeSessionKey: void 0 });
587
+ if (!goal) return c.json({
588
+ ok: false,
589
+ error: "Goal not found"
590
+ }, 404);
591
+ return c.json({
592
+ ok: true,
593
+ goal
594
+ });
595
+ });
596
+ authenticated.get("/api/goals/:goalId/runs", async (c) => {
597
+ const goalId = c.req.param("goalId");
598
+ if (!goals.get(goalId)) return c.json({
599
+ ok: false,
600
+ error: "Goal not found"
601
+ }, 404);
602
+ return c.json({
603
+ ok: true,
604
+ runs: goals.listRuns(goalId, parseLimit(c.req.query("limit")))
605
+ });
606
+ });
607
+ authenticated.get("/api/goals/:goalId/events", async (c) => {
608
+ const goalId = c.req.param("goalId");
609
+ if (!goals.get(goalId)) return c.json({
610
+ ok: false,
611
+ error: "Goal not found"
612
+ }, 404);
613
+ return c.json({
614
+ ok: true,
615
+ events: goals.listEvents(goalId, parseLimit(c.req.query("limit"), 100))
616
+ });
617
+ });
618
+ authenticated.get("/api/goals/:goalId/evidence", async (c) => {
619
+ const goalId = c.req.param("goalId");
620
+ if (!goals.get(goalId)) return c.json({
621
+ ok: false,
622
+ error: "Goal not found"
623
+ }, 404);
624
+ return c.json({
625
+ ok: true,
626
+ evidence: goals.listEvidence(goalId, parseLimit(c.req.query("limit"), 100))
627
+ });
628
+ });
629
+ authenticated.post("/api/goals/:goalId/evidence", async (c) => {
630
+ const goalId = c.req.param("goalId");
631
+ if (!goals.get(goalId)) return c.json({
632
+ ok: false,
633
+ error: "Goal not found"
634
+ }, 404);
635
+ const body = await c.req.json().catch(() => ({}));
636
+ const title = typeof body.title === "string" ? body.title.trim() : "";
637
+ const kind = body.kind;
638
+ if (!title) return c.json({
639
+ ok: false,
640
+ error: "Missing title"
198
641
  }, 400);
199
- if (mutation.kind === "error") return c.json({
642
+ if (kind !== "file" && kind !== "diff" && kind !== "command" && kind !== "test" && kind !== "link" && kind !== "message" && kind !== "artifact") return c.json({
200
643
  ok: false,
201
- error: mutation.error
644
+ error: "Invalid evidence kind"
202
645
  }, 400);
203
- if (mutation.kind === "noop") {
204
- const persistentGoal = readPersistentGoal(meta.customData);
205
- return c.json({
206
- ok: true,
207
- sessionKey,
208
- noop: true,
209
- message: mutation.message,
210
- persistentGoal
211
- });
212
- }
213
- const uiLocale = normalizeGoalUiLocale(body.uiLocale);
214
- const customData = uiLocale != null ? mergePersistentGoalUiLocale(mutation.customData, uiLocale) ?? mutation.customData : mutation.customData;
215
- await sm.updateSessionMetadata(sessionKey, { customData });
216
- const persistentGoal = readPersistentGoal((await sm.getSessionMetadata(sessionKey))?.customData);
646
+ const evidence = goals.addEvidence({
647
+ goalId,
648
+ runId: typeof body.runId === "string" ? body.runId : void 0,
649
+ kind,
650
+ title,
651
+ summary: typeof body.summary === "string" ? body.summary : void 0,
652
+ uri: typeof body.uri === "string" ? body.uri : void 0,
653
+ data: body.data
654
+ });
217
655
  return c.json({
218
656
  ok: true,
219
- sessionKey,
220
- op,
221
- persistentGoal
657
+ evidence
658
+ });
659
+ });
660
+ authenticated.post("/api/goals/:goalId/checklist", async (c) => {
661
+ const goalId = c.req.param("goalId");
662
+ if (!goals.get(goalId)) return c.json({
663
+ ok: false,
664
+ error: "Goal not found"
665
+ }, 404);
666
+ const body = await c.req.json().catch(() => ({}));
667
+ const text = typeof body.text === "string" ? body.text.trim() : "";
668
+ if (!text) return c.json({
669
+ ok: false,
670
+ error: "Missing text"
671
+ }, 400);
672
+ const goal = goals.updateChecklist(goalId, {
673
+ type: "add",
674
+ text,
675
+ addedBy: "user"
676
+ });
677
+ return c.json({
678
+ ok: true,
679
+ goal
680
+ });
681
+ });
682
+ authenticated.patch("/api/goals/:goalId/checklist/:itemId", async (c) => {
683
+ const goalId = c.req.param("goalId");
684
+ const itemId = c.req.param("itemId");
685
+ if (!goals.get(goalId)) return c.json({
686
+ ok: false,
687
+ error: "Goal not found"
688
+ }, 404);
689
+ const body = await c.req.json().catch(() => ({}));
690
+ const status = body.status;
691
+ if (status !== "pending" && status !== "completed" && status !== "impossible") return c.json({
692
+ ok: false,
693
+ error: "Invalid checklist status"
694
+ }, 400);
695
+ const goal = goals.updateChecklist(goalId, {
696
+ type: "mark",
697
+ itemId,
698
+ status,
699
+ evidenceSummary: typeof body.evidenceSummary === "string" ? body.evidenceSummary : void 0
700
+ });
701
+ return c.json({
702
+ ok: true,
703
+ goal
704
+ });
705
+ });
706
+ authenticated.delete("/api/goals/:goalId/checklist/:itemId", async (c) => {
707
+ const goalId = c.req.param("goalId");
708
+ if (!goals.get(goalId)) return c.json({
709
+ ok: false,
710
+ error: "Goal not found"
711
+ }, 404);
712
+ const goal = goals.updateChecklist(goalId, {
713
+ type: "remove",
714
+ itemId: c.req.param("itemId")
715
+ });
716
+ return c.json({
717
+ ok: true,
718
+ goal
222
719
  });
223
720
  });
224
721
  }