@xopcai/xopc 0.0.120 → 0.0.122

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 (403) hide show
  1. package/README.md +23 -3
  2. package/README.zh-CN.md +23 -3
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/dashscope/src/image-generation-provider.d.ts +6 -5
  5. package/dist/extensions/dashscope/src/image-generation-provider.js +40 -64
  6. package/dist/extensions/dashscope/src/image-generation-provider.js.map +1 -1
  7. package/dist/extensions/dashscope/src/index.d.ts +1 -1
  8. package/dist/extensions/dashscope/src/index.js +2 -2
  9. package/dist/extensions/dashscope/xopc.extension.json +3 -2
  10. package/dist/extensions/minimax/src/image-generation-provider.d.ts +7 -5
  11. package/dist/extensions/minimax/src/image-generation-provider.js +43 -37
  12. package/dist/extensions/minimax/src/image-generation-provider.js.map +1 -1
  13. package/dist/extensions/minimax/src/index.d.ts +1 -1
  14. package/dist/extensions/minimax/src/index.js +2 -2
  15. package/dist/extensions/minimax/xopc.extension.json +1 -1
  16. package/dist/extensions/telegram/xopc.extension.json +1 -1
  17. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +41 -0
  18. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-APTlX9Sq.js → agent-avatar-dicebear-CK3s5cJo.js} +1 -1
  19. package/dist/gateway/static/root/assets/agents-SsQrj9B-.js +2 -0
  20. package/dist/gateway/static/root/assets/{app-management-settings-panel-DTKc5HHT.js → app-management-settings-panel-CWsNHtTs.js} +1 -1
  21. package/dist/gateway/static/root/assets/{appearance-settings-BTciFrE9.js → appearance-settings-C4b8y6iZ.js} +1 -1
  22. package/dist/gateway/static/root/assets/apps-page-CYb6fame.js +1 -0
  23. package/dist/gateway/static/root/assets/{archive-plugin-CiHaUMII.js → archive-plugin-DAtNW3Ia.js} +1 -1
  24. package/dist/gateway/static/root/assets/{attachment-load-t4gSrNjL.js → attachment-load-Dm-RY54y.js} +1 -1
  25. package/dist/gateway/static/root/assets/automation-suggestion-card-BKHewSVT.js +1 -0
  26. package/dist/gateway/static/root/assets/automations-page-DpOOq1nk.js +1 -0
  27. package/dist/gateway/static/root/assets/{binary-plugins-BAbSldW5.js → binary-plugins-BG6Xnk71.js} +1 -1
  28. package/dist/gateway/static/root/assets/{block-editor-BNr_82xl.js → block-editor-DfndiO3h.js} +28 -28
  29. package/dist/gateway/static/root/assets/browser-settings-page-9nXxgh4u.js +8 -0
  30. package/dist/gateway/static/root/assets/{capability-presets-api-tzD702Gg.js → capability-presets-api-Cx93GLdw.js} +1 -1
  31. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-AGhTueAc.js → capability-presets-settings-panel-D528_YFy.js} +1 -1
  32. package/dist/gateway/static/root/assets/{channel-recipient-api-DL_KzwGE.js → channel-recipient-api-DdPTtEs8.js} +1 -1
  33. package/dist/gateway/static/root/assets/channels-settings-Ck-3h5lI.js +1 -0
  34. package/dist/gateway/static/root/assets/connectors-page-DL-fAqE_.js +2 -0
  35. package/dist/gateway/static/root/assets/directory-picker-path-field-D835EHJd.js +1 -0
  36. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +1 -0
  37. package/dist/gateway/static/root/assets/dist-wO9a2_ID.js +1 -0
  38. package/dist/gateway/static/root/assets/dreaming-settings-CCa1F7Fg.js +1 -0
  39. package/dist/gateway/static/root/assets/{extension-debug-page-Dl2kO0Sf.js → extension-debug-page-W2ITCPSA.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-page-DmbLPsx_.js → extension-page-DrvUytvn.js} +1 -1
  41. package/dist/gateway/static/root/assets/extension-settings-page-qM8aLT5u.js +1 -0
  42. package/dist/gateway/static/root/assets/{fetch-B3ME5Eri.js → fetch-ovkvM8KQ.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-config-api-DI9_BBTo.js → gateway-config-api-BB3biuD0.js} +1 -1
  44. package/dist/gateway/static/root/assets/gateway-settings-mmmnIH27.js +1 -0
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-CSZQTz6K.js → gateway-startup-retry-CanQ8UcR.js} +1 -1
  46. package/dist/gateway/static/root/assets/goal-create-dialog-CNqNdEkQ.js +1 -0
  47. package/dist/gateway/static/root/assets/goal-detail-page-Ceu5zrN6.js +1 -0
  48. package/dist/gateway/static/root/assets/{goals-config-api-Bhzqrp2w.js → goals-config-api-BBOX6mUl.js} +1 -1
  49. package/dist/gateway/static/root/assets/goals-page-BP1kfvWv.js +2 -0
  50. package/dist/gateway/static/root/assets/goals-settings-Bh3A7OZV.js +1 -0
  51. package/dist/gateway/static/root/assets/heartbeat-settings-YoYgKlfX.js +1 -0
  52. package/dist/gateway/static/root/assets/index-DdqSO9R2.js +191 -0
  53. package/dist/gateway/static/root/assets/index-jGB-2nI-.css +1 -0
  54. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-kMp08SlX.js → keyboard-shortcuts-settings-B4TKJHla.js} +1 -1
  55. package/dist/gateway/static/root/assets/logs-page-BgVk5DvZ.js +2 -0
  56. package/dist/gateway/static/root/assets/{markdown-split-Bc0w40vz.js → markdown-split-DcFtdLci.js} +1 -1
  57. package/dist/gateway/static/root/assets/{media-plugins-DJ_HvgIy.js → media-plugins-B6SmeLVB.js} +1 -1
  58. package/dist/gateway/static/root/assets/messages-B5O4OIEo.js +3 -0
  59. package/dist/gateway/static/root/assets/models-hub-panel-BU0x8PGP.js +2 -0
  60. package/dist/gateway/static/root/assets/notes-page-D6JYVP4I.js +1 -0
  61. package/dist/gateway/static/root/assets/notes-workbench-mqRJYnJS.js +2 -0
  62. package/dist/gateway/static/root/assets/{preview-open-alternatives-BbA7sRd_.js → preview-open-alternatives-C29O19s7.js} +1 -1
  63. package/dist/gateway/static/root/assets/project-detail-page-DOTgzoeh.js +1 -0
  64. package/dist/gateway/static/root/assets/projects-page-DGUIb4y5.js +1 -0
  65. package/dist/gateway/static/root/assets/remote-access-hub-DVKKUj3u.js +1 -0
  66. package/dist/gateway/static/root/assets/{save-bar-controls-Dividh61.js → save-bar-controls-B4ad9GfB.js} +1 -1
  67. package/dist/gateway/static/root/assets/schedule-field-DdYncfLR.js +1 -0
  68. package/dist/gateway/static/root/assets/schema-form-BMTrDE-7.js +1 -0
  69. package/dist/gateway/static/root/assets/segmented-styles-BL8oLBEp.js +1 -0
  70. package/dist/gateway/static/root/assets/sessions-page-BVbzUWxW.js +1 -0
  71. package/dist/gateway/static/root/assets/settings-advanced-gate-DrNNoSqE.js +1 -0
  72. package/dist/gateway/static/root/assets/{settings-collapsible-section-BMCOfuE_.js → settings-collapsible-section-MwTW2eK4.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-form-section-DBkGwpIN.js → settings-form-section-Dg6LBbcr.js} +1 -1
  74. package/dist/gateway/static/root/assets/settings-page-CMDqgeMR.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-page-layout-BX4T-OLF.js +1 -0
  76. package/dist/gateway/static/root/assets/setup-status-panel-Ce1pcFtR.js +1 -0
  77. package/dist/gateway/static/root/assets/share-preview-page-DWE-dUFh.js +2 -0
  78. package/dist/gateway/static/root/assets/shares-settings-aKSraR8l.js +1 -0
  79. package/dist/gateway/static/root/assets/skill-reload-api-CS-FU_B-.js +1 -0
  80. package/dist/gateway/static/root/assets/skills-page-BaF3u0LA.js +2 -0
  81. package/dist/gateway/static/root/assets/{system-settings-panel-CrmEnyX4.js → system-settings-panel-Dd6Y35Cm.js} +1 -1
  82. package/dist/gateway/static/root/assets/{typed-models-lib-BAsGn25g.js → typed-models-lib-Cx6XV5A2.js} +1 -1
  83. package/dist/gateway/static/root/assets/{use-channel-catalog-C7vcAoGb.js → use-channel-catalog-D4sMbmy7.js} +1 -1
  84. package/dist/gateway/static/root/assets/user-profile-settings-panel-Bx-hjMQc.js +1 -0
  85. package/dist/gateway/static/root/assets/{utils-Dl9efgnV.js → utils-D7b_vZnv.js} +1 -1
  86. package/dist/gateway/static/root/assets/voice-api-key-field-CkhbRt1q.js +1 -0
  87. package/dist/gateway/static/root/assets/workflow-run-setup-panel--TdohF5N.js +3 -0
  88. package/dist/gateway/static/root/assets/workflow-start-dialog-B0lavx_o.js +1 -0
  89. package/dist/gateway/static/root/assets/workflows-page-CZR05Bu_.js +18 -0
  90. package/dist/gateway/static/root/index.html +7 -8
  91. package/dist/package.js +1 -1
  92. package/dist/src/agent/agent-manager.d.ts +2 -0
  93. package/dist/src/agent/agent-manager.js +47 -7
  94. package/dist/src/agent/agent-manager.js.map +1 -1
  95. package/dist/src/agent/context/project-context.d.ts +19 -0
  96. package/dist/src/agent/context/project-context.js +90 -0
  97. package/dist/src/agent/context/project-context.js.map +1 -0
  98. package/dist/src/agent/embedded/xopc-auth-storage.d.ts +1 -5
  99. package/dist/src/agent/embedded/xopc-auth-storage.js +2 -8
  100. package/dist/src/agent/embedded/xopc-auth-storage.js.map +1 -1
  101. package/dist/src/agent/embedded/xopc-tools-bridge.js +23 -0
  102. package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
  103. package/dist/src/agent/goals/checklist-judge.js +1 -1
  104. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  105. package/dist/src/agent/goals/goal-locale.js +2 -2
  106. package/dist/src/agent/goals/judge.js +1 -1
  107. package/dist/src/agent/goals/judge.js.map +1 -1
  108. package/dist/src/agent/image/tool-model-config.d.ts +2 -0
  109. package/dist/src/agent/image/tool-model-config.js +2 -2
  110. package/dist/src/agent/image/tool-model-config.js.map +1 -1
  111. package/dist/src/agent/image/understanding/pi-ai-provider.js +1 -1
  112. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  113. package/dist/src/agent/memory/compaction.d.ts +1 -1
  114. package/dist/src/agent/memory/compaction.js +1 -1
  115. package/dist/src/agent/memory/compaction.js.map +1 -1
  116. package/dist/src/agent/memory/types.d.ts +1 -0
  117. package/dist/src/agent/middleware/self-verify.d.ts +3 -0
  118. package/dist/src/agent/middleware/self-verify.js +18 -0
  119. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  120. package/dist/src/agent/orchestration/agent-event-handler.js +28 -3
  121. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  122. package/dist/src/agent/prompt/sections/tooling.js +21 -5
  123. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  124. package/dist/src/agent/prompt/service-prompt-builder.d.ts +1 -0
  125. package/dist/src/agent/prompt/service-prompt-builder.js +3 -0
  126. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  127. package/dist/src/agent/prompt/system-prompt-params.d.ts +2 -0
  128. package/dist/src/agent/prompt/system-prompt-params.js +1 -0
  129. package/dist/src/agent/prompt/system-prompt-params.js.map +1 -1
  130. package/dist/src/agent/prompt/system-prompt.d.ts +2 -0
  131. package/dist/src/agent/prompt/system-prompt.js +14 -1
  132. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  133. package/dist/src/agent/sandbox/path-policy.js +30 -6
  134. package/dist/src/agent/sandbox/path-policy.js.map +1 -1
  135. package/dist/src/agent/service/btw-query.js +1 -1
  136. package/dist/src/agent/service/btw-query.js.map +1 -1
  137. package/dist/src/agent/service.js +4 -3
  138. package/dist/src/agent/service.js.map +1 -1
  139. package/dist/src/agent/session/session-config-service.js +6 -1
  140. package/dist/src/agent/session/session-config-service.js.map +1 -1
  141. package/dist/src/agent/session/session-hydrator.js +7 -3
  142. package/dist/src/agent/session/session-hydrator.js.map +1 -1
  143. package/dist/src/agent/session/session-inspector.js +9 -5
  144. package/dist/src/agent/session/session-inspector.js.map +1 -1
  145. package/dist/src/agent/starter-agents.js +18 -47
  146. package/dist/src/agent/starter-agents.js.map +1 -1
  147. package/dist/src/agent/tools/image-generate-tool.js +12 -1
  148. package/dist/src/agent/tools/image-generate-tool.js.map +1 -1
  149. package/dist/src/agent/tools/session-search-tool.js +1 -1
  150. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  151. package/dist/src/agent/tools/web-extract.js +1 -1
  152. package/dist/src/agent/tools/web-extract.js.map +1 -1
  153. package/dist/src/agent/workflow/index.js +2 -2
  154. package/dist/src/agent/workflow/runtime.js +1 -1
  155. package/dist/src/agent-manifest/index.js +2 -2
  156. package/dist/src/agent-manifest/schema.d.ts +66 -0
  157. package/dist/src/agent-manifest/schema.js +28 -2
  158. package/dist/src/agent-manifest/schema.js.map +1 -1
  159. package/dist/src/automations/api/routes.js +13 -2
  160. package/dist/src/automations/api/routes.js.map +1 -1
  161. package/dist/src/automations/domain/types.d.ts +2 -0
  162. package/dist/src/automations/domain/validation.d.ts +3 -0
  163. package/dist/src/automations/domain/validation.js +1 -0
  164. package/dist/src/automations/domain/validation.js.map +1 -1
  165. package/dist/src/automations/draft/automation-draft-service.js +1 -1
  166. package/dist/src/automations/draft/automation-draft-service.js.map +1 -1
  167. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -0
  168. package/dist/src/automations/service/action-executor.js +3 -1
  169. package/dist/src/automations/service/action-executor.js.map +1 -1
  170. package/dist/src/automations/service/automation-service.d.ts +4 -1
  171. package/dist/src/automations/service/automation-service.js +2 -2
  172. package/dist/src/automations/service/automation-service.js.map +1 -1
  173. package/dist/src/automations/storage/automation-repository.d.ts +3 -1
  174. package/dist/src/automations/storage/automation-repository.js +7 -5
  175. package/dist/src/automations/storage/automation-repository.js.map +1 -1
  176. package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
  177. package/dist/src/automations/storage/automation-run-repository.js +12 -1
  178. package/dist/src/automations/storage/automation-run-repository.js.map +1 -1
  179. package/dist/src/chat-commands/context.js +2 -1
  180. package/dist/src/chat-commands/context.js.map +1 -1
  181. package/dist/src/cli/command-loaders.js +1 -0
  182. package/dist/src/cli/command-loaders.js.map +1 -1
  183. package/dist/src/cli/command-manifest.js +4 -0
  184. package/dist/src/cli/command-manifest.js.map +1 -1
  185. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  186. package/dist/src/cli/commands/goal.js +27 -4
  187. package/dist/src/cli/commands/goal.js.map +1 -1
  188. package/dist/src/cli/commands/onboard/model.js +161 -11
  189. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  190. package/dist/src/cli/commands/project.d.ts +4 -0
  191. package/dist/src/cli/commands/project.js +239 -0
  192. package/dist/src/cli/commands/project.js.map +1 -0
  193. package/dist/src/config/default-model.d.ts +11 -0
  194. package/dist/src/config/default-model.js +19 -0
  195. package/dist/src/config/default-model.js.map +1 -0
  196. package/dist/src/config/index.js +2 -2
  197. package/dist/src/config/schema.d.ts +71 -11
  198. package/dist/src/config/schema.js +57 -22
  199. package/dist/src/config/schema.js.map +1 -1
  200. package/dist/src/connectors/registries/smithery.js +10 -9
  201. package/dist/src/connectors/registries/smithery.js.map +1 -1
  202. package/dist/src/daemon/install-plan.js +2 -1
  203. package/dist/src/daemon/install-plan.js.map +1 -1
  204. package/dist/src/gateway/global-defaults-admin.js +6 -16
  205. package/dist/src/gateway/global-defaults-admin.js.map +1 -1
  206. package/dist/src/gateway/hono/lib/config-payload.d.ts +24 -0
  207. package/dist/src/gateway/hono/routes/agents.js +1 -79
  208. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  209. package/dist/src/gateway/hono/routes/goals.js +51 -4
  210. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  211. package/dist/src/gateway/hono/routes/index.js +2 -0
  212. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  213. package/dist/src/gateway/hono/routes/memory.js +5 -1
  214. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  215. package/dist/src/gateway/hono/routes/models.js +132 -14
  216. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  217. package/dist/src/gateway/hono/routes/notes.js +5 -0
  218. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  219. package/dist/src/gateway/hono/routes/projects.d.ts +3 -0
  220. package/dist/src/gateway/hono/routes/projects.js +578 -0
  221. package/dist/src/gateway/hono/routes/projects.js.map +1 -0
  222. package/dist/src/gateway/hono/routes/sessions.js +47 -7
  223. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  224. package/dist/src/gateway/hono/routes/voice.js +1 -1
  225. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  226. package/dist/src/gateway/hono/routes/workflows.js +27 -4
  227. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  228. package/dist/src/gateway/image-capabilities.d.ts +11 -1
  229. package/dist/src/gateway/image-capabilities.js +32 -43
  230. package/dist/src/gateway/image-capabilities.js.map +1 -1
  231. package/dist/src/gateway/service.d.ts +3 -0
  232. package/dist/src/gateway/service.js +10 -3
  233. package/dist/src/gateway/service.js.map +1 -1
  234. package/dist/src/gateway/workspace-editor-path.js +9 -1
  235. package/dist/src/gateway/workspace-editor-path.js.map +1 -1
  236. package/dist/src/generated/bundled-image-generation-providers.d.ts +4 -2
  237. package/dist/src/generated/bundled-image-generation-providers.js +6 -4
  238. package/dist/src/generated/bundled-image-generation-providers.js.map +1 -1
  239. package/dist/src/goals/goal-service.d.ts +1 -1
  240. package/dist/src/goals/goal-service.js +2 -1
  241. package/dist/src/goals/goal-service.js.map +1 -1
  242. package/dist/src/goals/goal-store.d.ts +1 -1
  243. package/dist/src/goals/goal-store.js +12 -6
  244. package/dist/src/goals/goal-store.js.map +1 -1
  245. package/dist/src/goals/goal-workflow-judge.js +1 -1
  246. package/dist/src/goals/types.d.ts +3 -0
  247. package/dist/src/i18n/goals-bundle.js +1 -1
  248. package/dist/src/i18n/index.js +1 -1
  249. package/dist/src/i18n/share-tool-bundle.js +2 -2
  250. package/dist/src/media/paths.js +3 -4
  251. package/dist/src/media/paths.js.map +1 -1
  252. package/dist/src/notes/agent-context.js +2 -2
  253. package/dist/src/notes/service.js +1 -1
  254. package/dist/src/notes/service.js.map +1 -1
  255. package/dist/src/projects/automation-bind.d.ts +1 -0
  256. package/dist/src/projects/automation-bind.js +16 -0
  257. package/dist/src/projects/automation-bind.js.map +1 -0
  258. package/dist/src/projects/goal-bind.d.ts +4 -0
  259. package/dist/src/projects/goal-bind.js +40 -0
  260. package/dist/src/projects/goal-bind.js.map +1 -0
  261. package/dist/src/projects/index.d.ts +11 -0
  262. package/dist/src/projects/index.js +11 -0
  263. package/dist/src/projects/memory-bind.d.ts +1 -0
  264. package/dist/src/projects/memory-bind.js +16 -0
  265. package/dist/src/projects/memory-bind.js.map +1 -0
  266. package/dist/src/projects/project-agent.d.ts +10 -0
  267. package/dist/src/projects/project-agent.js +27 -0
  268. package/dist/src/projects/project-agent.js.map +1 -0
  269. package/dist/src/projects/project-loop.d.ts +58 -0
  270. package/dist/src/projects/project-loop.js +118 -0
  271. package/dist/src/projects/project-loop.js.map +1 -0
  272. package/dist/src/projects/project-service.d.ts +26 -0
  273. package/dist/src/projects/project-service.js +94 -0
  274. package/dist/src/projects/project-service.js.map +1 -0
  275. package/dist/src/projects/project-store.d.ts +31 -0
  276. package/dist/src/projects/project-store.js +193 -0
  277. package/dist/src/projects/project-store.js.map +1 -0
  278. package/dist/src/projects/session-bind.d.ts +5 -0
  279. package/dist/src/projects/session-bind.js +46 -0
  280. package/dist/src/projects/session-bind.js.map +1 -0
  281. package/dist/src/projects/types.d.ts +60 -0
  282. package/dist/src/projects/types.js +1 -0
  283. package/dist/src/projects/workflow-bind.d.ts +1 -0
  284. package/dist/src/projects/workflow-bind.js +16 -0
  285. package/dist/src/projects/workflow-bind.js.map +1 -0
  286. package/dist/src/projects/workspace.d.ts +5 -0
  287. package/dist/src/projects/workspace.js +25 -0
  288. package/dist/src/projects/workspace.js.map +1 -0
  289. package/dist/src/providers/domestic-presets.d.ts +615 -0
  290. package/dist/src/providers/domestic-presets.js +834 -0
  291. package/dist/src/providers/domestic-presets.js.map +1 -0
  292. package/dist/src/providers/env-keys.js +29 -5
  293. package/dist/src/providers/env-keys.js.map +1 -1
  294. package/dist/src/providers/extension-stream-bridge.js +1 -1
  295. package/dist/src/providers/extension-stream-bridge.js.map +1 -1
  296. package/dist/src/providers/index.d.ts +5 -5
  297. package/dist/src/providers/index.js +101 -21
  298. package/dist/src/providers/index.js.map +1 -1
  299. package/dist/src/providers/model-discovery.d.ts +17 -0
  300. package/dist/src/providers/model-discovery.js +61 -0
  301. package/dist/src/providers/model-discovery.js.map +1 -0
  302. package/dist/src/providers/model-registry.d.ts +1 -1
  303. package/dist/src/providers/model-registry.js +1 -1
  304. package/dist/src/providers/model-registry.js.map +1 -1
  305. package/dist/src/providers/presentation.js +185 -14
  306. package/dist/src/providers/presentation.js.map +1 -1
  307. package/dist/src/session/index.d.ts +1 -1
  308. package/dist/src/session/index.js +3 -3
  309. package/dist/src/session/session-title.js +1 -1
  310. package/dist/src/session/session-title.js.map +1 -1
  311. package/dist/src/session/session-workspace.d.ts +4 -2
  312. package/dist/src/session/session-workspace.js +10 -3
  313. package/dist/src/session/session-workspace.js.map +1 -1
  314. package/dist/src/session/types.d.ts +3 -0
  315. package/dist/src/session/types.js.map +1 -1
  316. package/dist/src/storage/sqlite/memory-records-repository.d.ts +3 -0
  317. package/dist/src/storage/sqlite/memory-records-repository.js +16 -5
  318. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  319. package/dist/src/storage/sqlite/migrations/019_projects.sql +40 -0
  320. package/dist/src/storage/sqlite/migrations/020_project_default_agent.sql +1 -0
  321. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  322. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  323. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  324. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  325. package/dist/src/storage/sqlite/notes-repository.js +20 -4
  326. package/dist/src/storage/sqlite/notes-repository.js.map +1 -1
  327. package/dist/src/storage/sqlite/row-mappers.d.ts +2 -0
  328. package/dist/src/storage/sqlite/row-mappers.js +2 -0
  329. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  330. package/dist/src/storage/sqlite/schema.js +1 -1
  331. package/dist/src/storage/sqlite/session-repository.js +10 -5
  332. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  333. package/dist/src/storage/sqlite/transcript-repository.js +8 -0
  334. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  335. package/dist/src/tui/backends/embedded-backend.js +1 -1
  336. package/dist/src/tui/tui-commands.js +145 -0
  337. package/dist/src/tui/tui-commands.js.map +1 -1
  338. package/dist/src/tui/xopc-tui-keybindings.d.ts +1 -1
  339. package/dist/src/voice/tts/summarize.js +1 -1
  340. package/dist/src/voice/tts/summarize.js.map +1 -1
  341. package/dist/src/workflows/domain/run.d.ts +1 -0
  342. package/dist/src/workflows/domain/run.js.map +1 -1
  343. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  344. package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
  345. package/dist/src/workflows/index.js +1 -1
  346. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  347. package/dist/src/workflows/service/workflow-run-service.js +18 -4
  348. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  349. package/dist/src/workflows/service/workflow-run-service.types.d.ts +2 -0
  350. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  351. package/dist/src/workflows/service/workflow-session-bridge.js +3 -0
  352. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  353. package/dist/src/workflows/store/run-index-store.d.ts +1 -0
  354. package/dist/src/workflows/store/run-index-store.js +13 -3
  355. package/dist/src/workflows/store/run-index-store.js.map +1 -1
  356. package/dist/src/workflows/store/run-store.d.ts +3 -1
  357. package/dist/src/workflows/store/run-store.js +5 -2
  358. package/dist/src/workflows/store/run-store.js.map +1 -1
  359. package/package.json +15 -6
  360. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +0 -41
  361. package/dist/gateway/static/root/assets/agents-CFW_FS_V.js +0 -2
  362. package/dist/gateway/static/root/assets/apps-page-DT52OrbM.js +0 -1
  363. package/dist/gateway/static/root/assets/automation-suggestion-card-CtysjSoQ.js +0 -1
  364. package/dist/gateway/static/root/assets/automations-page-B2YvT3ES.js +0 -1
  365. package/dist/gateway/static/root/assets/browser-settings-page-BQEXPhDU.js +0 -8
  366. package/dist/gateway/static/root/assets/channels-settings-DRTutLlN.js +0 -1
  367. package/dist/gateway/static/root/assets/connectors-page-DneJVuge.js +0 -2
  368. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +0 -1
  369. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +0 -1
  370. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +0 -1
  371. package/dist/gateway/static/root/assets/dreaming-settings-BEwWA1yf.js +0 -1
  372. package/dist/gateway/static/root/assets/extension-settings-page-BS2rx40e.js +0 -1
  373. package/dist/gateway/static/root/assets/gateway-settings-DAFI_T0W.js +0 -1
  374. package/dist/gateway/static/root/assets/goal-detail-page-DLuz4jC9.js +0 -1
  375. package/dist/gateway/static/root/assets/goals-page-DTAfv9Ft.js +0 -2
  376. package/dist/gateway/static/root/assets/goals-settings-CWN2iirQ.js +0 -1
  377. package/dist/gateway/static/root/assets/heartbeat-settings-CkkkHvOi.js +0 -1
  378. package/dist/gateway/static/root/assets/index-CnjzMw5i.js +0 -191
  379. package/dist/gateway/static/root/assets/index-E1QinYKp.css +0 -1
  380. package/dist/gateway/static/root/assets/logs-page-CDXDlS_W.js +0 -2
  381. package/dist/gateway/static/root/assets/messages-CISb1HLv.js +0 -3
  382. package/dist/gateway/static/root/assets/models-hub-panel-BTwxMIgZ.js +0 -2
  383. package/dist/gateway/static/root/assets/note-detail-page-BBfOeB0m.js +0 -2
  384. package/dist/gateway/static/root/assets/note-image-lightbox-4zntqpZq.js +0 -1
  385. package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +0 -1
  386. package/dist/gateway/static/root/assets/notes-page-VocWOjoK.js +0 -1
  387. package/dist/gateway/static/root/assets/remote-access-hub-CXwjuD_Q.js +0 -1
  388. package/dist/gateway/static/root/assets/schedule-field-pRheF2CO.js +0 -1
  389. package/dist/gateway/static/root/assets/schema-form-D6PiPxfr.js +0 -1
  390. package/dist/gateway/static/root/assets/sessions-page-CpcVySQK.js +0 -1
  391. package/dist/gateway/static/root/assets/settings-advanced-gate-BVy_TawT.js +0 -1
  392. package/dist/gateway/static/root/assets/settings-page-CZpNyCWn.js +0 -1
  393. package/dist/gateway/static/root/assets/settings-page-layout-NxoW5Y57.js +0 -1
  394. package/dist/gateway/static/root/assets/setup-status-panel-MVHLLu_a.js +0 -1
  395. package/dist/gateway/static/root/assets/share-preview-page-B0suFCfj.js +0 -2
  396. package/dist/gateway/static/root/assets/shares-settings-C6DBbQGo.js +0 -1
  397. package/dist/gateway/static/root/assets/skill-reload-api-6hJmhwSn.js +0 -1
  398. package/dist/gateway/static/root/assets/skills-page-Im1MA0Iw.js +0 -2
  399. package/dist/gateway/static/root/assets/user-profile-settings-panel-QAQWGelF.js +0 -1
  400. package/dist/gateway/static/root/assets/voice-api-key-field-D-6XueTv.js +0 -1
  401. package/dist/gateway/static/root/assets/voice-player-store-CMC5NOJp.js +0 -1
  402. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DVPllR4k.js +0 -3
  403. package/dist/gateway/static/root/assets/workflows-page-B94WISTW.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"web-extract.js","names":[],"sources":["../../../../src/agent/tools/web-extract.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport type { Config } from '../../config/schema.js';\nimport { getDefaultModelSync, resolveModel } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { checkUrlSafety, checkWebsiteBlocklist, cleanBase64Images } from './url-safety.js';\n\nconst log = createLogger('web-extract');\n\nexport const DEFAULT_WEB_EXTRACT_MAX_LENGTH = 15_000;\nexport const MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT = 200_000;\nconst EXTRACTION_TIMEOUT_MS = 30_000;\n\n// Large-document chunked processing thresholds (inspired by hermes-agent)\nconst MAX_CONTENT_SIZE = 2_000_000; // 2M chars — refuse entirely above this\nconst CHUNK_THRESHOLD = 500_000; // 500k chars — use chunked processing above this\nconst CHUNK_SIZE = 100_000; // 100k chars per chunk\nconst MAX_OUTPUT_SIZE = 15_000; // Hard cap on final output size\n\nconst WebExtractSchema = Type.Object({\n url: Type.String({ description: 'URL to extract content from' }),\n instruction: Type.Optional(\n Type.String({\n description:\n 'What to extract or focus on. Examples: \"main article text\", ' +\n '\"pricing table\", \"API documentation for the auth endpoint\". ' +\n 'If omitted, extracts the main content.',\n }),\n ),\n maxLength: Type.Optional(\n Type.Number({\n description: 'Maximum characters in the extracted content (default: from config or 15000)',\n }),\n ),\n});\n\nexport interface WebExtractDeps {\n getConfig: () => Config | undefined;\n}\n\nasync function fetchPageContent(url: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(url, {\n signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; xopc/1.0)',\n Accept: 'text/html,application/xhtml+xml,text/plain,application/json',\n },\n redirect: 'follow',\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n const json: unknown = await response.json();\n return JSON.stringify(json, null, 2);\n }\n\n return await response.text();\n}\n\nexport function stripHtmlBoilerplate(\n html: string,\n maxRaw = MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT,\n): string {\n let cleaned = html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<svg[\\s\\S]*?<\\/svg>/gi, '')\n .replace(/<noscript[\\s\\S]*?<\\/noscript>/gi, '')\n .replace(/<!--[\\s\\S]*?-->/g, '');\n\n // Remove base64 images early to avoid wasting characters on them\n cleaned = cleanBase64Images(cleaned);\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n if (cleaned.length > maxRaw) {\n cleaned = cleaned.slice(0, maxRaw) + '\\n\\n[...truncated]';\n }\n\n return cleaned;\n}\n\nfunction resolveExtractionModel(config?: Config) {\n const envRef = process.env.XOPC_WEB_EXTRACT_MODEL?.trim();\n const ref = envRef;\n\n if (ref) {\n try {\n return resolveModel(ref);\n } catch {\n /* fall through */\n }\n }\n\n const defaultRef = getDefaultModelSync(config);\n if (!defaultRef) {\n throw new Error('No global default model configured for web extraction');\n }\n\n return resolveModel(defaultRef);\n}\n\nfunction buildExtractionSystemPrompt(maxLength: number): string {\n return (\n 'You are a web content extractor. Given raw HTML/text from a web page, ' +\n 'extract the relevant content as clean, well-structured markdown.\\n\\n' +\n 'Rules:\\n' +\n '- Remove navigation, headers, footers, ads, cookie banners, sidebars\\n' +\n '- Preserve the main content structure (headings, lists, tables, code blocks)\\n' +\n '- Keep URLs for important links\\n' +\n '- If the page has structured data (tables, specs), preserve the structure\\n' +\n `- Keep output under ${maxLength} characters\\n` +\n '- If content is truncated, note what was cut\\n' +\n '- Output ONLY the extracted content, no meta-commentary'\n );\n}\n\n// ---------------------------------------------------------------------------\n// LLM call helper — shared by single-pass and chunked extraction\n// ---------------------------------------------------------------------------\n\nfunction buildTimeoutSignal(signal: AbortSignal | undefined): AbortSignal | undefined {\n const timeoutSignal =\n typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function'\n ? AbortSignal.timeout(EXTRACTION_TIMEOUT_MS)\n : undefined;\n if (signal && timeoutSignal && typeof AbortSignal.any === 'function') {\n return AbortSignal.any([signal, timeoutSignal]);\n }\n return signal ?? timeoutSignal;\n}\n\nfunction extractTextFromCompletion(result: { content?: unknown }): string {\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n return text.trim();\n}\n\nasync function callExtractionLlm(\n systemPrompt: string,\n userPrompt: string,\n maxTokens: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n const model = resolveExtractionModel(config);\n const userMsg: UserMessage = {\n role: 'user',\n content: `${systemPrompt}\\n\\n---\\n\\n${userPrompt}`,\n timestamp: Date.now(),\n };\n\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens,\n temperature: 0.2,\n signal: buildTimeoutSignal(signal) as AbortSignal,\n },\n );\n\n return extractTextFromCompletion(result);\n}\n\n// ---------------------------------------------------------------------------\n// Single-pass extraction (content < CHUNK_THRESHOLD)\n// ---------------------------------------------------------------------------\n\nasync function extractWithLlm(\n rawContent: string,\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n const contentLength = rawContent.length;\n\n // Refuse absurdly large content\n if (contentLength > MAX_CONTENT_SIZE) {\n const sizeMb = (contentLength / 1_000_000).toFixed(1);\n return (\n `[Content too large to process: ${sizeMb}MB. ` +\n 'Try using web_fetch for raw text, or search for a more focused source.]'\n );\n }\n\n // Route to chunked processing for large documents\n if (contentLength > CHUNK_THRESHOLD) {\n log.info(\n { url, contentLength, chunkSize: CHUNK_SIZE },\n 'Large document detected, using chunked extraction',\n );\n return extractLargeDocumentChunked(rawContent, url, instruction, maxLength, config, signal);\n }\n\n // Standard single-pass extraction\n const systemPrompt = buildExtractionSystemPrompt(maxLength);\n const body = instruction\n ? `Extract from this page (${url}):\\n\\nFOCUS: ${instruction}\\n\\n---\\n\\n${rawContent}`\n : `Extract the main content from this page (${url}):\\n\\n---\\n\\n${rawContent}`;\n\n const text = await callExtractionLlm(\n systemPrompt,\n body,\n Math.min(Math.ceil(maxLength / 3), 8000),\n config,\n signal,\n );\n\n if (!text) return 'No content could be extracted.';\n\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n if (text.length > outputCap) {\n return text.slice(0, outputCap) + '\\n\\n[...output truncated to maxLength]';\n }\n\n log.debug(\n { url, originalChars: contentLength, extractedChars: text.length },\n 'Single-pass extraction complete',\n );\n return text;\n}\n\n// ---------------------------------------------------------------------------\n// Chunked extraction for large documents (inspired by hermes-agent)\n//\n// Flow: split → parallel chunk summaries → synthesis pass\n// ---------------------------------------------------------------------------\n\nasync function extractLargeDocumentChunked(\n content: string,\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n // Split content into chunks\n const chunks: string[] = [];\n for (let offset = 0; offset < content.length; offset += CHUNK_SIZE) {\n chunks.push(content.slice(offset, offset + CHUNK_SIZE));\n }\n log.info({ url, chunkCount: chunks.length, chunkSize: CHUNK_SIZE }, 'Split into chunks');\n\n // Summarize each chunk in parallel\n const chunkPromises = chunks.map(async (chunk, index) => {\n const chunkLabel = `[Chunk ${index + 1}/${chunks.length}]`;\n try {\n const systemPrompt =\n 'You are an expert content analyst processing a SECTION of a larger document. ' +\n 'Extract and summarize the key information from THIS SECTION ONLY.\\n\\n' +\n 'Guidelines:\\n' +\n '- Do NOT write introductions or conclusions — this is a partial document\\n' +\n '- Extract ALL key facts, figures, data points, and insights\\n' +\n '- Preserve important quotes, code snippets, and specific details verbatim\\n' +\n '- Use bullet points and structured formatting\\n' +\n '- Note references to other sections without trying to resolve them';\n\n const focusLine = instruction ? `\\nFOCUS: ${instruction}\\n` : '';\n const userPrompt =\n `${chunkLabel} Extract key information from this section of ${url}:` +\n `${focusLine}\\n\\n${chunk}`;\n\n const summary = await callExtractionLlm(systemPrompt, userPrompt, 6000, config, signal);\n if (summary) {\n log.debug(\n { url, chunk: index + 1, originalChars: chunk.length, summaryChars: summary.length },\n 'Chunk summarized',\n );\n }\n return { index, summary: summary || null };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, chunk: index + 1, error: message }, 'Chunk summarization failed');\n return { index, summary: null };\n }\n });\n\n const chunkResults = await Promise.all(chunkPromises);\n\n // Collect successful summaries in order\n const summaries: string[] = [];\n for (const { index, summary } of chunkResults.sort((a, b) => a.index - b.index)) {\n if (summary) {\n summaries.push(`## Section ${index + 1}\\n${summary}`);\n }\n }\n\n if (summaries.length === 0) {\n // All chunks failed — fall back to truncated raw content\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n const truncated = content.slice(0, outputCap);\n return truncated + '\\n\\n[...all chunk summaries failed; showing truncated raw content]';\n }\n\n log.info(\n { url, successfulChunks: summaries.length, totalChunks: chunks.length },\n 'Chunk summaries collected, synthesizing',\n );\n\n // Single chunk — return directly\n if (summaries.length === 1) {\n const result = summaries[0];\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n return result.length > outputCap\n ? result.slice(0, outputCap) + '\\n\\n[...truncated]'\n : result;\n }\n\n // Synthesize multiple chunk summaries into one cohesive summary\n return synthesizeChunkSummaries(summaries, url, instruction, maxLength, config, signal, content.length);\n}\n\nasync function synthesizeChunkSummaries(\n summaries: string[],\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n originalContentLength: number,\n): Promise<string> {\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n\n const systemPrompt =\n 'You synthesize multiple section summaries into one cohesive, comprehensive summary. ' +\n 'Remove redundancy, preserve all key facts and actionable information, ' +\n 'and organize with clear markdown structure.';\n\n const focusLine = instruction ? `\\nFOCUS: ${instruction}\\n` : '';\n const combined = summaries.join('\\n\\n---\\n\\n');\n const userPrompt =\n `Synthesize these section summaries from ${url} into ONE unified markdown summary ` +\n `(under ${outputCap} characters):${focusLine}\\n\\n${combined}`;\n\n try {\n const synthesized = await callExtractionLlm(systemPrompt, userPrompt, 8000, config, signal);\n\n if (!synthesized) {\n // Synthesis LLM returned empty — fall back to concatenation\n log.warn({ url }, 'Synthesis returned empty, concatenating chunk summaries');\n const fallback = summaries.join('\\n\\n');\n return fallback.length > outputCap\n ? fallback.slice(0, outputCap) + '\\n\\n[...truncated]'\n : fallback;\n }\n\n const finalOutput = synthesized.length > outputCap\n ? synthesized.slice(0, outputCap) + '\\n\\n[...summary truncated for context management]'\n : synthesized;\n\n const compressionRatio = finalOutput.length / originalContentLength;\n log.info(\n {\n url,\n originalChars: originalContentLength,\n extractedChars: finalOutput.length,\n compressionPercent: `${(compressionRatio * 100).toFixed(1)}%`,\n },\n 'Chunked extraction complete',\n );\n\n return finalOutput;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, error: message }, 'Synthesis failed, concatenating chunk summaries');\n const fallback = summaries.join('\\n\\n');\n return fallback.length > outputCap\n ? fallback.slice(0, outputCap) + '\\n\\n[...truncated due to synthesis failure]'\n : fallback;\n }\n}\n\ntype WebExtractParams = { url: string; instruction?: string; maxLength?: number };\n\nfunction resolveConfiguredMaxLength(): number {\n return DEFAULT_WEB_EXTRACT_MAX_LENGTH;\n}\n\nexport function createWebExtractTool(deps: WebExtractDeps): AgentTool {\n return {\n name: 'web_extract',\n label: '📄 Web Extract',\n description:\n 'Extract and summarize content from a web page using LLM-powered extraction.\\n\\n' +\n 'Unlike web_fetch (which returns cleaned plain text from HTML), this tool uses a ' +\n 'dedicated model pass to produce focused markdown. Use when you need semantic extraction ' +\n 'or a specific focus (instruction), not just a single readability pass.\\n\\n' +\n 'WHEN TO USE:\\n' +\n '- Reading articles, blog posts, documentation\\n' +\n '- Extracting specific data (pricing, specs, API docs)\\n' +\n '- Summarizing long pages to save context\\n\\n' +\n 'WHEN TO USE web_fetch INSTEAD:\\n' +\n '- Inspecting raw-ish page text quickly without an extra LLM call\\n' +\n '- Downloading JSON/API responses\\n' +\n '- Debugging page rendering issues',\n parameters: WebExtractSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n signal?: AbortSignal,\n ): Promise<AgentToolResult<{ url: string; extractedLength: number }>> {\n const { url, instruction } = params as WebExtractParams;\n const cfg = deps.getConfig();\n const maxLength = (params as WebExtractParams).maxLength ?? resolveConfiguredMaxLength();\n\n try {\n // SSRF protection\n const safety = checkUrlSafety(url);\n if (!safety.safe) {\n return {\n content: [{ type: 'text', text: `Blocked: ${safety.reason}` }],\n details: { url, extractedLength: 0 },\n };\n }\n\n // Website blocklist check\n const blocked = checkWebsiteBlocklist(url, cfg?.tools?.web?.blocklist);\n if (blocked) {\n return {\n content: [{ type: 'text', text: `Blocked: ${blocked.message}` }],\n details: { url, extractedLength: 0 },\n };\n }\n\n const rawContent = await fetchPageContent(url, signal);\n const cleaned = stripHtmlBoilerplate(rawContent);\n const trimmed = cleaned.trim();\n const looksStructured = trimmed.startsWith('{') || trimmed.startsWith('[');\n if (trimmed.length < 100 && !looksStructured) {\n return {\n content: [\n { type: 'text', text: `Page at ${url} appears to have no extractable content.` },\n ],\n details: { url, extractedLength: 0 },\n };\n }\n\n const extracted = await extractWithLlm(\n cleaned,\n url,\n instruction,\n maxLength,\n cfg,\n signal,\n );\n\n return {\n content: [{ type: 'text', text: extracted }],\n details: { url, extractedLength: extracted.length },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, error: message }, 'web_extract failed');\n return {\n content: [{ type: 'text', text: `Failed to extract content from ${url}: ${message}` }],\n details: { url, extractedLength: 0 },\n };\n }\n },\n } as any;\n}\n"],"mappings":";;;;;;;gBAK6E;aACxB;AAGrD,MAAM,MAAM,aAAa,cAAc;AAEvC,MAAa,iCAAiC;AAC9C,MAAa,qCAAqC;AAClD,MAAM,wBAAwB;AAG9B,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AACnB,MAAM,kBAAkB;AAExB,MAAM,mBAAmB,KAAK,OAAO;CACnC,KAAK,KAAK,OAAO,EAAE,aAAa,+BAA+B,CAAC;CAChE,aAAa,KAAK,SAChB,KAAK,OAAO,EACV,aACE,wKAGH,CAAC,CACH;CACD,WAAW,KAAK,SACd,KAAK,OAAO,EACV,aAAa,+EACd,CAAC,CACH;CACF,CAAC;AAMF,eAAe,iBAAiB,KAAa,QAAuC;CAClF,MAAM,WAAW,MAAM,MAAM,KAAK;EAChC;EACA,SAAS;GACP,cAAc;GACd,QAAQ;GACT;EACD,UAAU;EACX,CAAC;AAEF,KAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,QAAQ,SAAS,OAAO,IAAI,SAAS,aAAa;AAIpE,MADoB,SAAS,QAAQ,IAAI,eAAe,IAAI,IAC5C,SAAS,mBAAmB,EAAE;EAC5C,MAAM,OAAgB,MAAM,SAAS,MAAM;AAC3C,SAAO,KAAK,UAAU,MAAM,MAAM,EAAE;;AAGtC,QAAO,MAAM,SAAS,MAAM;;AAG9B,SAAgB,qBACd,MACA,SAAS,oCACD;CACR,IAAI,UAAU,KACX,QAAQ,+BAA+B,GAAG,CAC1C,QAAQ,6BAA6B,GAAG,CACxC,QAAQ,yBAAyB,GAAG,CACpC,QAAQ,mCAAmC,GAAG,CAC9C,QAAQ,oBAAoB,GAAG;AAGlC,WAAU,kBAAkB,QAAQ;AACpC,WAAU,QAAQ,QAAQ,QAAQ,IAAI,CAAC,MAAM;AAE7C,KAAI,QAAQ,SAAS,OACnB,WAAU,QAAQ,MAAM,GAAG,OAAO,GAAG;AAGvC,QAAO;;AAGT,SAAS,uBAAuB,QAAiB;CAE/C,MAAM,MADS,QAAQ,IAAI,wBAAwB,MAAM;AAGzD,KAAI,IACF,KAAI;AACF,SAAO,aAAa,IAAI;SAClB;CAKV,MAAM,aAAa,oBAAoB,OAAO;AAC9C,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,wDAAwD;AAG1E,QAAO,aAAa,WAAW;;AAGjC,SAAS,4BAA4B,WAA2B;AAC9D,QACE;;;;;;;sBAOuB,UAAU;;;AAUrC,SAAS,mBAAmB,QAA0D;CACpF,MAAM,gBACJ,OAAO,gBAAgB,eAAe,OAAO,YAAY,YAAY,aACjE,YAAY,QAAQ,sBAAsB,GAC1C,KAAA;AACN,KAAI,UAAU,iBAAiB,OAAO,YAAY,QAAQ,WACxD,QAAO,YAAY,IAAI,CAAC,QAAQ,cAAc,CAAC;AAEjD,QAAO,UAAU;;AAGnB,SAAS,0BAA0B,QAAuC;CACxE,IAAI,OAAO;AACX,KAAI,MAAM,QAAQ,OAAO,QAAQ;OAC1B,MAAM,KAAK,OAAO,QACrB,KAAI,KAAK,OAAO,MAAM,YAAa,EAAwB,SAAS,OAClE,SAAQ,OAAQ,EAAwB,QAAQ,GAAG;;AAIzD,QAAO,KAAK,MAAM;;AAGpB,eAAe,kBACb,cACA,YACA,WACA,QACA,QACiB;AAkBjB,QAAO,0BAA0B,MAVZ,SAPP,uBAAuB,OAQ9B,EACL,EAAE,UAAU,CAAC;EAPb,MAAM;EACN,SAAS,GAAG,aAAa,aAAa;EACtC,WAAW,KAAK,KAAK;EAKD,CAAC,EAAE,EACvB;EACE;EACA,aAAa;EACb,QAAQ,mBAAmB,OAAO;EACnC,CACF,CAEuC;;AAO1C,eAAe,eACb,YACA,KACA,aACA,WACA,QACA,QACiB;CACjB,MAAM,gBAAgB,WAAW;AAGjC,KAAI,gBAAgB,iBAElB,QACE,mCAFc,gBAAgB,KAAW,QAAQ,EAET,CAAC;AAM7C,KAAI,gBAAgB,iBAAiB;AACnC,MAAI,KACF;GAAE;GAAK;GAAe,WAAW;GAAY,EAC7C,oDACD;AACD,SAAO,4BAA4B,YAAY,KAAK,aAAa,WAAW,QAAQ,OAAO;;CAS7F,MAAM,OAAO,MAAM,kBALE,4BAA4B,UAMnC,EALD,cACT,2BAA2B,IAAI,eAAe,YAAY,aAAa,eACvE,4CAA4C,IAAI,eAAe,cAKjE,KAAK,IAAI,KAAK,KAAK,YAAY,EAAE,EAAE,IAAK,EACxC,QACA,OACD;AAED,KAAI,CAAC,KAAM,QAAO;CAElB,MAAM,YAAY,KAAK,IAAI,WAAW,gBAAgB;AACtD,KAAI,KAAK,SAAS,UAChB,QAAO,KAAK,MAAM,GAAG,UAAU,GAAG;AAGpC,KAAI,MACF;EAAE;EAAK,eAAe;EAAe,gBAAgB,KAAK;EAAQ,EAClE,kCACD;AACD,QAAO;;AAST,eAAe,4BACb,SACA,KACA,aACA,WACA,QACA,QACiB;CAEjB,MAAM,SAAmB,EAAE;AAC3B,MAAK,IAAI,SAAS,GAAG,SAAS,QAAQ,QAAQ,UAAU,WACtD,QAAO,KAAK,QAAQ,MAAM,QAAQ,SAAS,WAAW,CAAC;AAEzD,KAAI,KAAK;EAAE;EAAK,YAAY,OAAO;EAAQ,WAAW;EAAY,EAAE,oBAAoB;CAGxF,MAAM,gBAAgB,OAAO,IAAI,OAAO,OAAO,UAAU;EACvD,MAAM,aAAa,UAAU,QAAQ,EAAE,GAAG,OAAO,OAAO;AACxD,MAAI;GAgBF,MAAM,UAAU,MAAM,kBAAkB,seAAc,GAHjD,WAAW,gDAAgD,IAAI,GAFlD,cAAc,YAAY,YAAY,MAAM,GAG/C,MAAM,SAE6C,KAAM,QAAQ,OAAO;AACvF,OAAI,QACF,KAAI,MACF;IAAE;IAAK,OAAO,QAAQ;IAAG,eAAe,MAAM;IAAQ,cAAc,QAAQ;IAAQ,EACpF,mBACD;AAEH,UAAO;IAAE;IAAO,SAAS,WAAW;IAAM;WACnC,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,OAAI,KAAK;IAAE;IAAK,OAAO,QAAQ;IAAG,OAAO;IAAS,EAAE,6BAA6B;AACjF,UAAO;IAAE;IAAO,SAAS;IAAM;;GAEjC;CAEF,MAAM,eAAe,MAAM,QAAQ,IAAI,cAAc;CAGrD,MAAM,YAAsB,EAAE;AAC9B,MAAK,MAAM,EAAE,OAAO,aAAa,aAAa,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CAC7E,KAAI,QACF,WAAU,KAAK,cAAc,QAAQ,EAAE,IAAI,UAAU;AAIzD,KAAI,UAAU,WAAW,GAAG;EAE1B,MAAM,YAAY,KAAK,IAAI,WAAW,gBAAgB;AAEtD,SADkB,QAAQ,MAAM,GAAG,UACnB,GAAG;;AAGrB,KAAI,KACF;EAAE;EAAK,kBAAkB,UAAU;EAAQ,aAAa,OAAO;EAAQ,EACvE,0CACD;AAGD,KAAI,UAAU,WAAW,GAAG;EAC1B,MAAM,SAAS,UAAU;EACzB,MAAM,YAAY,KAAK,IAAI,WAAW,gBAAgB;AACtD,SAAO,OAAO,SAAS,YACnB,OAAO,MAAM,GAAG,UAAU,GAAG,uBAC7B;;AAIN,QAAO,yBAAyB,WAAW,KAAK,aAAa,WAAW,QAAQ,QAAQ,QAAQ,OAAO;;AAGzG,eAAe,yBACb,WACA,KACA,aACA,WACA,QACA,QACA,uBACiB;CACjB,MAAM,YAAY,KAAK,IAAI,WAAW,gBAAgB;CAEtD,MAAM,eACJ;CAMF,MAAM,aACJ,2CAA2C,IAAI,4CACrC,UAAU,eAJJ,cAAc,YAAY,YAAY,MAAM,GAIf,MAH9B,UAAU,KAAK,cAG6B;AAE7D,KAAI;EACF,MAAM,cAAc,MAAM,kBAAkB,cAAc,YAAY,KAAM,QAAQ,OAAO;AAE3F,MAAI,CAAC,aAAa;AAEhB,OAAI,KAAK,EAAE,KAAK,EAAE,0DAA0D;GAC5E,MAAM,WAAW,UAAU,KAAK,OAAO;AACvC,UAAO,SAAS,SAAS,YACrB,SAAS,MAAM,GAAG,UAAU,GAAG,uBAC/B;;EAGN,MAAM,cAAc,YAAY,SAAS,YACrC,YAAY,MAAM,GAAG,UAAU,GAAG,sDAClC;EAEJ,MAAM,mBAAmB,YAAY,SAAS;AAC9C,MAAI,KACF;GACE;GACA,eAAe;GACf,gBAAgB,YAAY;GAC5B,oBAAoB,IAAI,mBAAmB,KAAK,QAAQ,EAAE,CAAC;GAC5D,EACD,8BACD;AAED,SAAO;UACA,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,MAAI,KAAK;GAAE;GAAK,OAAO;GAAS,EAAE,kDAAkD;EACpF,MAAM,WAAW,UAAU,KAAK,OAAO;AACvC,SAAO,SAAS,SAAS,YACrB,SAAS,MAAM,GAAG,UAAU,GAAG,gDAC/B;;;AAMR,SAAS,6BAAqC;AAC5C,QAAO;;AAGT,SAAgB,qBAAqB,MAAiC;AACpE,QAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EAYF,YAAY;EAEZ,MAAM,QACJ,aACA,QACA,QACoE;GACpE,MAAM,EAAE,KAAK,gBAAgB;GAC7B,MAAM,MAAM,KAAK,WAAW;GAC5B,MAAM,YAAa,OAA4B,aAAa,4BAA4B;AAExF,OAAI;IAEF,MAAM,SAAS,eAAe,IAAI;AAClC,QAAI,CAAC,OAAO,KACV,QAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,YAAY,OAAO;MAAU,CAAC;KAC9D,SAAS;MAAE;MAAK,iBAAiB;MAAG;KACrC;IAIH,MAAM,UAAU,sBAAsB,KAAK,KAAK,OAAO,KAAK,UAAU;AACtE,QAAI,QACF,QAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,YAAY,QAAQ;MAAW,CAAC;KAChE,SAAS;MAAE;MAAK,iBAAiB;MAAG;KACrC;IAIH,MAAM,UAAU,qBAAqB,MADZ,iBAAiB,KAAK,OAAO,CACN;IAChD,MAAM,UAAU,QAAQ,MAAM;IAC9B,MAAM,kBAAkB,QAAQ,WAAW,IAAI,IAAI,QAAQ,WAAW,IAAI;AAC1E,QAAI,QAAQ,SAAS,OAAO,CAAC,gBAC3B,QAAO;KACL,SAAS,CACP;MAAE,MAAM;MAAQ,MAAM,WAAW,IAAI;MAA2C,CACjF;KACD,SAAS;MAAE;MAAK,iBAAiB;MAAG;KACrC;IAGH,MAAM,YAAY,MAAM,eACtB,SACA,KACA,aACA,WACA,KACA,OACD;AAED,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAW,CAAC;KAC5C,SAAS;MAAE;MAAK,iBAAiB,UAAU;MAAQ;KACpD;YACM,OAAO;IACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAI,KAAK;KAAE;KAAK,OAAO;KAAS,EAAE,qBAAqB;AACvD,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,kCAAkC,IAAI,IAAI;MAAW,CAAC;KACtF,SAAS;MAAE;MAAK,iBAAiB;MAAG;KACrC;;;EAGN"}
1
+ {"version":3,"file":"web-extract.js","names":[],"sources":["../../../../src/agent/tools/web-extract.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai/compat';\n\nimport type { Config } from '../../config/schema.js';\nimport { getDefaultModelSync, resolveModel } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { checkUrlSafety, checkWebsiteBlocklist, cleanBase64Images } from './url-safety.js';\n\nconst log = createLogger('web-extract');\n\nexport const DEFAULT_WEB_EXTRACT_MAX_LENGTH = 15_000;\nexport const MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT = 200_000;\nconst EXTRACTION_TIMEOUT_MS = 30_000;\n\n// Large-document chunked processing thresholds (inspired by hermes-agent)\nconst MAX_CONTENT_SIZE = 2_000_000; // 2M chars — refuse entirely above this\nconst CHUNK_THRESHOLD = 500_000; // 500k chars — use chunked processing above this\nconst CHUNK_SIZE = 100_000; // 100k chars per chunk\nconst MAX_OUTPUT_SIZE = 15_000; // Hard cap on final output size\n\nconst WebExtractSchema = Type.Object({\n url: Type.String({ description: 'URL to extract content from' }),\n instruction: Type.Optional(\n Type.String({\n description:\n 'What to extract or focus on. Examples: \"main article text\", ' +\n '\"pricing table\", \"API documentation for the auth endpoint\". ' +\n 'If omitted, extracts the main content.',\n }),\n ),\n maxLength: Type.Optional(\n Type.Number({\n description: 'Maximum characters in the extracted content (default: from config or 15000)',\n }),\n ),\n});\n\nexport interface WebExtractDeps {\n getConfig: () => Config | undefined;\n}\n\nasync function fetchPageContent(url: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(url, {\n signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; xopc/1.0)',\n Accept: 'text/html,application/xhtml+xml,text/plain,application/json',\n },\n redirect: 'follow',\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n const json: unknown = await response.json();\n return JSON.stringify(json, null, 2);\n }\n\n return await response.text();\n}\n\nexport function stripHtmlBoilerplate(\n html: string,\n maxRaw = MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT,\n): string {\n let cleaned = html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<svg[\\s\\S]*?<\\/svg>/gi, '')\n .replace(/<noscript[\\s\\S]*?<\\/noscript>/gi, '')\n .replace(/<!--[\\s\\S]*?-->/g, '');\n\n // Remove base64 images early to avoid wasting characters on them\n cleaned = cleanBase64Images(cleaned);\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n if (cleaned.length > maxRaw) {\n cleaned = cleaned.slice(0, maxRaw) + '\\n\\n[...truncated]';\n }\n\n return cleaned;\n}\n\nfunction resolveExtractionModel(config?: Config) {\n const envRef = process.env.XOPC_WEB_EXTRACT_MODEL?.trim();\n const ref = envRef;\n\n if (ref) {\n try {\n return resolveModel(ref);\n } catch {\n /* fall through */\n }\n }\n\n const defaultRef = getDefaultModelSync(config);\n if (!defaultRef) {\n throw new Error('No global default model configured for web extraction');\n }\n\n return resolveModel(defaultRef);\n}\n\nfunction buildExtractionSystemPrompt(maxLength: number): string {\n return (\n 'You are a web content extractor. Given raw HTML/text from a web page, ' +\n 'extract the relevant content as clean, well-structured markdown.\\n\\n' +\n 'Rules:\\n' +\n '- Remove navigation, headers, footers, ads, cookie banners, sidebars\\n' +\n '- Preserve the main content structure (headings, lists, tables, code blocks)\\n' +\n '- Keep URLs for important links\\n' +\n '- If the page has structured data (tables, specs), preserve the structure\\n' +\n `- Keep output under ${maxLength} characters\\n` +\n '- If content is truncated, note what was cut\\n' +\n '- Output ONLY the extracted content, no meta-commentary'\n );\n}\n\n// ---------------------------------------------------------------------------\n// LLM call helper — shared by single-pass and chunked extraction\n// ---------------------------------------------------------------------------\n\nfunction buildTimeoutSignal(signal: AbortSignal | undefined): AbortSignal | undefined {\n const timeoutSignal =\n typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function'\n ? AbortSignal.timeout(EXTRACTION_TIMEOUT_MS)\n : undefined;\n if (signal && timeoutSignal && typeof AbortSignal.any === 'function') {\n return AbortSignal.any([signal, timeoutSignal]);\n }\n return signal ?? timeoutSignal;\n}\n\nfunction extractTextFromCompletion(result: { content?: unknown }): string {\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n return text.trim();\n}\n\nasync function callExtractionLlm(\n systemPrompt: string,\n userPrompt: string,\n maxTokens: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n const model = resolveExtractionModel(config);\n const userMsg: UserMessage = {\n role: 'user',\n content: `${systemPrompt}\\n\\n---\\n\\n${userPrompt}`,\n timestamp: Date.now(),\n };\n\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens,\n temperature: 0.2,\n signal: buildTimeoutSignal(signal) as AbortSignal,\n },\n );\n\n return extractTextFromCompletion(result);\n}\n\n// ---------------------------------------------------------------------------\n// Single-pass extraction (content < CHUNK_THRESHOLD)\n// ---------------------------------------------------------------------------\n\nasync function extractWithLlm(\n rawContent: string,\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n const contentLength = rawContent.length;\n\n // Refuse absurdly large content\n if (contentLength > MAX_CONTENT_SIZE) {\n const sizeMb = (contentLength / 1_000_000).toFixed(1);\n return (\n `[Content too large to process: ${sizeMb}MB. ` +\n 'Try using web_fetch for raw text, or search for a more focused source.]'\n );\n }\n\n // Route to chunked processing for large documents\n if (contentLength > CHUNK_THRESHOLD) {\n log.info(\n { url, contentLength, chunkSize: CHUNK_SIZE },\n 'Large document detected, using chunked extraction',\n );\n return extractLargeDocumentChunked(rawContent, url, instruction, maxLength, config, signal);\n }\n\n // Standard single-pass extraction\n const systemPrompt = buildExtractionSystemPrompt(maxLength);\n const body = instruction\n ? `Extract from this page (${url}):\\n\\nFOCUS: ${instruction}\\n\\n---\\n\\n${rawContent}`\n : `Extract the main content from this page (${url}):\\n\\n---\\n\\n${rawContent}`;\n\n const text = await callExtractionLlm(\n systemPrompt,\n body,\n Math.min(Math.ceil(maxLength / 3), 8000),\n config,\n signal,\n );\n\n if (!text) return 'No content could be extracted.';\n\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n if (text.length > outputCap) {\n return text.slice(0, outputCap) + '\\n\\n[...output truncated to maxLength]';\n }\n\n log.debug(\n { url, originalChars: contentLength, extractedChars: text.length },\n 'Single-pass extraction complete',\n );\n return text;\n}\n\n// ---------------------------------------------------------------------------\n// Chunked extraction for large documents (inspired by hermes-agent)\n//\n// Flow: split → parallel chunk summaries → synthesis pass\n// ---------------------------------------------------------------------------\n\nasync function extractLargeDocumentChunked(\n content: string,\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n): Promise<string> {\n // Split content into chunks\n const chunks: string[] = [];\n for (let offset = 0; offset < content.length; offset += CHUNK_SIZE) {\n chunks.push(content.slice(offset, offset + CHUNK_SIZE));\n }\n log.info({ url, chunkCount: chunks.length, chunkSize: CHUNK_SIZE }, 'Split into chunks');\n\n // Summarize each chunk in parallel\n const chunkPromises = chunks.map(async (chunk, index) => {\n const chunkLabel = `[Chunk ${index + 1}/${chunks.length}]`;\n try {\n const systemPrompt =\n 'You are an expert content analyst processing a SECTION of a larger document. ' +\n 'Extract and summarize the key information from THIS SECTION ONLY.\\n\\n' +\n 'Guidelines:\\n' +\n '- Do NOT write introductions or conclusions — this is a partial document\\n' +\n '- Extract ALL key facts, figures, data points, and insights\\n' +\n '- Preserve important quotes, code snippets, and specific details verbatim\\n' +\n '- Use bullet points and structured formatting\\n' +\n '- Note references to other sections without trying to resolve them';\n\n const focusLine = instruction ? `\\nFOCUS: ${instruction}\\n` : '';\n const userPrompt =\n `${chunkLabel} Extract key information from this section of ${url}:` +\n `${focusLine}\\n\\n${chunk}`;\n\n const summary = await callExtractionLlm(systemPrompt, userPrompt, 6000, config, signal);\n if (summary) {\n log.debug(\n { url, chunk: index + 1, originalChars: chunk.length, summaryChars: summary.length },\n 'Chunk summarized',\n );\n }\n return { index, summary: summary || null };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, chunk: index + 1, error: message }, 'Chunk summarization failed');\n return { index, summary: null };\n }\n });\n\n const chunkResults = await Promise.all(chunkPromises);\n\n // Collect successful summaries in order\n const summaries: string[] = [];\n for (const { index, summary } of chunkResults.sort((a, b) => a.index - b.index)) {\n if (summary) {\n summaries.push(`## Section ${index + 1}\\n${summary}`);\n }\n }\n\n if (summaries.length === 0) {\n // All chunks failed — fall back to truncated raw content\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n const truncated = content.slice(0, outputCap);\n return truncated + '\\n\\n[...all chunk summaries failed; showing truncated raw content]';\n }\n\n log.info(\n { url, successfulChunks: summaries.length, totalChunks: chunks.length },\n 'Chunk summaries collected, synthesizing',\n );\n\n // Single chunk — return directly\n if (summaries.length === 1) {\n const result = summaries[0];\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n return result.length > outputCap\n ? result.slice(0, outputCap) + '\\n\\n[...truncated]'\n : result;\n }\n\n // Synthesize multiple chunk summaries into one cohesive summary\n return synthesizeChunkSummaries(summaries, url, instruction, maxLength, config, signal, content.length);\n}\n\nasync function synthesizeChunkSummaries(\n summaries: string[],\n url: string,\n instruction: string | undefined,\n maxLength: number,\n config: Config | undefined,\n signal: AbortSignal | undefined,\n originalContentLength: number,\n): Promise<string> {\n const outputCap = Math.min(maxLength, MAX_OUTPUT_SIZE);\n\n const systemPrompt =\n 'You synthesize multiple section summaries into one cohesive, comprehensive summary. ' +\n 'Remove redundancy, preserve all key facts and actionable information, ' +\n 'and organize with clear markdown structure.';\n\n const focusLine = instruction ? `\\nFOCUS: ${instruction}\\n` : '';\n const combined = summaries.join('\\n\\n---\\n\\n');\n const userPrompt =\n `Synthesize these section summaries from ${url} into ONE unified markdown summary ` +\n `(under ${outputCap} characters):${focusLine}\\n\\n${combined}`;\n\n try {\n const synthesized = await callExtractionLlm(systemPrompt, userPrompt, 8000, config, signal);\n\n if (!synthesized) {\n // Synthesis LLM returned empty — fall back to concatenation\n log.warn({ url }, 'Synthesis returned empty, concatenating chunk summaries');\n const fallback = summaries.join('\\n\\n');\n return fallback.length > outputCap\n ? fallback.slice(0, outputCap) + '\\n\\n[...truncated]'\n : fallback;\n }\n\n const finalOutput = synthesized.length > outputCap\n ? synthesized.slice(0, outputCap) + '\\n\\n[...summary truncated for context management]'\n : synthesized;\n\n const compressionRatio = finalOutput.length / originalContentLength;\n log.info(\n {\n url,\n originalChars: originalContentLength,\n extractedChars: finalOutput.length,\n compressionPercent: `${(compressionRatio * 100).toFixed(1)}%`,\n },\n 'Chunked extraction complete',\n );\n\n return finalOutput;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, error: message }, 'Synthesis failed, concatenating chunk summaries');\n const fallback = summaries.join('\\n\\n');\n return fallback.length > outputCap\n ? fallback.slice(0, outputCap) + '\\n\\n[...truncated due to synthesis failure]'\n : fallback;\n }\n}\n\ntype WebExtractParams = { url: string; instruction?: string; maxLength?: number };\n\nfunction resolveConfiguredMaxLength(): number {\n return DEFAULT_WEB_EXTRACT_MAX_LENGTH;\n}\n\nexport function createWebExtractTool(deps: WebExtractDeps): AgentTool {\n return {\n name: 'web_extract',\n label: '📄 Web Extract',\n description:\n 'Extract and summarize content from a web page using LLM-powered extraction.\\n\\n' +\n 'Unlike web_fetch (which returns cleaned plain text from HTML), this tool uses a ' +\n 'dedicated model pass to produce focused markdown. Use when you need semantic extraction ' +\n 'or a specific focus (instruction), not just a single readability pass.\\n\\n' +\n 'WHEN TO USE:\\n' +\n '- Reading articles, blog posts, documentation\\n' +\n '- Extracting specific data (pricing, specs, API docs)\\n' +\n '- Summarizing long pages to save context\\n\\n' +\n 'WHEN TO USE web_fetch INSTEAD:\\n' +\n '- Inspecting raw-ish page text quickly without an extra LLM call\\n' +\n '- Downloading JSON/API responses\\n' +\n '- Debugging page rendering issues',\n parameters: WebExtractSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n signal?: AbortSignal,\n ): Promise<AgentToolResult<{ url: string; extractedLength: number }>> {\n const { url, instruction } = params as WebExtractParams;\n const cfg = deps.getConfig();\n const maxLength = (params as WebExtractParams).maxLength ?? resolveConfiguredMaxLength();\n\n try {\n // SSRF protection\n const safety = checkUrlSafety(url);\n if (!safety.safe) {\n return {\n content: [{ type: 'text', text: `Blocked: ${safety.reason}` }],\n details: { url, extractedLength: 0 },\n };\n }\n\n // Website blocklist check\n const blocked = checkWebsiteBlocklist(url, cfg?.tools?.web?.blocklist);\n if (blocked) {\n return {\n content: [{ type: 'text', text: `Blocked: ${blocked.message}` }],\n details: { url, extractedLength: 0 },\n };\n }\n\n const rawContent = await fetchPageContent(url, signal);\n const cleaned = stripHtmlBoilerplate(rawContent);\n const trimmed = cleaned.trim();\n const looksStructured = trimmed.startsWith('{') || trimmed.startsWith('[');\n if (trimmed.length < 100 && !looksStructured) {\n return {\n content: [\n { type: 'text', text: `Page at ${url} appears to have no extractable content.` },\n ],\n details: { url, extractedLength: 0 },\n };\n }\n\n const extracted = await extractWithLlm(\n cleaned,\n url,\n instruction,\n maxLength,\n cfg,\n signal,\n );\n\n return {\n content: [{ type: 'text', text: extracted }],\n details: { url, extractedLength: extracted.length },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n log.warn({ url, error: message }, 'web_extract failed');\n return {\n content: [{ type: 'text', text: `Failed to extract content from ${url}: ${message}` }],\n details: { url, extractedLength: 0 },\n };\n }\n },\n } as any;\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
+ import { emptySnapshotFor } from "./snapshot-empty.js";
2
+ import { createWorkflowSnapshot, previewValue, recomputeCounts, renderWorkflowText } from "./snapshot.js";
1
3
  import { applySubagentProgress } from "./agent-progress.js";
2
4
  import { BUILTIN_WORKFLOWS } from "./builtins/index.js";
3
5
  import { parseWorkflowScript } from "./parser.js";
4
6
  import { createWorkflowCatalog, defaultUserDir } from "./catalog.js";
5
7
  import { _resetLastWorkflowMemoryForTests, getLastWorkflowMemory } from "./last-run-memory.js";
6
- import { emptySnapshotFor } from "./snapshot-empty.js";
7
- import { createWorkflowSnapshot, previewValue, recomputeCounts, renderWorkflowText } from "./snapshot.js";
8
8
  import { WorkflowProgressBroker, _resetWorkflowProgressBrokerForTests, getWorkflowProgressBroker } from "./progress-broker.js";
9
9
  import { runWorkflow } from "./runtime.js";
10
10
  import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
@@ -1,5 +1,5 @@
1
- import { parseWorkflowScript } from "./parser.js";
2
1
  import { emptySnapshotFor } from "./snapshot-empty.js";
2
+ import { parseWorkflowScript } from "./parser.js";
3
3
  import { availableParallelism } from "node:os";
4
4
  import { Script, createContext } from "node:vm";
5
5
  //#region src/agent/workflow/runtime.ts
@@ -1,10 +1,10 @@
1
- import { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, init_schema } from "./schema.js";
1
+ import { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, AgentToolModelSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, init_schema } from "./schema.js";
2
2
  import { getManifestSource, resolveEffectiveAgentManifest } from "./resolver.js";
3
3
  import { validateAgentManifest } from "./validator.js";
4
4
  import { buildAgentManifestPromptSection } from "./prompt.js";
5
5
  //#region src/agent-manifest/index.ts
6
6
  init_schema();
7
7
  //#endregion
8
- export { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, buildAgentManifestPromptSection, getManifestSource, resolveEffectiveAgentManifest, validateAgentManifest };
8
+ export { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, AgentToolModelSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, buildAgentManifestPromptSection, getManifestSource, resolveEffectiveAgentManifest, validateAgentManifest };
9
9
 
10
10
  //# sourceMappingURL=index.js.map
@@ -5,6 +5,12 @@ export declare const ManifestModelRoleSchema: z.ZodObject<{
5
5
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
6
  description: z.ZodOptional<z.ZodString>;
7
7
  }, z.core.$strict>;
8
+ export declare const AgentToolModelSchema: z.ZodObject<{
9
+ primary: z.ZodString;
10
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
12
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
13
+ }, z.core.$strict>;
8
14
  export declare const ModelPolicySchema: z.ZodObject<{
9
15
  defaultRole: z.ZodString;
10
16
  roles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -12,6 +18,18 @@ export declare const ModelPolicySchema: z.ZodObject<{
12
18
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
13
19
  description: z.ZodOptional<z.ZodString>;
14
20
  }, z.core.$strict>>>;
21
+ imageModel: z.ZodOptional<z.ZodObject<{
22
+ primary: z.ZodString;
23
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
24
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
25
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
26
+ }, z.core.$strict>>;
27
+ imageGenerationModel: z.ZodOptional<z.ZodObject<{
28
+ primary: z.ZodString;
29
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
31
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strict>>;
15
33
  policy: z.ZodOptional<z.ZodObject<{
16
34
  allowFallbacks: z.ZodOptional<z.ZodBoolean>;
17
35
  maxCostTier: z.ZodOptional<z.ZodEnum<{
@@ -28,6 +46,18 @@ export declare const ModelPolicyPatchSchema: z.ZodObject<{
28
46
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
29
47
  description: z.ZodOptional<z.ZodString>;
30
48
  }, z.core.$strict>>>;
49
+ imageModel: z.ZodOptional<z.ZodObject<{
50
+ primary: z.ZodString;
51
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
53
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
54
+ }, z.core.$strict>>;
55
+ imageGenerationModel: z.ZodOptional<z.ZodObject<{
56
+ primary: z.ZodString;
57
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
58
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
59
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
60
+ }, z.core.$strict>>;
31
61
  policy: z.ZodOptional<z.ZodObject<{
32
62
  allowFallbacks: z.ZodOptional<z.ZodBoolean>;
33
63
  maxCostTier: z.ZodOptional<z.ZodEnum<{
@@ -359,6 +389,18 @@ export declare const AgentManifestSchema: z.ZodObject<{
359
389
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
360
390
  description: z.ZodOptional<z.ZodString>;
361
391
  }, z.core.$strict>>>;
392
+ imageModel: z.ZodOptional<z.ZodObject<{
393
+ primary: z.ZodString;
394
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
395
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
396
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
397
+ }, z.core.$strict>>;
398
+ imageGenerationModel: z.ZodOptional<z.ZodObject<{
399
+ primary: z.ZodString;
400
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
401
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
402
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
403
+ }, z.core.$strict>>;
362
404
  policy: z.ZodOptional<z.ZodObject<{
363
405
  allowFallbacks: z.ZodOptional<z.ZodBoolean>;
364
406
  maxCostTier: z.ZodOptional<z.ZodEnum<{
@@ -784,6 +826,18 @@ export declare const AgentConfigEntrySchema: z.ZodObject<{
784
826
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
785
827
  description: z.ZodOptional<z.ZodString>;
786
828
  }, z.core.$strict>>>;
829
+ imageModel: z.ZodOptional<z.ZodObject<{
830
+ primary: z.ZodString;
831
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
832
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
833
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
834
+ }, z.core.$strict>>;
835
+ imageGenerationModel: z.ZodOptional<z.ZodObject<{
836
+ primary: z.ZodString;
837
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
838
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
839
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
840
+ }, z.core.$strict>>;
787
841
  policy: z.ZodOptional<z.ZodObject<{
788
842
  allowFallbacks: z.ZodOptional<z.ZodBoolean>;
789
843
  maxCostTier: z.ZodOptional<z.ZodEnum<{
@@ -807,6 +861,18 @@ export declare const CapabilityPresetSchema: z.ZodObject<{
807
861
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
808
862
  description: z.ZodOptional<z.ZodString>;
809
863
  }, z.core.$strict>>>;
864
+ imageModel: z.ZodOptional<z.ZodObject<{
865
+ primary: z.ZodString;
866
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
867
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
868
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
869
+ }, z.core.$strict>>;
870
+ imageGenerationModel: z.ZodOptional<z.ZodObject<{
871
+ primary: z.ZodString;
872
+ fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
873
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
874
+ autoProviderFallback: z.ZodOptional<z.ZodBoolean>;
875
+ }, z.core.$strict>>;
810
876
  policy: z.ZodOptional<z.ZodObject<{
811
877
  allowFallbacks: z.ZodOptional<z.ZodBoolean>;
812
878
  maxCostTier: z.ZodOptional<z.ZodEnum<{
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { z } from "zod";
3
3
  //#region src/agent-manifest/schema.ts
4
- var IdSchema, DEFAULT_CAPABILITY_PRESET_ID, ManifestModelRoleSchema, ModelPolicySchema, ModelPolicyPatchSchema, ToolModeSchema, ToolScopeSchema, ToolPolicySchema, ToolPolicySetSchema, SkillPolicySchema, DreamingPhasePolicySchema, DreamingLightPolicySchema, DreamingDeepPolicySchema, DreamingRemPolicySchema, DreamingPolicySchema, MemoryPolicySchema, WorkflowPolicySchema, BoundaryPolicySchema, WorkspacePolicySchema, RuntimePolicySchema, PromptPolicySchema, AgentIdentitySchema, AgentResponsibilitiesSchema, AgentManifestSchema, AgentConfigEntrySchema, CapabilityPresetSchema;
4
+ var IdSchema, DEFAULT_CAPABILITY_PRESET_ID, ManifestModelRoleSchema, AgentToolModelSchema, ModelPolicySchema, ModelPolicyPatchSchema, ToolModeSchema, ToolScopeSchema, ToolPolicySchema, ToolPolicySetSchema, SkillPolicySchema, DreamingPhasePolicySchema, DreamingLightPolicySchema, DreamingDeepPolicySchema, DreamingRemPolicySchema, DreamingPolicySchema, MemoryPolicySchema, WorkflowPolicySchema, BoundaryPolicySchema, WorkspacePolicySchema, RuntimePolicySchema, PromptPolicySchema, AgentIdentitySchema, AgentResponsibilitiesSchema, AgentManifestSchema, AgentConfigEntrySchema, CapabilityPresetSchema;
5
5
  var init_schema = __esmMin((() => {
6
6
  IdSchema = z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/);
7
7
  DEFAULT_CAPABILITY_PRESET_ID = "default";
@@ -26,9 +26,33 @@ var init_schema = __esmMin((() => {
26
26
  path: ["fallbacks", index]
27
27
  });
28
28
  });
29
+ AgentToolModelSchema = z.object({
30
+ primary: z.string().min(1),
31
+ fallbacks: z.array(z.string().min(1)).optional(),
32
+ timeoutMs: z.number().int().positive().optional(),
33
+ autoProviderFallback: z.boolean().optional()
34
+ }).strict().superRefine((entry, ctx) => {
35
+ const validateRef = (ref) => {
36
+ const trimmed = ref.trim();
37
+ const idx = trimmed.indexOf("/");
38
+ return idx > 0 && idx < trimmed.length - 1;
39
+ };
40
+ if (!validateRef(entry.primary)) ctx.addIssue({
41
+ code: "custom",
42
+ message: `primary must be provider/model format (got '${entry.primary}')`,
43
+ path: ["primary"]
44
+ });
45
+ for (const [index, fallback] of (entry.fallbacks ?? []).entries()) if (!validateRef(fallback)) ctx.addIssue({
46
+ code: "custom",
47
+ message: `fallback must be provider/model format (got '${fallback}')`,
48
+ path: ["fallbacks", index]
49
+ });
50
+ });
29
51
  ModelPolicySchema = z.object({
30
52
  defaultRole: IdSchema,
31
53
  roles: z.record(IdSchema, ManifestModelRoleSchema).default({}),
54
+ imageModel: AgentToolModelSchema.optional(),
55
+ imageGenerationModel: AgentToolModelSchema.optional(),
32
56
  policy: z.object({
33
57
  allowFallbacks: z.boolean().optional(),
34
58
  maxCostTier: z.enum([
@@ -41,6 +65,8 @@ var init_schema = __esmMin((() => {
41
65
  ModelPolicyPatchSchema = z.object({
42
66
  defaultRole: IdSchema.optional(),
43
67
  roles: z.record(IdSchema, ManifestModelRoleSchema).optional(),
68
+ imageModel: AgentToolModelSchema.optional(),
69
+ imageGenerationModel: AgentToolModelSchema.optional(),
44
70
  policy: z.object({
45
71
  allowFallbacks: z.boolean().optional(),
46
72
  maxCostTier: z.enum([
@@ -273,6 +299,6 @@ var init_schema = __esmMin((() => {
273
299
  }));
274
300
  //#endregion
275
301
  init_schema();
276
- export { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, init_schema };
302
+ export { AgentConfigEntrySchema, AgentIdentitySchema, AgentManifestSchema, AgentResponsibilitiesSchema, AgentToolModelSchema, BoundaryPolicySchema, CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, DreamingDeepPolicySchema, DreamingLightPolicySchema, DreamingPhasePolicySchema, DreamingPolicySchema, DreamingRemPolicySchema, ManifestModelRoleSchema, MemoryPolicySchema, ModelPolicyPatchSchema, ModelPolicySchema, PromptPolicySchema, RuntimePolicySchema, SkillPolicySchema, ToolModeSchema, ToolPolicySchema, ToolPolicySetSchema, ToolScopeSchema, WorkflowPolicySchema, WorkspacePolicySchema, init_schema };
277
303
 
278
304
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../src/agent-manifest/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nconst IdSchema = z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/);\n\nexport const DEFAULT_CAPABILITY_PRESET_ID = 'default';\n\nexport const ManifestModelRoleSchema = z\n .object({\n model: z.string().min(1),\n fallbacks: z.array(z.string().min(1)).optional(),\n description: z.string().max(500).optional(),\n })\n .strict()\n .superRefine((entry, ctx) => {\n const validateRef = (ref: string) => {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n return idx > 0 && idx < trimmed.length - 1;\n };\n if (!validateRef(entry.model)) {\n ctx.addIssue({\n code: 'custom',\n message: `model must be provider/model format (got '${entry.model}')`,\n path: ['model'],\n });\n }\n for (const [index, fallback] of (entry.fallbacks ?? []).entries()) {\n if (!validateRef(fallback)) {\n ctx.addIssue({\n code: 'custom',\n message: `fallback must be provider/model format (got '${fallback}')`,\n path: ['fallbacks', index],\n });\n }\n }\n });\n\nexport const ModelPolicySchema = z\n .object({\n defaultRole: IdSchema,\n roles: z.record(IdSchema, ManifestModelRoleSchema).default({}),\n policy: z\n .object({\n allowFallbacks: z.boolean().optional(),\n maxCostTier: z.enum(['low', 'medium', 'high']).optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ModelPolicyPatchSchema = z\n .object({\n defaultRole: IdSchema.optional(),\n roles: z.record(IdSchema, ManifestModelRoleSchema).optional(),\n policy: z\n .object({\n allowFallbacks: z.boolean().optional(),\n maxCostTier: z.enum(['low', 'medium', 'high']).optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ToolModeSchema = z.enum(['allow', 'confirm', 'deny']);\nexport const ToolScopeSchema = z.enum(['readonly', 'workspace', 'unrestricted']);\n\nexport const ToolPolicySchema = z\n .object({\n mode: ToolModeSchema,\n scope: ToolScopeSchema.optional(),\n limits: z\n .object({\n maxCallsPerTurn: z.number().int().positive().optional(),\n timeoutMs: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ToolPolicySetSchema = z\n .object({\n builtin: z.record(z.string().min(1), ToolPolicySchema).default({}),\n mcp: z\n .object({\n servers: z.record(z.string().min(1), ToolPolicySchema).optional(),\n tools: z.record(z.string().min(1), ToolPolicySchema).optional(),\n })\n .strict()\n .optional(),\n })\n .strict()\n .default({ builtin: {} });\n\nexport const SkillPolicySchema = z\n .object({\n mode: z.enum(['all', 'allowlist', 'denylist', 'off']).default('all'),\n allow: z.array(z.string().min(1)).optional(),\n deny: z.array(z.string().min(1)).optional(),\n })\n .strict()\n .default({ mode: 'all' });\n\nexport const DreamingPhasePolicySchema = z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().min(1).optional(),\n })\n .strict();\n\nexport const DreamingLightPolicySchema = DreamingPhasePolicySchema.extend({\n lookbackDays: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n dedupeSimilarity: z.number().min(0).max(1).optional(),\n}).strict();\n\nexport const DreamingDeepPolicySchema = DreamingPhasePolicySchema.extend({\n minScore: z.number().min(0).max(1).optional(),\n minRecallCount: z.number().int().positive().optional(),\n minUniqueQueries: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n recencyHalfLifeDays: z.number().positive().optional(),\n maxAgeDays: z.number().positive().optional(),\n}).strict();\n\nexport const DreamingRemPolicySchema = DreamingPhasePolicySchema.extend({\n lookbackDays: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n minPatternStrength: z.number().min(0).max(1).optional(),\n}).strict();\n\nexport const DreamingPolicySchema = z\n .object({\n enabled: z.boolean().default(false),\n frequency: z.string().min(1).optional(),\n timezone: z.string().optional(),\n phases: z\n .object({\n light: DreamingLightPolicySchema.optional(),\n deep: DreamingDeepPolicySchema.optional(),\n rem: DreamingRemPolicySchema.optional(),\n })\n .strict()\n .optional(),\n })\n .strict()\n .optional();\n\nexport const MemoryPolicySchema = z\n .object({\n mode: z.enum(['off', 'readOnly', 'confirmWrite', 'auto']).default('off'),\n sources: z\n .array(z.enum(['session', 'userProfile', 'agentProfile', 'curated', 'workspace']))\n .default(['session']),\n writePolicy: z\n .object({\n userProfile: z.enum(['deny', 'confirm', 'allow']).optional(),\n agentProfile: z.enum(['deny', 'confirm', 'allow']).optional(),\n curated: z.enum(['deny', 'confirm', 'allow']).optional(),\n workspace: z.enum(['deny', 'confirm', 'allow']).optional(),\n })\n .strict()\n .optional(),\n retention: z\n .object({\n compaction: z.boolean().default(true),\n maxAgeDays: z.number().int().positive().optional(),\n maxItems: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n privacy: z\n .object({\n crossAgentSharing: z.enum(['deny', 'readOnly', 'allow']).default('deny'),\n sensitiveWritePolicy: z.enum(['deny', 'confirm', 'allow']).default('confirm'),\n })\n .strict()\n .optional(),\n providerRouting: z\n .object({\n searchStrategy: z\n .enum(['local-first', 'external-first', 'fanout', 'local-only', 'external-only'])\n .default('fanout'),\n writeStrategy: z\n .enum(['local-first', 'external-first', 'write-through', 'local-only', 'external-only'])\n .default('local-first'),\n allowExternalWrites: z.boolean().default(false),\n allowedProviderIds: z.array(z.string().min(1)).optional(),\n autoWriteKinds: z\n .array(\n z.enum([\n 'user_profile',\n 'agent_note',\n 'workspace_fact',\n 'daily_note',\n 'session_summary',\n 'derived_insight',\n ]),\n )\n .optional(),\n })\n .strict()\n .optional(),\n dreaming: DreamingPolicySchema,\n })\n .strict()\n .default({ mode: 'off', sources: ['session'] });\n\nexport const WorkflowPolicySchema = z\n .object({\n default: z.string().min(1).optional(),\n allowed: z.array(z.string().min(1)).optional(),\n suggested: z\n .array(\n z\n .object({\n intent: z.string().min(1),\n workflow: z.string().min(1),\n })\n .strict(),\n )\n .optional(),\n })\n .strict()\n .default({});\n\nexport const BoundaryPolicySchema = z\n .object({\n requiresConfirmation: z.array(z.string().min(1)).default([]),\n forbidden: z.array(z.string().min(1)).default([]),\n escalation: z.array(z.string().min(1)).default([]),\n })\n .strict()\n .default({ requiresConfirmation: [], forbidden: [], escalation: [] });\n\nexport const WorkspacePolicySchema = z\n .object({\n root: z.string().min(1),\n })\n .strict();\n\nexport const RuntimePolicySchema = z\n .object({\n maxTurns: z.number().int().positive().optional(),\n timeoutMs: z.number().int().positive().optional(),\n maxToolFailuresPerTurn: z.number().int().positive().optional(),\n })\n .strict()\n .optional();\n\nexport const PromptPolicySchema = z\n .object({\n customInstructions: z.string().optional(),\n })\n .strict()\n .optional();\n\nexport const AgentIdentitySchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n role: z.string().min(1),\n language: z.string().min(1).default('en'),\n tone: z.string().min(1).default('direct'),\n avatar: z.string().optional(),\n })\n .strict();\n\nexport const AgentResponsibilitiesSchema = z\n .object({\n primary: z.array(z.string().min(1)).min(1),\n secondary: z.array(z.string().min(1)).optional(),\n outOfScope: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nexport const AgentManifestSchema = z\n .object({\n id: IdSchema,\n enabled: z.boolean().default(true),\n extends: z.array(IdSchema).optional(),\n identity: AgentIdentitySchema,\n responsibilities: AgentResponsibilitiesSchema,\n workspace: WorkspacePolicySchema,\n models: ModelPolicySchema,\n tools: ToolPolicySetSchema,\n skills: SkillPolicySchema,\n memory: MemoryPolicySchema,\n workflows: WorkflowPolicySchema,\n boundaries: BoundaryPolicySchema,\n runtime: RuntimePolicySchema,\n prompt: PromptPolicySchema,\n })\n .strict();\n\nexport const AgentConfigEntrySchema = AgentManifestSchema.extend({\n models: ModelPolicySchema.optional(),\n}).strict();\n\nexport const CapabilityPresetSchema = z\n .object({\n id: IdSchema,\n name: z.string().min(1),\n description: z.string().optional(),\n version: z.number().int().positive().default(1),\n extends: z.array(IdSchema).optional(),\n models: ModelPolicyPatchSchema.optional(),\n tools: ToolPolicySetSchema.optional(),\n skills: SkillPolicySchema.optional(),\n memory: MemoryPolicySchema.optional(),\n workflows: WorkflowPolicySchema.optional(),\n boundaries: BoundaryPolicySchema.optional(),\n runtime: RuntimePolicySchema,\n locks: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nexport type AgentManifest = z.infer<typeof AgentManifestSchema>;\nexport type AgentConfigEntry = z.infer<typeof AgentConfigEntrySchema>;\nexport type CapabilityPreset = z.infer<typeof CapabilityPresetSchema>;\nexport type EffectiveAgentManifest = AgentManifest;\nexport type ToolPolicy = z.infer<typeof ToolPolicySchema>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../src/agent-manifest/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nconst IdSchema = z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/);\n\nexport const DEFAULT_CAPABILITY_PRESET_ID = 'default';\n\nexport const ManifestModelRoleSchema = z\n .object({\n model: z.string().min(1),\n fallbacks: z.array(z.string().min(1)).optional(),\n description: z.string().max(500).optional(),\n })\n .strict()\n .superRefine((entry, ctx) => {\n const validateRef = (ref: string) => {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n return idx > 0 && idx < trimmed.length - 1;\n };\n if (!validateRef(entry.model)) {\n ctx.addIssue({\n code: 'custom',\n message: `model must be provider/model format (got '${entry.model}')`,\n path: ['model'],\n });\n }\n for (const [index, fallback] of (entry.fallbacks ?? []).entries()) {\n if (!validateRef(fallback)) {\n ctx.addIssue({\n code: 'custom',\n message: `fallback must be provider/model format (got '${fallback}')`,\n path: ['fallbacks', index],\n });\n }\n }\n });\n\nexport const AgentToolModelSchema = z\n .object({\n primary: z.string().min(1),\n fallbacks: z.array(z.string().min(1)).optional(),\n timeoutMs: z.number().int().positive().optional(),\n autoProviderFallback: z.boolean().optional(),\n })\n .strict()\n .superRefine((entry, ctx) => {\n const validateRef = (ref: string) => {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n return idx > 0 && idx < trimmed.length - 1;\n };\n if (!validateRef(entry.primary)) {\n ctx.addIssue({\n code: 'custom',\n message: `primary must be provider/model format (got '${entry.primary}')`,\n path: ['primary'],\n });\n }\n for (const [index, fallback] of (entry.fallbacks ?? []).entries()) {\n if (!validateRef(fallback)) {\n ctx.addIssue({\n code: 'custom',\n message: `fallback must be provider/model format (got '${fallback}')`,\n path: ['fallbacks', index],\n });\n }\n }\n });\n\nexport const ModelPolicySchema = z\n .object({\n defaultRole: IdSchema,\n roles: z.record(IdSchema, ManifestModelRoleSchema).default({}),\n imageModel: AgentToolModelSchema.optional(),\n imageGenerationModel: AgentToolModelSchema.optional(),\n policy: z\n .object({\n allowFallbacks: z.boolean().optional(),\n maxCostTier: z.enum(['low', 'medium', 'high']).optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ModelPolicyPatchSchema = z\n .object({\n defaultRole: IdSchema.optional(),\n roles: z.record(IdSchema, ManifestModelRoleSchema).optional(),\n imageModel: AgentToolModelSchema.optional(),\n imageGenerationModel: AgentToolModelSchema.optional(),\n policy: z\n .object({\n allowFallbacks: z.boolean().optional(),\n maxCostTier: z.enum(['low', 'medium', 'high']).optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ToolModeSchema = z.enum(['allow', 'confirm', 'deny']);\nexport const ToolScopeSchema = z.enum(['readonly', 'workspace', 'unrestricted']);\n\nexport const ToolPolicySchema = z\n .object({\n mode: ToolModeSchema,\n scope: ToolScopeSchema.optional(),\n limits: z\n .object({\n maxCallsPerTurn: z.number().int().positive().optional(),\n timeoutMs: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const ToolPolicySetSchema = z\n .object({\n builtin: z.record(z.string().min(1), ToolPolicySchema).default({}),\n mcp: z\n .object({\n servers: z.record(z.string().min(1), ToolPolicySchema).optional(),\n tools: z.record(z.string().min(1), ToolPolicySchema).optional(),\n })\n .strict()\n .optional(),\n })\n .strict()\n .default({ builtin: {} });\n\nexport const SkillPolicySchema = z\n .object({\n mode: z.enum(['all', 'allowlist', 'denylist', 'off']).default('all'),\n allow: z.array(z.string().min(1)).optional(),\n deny: z.array(z.string().min(1)).optional(),\n })\n .strict()\n .default({ mode: 'all' });\n\nexport const DreamingPhasePolicySchema = z\n .object({\n enabled: z.boolean().optional(),\n cron: z.string().min(1).optional(),\n })\n .strict();\n\nexport const DreamingLightPolicySchema = DreamingPhasePolicySchema.extend({\n lookbackDays: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n dedupeSimilarity: z.number().min(0).max(1).optional(),\n}).strict();\n\nexport const DreamingDeepPolicySchema = DreamingPhasePolicySchema.extend({\n minScore: z.number().min(0).max(1).optional(),\n minRecallCount: z.number().int().positive().optional(),\n minUniqueQueries: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n recencyHalfLifeDays: z.number().positive().optional(),\n maxAgeDays: z.number().positive().optional(),\n}).strict();\n\nexport const DreamingRemPolicySchema = DreamingPhasePolicySchema.extend({\n lookbackDays: z.number().int().positive().optional(),\n limit: z.number().int().nonnegative().optional(),\n minPatternStrength: z.number().min(0).max(1).optional(),\n}).strict();\n\nexport const DreamingPolicySchema = z\n .object({\n enabled: z.boolean().default(false),\n frequency: z.string().min(1).optional(),\n timezone: z.string().optional(),\n phases: z\n .object({\n light: DreamingLightPolicySchema.optional(),\n deep: DreamingDeepPolicySchema.optional(),\n rem: DreamingRemPolicySchema.optional(),\n })\n .strict()\n .optional(),\n })\n .strict()\n .optional();\n\nexport const MemoryPolicySchema = z\n .object({\n mode: z.enum(['off', 'readOnly', 'confirmWrite', 'auto']).default('off'),\n sources: z\n .array(z.enum(['session', 'userProfile', 'agentProfile', 'curated', 'workspace']))\n .default(['session']),\n writePolicy: z\n .object({\n userProfile: z.enum(['deny', 'confirm', 'allow']).optional(),\n agentProfile: z.enum(['deny', 'confirm', 'allow']).optional(),\n curated: z.enum(['deny', 'confirm', 'allow']).optional(),\n workspace: z.enum(['deny', 'confirm', 'allow']).optional(),\n })\n .strict()\n .optional(),\n retention: z\n .object({\n compaction: z.boolean().default(true),\n maxAgeDays: z.number().int().positive().optional(),\n maxItems: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n privacy: z\n .object({\n crossAgentSharing: z.enum(['deny', 'readOnly', 'allow']).default('deny'),\n sensitiveWritePolicy: z.enum(['deny', 'confirm', 'allow']).default('confirm'),\n })\n .strict()\n .optional(),\n providerRouting: z\n .object({\n searchStrategy: z\n .enum(['local-first', 'external-first', 'fanout', 'local-only', 'external-only'])\n .default('fanout'),\n writeStrategy: z\n .enum(['local-first', 'external-first', 'write-through', 'local-only', 'external-only'])\n .default('local-first'),\n allowExternalWrites: z.boolean().default(false),\n allowedProviderIds: z.array(z.string().min(1)).optional(),\n autoWriteKinds: z\n .array(\n z.enum([\n 'user_profile',\n 'agent_note',\n 'workspace_fact',\n 'daily_note',\n 'session_summary',\n 'derived_insight',\n ]),\n )\n .optional(),\n })\n .strict()\n .optional(),\n dreaming: DreamingPolicySchema,\n })\n .strict()\n .default({ mode: 'off', sources: ['session'] });\n\nexport const WorkflowPolicySchema = z\n .object({\n default: z.string().min(1).optional(),\n allowed: z.array(z.string().min(1)).optional(),\n suggested: z\n .array(\n z\n .object({\n intent: z.string().min(1),\n workflow: z.string().min(1),\n })\n .strict(),\n )\n .optional(),\n })\n .strict()\n .default({});\n\nexport const BoundaryPolicySchema = z\n .object({\n requiresConfirmation: z.array(z.string().min(1)).default([]),\n forbidden: z.array(z.string().min(1)).default([]),\n escalation: z.array(z.string().min(1)).default([]),\n })\n .strict()\n .default({ requiresConfirmation: [], forbidden: [], escalation: [] });\n\nexport const WorkspacePolicySchema = z\n .object({\n root: z.string().min(1),\n })\n .strict();\n\nexport const RuntimePolicySchema = z\n .object({\n maxTurns: z.number().int().positive().optional(),\n timeoutMs: z.number().int().positive().optional(),\n maxToolFailuresPerTurn: z.number().int().positive().optional(),\n })\n .strict()\n .optional();\n\nexport const PromptPolicySchema = z\n .object({\n customInstructions: z.string().optional(),\n })\n .strict()\n .optional();\n\nexport const AgentIdentitySchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n role: z.string().min(1),\n language: z.string().min(1).default('en'),\n tone: z.string().min(1).default('direct'),\n avatar: z.string().optional(),\n })\n .strict();\n\nexport const AgentResponsibilitiesSchema = z\n .object({\n primary: z.array(z.string().min(1)).min(1),\n secondary: z.array(z.string().min(1)).optional(),\n outOfScope: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nexport const AgentManifestSchema = z\n .object({\n id: IdSchema,\n enabled: z.boolean().default(true),\n extends: z.array(IdSchema).optional(),\n identity: AgentIdentitySchema,\n responsibilities: AgentResponsibilitiesSchema,\n workspace: WorkspacePolicySchema,\n models: ModelPolicySchema,\n tools: ToolPolicySetSchema,\n skills: SkillPolicySchema,\n memory: MemoryPolicySchema,\n workflows: WorkflowPolicySchema,\n boundaries: BoundaryPolicySchema,\n runtime: RuntimePolicySchema,\n prompt: PromptPolicySchema,\n })\n .strict();\n\nexport const AgentConfigEntrySchema = AgentManifestSchema.extend({\n models: ModelPolicySchema.optional(),\n}).strict();\n\nexport const CapabilityPresetSchema = z\n .object({\n id: IdSchema,\n name: z.string().min(1),\n description: z.string().optional(),\n version: z.number().int().positive().default(1),\n extends: z.array(IdSchema).optional(),\n models: ModelPolicyPatchSchema.optional(),\n tools: ToolPolicySetSchema.optional(),\n skills: SkillPolicySchema.optional(),\n memory: MemoryPolicySchema.optional(),\n workflows: WorkflowPolicySchema.optional(),\n boundaries: BoundaryPolicySchema.optional(),\n runtime: RuntimePolicySchema,\n locks: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nexport type AgentManifest = z.infer<typeof AgentManifestSchema>;\nexport type AgentConfigEntry = z.infer<typeof AgentConfigEntrySchema>;\nexport type CapabilityPreset = z.infer<typeof CapabilityPresetSchema>;\nexport type EffectiveAgentManifest = AgentManifest;\nexport type ToolPolicy = z.infer<typeof ToolPolicySchema>;\n"],"mappings":";;;;;AAEM,YAAW,EAAE,QAAQ,CAAC,MAAM,0BAA0B;AAE/C,gCAA+B;AAE/B,2BAA0B,EACpC,OAAO;EACN,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE;EACxB,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAChD,aAAa,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU;EAC5C,CAAC,CACD,QAAQ,CACR,aAAa,OAAO,QAAQ;EAC3B,MAAM,eAAe,QAAgB;GACnC,MAAM,UAAU,IAAI,MAAM;GAC1B,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAChC,UAAO,MAAM,KAAK,MAAM,QAAQ,SAAS;;AAE3C,MAAI,CAAC,YAAY,MAAM,MAAM,CAC3B,KAAI,SAAS;GACX,MAAM;GACN,SAAS,6CAA6C,MAAM,MAAM;GAClE,MAAM,CAAC,QAAQ;GAChB,CAAC;AAEJ,OAAK,MAAM,CAAC,OAAO,cAAc,MAAM,aAAa,EAAE,EAAE,SAAS,CAC/D,KAAI,CAAC,YAAY,SAAS,CACxB,KAAI,SAAS;GACX,MAAM;GACN,SAAS,gDAAgD,SAAS;GAClE,MAAM,CAAC,aAAa,MAAM;GAC3B,CAAC;GAGN;AAES,wBAAuB,EACjC,OAAO;EACN,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE;EAC1B,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAChD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACjD,sBAAsB,EAAE,SAAS,CAAC,UAAU;EAC7C,CAAC,CACD,QAAQ,CACR,aAAa,OAAO,QAAQ;EAC3B,MAAM,eAAe,QAAgB;GACnC,MAAM,UAAU,IAAI,MAAM;GAC1B,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAChC,UAAO,MAAM,KAAK,MAAM,QAAQ,SAAS;;AAE3C,MAAI,CAAC,YAAY,MAAM,QAAQ,CAC7B,KAAI,SAAS;GACX,MAAM;GACN,SAAS,+CAA+C,MAAM,QAAQ;GACtE,MAAM,CAAC,UAAU;GAClB,CAAC;AAEJ,OAAK,MAAM,CAAC,OAAO,cAAc,MAAM,aAAa,EAAE,EAAE,SAAS,CAC/D,KAAI,CAAC,YAAY,SAAS,CACxB,KAAI,SAAS;GACX,MAAM;GACN,SAAS,gDAAgD,SAAS;GAClE,MAAM,CAAC,aAAa,MAAM;GAC3B,CAAC;GAGN;AAES,qBAAoB,EAC9B,OAAO;EACN,aAAa;EACb,OAAO,EAAE,OAAO,UAAU,wBAAwB,CAAC,QAAQ,EAAE,CAAC;EAC9D,YAAY,qBAAqB,UAAU;EAC3C,sBAAsB,qBAAqB,UAAU;EACrD,QAAQ,EACL,OAAO;GACN,gBAAgB,EAAE,SAAS,CAAC,UAAU;GACtC,aAAa,EAAE,KAAK;IAAC;IAAO;IAAU;IAAO,CAAC,CAAC,UAAU;GAC1D,CAAC,CACD,QAAQ,CACR,UAAU;EACd,CAAC,CACD,QAAQ;AAEE,0BAAyB,EACnC,OAAO;EACN,aAAa,SAAS,UAAU;EAChC,OAAO,EAAE,OAAO,UAAU,wBAAwB,CAAC,UAAU;EAC7D,YAAY,qBAAqB,UAAU;EAC3C,sBAAsB,qBAAqB,UAAU;EACrD,QAAQ,EACL,OAAO;GACN,gBAAgB,EAAE,SAAS,CAAC,UAAU;GACtC,aAAa,EAAE,KAAK;IAAC;IAAO;IAAU;IAAO,CAAC,CAAC,UAAU;GAC1D,CAAC,CACD,QAAQ,CACR,UAAU;EACd,CAAC,CACD,QAAQ;AAEE,kBAAiB,EAAE,KAAK;EAAC;EAAS;EAAW;EAAO,CAAC;AACrD,mBAAkB,EAAE,KAAK;EAAC;EAAY;EAAa;EAAe,CAAC;AAEnE,oBAAmB,EAC7B,OAAO;EACN,MAAM;EACN,OAAO,gBAAgB,UAAU;EACjC,QAAQ,EACL,OAAO;GACN,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GACvD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GAClD,CAAC,CACD,QAAQ,CACR,UAAU;EACd,CAAC,CACD,QAAQ;AAEE,uBAAsB,EAChC,OAAO;EACN,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAAC;EAClE,KAAK,EACF,OAAO;GACN,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,iBAAiB,CAAC,UAAU;GACjE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,iBAAiB,CAAC,UAAU;GAChE,CAAC,CACD,QAAQ,CACR,UAAU;EACd,CAAC,CACD,QAAQ,CACR,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC;AAEd,qBAAoB,EAC9B,OAAO;EACN,MAAM,EAAE,KAAK;GAAC;GAAO;GAAa;GAAY;GAAM,CAAC,CAAC,QAAQ,MAAM;EACpE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAC5C,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAC5C,CAAC,CACD,QAAQ,CACR,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEd,6BAA4B,EACtC,OAAO;EACN,SAAS,EAAE,SAAS,CAAC,UAAU;EAC/B,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACnC,CAAC,CACD,QAAQ;AAEE,6BAA4B,0BAA0B,OAAO;EACxE,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACpD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU;EAChD,kBAAkB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;EACtD,CAAC,CAAC,QAAQ;AAEE,4BAA2B,0BAA0B,OAAO;EACvE,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;EAC7C,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACtD,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACxD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU;EAChD,qBAAqB,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;EACrD,YAAY,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;EAC7C,CAAC,CAAC,QAAQ;AAEE,2BAA0B,0BAA0B,OAAO;EACtE,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACpD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU;EAChD,oBAAoB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;EACxD,CAAC,CAAC,QAAQ;AAEE,wBAAuB,EACjC,OAAO;EACN,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;EACnC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACvC,UAAU,EAAE,QAAQ,CAAC,UAAU;EAC/B,QAAQ,EACL,OAAO;GACN,OAAO,0BAA0B,UAAU;GAC3C,MAAM,yBAAyB,UAAU;GACzC,KAAK,wBAAwB,UAAU;GACxC,CAAC,CACD,QAAQ,CACR,UAAU;EACd,CAAC,CACD,QAAQ,CACR,UAAU;AAEA,sBAAqB,EAC/B,OAAO;EACN,MAAM,EAAE,KAAK;GAAC;GAAO;GAAY;GAAgB;GAAO,CAAC,CAAC,QAAQ,MAAM;EACxE,SAAS,EACN,MAAM,EAAE,KAAK;GAAC;GAAW;GAAe;GAAgB;GAAW;GAAY,CAAC,CAAC,CACjF,QAAQ,CAAC,UAAU,CAAC;EACvB,aAAa,EACV,OAAO;GACN,aAAa,EAAE,KAAK;IAAC;IAAQ;IAAW;IAAQ,CAAC,CAAC,UAAU;GAC5D,cAAc,EAAE,KAAK;IAAC;IAAQ;IAAW;IAAQ,CAAC,CAAC,UAAU;GAC7D,SAAS,EAAE,KAAK;IAAC;IAAQ;IAAW;IAAQ,CAAC,CAAC,UAAU;GACxD,WAAW,EAAE,KAAK;IAAC;IAAQ;IAAW;IAAQ,CAAC,CAAC,UAAU;GAC3D,CAAC,CACD,QAAQ,CACR,UAAU;EACb,WAAW,EACR,OAAO;GACN,YAAY,EAAE,SAAS,CAAC,QAAQ,KAAK;GACrC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GAClD,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;GACjD,CAAC,CACD,QAAQ,CACR,UAAU;EACb,SAAS,EACN,OAAO;GACN,mBAAmB,EAAE,KAAK;IAAC;IAAQ;IAAY;IAAQ,CAAC,CAAC,QAAQ,OAAO;GACxE,sBAAsB,EAAE,KAAK;IAAC;IAAQ;IAAW;IAAQ,CAAC,CAAC,QAAQ,UAAU;GAC9E,CAAC,CACD,QAAQ,CACR,UAAU;EACb,iBAAiB,EACd,OAAO;GACN,gBAAgB,EACb,KAAK;IAAC;IAAe;IAAkB;IAAU;IAAc;IAAgB,CAAC,CAChF,QAAQ,SAAS;GACpB,eAAe,EACZ,KAAK;IAAC;IAAe;IAAkB;IAAiB;IAAc;IAAgB,CAAC,CACvF,QAAQ,cAAc;GACzB,qBAAqB,EAAE,SAAS,CAAC,QAAQ,MAAM;GAC/C,oBAAoB,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;GACzD,gBAAgB,EACb,MACC,EAAE,KAAK;IACL;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,CACH,CACA,UAAU;GACd,CAAC,CACD,QAAQ,CACR,UAAU;EACb,UAAU;EACX,CAAC,CACD,QAAQ,CACR,QAAQ;EAAE,MAAM;EAAO,SAAS,CAAC,UAAU;EAAE,CAAC;AAEpC,wBAAuB,EACjC,OAAO;EACN,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACrC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAC9C,WAAW,EACR,MACC,EACG,OAAO;GACN,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;GACzB,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE;GAC5B,CAAC,CACD,QAAQ,CACZ,CACA,UAAU;EACd,CAAC,CACD,QAAQ,CACR,QAAQ,EAAE,CAAC;AAED,wBAAuB,EACjC,OAAO;EACN,sBAAsB,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC5D,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;EACjD,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;EACnD,CAAC,CACD,QAAQ,CACR,QAAQ;EAAE,sBAAsB,EAAE;EAAE,WAAW,EAAE;EAAE,YAAY,EAAE;EAAE,CAAC;AAE1D,yBAAwB,EAClC,OAAO,EACN,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,EACxB,CAAC,CACD,QAAQ;AAEE,uBAAsB,EAChC,OAAO;EACN,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EAChD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EACjD,wBAAwB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;EAC/D,CAAC,CACD,QAAQ,CACR,UAAU;AAEA,sBAAqB,EAC/B,OAAO,EACN,oBAAoB,EAAE,QAAQ,CAAC,UAAU,EAC1C,CAAC,CACD,QAAQ,CACR,UAAU;AAEA,uBAAsB,EAChC,OAAO;EACN,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE;EACvB,aAAa,EAAE,QAAQ,CAAC,UAAU;EAClC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE;EACvB,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,KAAK;EACzC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,SAAS;EACzC,QAAQ,EAAE,QAAQ,CAAC,UAAU;EAC9B,CAAC,CACD,QAAQ;AAEE,+BAA8B,EACxC,OAAO;EACN,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;EAC1C,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAChD,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAClD,CAAC,CACD,QAAQ;AAEE,uBAAsB,EAChC,OAAO;EACN,IAAI;EACJ,SAAS,EAAE,SAAS,CAAC,QAAQ,KAAK;EAClC,SAAS,EAAE,MAAM,SAAS,CAAC,UAAU;EACrC,UAAU;EACV,kBAAkB;EAClB,WAAW;EACX,QAAQ;EACR,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,WAAW;EACX,YAAY;EACZ,SAAS;EACT,QAAQ;EACT,CAAC,CACD,QAAQ;AAEE,0BAAyB,oBAAoB,OAAO,EAC/D,QAAQ,kBAAkB,UAAU,EACrC,CAAC,CAAC,QAAQ;AAEE,0BAAyB,EACnC,OAAO;EACN,IAAI;EACJ,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE;EACvB,aAAa,EAAE,QAAQ,CAAC,UAAU;EAClC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE;EAC/C,SAAS,EAAE,MAAM,SAAS,CAAC,UAAU;EACrC,QAAQ,uBAAuB,UAAU;EACzC,OAAO,oBAAoB,UAAU;EACrC,QAAQ,kBAAkB,UAAU;EACpC,QAAQ,mBAAmB,UAAU;EACrC,WAAW,qBAAqB,UAAU;EAC1C,YAAY,qBAAqB,UAAU;EAC3C,SAAS;EACT,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU;EAC7C,CAAC,CACD,QAAQ"}
@@ -14,15 +14,21 @@ function parseLimit(raw, fallback) {
14
14
  const parsed = raw ? Number.parseInt(raw, 10) : fallback;
15
15
  return Number.isFinite(parsed) ? parsed : fallback;
16
16
  }
17
+ function parseProjectId(raw) {
18
+ return raw?.trim() || void 0;
19
+ }
17
20
  function registerAutomationRoutes(authenticated, deps) {
18
21
  const { service } = deps;
19
22
  authenticated.get("/api/automations", async (c) => {
20
- const automations = await service.automationServiceInstance.list();
23
+ const projectId = parseProjectId(c.req.query("projectId"));
24
+ if (projectId && !service.projects.get(projectId)) return c.json({ error: "Project not found" }, 404);
25
+ const automations = await service.automationServiceInstance.list({ projectId });
21
26
  return c.json({ automations });
22
27
  });
23
28
  authenticated.post("/api/automations", async (c) => {
24
29
  try {
25
30
  const body = await c.req.json();
31
+ if (body.projectId && !service.projects.get(body.projectId)) return c.json({ error: "Project not found" }, 404);
26
32
  const automation = await service.automationServiceInstance.create(body);
27
33
  return c.json({ automation }, 201);
28
34
  } catch (err) {
@@ -63,8 +69,11 @@ function registerAutomationRoutes(authenticated, deps) {
63
69
  });
64
70
  authenticated.get("/api/automation-runs", async (c) => {
65
71
  const automationId = c.req.query("automationId")?.trim();
72
+ const projectId = parseProjectId(c.req.query("projectId"));
73
+ if (projectId && !service.projects.get(projectId)) return c.json({ error: "Project not found" }, 404);
66
74
  const runs = await service.automationServiceInstance.listRuns({
67
75
  automationId: automationId || void 0,
76
+ projectId: automationId ? void 0 : projectId,
68
77
  limit: parseLimit(c.req.query("limit"), 50)
69
78
  });
70
79
  return c.json({ runs });
@@ -149,7 +158,9 @@ function registerAutomationRoutes(authenticated, deps) {
149
158
  });
150
159
  authenticated.patch("/api/automations/:id", async (c) => {
151
160
  try {
152
- const automation = await service.automationServiceInstance.update(c.req.param("id"), await c.req.json());
161
+ const patch = await c.req.json();
162
+ if (patch.projectId && !service.projects.get(patch.projectId)) return c.json({ error: "Project not found" }, 404);
163
+ const automation = await service.automationServiceInstance.update(c.req.param("id"), patch);
153
164
  if (!automation) return c.json({ error: "Automation not found" }, 404);
154
165
  return c.json({ automation });
155
166
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","names":[],"sources":["../../../../src/automations/api/routes.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { resolveDefaultAgentId } from '../../agent/agent-scope.js';\nimport type { AuthenticatedRouteDeps } from '../../gateway/hono/routes/deps.js';\nimport { logRouteError } from '../../gateway/hono/lib/route-logger.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { AutomationDraftService, simulateAutomation } from '../draft/index.js';\nimport type { CreateAutomationInput } from '../domain/validation.js';\nimport { AutomationAlreadyRunningError } from '../service/automation-service.js';\n\nconst log = createLogger('Gateway:Automations');\n\nfunction parseLimit(raw: string | undefined, fallback: number): number {\n const parsed = raw ? Number.parseInt(raw, 10) : fallback;\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n\nexport function registerAutomationRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/automations', async (c) => {\n const automations = await service.automationServiceInstance.list();\n return c.json({ automations });\n });\n\n authenticated.post('/api/automations', async (c) => {\n try {\n const body = await c.req.json();\n const automation = await service.automationServiceInstance.create(body);\n return c.json({ automation }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'create' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation' }, 400);\n }\n });\n\n authenticated.get('/api/automations/metrics', async (c) => {\n const metrics = await service.automationServiceInstance.getMetrics();\n return c.json(metrics);\n });\n\n authenticated.post('/api/automations/draft', async (c) => {\n const body = await c.req.json().catch(() => null) as {\n prompt?: unknown;\n agentId?: unknown;\n language?: unknown;\n } | null;\n const prompt = typeof body?.prompt === 'string' ? body.prompt.trim() : '';\n if (!prompt) return c.json({ error: 'prompt is required' }, 400);\n const agentId = typeof body?.agentId === 'string' && body.agentId.trim()\n ? body.agentId.trim()\n : resolveDefaultAgentId(service.currentConfig);\n const draftService = new AutomationDraftService({ config: service.currentConfig });\n try {\n const draft = await draftService.createDraft({\n prompt,\n agentId,\n language: body?.language === 'zh' ? 'zh' : 'en',\n }, c.req.raw.signal);\n return c.json({ draft }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'draft' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation draft' }, 400);\n }\n });\n\n authenticated.post('/api/automations/simulate', async (c) => {\n try {\n const body = await c.req.json() as CreateAutomationInput;\n return c.json({ simulation: simulateAutomation(body) });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'simulate' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to simulate automation' }, 400);\n }\n });\n\n authenticated.get('/api/automation-runs', async (c) => {\n const automationId = c.req.query('automationId')?.trim();\n const runs = await service.automationServiceInstance.listRuns({\n automationId: automationId || undefined,\n limit: parseLimit(c.req.query('limit'), 50),\n });\n return c.json({ runs });\n });\n\n authenticated.get('/api/automation-runs/product-events', async (c) => {\n const eventType = c.req.query('eventType')?.trim();\n if (!eventType) return c.json({ error: 'eventType is required' }, 400);\n const payloadKey = c.req.query('payloadKey')?.trim();\n const payloadValue = c.req.query('payloadValue')?.trim();\n const items = await service.automationServiceInstance.listRunsForProductEvent({\n eventType,\n source: c.req.query('source')?.trim() || undefined,\n payloadKey: payloadKey || undefined,\n payloadValue: payloadValue || undefined,\n limit: parseLimit(c.req.query('limit'), 10),\n });\n return c.json({ items });\n });\n\n authenticated.get('/api/automation-runs/:runId', async (c) => {\n const run = await service.automationServiceInstance.getRun(c.req.param('runId'));\n if (!run) return c.json({ error: 'Run not found' }, 404);\n return c.json({ run });\n });\n\n authenticated.get('/api/automation-runs/:runId/events', async (c) => {\n const runId = c.req.param('runId');\n const run = await service.automationServiceInstance.getRun(runId);\n if (!run) return c.json({ error: 'Run not found' }, 404);\n const events = await service.automationServiceInstance.listRunEvents(runId);\n return c.json({ events });\n });\n\n authenticated.post('/api/automation-runs/:runId/rerun', async (c) => {\n try {\n const run = await service.automationServiceInstance.rerunFromRun(c.req.param('runId'));\n return c.json({ run }, 201);\n } catch (err) {\n if (err instanceof AutomationAlreadyRunningError) {\n return c.json({\n error: err.message,\n code: 'automation_already_running',\n automationId: err.automationId,\n runningRunId: err.runningRunId,\n }, 409);\n }\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'rerun' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to rerun automation' }, 400);\n }\n });\n\n authenticated.post('/api/automation-runs/:runId/repair-draft', async (c) => {\n const runId = c.req.param('runId');\n const run = await service.automationServiceInstance.getRun(runId);\n if (!run) return c.json({ error: 'Run not found' }, 404);\n if (!['failed', 'timeout', 'cancelled'].includes(run.status)) {\n return c.json({ error: 'Repair draft is only available for failed, timed out, or cancelled runs' }, 400);\n }\n const automation = await service.automationServiceInstance.get(run.automationId);\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n const body = await c.req.json().catch(() => null) as { agentId?: unknown; language?: unknown } | null;\n const agentId = typeof body?.agentId === 'string' && body.agentId.trim()\n ? body.agentId.trim()\n : resolveDefaultAgentId(service.currentConfig);\n const events = await service.automationServiceInstance.listRunEvents(runId);\n const draftService = new AutomationDraftService({ config: service.currentConfig });\n try {\n const repair = await draftService.createRepairDraft({\n agentId,\n automation,\n run,\n events,\n language: body?.language === 'zh' ? 'zh' : 'en',\n }, c.req.raw.signal);\n return c.json({ repair }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'repairDraft' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation repair draft' }, 400);\n }\n });\n\n authenticated.post('/api/automation-runs/:runId/cancel', async (c) => {\n const cancelled = await service.automationServiceInstance.cancelRun(c.req.param('runId'));\n return c.json({ cancelled });\n });\n\n authenticated.get('/api/automations/:id', async (c) => {\n const automation = await service.automationServiceInstance.get(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n\n authenticated.patch('/api/automations/:id', async (c) => {\n try {\n const automation = await service.automationServiceInstance.update(c.req.param('id'), await c.req.json());\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'update' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to update automation' }, 400);\n }\n });\n\n authenticated.delete('/api/automations/:id', async (c) => {\n const removed = await service.automationServiceInstance.remove(c.req.param('id'));\n return c.json({ removed });\n });\n\n authenticated.post('/api/automations/:id/run', async (c) => {\n try {\n const run = await service.automationServiceInstance.runNow(c.req.param('id'));\n return c.json({ run });\n } catch (err) {\n if (err instanceof AutomationAlreadyRunningError) {\n return c.json({\n error: err.message,\n code: 'automation_already_running',\n automationId: err.automationId,\n runningRunId: err.runningRunId,\n }, 409);\n }\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'run' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to run automation' }, 400);\n }\n });\n\n authenticated.post('/api/automations/:id/pause', async (c) => {\n const automation = await service.automationServiceInstance.pause(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n\n authenticated.post('/api/automations/:id/resume', async (c) => {\n const automation = await service.automationServiceInstance.resume(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n}\n"],"mappings":";;;;;;;;;kBAEmE;aAGd;AAKrD,MAAM,MAAM,aAAa,sBAAsB;AAE/C,SAAS,WAAW,KAAyB,UAA0B;CACrE,MAAM,SAAS,MAAM,OAAO,SAAS,KAAK,GAAG,GAAG;AAChD,QAAO,OAAO,SAAS,OAAO,GAAG,SAAS;;AAG5C,SAAgB,yBAAyB,eAAqB,MAAoC;CAChG,MAAM,EAAE,YAAY;AAEpB,eAAc,IAAI,oBAAoB,OAAO,MAAM;EACjD,MAAM,cAAc,MAAM,QAAQ,0BAA0B,MAAM;AAClE,SAAO,EAAE,KAAK,EAAE,aAAa,CAAC;GAC9B;AAEF,eAAc,KAAK,oBAAoB,OAAO,MAAM;AAClD,MAAI;GACF,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM;GAC/B,MAAM,aAAa,MAAM,QAAQ,0BAA0B,OAAO,KAAK;AACvE,UAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI;WAC3B,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,UAAU,CAAC;AAChF,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,+BAA+B,EAAE,IAAI;;GAEnG;AAEF,eAAc,IAAI,4BAA4B,OAAO,MAAM;EACzD,MAAM,UAAU,MAAM,QAAQ,0BAA0B,YAAY;AACpE,SAAO,EAAE,KAAK,QAAQ;GACtB;AAEF,eAAc,KAAK,0BAA0B,OAAO,MAAM;EACxD,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK;EAKjD,MAAM,SAAS,OAAO,MAAM,WAAW,WAAW,KAAK,OAAO,MAAM,GAAG;AACvE,MAAI,CAAC,OAAQ,QAAO,EAAE,KAAK,EAAE,OAAO,sBAAsB,EAAE,IAAI;EAChE,MAAM,UAAU,OAAO,MAAM,YAAY,YAAY,KAAK,QAAQ,MAAM,GACpE,KAAK,QAAQ,MAAM,GACnB,sBAAsB,QAAQ,cAAc;EAChD,MAAM,eAAe,IAAI,uBAAuB,EAAE,QAAQ,QAAQ,eAAe,CAAC;AAClF,MAAI;GACF,MAAM,QAAQ,MAAM,aAAa,YAAY;IAC3C;IACA;IACA,UAAU,MAAM,aAAa,OAAO,OAAO;IAC5C,EAAE,EAAE,IAAI,IAAI,OAAO;AACpB,UAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI;WACtB,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,SAAS,CAAC;AAC/E,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,qCAAqC,EAAE,IAAI;;GAEzG;AAEF,eAAc,KAAK,6BAA6B,OAAO,MAAM;AAC3D,MAAI;GACF,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM;AAC/B,UAAO,EAAE,KAAK,EAAE,YAAY,mBAAmB,KAAK,EAAE,CAAC;WAChD,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,YAAY,CAAC;AAClF,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,iCAAiC,EAAE,IAAI;;GAErG;AAEF,eAAc,IAAI,wBAAwB,OAAO,MAAM;EACrD,MAAM,eAAe,EAAE,IAAI,MAAM,eAAe,EAAE,MAAM;EACxD,MAAM,OAAO,MAAM,QAAQ,0BAA0B,SAAS;GAC5D,cAAc,gBAAgB,KAAA;GAC9B,OAAO,WAAW,EAAE,IAAI,MAAM,QAAQ,EAAE,GAAG;GAC5C,CAAC;AACF,SAAO,EAAE,KAAK,EAAE,MAAM,CAAC;GACvB;AAEF,eAAc,IAAI,uCAAuC,OAAO,MAAM;EACpE,MAAM,YAAY,EAAE,IAAI,MAAM,YAAY,EAAE,MAAM;AAClD,MAAI,CAAC,UAAW,QAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,EAAE,IAAI;EACtE,MAAM,aAAa,EAAE,IAAI,MAAM,aAAa,EAAE,MAAM;EACpD,MAAM,eAAe,EAAE,IAAI,MAAM,eAAe,EAAE,MAAM;EACxD,MAAM,QAAQ,MAAM,QAAQ,0BAA0B,wBAAwB;GAC5E;GACA,QAAQ,EAAE,IAAI,MAAM,SAAS,EAAE,MAAM,IAAI,KAAA;GACzC,YAAY,cAAc,KAAA;GAC1B,cAAc,gBAAgB,KAAA;GAC9B,OAAO,WAAW,EAAE,IAAI,MAAM,QAAQ,EAAE,GAAG;GAC5C,CAAC;AACF,SAAO,EAAE,KAAK,EAAE,OAAO,CAAC;GACxB;AAEF,eAAc,IAAI,+BAA+B,OAAO,MAAM;EAC5D,MAAM,MAAM,MAAM,QAAQ,0BAA0B,OAAO,EAAE,IAAI,MAAM,QAAQ,CAAC;AAChF,MAAI,CAAC,IAAK,QAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,EAAE,IAAI;AACxD,SAAO,EAAE,KAAK,EAAE,KAAK,CAAC;GACtB;AAEF,eAAc,IAAI,sCAAsC,OAAO,MAAM;EACnE,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ;AAElC,MAAI,CAAC,MADa,QAAQ,0BAA0B,OAAO,MAAM,CACvD,QAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,EAAE,IAAI;EACxD,MAAM,SAAS,MAAM,QAAQ,0BAA0B,cAAc,MAAM;AAC3E,SAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;GACzB;AAEF,eAAc,KAAK,qCAAqC,OAAO,MAAM;AACnE,MAAI;GACF,MAAM,MAAM,MAAM,QAAQ,0BAA0B,aAAa,EAAE,IAAI,MAAM,QAAQ,CAAC;AACtF,UAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI;WACpB,KAAK;AACZ,OAAI,eAAe,8BACjB,QAAO,EAAE,KAAK;IACZ,OAAO,IAAI;IACX,MAAM;IACN,cAAc,IAAI;IAClB,cAAc,IAAI;IACnB,EAAE,IAAI;AAET,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,SAAS,CAAC;AAC/E,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,8BAA8B,EAAE,IAAI;;GAElG;AAEF,eAAc,KAAK,4CAA4C,OAAO,MAAM;EAC1E,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ;EAClC,MAAM,MAAM,MAAM,QAAQ,0BAA0B,OAAO,MAAM;AACjE,MAAI,CAAC,IAAK,QAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,EAAE,IAAI;AACxD,MAAI,CAAC;GAAC;GAAU;GAAW;GAAY,CAAC,SAAS,IAAI,OAAO,CAC1D,QAAO,EAAE,KAAK,EAAE,OAAO,2EAA2E,EAAE,IAAI;EAE1G,MAAM,aAAa,MAAM,QAAQ,0BAA0B,IAAI,IAAI,aAAa;AAChF,MAAI,CAAC,WAAY,QAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,EAAE,IAAI;EACtE,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK;EACjD,MAAM,UAAU,OAAO,MAAM,YAAY,YAAY,KAAK,QAAQ,MAAM,GACpE,KAAK,QAAQ,MAAM,GACnB,sBAAsB,QAAQ,cAAc;EAChD,MAAM,SAAS,MAAM,QAAQ,0BAA0B,cAAc,MAAM;EAC3E,MAAM,eAAe,IAAI,uBAAuB,EAAE,QAAQ,QAAQ,eAAe,CAAC;AAClF,MAAI;GACF,MAAM,SAAS,MAAM,aAAa,kBAAkB;IAClD;IACA;IACA;IACA;IACA,UAAU,MAAM,aAAa,OAAO,OAAO;IAC5C,EAAE,EAAE,IAAI,IAAI,OAAO;AACpB,UAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI;WACvB,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,eAAe,CAAC;AACrF,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,4CAA4C,EAAE,IAAI;;GAEhH;AAEF,eAAc,KAAK,sCAAsC,OAAO,MAAM;EACpE,MAAM,YAAY,MAAM,QAAQ,0BAA0B,UAAU,EAAE,IAAI,MAAM,QAAQ,CAAC;AACzF,SAAO,EAAE,KAAK,EAAE,WAAW,CAAC;GAC5B;AAEF,eAAc,IAAI,wBAAwB,OAAO,MAAM;EACrD,MAAM,aAAa,MAAM,QAAQ,0BAA0B,IAAI,EAAE,IAAI,MAAM,KAAK,CAAC;AACjF,MAAI,CAAC,WAAY,QAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,EAAE,IAAI;AACtE,SAAO,EAAE,KAAK,EAAE,YAAY,CAAC;GAC7B;AAEF,eAAc,MAAM,wBAAwB,OAAO,MAAM;AACvD,MAAI;GACF,MAAM,aAAa,MAAM,QAAQ,0BAA0B,OAAO,EAAE,IAAI,MAAM,KAAK,EAAE,MAAM,EAAE,IAAI,MAAM,CAAC;AACxG,OAAI,CAAC,WAAY,QAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,EAAE,IAAI;AACtE,UAAO,EAAE,KAAK,EAAE,YAAY,CAAC;WACtB,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,UAAU,CAAC;AAChF,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,+BAA+B,EAAE,IAAI;;GAEnG;AAEF,eAAc,OAAO,wBAAwB,OAAO,MAAM;EACxD,MAAM,UAAU,MAAM,QAAQ,0BAA0B,OAAO,EAAE,IAAI,MAAM,KAAK,CAAC;AACjF,SAAO,EAAE,KAAK,EAAE,SAAS,CAAC;GAC1B;AAEF,eAAc,KAAK,4BAA4B,OAAO,MAAM;AAC1D,MAAI;GACF,MAAM,MAAM,MAAM,QAAQ,0BAA0B,OAAO,EAAE,IAAI,MAAM,KAAK,CAAC;AAC7E,UAAO,EAAE,KAAK,EAAE,KAAK,CAAC;WACf,KAAK;AACZ,OAAI,eAAe,8BACjB,QAAO,EAAE,KAAK;IACZ,OAAO,IAAI;IACX,MAAM;IACN,cAAc,IAAI;IAClB,cAAc,IAAI;IACnB,EAAE,IAAI;AAET,iBAAc,KAAK,GAAG,KAAK,6BAA6B,EAAE,WAAW,OAAO,CAAC;AAC7E,UAAO,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,4BAA4B,EAAE,IAAI;;GAEhG;AAEF,eAAc,KAAK,8BAA8B,OAAO,MAAM;EAC5D,MAAM,aAAa,MAAM,QAAQ,0BAA0B,MAAM,EAAE,IAAI,MAAM,KAAK,CAAC;AACnF,MAAI,CAAC,WAAY,QAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,EAAE,IAAI;AACtE,SAAO,EAAE,KAAK,EAAE,YAAY,CAAC;GAC7B;AAEF,eAAc,KAAK,+BAA+B,OAAO,MAAM;EAC7D,MAAM,aAAa,MAAM,QAAQ,0BAA0B,OAAO,EAAE,IAAI,MAAM,KAAK,CAAC;AACpF,MAAI,CAAC,WAAY,QAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,EAAE,IAAI;AACtE,SAAO,EAAE,KAAK,EAAE,YAAY,CAAC;GAC7B"}
1
+ {"version":3,"file":"routes.js","names":[],"sources":["../../../../src/automations/api/routes.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { resolveDefaultAgentId } from '../../agent/agent-scope.js';\nimport type { AuthenticatedRouteDeps } from '../../gateway/hono/routes/deps.js';\nimport { logRouteError } from '../../gateway/hono/lib/route-logger.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { AutomationDraftService, simulateAutomation } from '../draft/index.js';\nimport type { CreateAutomationInput } from '../domain/validation.js';\nimport { AutomationAlreadyRunningError } from '../service/automation-service.js';\n\nconst log = createLogger('Gateway:Automations');\n\nfunction parseLimit(raw: string | undefined, fallback: number): number {\n const parsed = raw ? Number.parseInt(raw, 10) : fallback;\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n\nfunction parseProjectId(raw: string | undefined): string | undefined {\n const trimmed = raw?.trim();\n return trimmed || undefined;\n}\n\nexport function registerAutomationRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/automations', async (c) => {\n const projectId = parseProjectId(c.req.query('projectId'));\n if (projectId && !service.projects.get(projectId)) {\n return c.json({ error: 'Project not found' }, 404);\n }\n const automations = await service.automationServiceInstance.list({ projectId });\n return c.json({ automations });\n });\n\n authenticated.post('/api/automations', async (c) => {\n try {\n const body = await c.req.json() as CreateAutomationInput;\n if (body.projectId && !service.projects.get(body.projectId)) {\n return c.json({ error: 'Project not found' }, 404);\n }\n const automation = await service.automationServiceInstance.create(body);\n return c.json({ automation }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'create' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation' }, 400);\n }\n });\n\n authenticated.get('/api/automations/metrics', async (c) => {\n const metrics = await service.automationServiceInstance.getMetrics();\n return c.json(metrics);\n });\n\n authenticated.post('/api/automations/draft', async (c) => {\n const body = await c.req.json().catch(() => null) as {\n prompt?: unknown;\n agentId?: unknown;\n language?: unknown;\n } | null;\n const prompt = typeof body?.prompt === 'string' ? body.prompt.trim() : '';\n if (!prompt) return c.json({ error: 'prompt is required' }, 400);\n const agentId = typeof body?.agentId === 'string' && body.agentId.trim()\n ? body.agentId.trim()\n : resolveDefaultAgentId(service.currentConfig);\n const draftService = new AutomationDraftService({ config: service.currentConfig });\n try {\n const draft = await draftService.createDraft({\n prompt,\n agentId,\n language: body?.language === 'zh' ? 'zh' : 'en',\n }, c.req.raw.signal);\n return c.json({ draft }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'draft' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation draft' }, 400);\n }\n });\n\n authenticated.post('/api/automations/simulate', async (c) => {\n try {\n const body = await c.req.json() as CreateAutomationInput;\n return c.json({ simulation: simulateAutomation(body) });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'simulate' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to simulate automation' }, 400);\n }\n });\n\n authenticated.get('/api/automation-runs', async (c) => {\n const automationId = c.req.query('automationId')?.trim();\n const projectId = parseProjectId(c.req.query('projectId'));\n if (projectId && !service.projects.get(projectId)) {\n return c.json({ error: 'Project not found' }, 404);\n }\n const runs = await service.automationServiceInstance.listRuns({\n automationId: automationId || undefined,\n projectId: automationId ? undefined : projectId,\n limit: parseLimit(c.req.query('limit'), 50),\n });\n return c.json({ runs });\n });\n\n authenticated.get('/api/automation-runs/product-events', async (c) => {\n const eventType = c.req.query('eventType')?.trim();\n if (!eventType) return c.json({ error: 'eventType is required' }, 400);\n const payloadKey = c.req.query('payloadKey')?.trim();\n const payloadValue = c.req.query('payloadValue')?.trim();\n const items = await service.automationServiceInstance.listRunsForProductEvent({\n eventType,\n source: c.req.query('source')?.trim() || undefined,\n payloadKey: payloadKey || undefined,\n payloadValue: payloadValue || undefined,\n limit: parseLimit(c.req.query('limit'), 10),\n });\n return c.json({ items });\n });\n\n authenticated.get('/api/automation-runs/:runId', async (c) => {\n const run = await service.automationServiceInstance.getRun(c.req.param('runId'));\n if (!run) return c.json({ error: 'Run not found' }, 404);\n return c.json({ run });\n });\n\n authenticated.get('/api/automation-runs/:runId/events', async (c) => {\n const runId = c.req.param('runId');\n const run = await service.automationServiceInstance.getRun(runId);\n if (!run) return c.json({ error: 'Run not found' }, 404);\n const events = await service.automationServiceInstance.listRunEvents(runId);\n return c.json({ events });\n });\n\n authenticated.post('/api/automation-runs/:runId/rerun', async (c) => {\n try {\n const run = await service.automationServiceInstance.rerunFromRun(c.req.param('runId'));\n return c.json({ run }, 201);\n } catch (err) {\n if (err instanceof AutomationAlreadyRunningError) {\n return c.json({\n error: err.message,\n code: 'automation_already_running',\n automationId: err.automationId,\n runningRunId: err.runningRunId,\n }, 409);\n }\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'rerun' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to rerun automation' }, 400);\n }\n });\n\n authenticated.post('/api/automation-runs/:runId/repair-draft', async (c) => {\n const runId = c.req.param('runId');\n const run = await service.automationServiceInstance.getRun(runId);\n if (!run) return c.json({ error: 'Run not found' }, 404);\n if (!['failed', 'timeout', 'cancelled'].includes(run.status)) {\n return c.json({ error: 'Repair draft is only available for failed, timed out, or cancelled runs' }, 400);\n }\n const automation = await service.automationServiceInstance.get(run.automationId);\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n const body = await c.req.json().catch(() => null) as { agentId?: unknown; language?: unknown } | null;\n const agentId = typeof body?.agentId === 'string' && body.agentId.trim()\n ? body.agentId.trim()\n : resolveDefaultAgentId(service.currentConfig);\n const events = await service.automationServiceInstance.listRunEvents(runId);\n const draftService = new AutomationDraftService({ config: service.currentConfig });\n try {\n const repair = await draftService.createRepairDraft({\n agentId,\n automation,\n run,\n events,\n language: body?.language === 'zh' ? 'zh' : 'en',\n }, c.req.raw.signal);\n return c.json({ repair }, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'repairDraft' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to create automation repair draft' }, 400);\n }\n });\n\n authenticated.post('/api/automation-runs/:runId/cancel', async (c) => {\n const cancelled = await service.automationServiceInstance.cancelRun(c.req.param('runId'));\n return c.json({ cancelled });\n });\n\n authenticated.get('/api/automations/:id', async (c) => {\n const automation = await service.automationServiceInstance.get(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n\n authenticated.patch('/api/automations/:id', async (c) => {\n try {\n const patch = await c.req.json() as Partial<CreateAutomationInput> & { enabled?: boolean };\n if (patch.projectId && !service.projects.get(patch.projectId)) {\n return c.json({ error: 'Project not found' }, 404);\n }\n const automation = await service.automationServiceInstance.update(c.req.param('id'), patch);\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'update' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to update automation' }, 400);\n }\n });\n\n authenticated.delete('/api/automations/:id', async (c) => {\n const removed = await service.automationServiceInstance.remove(c.req.param('id'));\n return c.json({ removed });\n });\n\n authenticated.post('/api/automations/:id/run', async (c) => {\n try {\n const run = await service.automationServiceInstance.runNow(c.req.param('id'));\n return c.json({ run });\n } catch (err) {\n if (err instanceof AutomationAlreadyRunningError) {\n return c.json({\n error: err.message,\n code: 'automation_already_running',\n automationId: err.automationId,\n runningRunId: err.runningRunId,\n }, 409);\n }\n logRouteError(log, c, err, 'gateway.route.automations', { operation: 'run' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to run automation' }, 400);\n }\n });\n\n authenticated.post('/api/automations/:id/pause', async (c) => {\n const automation = await service.automationServiceInstance.pause(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n\n authenticated.post('/api/automations/:id/resume', async (c) => {\n const automation = await service.automationServiceInstance.resume(c.req.param('id'));\n if (!automation) return c.json({ error: 'Automation not found' }, 404);\n return c.json({ automation });\n });\n}\n"],"mappings":"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"}
@@ -74,6 +74,7 @@ export interface Automation {
74
74
  id: string;
75
75
  name: string;
76
76
  description?: string;
77
+ projectId?: string;
77
78
  enabled: boolean;
78
79
  trigger: AutomationTrigger;
79
80
  action: AutomationAction;
@@ -146,6 +147,7 @@ export interface AutomationDeps {
146
147
  getModelForSession?: (sessionKey: string) => string | undefined;
147
148
  };
148
149
  getDefaultAgentId?: () => string;
150
+ getProjectWorkspaceRoot?: (projectId: string) => string | undefined;
149
151
  workflowRunService?: {
150
152
  startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult>;
151
153
  };
@@ -99,6 +99,7 @@ export declare const AutomationSchema: z.ZodObject<{
99
99
  id: z.ZodString;
100
100
  name: z.ZodString;
101
101
  description: z.ZodOptional<z.ZodString>;
102
+ projectId: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
102
103
  enabled: z.ZodBoolean;
103
104
  trigger: z.ZodDiscriminatedUnion<[z.ZodObject<{
104
105
  kind: z.ZodLiteral<"manual">;
@@ -190,6 +191,7 @@ export declare const AutomationSchema: z.ZodObject<{
190
191
  export declare const CreateAutomationSchema: z.ZodObject<{
191
192
  description: z.ZodOptional<z.ZodString>;
192
193
  name: z.ZodString;
194
+ projectId: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
193
195
  trigger: z.ZodDiscriminatedUnion<[z.ZodObject<{
194
196
  kind: z.ZodLiteral<"manual">;
195
197
  }, z.core.$strict>, z.ZodObject<{
@@ -281,6 +283,7 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
281
283
  description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
282
284
  enabled: z.ZodOptional<z.ZodBoolean>;
283
285
  name: z.ZodOptional<z.ZodString>;
286
+ projectId: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodString>>>;
284
287
  trigger: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
285
288
  kind: z.ZodLiteral<"manual">;
286
289
  }, z.core.$strict>, z.ZodObject<{
@@ -117,6 +117,7 @@ const AutomationSchema = z.object({
117
117
  id: nonEmptyString.max(100),
118
118
  name: nonEmptyString.max(200),
119
119
  description: z.string().max(2e3).optional(),
120
+ projectId: optionalTrimmedString(100),
120
121
  enabled: z.boolean(),
121
122
  trigger: AutomationTriggerSchema,
122
123
  action: AutomationActionSchema,