@xopcai/xopc 0.0.88 → 0.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/extensions/weixin/src/api/api.js +2 -2
  11. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  12. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  13. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  17. package/dist/extensions/weixin/src/plugin.js +1 -1
  18. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  19. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  20. package/dist/gateway/static/root/assets/agents-B6PJB07W.js +222 -0
  21. package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +1 -0
  22. package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +1 -0
  23. package/dist/gateway/static/root/assets/{channels-status-swr-DIsl75Y3.js → channels-status-swr-DaHGkRF1.js} +1 -1
  24. package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +1 -0
  25. package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +1 -0
  26. package/dist/gateway/static/root/assets/{dist-CJwfHYvT.js → dist-6LecgDx5.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-debug-page-BVJohZoZ.js → extension-debug-page-CtuKJ9tE.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-BT2tmElC.js → extension-page-ykzjOkR5.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-BSS47c2j.js → extension-settings-page-Ce2qrdpO.js} +1 -1
  30. package/dist/gateway/static/root/assets/{fetch-BaFNUtkE.js → fetch-C9FFJjuH.js} +1 -1
  31. package/dist/gateway/static/root/assets/{field-primitives-QwYEq6Hz.js → field-primitives-BFcrNeTU.js} +1 -1
  32. package/dist/gateway/static/root/assets/{heartbeat-config-api-BVSidEDJ.js → heartbeat-config-api-CEg4Vr9R.js} +1 -1
  33. package/dist/gateway/static/root/assets/{index-qNrVJp-y.js → index-CZfy9oxs.js} +97 -97
  34. package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +1 -0
  35. package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +1 -0
  36. package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +1 -0
  37. package/dist/gateway/static/root/assets/{settings-form-section-B8N3A3Zo.js → settings-form-section-BqdzA28u.js} +1 -1
  38. package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +3 -0
  39. package/dist/gateway/static/root/assets/{share-preview-page-Q7KqkO-u.js → share-preview-page-Di5Bzh4g.js} +1 -1
  40. package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +2 -0
  41. package/dist/gateway/static/root/assets/{theme-store-BbRc5ugR.js → theme-store-CNqbmTNV.js} +1 -1
  42. package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +7 -0
  43. package/dist/gateway/static/root/assets/{utils-CxDGduqK.js → utils-BWm2tG2w.js} +1 -1
  44. package/dist/gateway/static/root/assets/{voice-api-key-field-CTyHz7L_.js → voice-api-key-field-X2UfnHeq.js} +1 -1
  45. package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +27 -0
  46. package/dist/gateway/static/root/index.html +5 -6
  47. package/dist/package.js +1 -1
  48. package/dist/src/agent/agent-manager.d.ts +2 -0
  49. package/dist/src/agent/agent-manager.js +8 -7
  50. package/dist/src/agent/agent-manager.js.map +1 -1
  51. package/dist/src/agent/agent-scope.js +1 -1
  52. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  53. package/dist/src/agent/context/workspace-seed.js +2 -2
  54. package/dist/src/agent/goals/goal-run-store.js +4 -4
  55. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  56. package/dist/src/agent/goals/post-turn.js +2 -2
  57. package/dist/src/agent/image/load-image-media.js +2 -2
  58. package/dist/src/agent/ipc/bus.js +1 -1
  59. package/dist/src/agent/ipc/inbox.js +2 -2
  60. package/dist/src/agent/ipc/socket.js +1 -1
  61. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  62. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  63. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  64. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  65. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  66. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  67. package/dist/src/agent/memory/dreaming/events.js +1 -1
  68. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  69. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  70. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  71. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  72. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  73. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  74. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  75. package/dist/src/agent/models/manager.js +1 -1
  76. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  77. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  78. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  79. package/dist/src/agent/sandbox/path-policy.js +2 -2
  80. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  81. package/dist/src/agent/service.js +6 -5
  82. package/dist/src/agent/service.js.map +1 -1
  83. package/dist/src/agent/service.types.d.ts +3 -1
  84. package/dist/src/agent/session/session-inspector.js +1 -1
  85. package/dist/src/agent/skills/config.js +1 -1
  86. package/dist/src/agent/skills/hub-hash.js +2 -2
  87. package/dist/src/agent/skills/hub-lock.js +1 -1
  88. package/dist/src/agent/skills/hub-pull.js +2 -2
  89. package/dist/src/agent/skills/index.js +1 -1
  90. package/dist/src/agent/skills/managed-store.js +1 -1
  91. package/dist/src/agent/skills/scanner.js +1 -1
  92. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  93. package/dist/src/agent/skills/skill-manager.js +1 -1
  94. package/dist/src/agent/tools/cronjob-tool.js +2 -1
  95. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  96. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  97. package/dist/src/agent/tools/factory.d.ts +3 -0
  98. package/dist/src/agent/tools/factory.js +3 -24
  99. package/dist/src/agent/tools/factory.js.map +1 -1
  100. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  101. package/dist/src/agent/tools/send-media.js +1 -1
  102. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  103. package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
  104. package/dist/src/agent/tools/workflow-tool.js +61 -261
  105. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  106. package/dist/src/agent/tools/write.js +1 -1
  107. package/dist/src/agent/workflow/catalog.js +1 -1
  108. package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
  109. package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
  110. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
  111. package/dist/src/auth/credentials.d.ts +14 -2
  112. package/dist/src/auth/credentials.js +40 -15
  113. package/dist/src/auth/credentials.js.map +1 -1
  114. package/dist/src/auth/oauth/types.d.ts +16 -0
  115. package/dist/src/auth/profiles/store.js +1 -1
  116. package/dist/src/auth/sync-provider-auth.js +1 -1
  117. package/dist/src/browser/cache-dir-policy.js +1 -1
  118. package/dist/src/browser/cdp-local-launcher.js +2 -2
  119. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  120. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  121. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  122. package/dist/src/browser/stealth.js +1 -1
  123. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  124. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  125. package/dist/src/channels/outbound/persist-store.js +1 -1
  126. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  127. package/dist/src/channels/pairing/pairing-store.js +2 -2
  128. package/dist/src/chat-commands/builtins/config.js +2 -2
  129. package/dist/src/chat-commands/context.js +1 -1
  130. package/dist/src/cli/commands/auth.js +6 -0
  131. package/dist/src/cli/commands/auth.js.map +1 -1
  132. package/dist/src/cli/commands/config.js +1 -1
  133. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  134. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  135. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  136. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  137. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  138. package/dist/src/cli/commands/extension-dev.js +1 -1
  139. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  140. package/dist/src/cli/commands/extension-pack.js +1 -1
  141. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  142. package/dist/src/cli/commands/gateway/logs.js +1 -1
  143. package/dist/src/cli/commands/image.js +1 -1
  144. package/dist/src/cli/commands/init.js +4 -4
  145. package/dist/src/cli/commands/onboard/model.js +6 -0
  146. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  147. package/dist/src/cli/commands/onboard.js +1 -1
  148. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  149. package/dist/src/config/agent-profile.js +1 -1
  150. package/dist/src/config/agent-typed-models.js +1 -1
  151. package/dist/src/config/gateway-bind.js +1 -1
  152. package/dist/src/config/index.js +5 -5
  153. package/dist/src/config/loader.js +2 -2
  154. package/dist/src/config/models-json.js +2 -2
  155. package/dist/src/config/paths-state.js +1 -1
  156. package/dist/src/config/profile.js +2 -2
  157. package/dist/src/config/workspace-path.js +1 -1
  158. package/dist/src/cron/executor.d.ts +2 -0
  159. package/dist/src/cron/executor.js +61 -7
  160. package/dist/src/cron/executor.js.map +1 -1
  161. package/dist/src/cron/job-content.js +2 -1
  162. package/dist/src/cron/job-content.js.map +1 -1
  163. package/dist/src/cron/persistence.js +1 -1
  164. package/dist/src/cron/run-log-store.js +1 -1
  165. package/dist/src/cron/types.d.ts +21 -1
  166. package/dist/src/cron/validation.d.ts +76 -0
  167. package/dist/src/cron/validation.js +26 -1
  168. package/dist/src/cron/validation.js.map +1 -1
  169. package/dist/src/daemon/constants.js +1 -1
  170. package/dist/src/daemon/install-plan.js +2 -2
  171. package/dist/src/daemon/launchd.js +2 -2
  172. package/dist/src/daemon/schtasks.js +2 -2
  173. package/dist/src/daemon/systemd.js +2 -2
  174. package/dist/src/extensions/bundle-mcp.js +1 -1
  175. package/dist/src/extensions/discover-extensions.js +1 -1
  176. package/dist/src/extensions/health.js +1 -1
  177. package/dist/src/extensions/loader.js +1 -1
  178. package/dist/src/extensions/lockfile.js +2 -2
  179. package/dist/src/gateway/agents-admin.js +3 -3
  180. package/dist/src/gateway/file-path-classifier.js +2 -2
  181. package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
  182. package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
  183. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  184. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  185. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  186. package/dist/src/gateway/hono/oauth-async.js +40 -15
  187. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  188. package/dist/src/gateway/hono/oauth.js +31 -6
  189. package/dist/src/gateway/hono/oauth.js.map +1 -1
  190. package/dist/src/gateway/hono/routes/agents.js +1 -1
  191. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  192. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  193. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  194. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  195. package/dist/src/gateway/hono/routes/models.js +12 -6
  196. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  197. package/dist/src/gateway/hono/routes/shares.js +1 -1
  198. package/dist/src/gateway/hono/routes/workflows.js +69 -190
  199. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  200. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  201. package/dist/src/gateway/lock.js +3 -3
  202. package/dist/src/gateway/ports.js +1 -1
  203. package/dist/src/gateway/service/agent-runner.js +2 -2
  204. package/dist/src/gateway/service/marketplace-service.js +2 -2
  205. package/dist/src/gateway/service.d.ts +5 -0
  206. package/dist/src/gateway/service.js +23 -3
  207. package/dist/src/gateway/service.js.map +1 -1
  208. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  209. package/dist/src/infra/restart.js +2 -2
  210. package/dist/src/infra/update-check.js +1 -1
  211. package/dist/src/infra/update-global.js +1 -1
  212. package/dist/src/infra/update-lock.js +3 -3
  213. package/dist/src/infra/update-runner.js +1 -1
  214. package/dist/src/infra/update-startup.js +2 -2
  215. package/dist/src/infra/write-file-atomic.js +2 -2
  216. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  217. package/dist/src/providers/index.d.ts +8 -0
  218. package/dist/src/providers/index.js +53 -14
  219. package/dist/src/providers/index.js.map +1 -1
  220. package/dist/src/providers/model-registry.js +1 -1
  221. package/dist/src/session/config-store.js +2 -2
  222. package/dist/src/session/init-session-turn.js +2 -2
  223. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  224. package/dist/src/session/parity/sessions-json-file.js +1 -1
  225. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  226. package/dist/src/session/parity/transcript-paths.js +1 -1
  227. package/dist/src/session/resolve-session.js +4 -4
  228. package/dist/src/session/search-index-cache.js +1 -1
  229. package/dist/src/session/search-index.js +1 -1
  230. package/dist/src/session/session-title.js +2 -2
  231. package/dist/src/session/store.js +5 -5
  232. package/dist/src/share/share-auto.js +2 -2
  233. package/dist/src/share/share-store.js +3 -3
  234. package/dist/src/share/share-thumbnail.js +2 -2
  235. package/dist/src/share/share-zip.js +1 -1
  236. package/dist/src/share/site-share-config.d.ts +3 -2
  237. package/dist/src/share/site-share-config.js.map +1 -1
  238. package/dist/src/share/site-share-store.js +3 -3
  239. package/dist/src/share/site-static-serve.js +1 -1
  240. package/dist/src/tui/clipboard-image.js +3 -3
  241. package/dist/src/tui/theme-manager.js +1 -1
  242. package/dist/src/tui/tui-keybindings-file.js +1 -1
  243. package/dist/src/tui/tui-scoped-models.js +2 -2
  244. package/dist/src/tui/tui-settings.js +1 -1
  245. package/dist/src/tui/tui.js +3 -3
  246. package/dist/src/tunnel/frpc-binary.js +3 -3
  247. package/dist/src/tunnel/frpc-config.js +1 -1
  248. package/dist/src/tunnel/frpc-extract.js +1 -1
  249. package/dist/src/tunnel/tunnel-state.js +1 -1
  250. package/dist/src/utils/logger/audit.js +1 -1
  251. package/dist/src/utils/logger/log-store.js +1 -1
  252. package/dist/src/utils/logger/rotation.js +1 -1
  253. package/dist/src/voice/tts/audio.js +1 -1
  254. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  255. package/dist/src/workflows/domain/command.d.ts +2 -1
  256. package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
  257. package/dist/src/workflows/domain/definition-utils.js +50 -0
  258. package/dist/src/workflows/domain/definition-utils.js.map +1 -0
  259. package/dist/src/workflows/domain/index.d.ts +2 -0
  260. package/dist/src/workflows/domain/index.js +3 -1
  261. package/dist/src/workflows/domain/run.d.ts +57 -0
  262. package/dist/src/workflows/domain/run.js.map +1 -1
  263. package/dist/src/workflows/domain/validation.d.ts +19 -0
  264. package/dist/src/workflows/domain/validation.js +66 -0
  265. package/dist/src/workflows/domain/validation.js.map +1 -0
  266. package/dist/src/workflows/engine/workflow-engine.d.ts +2 -1
  267. package/dist/src/workflows/engine/workflow-engine.js +1 -0
  268. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  269. package/dist/src/workflows/index.d.ts +4 -0
  270. package/dist/src/workflows/index.js +9 -2
  271. package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
  272. package/dist/src/workflows/service/run-view-to-snapshot.js +61 -0
  273. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
  274. package/dist/src/workflows/service/workflow-run-service.d.ts +36 -0
  275. package/dist/src/workflows/service/workflow-run-service.js +279 -0
  276. package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
  277. package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
  278. package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
  279. package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
  280. package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
  281. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
  282. package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
  283. package/dist/src/workflows/service/workflow-session-key.js +21 -0
  284. package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
  285. package/dist/src/workflows/store/event-store.js +1 -1
  286. package/dist/src/workflows/store/run-store.js +2 -1
  287. package/dist/src/workflows/store/run-store.js.map +1 -1
  288. package/package.json +1 -1
  289. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +0 -222
  290. package/dist/gateway/static/root/assets/apps-page-wKWf3l57.js +0 -1
  291. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +0 -1
  292. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +0 -1
  293. package/dist/gateway/static/root/assets/cron-api-N9hvuRrn.js +0 -1
  294. package/dist/gateway/static/root/assets/cron-page-tlNGNxhP.js +0 -1
  295. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +0 -1
  296. package/dist/gateway/static/root/assets/logs-page-DDonPVLn.js +0 -1
  297. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +0 -1
  298. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +0 -3
  299. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +0 -2
  300. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +0 -7
  301. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +0 -27
@@ -1,25 +1,13 @@
1
1
  import { init_agent_scope, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
2
- import { extractProfileAgentId } from "../../../config/agent-profile.js";
3
- import { init_providers, resolveModel } from "../../../providers/index.js";
4
2
  import { createWorkflowCatalog } from "../../../agent/workflow/catalog.js";
5
- import { DelegateSubagentRunner } from "../../../agent/workflow/subagent-runner.js";
6
- import { resolveModelRef } from "../../../config/agent-typed-models.js";
7
- import { AgentToolsFactory } from "../../../agent/tools/factory.js";
8
- import { isTerminalWorkflowRunStatus } from "../../../workflows/domain/run.js";
9
- import { WorkflowEngine } from "../../../workflows/engine/workflow-engine.js";
10
- import { WorkflowEventStore } from "../../../workflows/store/event-store.js";
11
- import { WorkflowRunStore } from "../../../workflows/store/run-store.js";
12
- import "../../../workflows/index.js";
13
- import { randomUUID } from "node:crypto";
3
+ import { buildWorkflowDefinition } from "../../../workflows/domain/definition-utils.js";
4
+ import { validateWorkflowDefinitionInput } from "../../../workflows/domain/validation.js";
5
+ import "../../../workflows/domain/index.js";
14
6
  //#region src/gateway/hono/routes/workflows.ts
15
7
  init_agent_scope();
16
- init_providers();
17
- const DEFAULT_WORKFLOW_CONCURRENCY = 4;
18
- const DEFAULT_WORKFLOW_TIMEOUT_SEC = 1800;
19
- const DEFAULT_WORKFLOW_MAX_SUBAGENTS = 100;
20
- const activeWorkflowRuns = /* @__PURE__ */ new Map();
21
8
  function registerWorkflowRoutes(authenticated, deps) {
22
9
  const { service } = deps;
10
+ const workflowRunService = service.createWorkflowRunService();
23
11
  authenticated.get("/api/workflows/definitions", (c) => {
24
12
  const catalog = createWorkflowCatalog();
25
13
  const definitions = catalog.list().map((entry) => {
@@ -41,12 +29,26 @@ function registerWorkflowRoutes(authenticated, deps) {
41
29
  return c.json({ error: err instanceof Error ? err.message : "Workflow definition not found" }, 404);
42
30
  }
43
31
  });
32
+ authenticated.post("/api/workflows/definitions/validate", async (c) => {
33
+ const body = await readJsonBody(c.req.raw);
34
+ const result = validateWorkflowDefinitionInput({
35
+ name: body.name,
36
+ script: body.script
37
+ });
38
+ return c.json(result);
39
+ });
44
40
  authenticated.post("/api/workflows/definitions", async (c) => {
45
41
  const body = await readJsonBody(c.req.raw);
46
- const name = body.name?.trim();
47
- const script = body.script?.trim();
48
- if (!name) return c.json({ error: "name is required" }, 400);
49
- if (!script) return c.json({ error: "script is required" }, 400);
42
+ const validation = validateWorkflowDefinitionInput({
43
+ name: body.name,
44
+ script: body.script
45
+ });
46
+ if (!validation.valid) return c.json({
47
+ error: validation.errors[0]?.message ?? "Invalid workflow definition",
48
+ validation
49
+ }, 400);
50
+ const name = body.name?.trim() ?? "";
51
+ const script = body.script ?? "";
50
52
  const catalog = createWorkflowCatalog();
51
53
  try {
52
54
  catalog.save(name, script);
@@ -69,7 +71,7 @@ function registerWorkflowRoutes(authenticated, deps) {
69
71
  });
70
72
  authenticated.get("/api/workflows/stats", async (c) => {
71
73
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
72
- const runs = await createRunStore(service.currentConfig, agentId).listRunSummaries(500);
74
+ const runs = await workflowRunService.createRunStore(agentId).listRunSummaries(500);
73
75
  return c.json({ stats: buildWorkflowStats(runs) });
74
76
  });
75
77
  authenticated.post("/api/workflows/runs", async (c) => {
@@ -77,67 +79,64 @@ function registerWorkflowRoutes(authenticated, deps) {
77
79
  const definitionId = body.definitionId?.trim();
78
80
  if (!definitionId) return c.json({ error: "definitionId is required" }, 400);
79
81
  const agentId = getAgentId(body.agentId ?? c.req.query("agentId"), service.currentConfig);
80
- const runId = await queueWorkflowRun({
81
- deps,
82
+ const parentSessionKey = body.parentSessionKey?.trim() || void 0;
83
+ const result = await workflowRunService.startWorkflowRun({
82
84
  agentId,
83
- sessionKey: body.sessionKey?.trim() || `workflow:${agentId}`,
84
85
  definitionId,
85
86
  input: body.input,
87
+ inputEnvelope: body.inputEnvelope,
86
88
  goal: body.goal,
87
- source: body.source ?? { kind: "webui" },
89
+ parentSessionKey,
90
+ source: normalizeWorkflowRunSource(body.source),
88
91
  concurrency: normalizePositiveInteger(body.concurrency),
89
92
  maxSubagents: normalizePositiveInteger(body.maxSubagents),
90
- tokenBudget: body.tokenBudget
93
+ tokenBudget: body.tokenBudget,
94
+ idempotencyKey: body.idempotencyKey
91
95
  });
92
- if (!runId) return c.json({ error: "Workflow definition not found" }, 404);
93
- return c.json({ runId }, 202);
96
+ if (result.ok === false) return c.json({
97
+ error: result.message,
98
+ code: result.code
99
+ }, result.httpStatus);
100
+ return c.json({
101
+ runId: result.runId,
102
+ sessionKey: result.sessionKey
103
+ }, 202);
94
104
  });
95
105
  authenticated.get("/api/workflows/runs", async (c) => {
96
106
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
97
107
  const rawLimit = c.req.query("limit");
98
108
  const limit = rawLimit ? Number.parseInt(rawLimit, 10) : 50;
99
- const runs = await createRunStore(service.currentConfig, agentId).listRunSummaries(Number.isFinite(limit) ? limit : 50);
109
+ const runs = await workflowRunService.createRunStore(agentId).listRunSummaries(Number.isFinite(limit) ? limit : 50);
100
110
  return c.json({ runs });
101
111
  });
102
112
  authenticated.post("/api/workflows/runs/:runId/cancel", async (c) => {
103
113
  const runId = c.req.param("runId");
104
114
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
105
- const runStore = createRunStore(service.currentConfig, agentId);
106
- const controller = activeWorkflowRuns.get(runId);
107
- if (controller) {
108
- controller.abort();
109
- activeWorkflowRuns.delete(runId);
110
- return c.json({ cancelled: true });
111
- }
112
- const view = await runStore.readRunView(runId);
113
- if (!view) return c.json({ error: "Workflow run not found" }, 404);
114
- if (isTerminalWorkflowRunStatus(view.run.status)) return c.json({
115
- cancelled: true,
116
- alreadyFinished: true
117
- });
118
- await new WorkflowEventStore(service.currentConfig, agentId).append({
115
+ const result = await workflowRunService.cancelWorkflowRun({
116
+ agentId,
119
117
  runId,
120
- type: "run_cancelled",
121
- payload: { reason: "Cancelled by user" }
118
+ reason: "Cancelled by user"
122
119
  });
123
- const updated = await runStore.rebuildRunView(runId);
124
- if (updated) service.emit("workflow.run.updated", {
125
- runId,
126
- view: updated
120
+ if (result.ok === false) return c.json({
121
+ error: result.message,
122
+ code: result.code
123
+ }, result.httpStatus);
124
+ return c.json({
125
+ cancelled: result.cancelled,
126
+ alreadyFinished: result.alreadyFinished
127
127
  });
128
- return c.json({ cancelled: true });
129
128
  });
130
129
  authenticated.get("/api/workflows/runs/:runId", async (c) => {
131
130
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
132
131
  const runId = c.req.param("runId");
133
- const view = await createRunStore(service.currentConfig, agentId).readRunView(runId);
132
+ const view = await workflowRunService.createRunStore(agentId).readRunView(runId);
134
133
  if (!view) return c.json({ error: "Workflow run not found" }, 404);
135
134
  return c.json({ view });
136
135
  });
137
136
  authenticated.post("/api/workflows/runs/:runId/rebuild", async (c) => {
138
137
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
139
138
  const runId = c.req.param("runId");
140
- const view = await createRunStore(service.currentConfig, agentId).rebuildRunView(runId);
139
+ const view = await workflowRunService.createRunStore(agentId).rebuildRunView(runId);
141
140
  if (!view) return c.json({ error: "Workflow run not found" }, 404);
142
141
  service.emit("workflow.run.updated", {
143
142
  runId,
@@ -148,104 +147,32 @@ function registerWorkflowRoutes(authenticated, deps) {
148
147
  authenticated.post("/api/workflows/runs/:runId/retry", async (c) => {
149
148
  const agentId = getAgentId(c.req.query("agentId"), service.currentConfig);
150
149
  const runId = c.req.param("runId");
151
- const existing = await createRunStore(service.currentConfig, agentId).readRunView(runId);
152
- if (!existing) return c.json({ error: "Workflow run not found" }, 404);
153
- const newRunId = await queueWorkflowRun({
154
- deps,
150
+ const result = await workflowRunService.retryWorkflowRun({
155
151
  agentId,
156
- sessionKey: `workflow:${agentId}`,
157
- definitionId: existing.run.definitionId,
158
- input: existing.run.input,
159
- goal: existing.run.goal,
160
- source: { kind: "webui" }
152
+ runId
161
153
  });
162
- if (!newRunId) return c.json({ error: "Workflow definition not found" }, 404);
163
- return c.json({ runId: newRunId }, 202);
154
+ if (result.ok === false) return c.json({
155
+ error: result.message,
156
+ code: result.code
157
+ }, result.httpStatus);
158
+ return c.json({
159
+ runId: result.runId,
160
+ sessionKey: result.sessionKey
161
+ }, 202);
164
162
  });
165
163
  }
166
- function createRunStore(config, agentId) {
167
- return new WorkflowRunStore(config, agentId, new WorkflowEventStore(config, agentId));
168
- }
169
164
  function getAgentId(rawAgentId, config) {
170
165
  const trimmed = rawAgentId?.trim();
171
166
  if (trimmed) return trimmed;
172
167
  return resolveDefaultAgentId(config);
173
168
  }
174
169
  function toWorkflowDefinition(loaded) {
175
- const nowMs = Date.now();
176
- const phases = loaded.meta.phases?.map((phase, index) => ({
177
- id: normalizeId(phase.title) || `phase-${index + 1}`,
178
- title: phase.title,
179
- description: phase.detail
180
- })) ?? [];
181
- return {
182
- id: loaded.name,
170
+ return buildWorkflowDefinition({
183
171
  name: loaded.name,
184
- title: toTitle(loaded.name),
185
- description: loaded.meta.description,
186
- version: "1.0.0",
187
- phases,
188
- runtime: {
189
- kind: "script",
190
- source: loaded.script
191
- },
192
- defaults: {
193
- concurrency: DEFAULT_WORKFLOW_CONCURRENCY,
194
- timeoutSec: DEFAULT_WORKFLOW_TIMEOUT_SEC,
195
- maxSubagents: loaded.meta.estimatedAgents?.max ?? DEFAULT_WORKFLOW_MAX_SUBAGENTS
196
- },
197
- metadata: {
198
- tags: loaded.meta.tags ?? [],
199
- builtIn: loaded.source === "builtin",
200
- source: loaded.source,
201
- whenToUse: loaded.meta.whenToUse,
202
- estimatedAgents: loaded.meta.estimatedAgents,
203
- examplePrompts: loaded.meta.examplePrompts,
204
- i18n: loaded.meta.i18n,
205
- createdAtMs: nowMs,
206
- updatedAtMs: nowMs
207
- }
208
- };
209
- }
210
- async function queueWorkflowRun(params) {
211
- const { deps, agentId, sessionKey, definitionId } = params;
212
- const { service } = deps;
213
- const catalog = createWorkflowCatalog();
214
- let definition;
215
- try {
216
- definition = toWorkflowDefinition(catalog.load(definitionId));
217
- } catch {
218
- return null;
219
- }
220
- const eventStore = new WorkflowEventStore(service.currentConfig, agentId);
221
- const runStore = new WorkflowRunStore(service.currentConfig, agentId, eventStore);
222
- const runId = randomUUID();
223
- const abortController = new AbortController();
224
- const engine = createWorkflowEngine({
225
- deps,
226
- eventStore,
227
- runStore,
228
- sessionKey
229
- });
230
- activeWorkflowRuns.set(runId, abortController);
231
- engine.startRun(definition, {
232
- runId,
233
- input: params.input,
234
- goal: params.goal,
235
- source: params.source,
236
- signal: abortController.signal,
237
- concurrency: params.concurrency,
238
- maxSubagents: params.maxSubagents,
239
- tokenBudget: params.tokenBudget
240
- }).catch((err) => {
241
- service.emit("workflow.run.error", {
242
- runId,
243
- error: err instanceof Error ? err.message : String(err)
244
- });
245
- }).finally(() => {
246
- activeWorkflowRuns.delete(runId);
172
+ source: loaded.source,
173
+ script: loaded.script,
174
+ meta: loaded.meta
247
175
  });
248
- return runId;
249
176
  }
250
177
  function buildWorkflowStats(runs) {
251
178
  const activeStatuses = new Set(["queued", "running"]);
@@ -278,52 +205,6 @@ function buildWorkflowStats(runs) {
278
205
  topDefinitions
279
206
  };
280
207
  }
281
- function createWorkflowEngine(params) {
282
- const { service } = params.deps;
283
- const runner = new DelegateSubagentRunner({
284
- workspace: service.currentWorkspacePath,
285
- bus: service.messageBusInstance,
286
- getDefaultModel: () => resolveModel(service.agentService.getModelForSession(params.sessionKey)),
287
- getConfig: () => service.currentConfig,
288
- buildChildTools: (childOptions) => buildWorkflowChildTools(childOptions)
289
- });
290
- return new WorkflowEngine({
291
- cwd: service.currentWorkspacePath,
292
- eventStore: params.eventStore,
293
- runStore: params.runStore,
294
- runner,
295
- resolveModelId: (modelId) => {
296
- const agentId = extractProfileAgentId(params.sessionKey, service.currentConfig);
297
- return resolveModel(resolveModelRef(service.currentConfig, agentId, modelId));
298
- },
299
- onEventAppended: (event) => {
300
- service.emit("workflow.event.appended", {
301
- runId: event.runId,
302
- event
303
- });
304
- },
305
- onRunViewUpdated: (view) => {
306
- service.emit("workflow.run.updated", {
307
- runId: view.run.id,
308
- view
309
- });
310
- }
311
- });
312
- }
313
- function buildWorkflowChildTools(childOptions) {
314
- return new AgentToolsFactory({
315
- workspace: childOptions.workspace,
316
- bus: childOptions.bus,
317
- getCurrentContext: () => null,
318
- getConfig: childOptions.getConfig,
319
- getPrimaryModel: () => childOptions.model,
320
- toolExecutorConfig: childOptions.toolExecutorConfig
321
- }).createAllTools({
322
- workspace: childOptions.workspace,
323
- getPrimaryModel: () => childOptions.model,
324
- disabledTools: new Set(["extensions"])
325
- });
326
- }
327
208
  async function readJsonBody(request) {
328
209
  try {
329
210
  return await request.json();
@@ -331,16 +212,14 @@ async function readJsonBody(request) {
331
212
  return {};
332
213
  }
333
214
  }
215
+ function normalizeWorkflowRunSource(source) {
216
+ if (!source) return { kind: "webui" };
217
+ return source;
218
+ }
334
219
  function normalizePositiveInteger(value) {
335
220
  if (typeof value !== "number" || !Number.isFinite(value) || value < 1) return;
336
221
  return Math.floor(value);
337
222
  }
338
- function normalizeId(value) {
339
- return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
340
- }
341
- function toTitle(value) {
342
- return value.split(/[_-]+/g).filter(Boolean).map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
343
- }
344
223
  //#endregion
345
224
  export { registerWorkflowRoutes };
346
225
 
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","names":["resolveModelById"],"sources":["../../../../../src/gateway/hono/routes/workflows.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { Hono } from 'hono';\n\nimport { resolveDefaultAgentId } from '../../../agent/agent-scope.js';\nimport type { BuildChildToolsOptions } from '../../../agent/child-agent-factory.js';\nimport { AgentToolsFactory } from '../../../agent/tools/factory.js';\nimport { createWorkflowCatalog } from '../../../agent/workflow/catalog.js';\nimport { DelegateSubagentRunner } from '../../../agent/workflow/subagent-runner.js';\nimport type { WorkflowDefinition, WorkflowRunSource, WorkflowRunSummary } from '../../../workflows/domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../../../workflows/domain/run.js';\nimport { WorkflowEngine, WorkflowEventStore, WorkflowRunStore } from '../../../workflows/index.js';\nimport { extractProfileAgentId } from '../../../config/agent-profile.js';\nimport { resolveModelRef } from '../../../config/agent-typed-models.js';\nimport { resolveModel as resolveModelById } from '../../../providers/index.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst DEFAULT_WORKFLOW_CONCURRENCY = 4;\nconst DEFAULT_WORKFLOW_TIMEOUT_SEC = 30 * 60;\nconst DEFAULT_WORKFLOW_MAX_SUBAGENTS = 100;\n\nconst activeWorkflowRuns = new Map<string, AbortController>();\n\ninterface StartWorkflowRunRequestBody {\n definitionId?: string;\n input?: unknown;\n goal?: string;\n agentId?: string;\n sessionKey?: string;\n source?: WorkflowRunSource;\n concurrency?: number;\n maxSubagents?: number;\n tokenBudget?: number | null;\n}\n\ninterface SaveWorkflowDefinitionRequestBody {\n name?: string;\n script?: string;\n}\n\nexport function registerWorkflowRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/workflows/definitions', (c) => {\n const catalog = createWorkflowCatalog();\n const definitions = catalog.list().map((entry) => {\n try {\n return toWorkflowDefinition(catalog.load(entry.name));\n } catch {\n return null;\n }\n }).filter((definition): definition is WorkflowDefinition => Boolean(definition));\n\n return c.json({ definitions });\n });\n\n authenticated.get('/api/workflows/definitions/:id', (c) => {\n const id = c.req.param('id');\n const catalog = createWorkflowCatalog();\n try {\n const definition = toWorkflowDefinition(catalog.load(id));\n return c.json({ definition });\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Workflow definition not found' }, 404);\n }\n });\n\n authenticated.post('/api/workflows/definitions', async (c) => {\n const body = await readJsonBody<SaveWorkflowDefinitionRequestBody>(c.req.raw);\n const name = body.name?.trim();\n const script = body.script?.trim();\n if (!name) {\n return c.json({ error: 'name is required' }, 400);\n }\n if (!script) {\n return c.json({ error: 'script is required' }, 400);\n }\n\n const catalog = createWorkflowCatalog();\n try {\n catalog.save(name, script);\n const definition = toWorkflowDefinition(catalog.load(name));\n return c.json({ definition }, 201);\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Failed to save workflow' }, 400);\n }\n });\n\n authenticated.delete('/api/workflows/definitions/:id', (c) => {\n const id = c.req.param('id').trim();\n if (!id) {\n return c.json({ error: 'id is required' }, 400);\n }\n\n const catalog = createWorkflowCatalog();\n try {\n const removed = catalog.remove(id);\n if (!removed) {\n return c.json({ error: 'User workflow not found or cannot delete built-in workflow' }, 404);\n }\n return c.json({ removed: true });\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Failed to delete workflow' }, 400);\n }\n });\n\n authenticated.get('/api/workflows/stats', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runStore = createRunStore(service.currentConfig, agentId);\n const runs = await runStore.listRunSummaries(500);\n return c.json({ stats: buildWorkflowStats(runs) });\n });\n\n authenticated.post('/api/workflows/runs', async (c) => {\n const body = await readJsonBody<StartWorkflowRunRequestBody>(c.req.raw);\n const definitionId = body.definitionId?.trim();\n if (!definitionId) {\n return c.json({ error: 'definitionId is required' }, 400);\n }\n\n const agentId = getAgentId(body.agentId ?? c.req.query('agentId'), service.currentConfig);\n const sessionKey = body.sessionKey?.trim() || `workflow:${agentId}`;\n const runId = await queueWorkflowRun({\n deps,\n agentId,\n sessionKey,\n definitionId,\n input: body.input,\n goal: body.goal,\n source: body.source ?? { kind: 'webui' },\n concurrency: normalizePositiveInteger(body.concurrency),\n maxSubagents: normalizePositiveInteger(body.maxSubagents),\n tokenBudget: body.tokenBudget,\n });\n\n if (!runId) {\n return c.json({ error: 'Workflow definition not found' }, 404);\n }\n\n return c.json({ runId }, 202);\n });\n\n authenticated.get('/api/workflows/runs', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Number.parseInt(rawLimit, 10) : 50;\n const runStore = createRunStore(service.currentConfig, agentId);\n const runs = await runStore.listRunSummaries(Number.isFinite(limit) ? limit : 50);\n return c.json({ runs });\n });\n\n authenticated.post('/api/workflows/runs/:runId/cancel', async (c) => {\n const runId = c.req.param('runId');\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runStore = createRunStore(service.currentConfig, agentId);\n\n const controller = activeWorkflowRuns.get(runId);\n if (controller) {\n controller.abort();\n activeWorkflowRuns.delete(runId);\n return c.json({ cancelled: true });\n }\n\n const view = await runStore.readRunView(runId);\n if (!view) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n\n if (isTerminalWorkflowRunStatus(view.run.status)) {\n return c.json({ cancelled: true, alreadyFinished: true });\n }\n\n const eventStore = new WorkflowEventStore(service.currentConfig, agentId);\n await eventStore.append({\n runId,\n type: 'run_cancelled',\n payload: { reason: 'Cancelled by user' },\n });\n const updated = await runStore.rebuildRunView(runId);\n if (updated) {\n service.emit('workflow.run.updated', { runId, view: updated });\n }\n return c.json({ cancelled: true });\n });\n\n authenticated.get('/api/workflows/runs/:runId', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const runStore = createRunStore(service.currentConfig, agentId);\n const view = await runStore.readRunView(runId);\n if (!view) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n return c.json({ view });\n });\n\n authenticated.post('/api/workflows/runs/:runId/rebuild', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const runStore = createRunStore(service.currentConfig, agentId);\n const view = await runStore.rebuildRunView(runId);\n if (!view) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n service.emit('workflow.run.updated', { runId, view });\n return c.json({ view });\n });\n\n authenticated.post('/api/workflows/runs/:runId/retry', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const runStore = createRunStore(service.currentConfig, agentId);\n const existing = await runStore.readRunView(runId);\n if (!existing) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n\n const sessionKey = `workflow:${agentId}`;\n const newRunId = await queueWorkflowRun({\n deps,\n agentId,\n sessionKey,\n definitionId: existing.run.definitionId,\n input: existing.run.input,\n goal: existing.run.goal,\n source: { kind: 'webui' },\n });\n\n if (!newRunId) {\n return c.json({ error: 'Workflow definition not found' }, 404);\n }\n\n return c.json({ runId: newRunId }, 202);\n });\n}\n\nfunction createRunStore(config: AuthenticatedRouteDeps['service']['currentConfig'], agentId: string): WorkflowRunStore {\n const eventStore = new WorkflowEventStore(config, agentId);\n return new WorkflowRunStore(config, agentId, eventStore);\n}\n\nfunction getAgentId(rawAgentId: string | undefined, config: AuthenticatedRouteDeps['service']['currentConfig']): string {\n const trimmed = rawAgentId?.trim();\n if (trimmed) {\n return trimmed;\n }\n return resolveDefaultAgentId(config);\n}\n\nfunction toWorkflowDefinition(loaded: ReturnType<ReturnType<typeof createWorkflowCatalog>['load']>): WorkflowDefinition {\n const nowMs = Date.now();\n const phases = loaded.meta.phases?.map((phase, index) => ({\n id: normalizeId(phase.title) || `phase-${index + 1}`,\n title: phase.title,\n description: phase.detail,\n })) ?? [];\n\n return {\n id: loaded.name,\n name: loaded.name,\n title: toTitle(loaded.name),\n description: loaded.meta.description,\n version: '1.0.0',\n phases,\n runtime: {\n kind: 'script',\n source: loaded.script,\n },\n defaults: {\n concurrency: DEFAULT_WORKFLOW_CONCURRENCY,\n timeoutSec: DEFAULT_WORKFLOW_TIMEOUT_SEC,\n maxSubagents: loaded.meta.estimatedAgents?.max ?? DEFAULT_WORKFLOW_MAX_SUBAGENTS,\n },\n metadata: {\n tags: loaded.meta.tags ?? [],\n builtIn: loaded.source === 'builtin',\n source: loaded.source,\n whenToUse: loaded.meta.whenToUse,\n estimatedAgents: loaded.meta.estimatedAgents,\n examplePrompts: loaded.meta.examplePrompts,\n i18n: loaded.meta.i18n,\n createdAtMs: nowMs,\n updatedAtMs: nowMs,\n },\n };\n}\n\ninterface QueueWorkflowRunParams {\n deps: AuthenticatedRouteDeps;\n agentId: string;\n sessionKey: string;\n definitionId: string;\n input?: unknown;\n goal?: string;\n source: WorkflowRunSource;\n concurrency?: number;\n maxSubagents?: number;\n tokenBudget?: number | null;\n}\n\nasync function queueWorkflowRun(params: QueueWorkflowRunParams): Promise<string | null> {\n const { deps, agentId, sessionKey, definitionId } = params;\n const { service } = deps;\n const catalog = createWorkflowCatalog();\n let definition: WorkflowDefinition;\n try {\n definition = toWorkflowDefinition(catalog.load(definitionId));\n } catch {\n return null;\n }\n\n const eventStore = new WorkflowEventStore(service.currentConfig, agentId);\n const runStore = new WorkflowRunStore(service.currentConfig, agentId, eventStore);\n const runId = randomUUID();\n const abortController = new AbortController();\n const engine = createWorkflowEngine({\n deps,\n eventStore,\n runStore,\n sessionKey,\n });\n\n activeWorkflowRuns.set(runId, abortController);\n void engine.startRun(definition, {\n runId,\n input: params.input,\n goal: params.goal,\n source: params.source,\n signal: abortController.signal,\n concurrency: params.concurrency,\n maxSubagents: params.maxSubagents,\n tokenBudget: params.tokenBudget,\n }).catch((err) => {\n service.emit('workflow.run.error', {\n runId,\n error: err instanceof Error ? err.message : String(err),\n });\n }).finally(() => {\n activeWorkflowRuns.delete(runId);\n });\n\n return runId;\n}\n\nfunction buildWorkflowStats(runs: WorkflowRunSummary[]): {\n totalRuns: number;\n activeRuns: number;\n succeededRuns: number;\n failedRuns: number;\n averageDurationMs: number | null;\n topDefinitions: Array<{ definitionId: string; count: number }>;\n} {\n const activeStatuses = new Set(['queued', 'running']);\n const succeededStatuses = new Set(['succeeded']);\n const failedStatuses = new Set(['failed', 'timeout', 'cancelled']);\n\n let durationTotal = 0;\n let durationCount = 0;\n const definitionCounts = new Map<string, number>();\n\n for (const run of runs) {\n definitionCounts.set(run.definitionId, (definitionCounts.get(run.definitionId) ?? 0) + 1);\n if (run.metrics.durationMs != null && Number.isFinite(run.metrics.durationMs)) {\n durationTotal += run.metrics.durationMs;\n durationCount += 1;\n }\n }\n\n const topDefinitions = [...definitionCounts.entries()]\n .sort((left, right) => right[1] - left[1])\n .slice(0, 5)\n .map(([definitionId, count]) => ({ definitionId, count }));\n\n return {\n totalRuns: runs.length,\n activeRuns: runs.filter((run) => activeStatuses.has(run.status)).length,\n succeededRuns: runs.filter((run) => succeededStatuses.has(run.status)).length,\n failedRuns: runs.filter((run) => failedStatuses.has(run.status)).length,\n averageDurationMs: durationCount > 0 ? Math.round(durationTotal / durationCount) : null,\n topDefinitions,\n };\n}\n\nfunction createWorkflowEngine(params: {\n deps: AuthenticatedRouteDeps;\n eventStore: WorkflowEventStore;\n runStore: WorkflowRunStore;\n sessionKey: string;\n}): WorkflowEngine {\n const { service } = params.deps;\n const runner = new DelegateSubagentRunner({\n workspace: service.currentWorkspacePath,\n bus: service.messageBusInstance,\n getDefaultModel: () => resolveModelById(service.agentService.getModelForSession(params.sessionKey)),\n getConfig: () => service.currentConfig,\n buildChildTools: (childOptions) => buildWorkflowChildTools(childOptions),\n });\n\n return new WorkflowEngine({\n cwd: service.currentWorkspacePath,\n eventStore: params.eventStore,\n runStore: params.runStore,\n runner,\n resolveModelId: (modelId) => {\n const agentId = extractProfileAgentId(params.sessionKey, service.currentConfig);\n return resolveModelById(resolveModelRef(service.currentConfig, agentId, modelId));\n },\n onEventAppended: (event) => {\n service.emit('workflow.event.appended', { runId: event.runId, event });\n },\n onRunViewUpdated: (view) => {\n service.emit('workflow.run.updated', { runId: view.run.id, view });\n },\n });\n}\n\nfunction buildWorkflowChildTools(childOptions: BuildChildToolsOptions) {\n const childFactory = new AgentToolsFactory({\n workspace: childOptions.workspace,\n bus: childOptions.bus,\n getCurrentContext: () => null,\n getConfig: childOptions.getConfig,\n getPrimaryModel: () => childOptions.model,\n toolExecutorConfig: childOptions.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOptions.workspace,\n getPrimaryModel: () => childOptions.model,\n disabledTools: new Set(['extensions']),\n });\n}\n\nasync function readJsonBody<T>(request: Request): Promise<T> {\n try {\n return await request.json() as T;\n } catch {\n return {} as T;\n }\n}\n\nfunction normalizePositiveInteger(value: number | undefined): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {\n return undefined;\n }\n return Math.floor(value);\n}\n\nfunction normalizeId(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction toTitle(value: string): string {\n return value\n .split(/[_-]+/g)\n .filter(Boolean)\n .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)\n .join(' ');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"workflows.js","names":[],"sources":["../../../../../src/gateway/hono/routes/workflows.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { resolveDefaultAgentId } from '../../../agent/agent-scope.js';\nimport { createWorkflowCatalog } from '../../../agent/workflow/catalog.js';\nimport type {\n WorkflowDefinition,\n WorkflowRunInputEnvelope,\n WorkflowRunSource,\n WorkflowRunSummary,\n} from '../../../workflows/domain/index.js';\nimport { buildWorkflowDefinition, validateWorkflowDefinitionInput } from '../../../workflows/domain/index.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\ninterface StartWorkflowRunRequestBody {\n definitionId?: string;\n input?: unknown;\n inputEnvelope?: WorkflowRunInputEnvelope;\n goal?: string;\n agentId?: string;\n parentSessionKey?: string;\n source?: WorkflowRunSource;\n concurrency?: number;\n maxSubagents?: number;\n tokenBudget?: number | null;\n idempotencyKey?: string;\n}\n\ninterface SaveWorkflowDefinitionRequestBody {\n name?: string;\n script?: string;\n}\n\nexport function registerWorkflowRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n const workflowRunService = service.createWorkflowRunService();\n\n authenticated.get('/api/workflows/definitions', (c) => {\n const catalog = createWorkflowCatalog();\n const definitions = catalog.list().map((entry) => {\n try {\n return toWorkflowDefinition(catalog.load(entry.name));\n } catch {\n return null;\n }\n }).filter((definition): definition is WorkflowDefinition => Boolean(definition));\n\n return c.json({ definitions });\n });\n\n authenticated.get('/api/workflows/definitions/:id', (c) => {\n const id = c.req.param('id');\n const catalog = createWorkflowCatalog();\n try {\n const definition = toWorkflowDefinition(catalog.load(id));\n return c.json({ definition });\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Workflow definition not found' }, 404);\n }\n });\n\n authenticated.post('/api/workflows/definitions/validate', async (c) => {\n const body = await readJsonBody<SaveWorkflowDefinitionRequestBody>(c.req.raw);\n const result = validateWorkflowDefinitionInput({\n name: body.name,\n script: body.script,\n });\n return c.json(result);\n });\n\n authenticated.post('/api/workflows/definitions', async (c) => {\n const body = await readJsonBody<SaveWorkflowDefinitionRequestBody>(c.req.raw);\n const validation = validateWorkflowDefinitionInput({\n name: body.name,\n script: body.script,\n });\n if (!validation.valid) {\n return c.json({ error: validation.errors[0]?.message ?? 'Invalid workflow definition', validation }, 400);\n }\n\n const name = body.name?.trim() ?? '';\n const script = body.script ?? '';\n const catalog = createWorkflowCatalog();\n try {\n catalog.save(name, script);\n const definition = toWorkflowDefinition(catalog.load(name));\n return c.json({ definition }, 201);\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Failed to save workflow' }, 400);\n }\n });\n\n authenticated.delete('/api/workflows/definitions/:id', (c) => {\n const id = c.req.param('id').trim();\n if (!id) {\n return c.json({ error: 'id is required' }, 400);\n }\n\n const catalog = createWorkflowCatalog();\n try {\n const removed = catalog.remove(id);\n if (!removed) {\n return c.json({ error: 'User workflow not found or cannot delete built-in workflow' }, 404);\n }\n return c.json({ removed: true });\n } catch (err) {\n return c.json({ error: err instanceof Error ? err.message : 'Failed to delete workflow' }, 400);\n }\n });\n\n authenticated.get('/api/workflows/stats', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runStore = workflowRunService.createRunStore(agentId);\n const runs = await runStore.listRunSummaries(500);\n return c.json({ stats: buildWorkflowStats(runs) });\n });\n\n authenticated.post('/api/workflows/runs', async (c) => {\n const body = await readJsonBody<StartWorkflowRunRequestBody>(c.req.raw);\n const definitionId = body.definitionId?.trim();\n if (!definitionId) {\n return c.json({ error: 'definitionId is required' }, 400);\n }\n\n const agentId = getAgentId(body.agentId ?? c.req.query('agentId'), service.currentConfig);\n const parentSessionKey = body.parentSessionKey?.trim() || undefined;\n const result = await workflowRunService.startWorkflowRun({\n agentId,\n definitionId,\n input: body.input,\n inputEnvelope: body.inputEnvelope,\n goal: body.goal,\n parentSessionKey,\n source: normalizeWorkflowRunSource(body.source),\n concurrency: normalizePositiveInteger(body.concurrency),\n maxSubagents: normalizePositiveInteger(body.maxSubagents),\n tokenBudget: body.tokenBudget,\n idempotencyKey: body.idempotencyKey,\n });\n\n if (result.ok === false) {\n return c.json({ error: result.message, code: result.code }, result.httpStatus);\n }\n\n return c.json({ runId: result.runId, sessionKey: result.sessionKey }, 202);\n });\n\n authenticated.get('/api/workflows/runs', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Number.parseInt(rawLimit, 10) : 50;\n const runStore = workflowRunService.createRunStore(agentId);\n const runs = await runStore.listRunSummaries(Number.isFinite(limit) ? limit : 50);\n return c.json({ runs });\n });\n\n authenticated.post('/api/workflows/runs/:runId/cancel', async (c) => {\n const runId = c.req.param('runId');\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const result = await workflowRunService.cancelWorkflowRun({\n agentId,\n runId,\n reason: 'Cancelled by user',\n });\n if (result.ok === false) {\n return c.json({ error: result.message, code: result.code }, result.httpStatus);\n }\n return c.json({\n cancelled: result.cancelled,\n alreadyFinished: result.alreadyFinished,\n });\n });\n\n authenticated.get('/api/workflows/runs/:runId', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const runStore = workflowRunService.createRunStore(agentId);\n const view = await runStore.readRunView(runId);\n if (!view) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n return c.json({ view });\n });\n\n authenticated.post('/api/workflows/runs/:runId/rebuild', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const runStore = workflowRunService.createRunStore(agentId);\n const view = await runStore.rebuildRunView(runId);\n if (!view) {\n return c.json({ error: 'Workflow run not found' }, 404);\n }\n service.emit('workflow.run.updated', { runId, view });\n return c.json({ view });\n });\n\n authenticated.post('/api/workflows/runs/:runId/retry', async (c) => {\n const agentId = getAgentId(c.req.query('agentId'), service.currentConfig);\n const runId = c.req.param('runId');\n const result = await workflowRunService.retryWorkflowRun({ agentId, runId });\n if (result.ok === false) {\n return c.json({ error: result.message, code: result.code }, result.httpStatus);\n }\n\n return c.json({ runId: result.runId, sessionKey: result.sessionKey }, 202);\n });\n}\n\nfunction getAgentId(rawAgentId: string | undefined, config: AuthenticatedRouteDeps['service']['currentConfig']): string {\n const trimmed = rawAgentId?.trim();\n if (trimmed) {\n return trimmed;\n }\n return resolveDefaultAgentId(config);\n}\n\nfunction toWorkflowDefinition(loaded: ReturnType<ReturnType<typeof createWorkflowCatalog>['load']>): WorkflowDefinition {\n return buildWorkflowDefinition({\n name: loaded.name,\n source: loaded.source,\n script: loaded.script,\n meta: loaded.meta,\n });\n}\n\nfunction buildWorkflowStats(runs: WorkflowRunSummary[]): {\n totalRuns: number;\n activeRuns: number;\n succeededRuns: number;\n failedRuns: number;\n averageDurationMs: number | null;\n topDefinitions: Array<{ definitionId: string; count: number }>;\n} {\n const activeStatuses = new Set(['queued', 'running']);\n const succeededStatuses = new Set(['succeeded']);\n const failedStatuses = new Set(['failed', 'timeout', 'cancelled']);\n\n let durationTotal = 0;\n let durationCount = 0;\n const definitionCounts = new Map<string, number>();\n\n for (const run of runs) {\n definitionCounts.set(run.definitionId, (definitionCounts.get(run.definitionId) ?? 0) + 1);\n if (run.metrics.durationMs != null && Number.isFinite(run.metrics.durationMs)) {\n durationTotal += run.metrics.durationMs;\n durationCount += 1;\n }\n }\n\n const topDefinitions = [...definitionCounts.entries()]\n .sort((left, right) => right[1] - left[1])\n .slice(0, 5)\n .map(([definitionId, count]) => ({ definitionId, count }));\n\n return {\n totalRuns: runs.length,\n activeRuns: runs.filter((run) => activeStatuses.has(run.status)).length,\n succeededRuns: runs.filter((run) => succeededStatuses.has(run.status)).length,\n failedRuns: runs.filter((run) => failedStatuses.has(run.status)).length,\n averageDurationMs: durationCount > 0 ? Math.round(durationTotal / durationCount) : null,\n topDefinitions,\n };\n}\n\nasync function readJsonBody<T>(request: Request): Promise<T> {\n try {\n return await request.json() as T;\n } catch {\n return {} as T;\n }\n}\n\nfunction normalizeWorkflowRunSource(source: WorkflowRunSource | undefined): WorkflowRunSource {\n if (!source) {\n return { kind: 'webui' };\n }\n return source;\n}\n\nfunction normalizePositiveInteger(value: number | undefined): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {\n return undefined;\n }\n return Math.floor(value);\n}\n\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { createLogger } from "../../../utils/logger/index.js";
2
- import { init_logger } from "../../../utils/logger.js";
3
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentHomeDir, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
4
2
  import { extractProfileAgentId } from "../../../config/agent-profile.js";
3
+ import { createLogger } from "../../../utils/logger/index.js";
4
+ import { init_logger } from "../../../utils/logger.js";
5
5
  import { validateWritePath } from "../../../agent/sandbox/path-policy.js";
6
6
  import { isPathUnderWorkspace, resolveWorkspaceSafePath, toWorkspaceRelativePosix } from "../../workspace-editor-path.js";
7
7
  import { resolveSafeInboundFilePath } from "../../../channels/attachments/inbound-persist.js";
@@ -12,10 +12,10 @@ import { fileReferenceRegistry } from "../../file-reference-registry.js";
12
12
  import { resolveHeartbeatMdPath } from "../../workspace-heartbeat-path.js";
13
13
  import { listWorkspaceRelativeFilesFsFallback } from "../../workspace-fs-file-list.js";
14
14
  import { runRipgrepInDirectory, runRipgrepListFiles } from "../../workspace-ripgrep.js";
15
- import { randomUUID } from "node:crypto";
15
+ import { basename, dirname, join, resolve } from "node:path";
16
16
  import { constants } from "node:fs";
17
+ import { randomUUID } from "node:crypto";
17
18
  import { copyFile, link, mkdir, readFile, readdir, rename, stat, unlink, writeFile } from "node:fs/promises";
18
- import { basename, dirname, join, resolve } from "node:path";
19
19
  //#region src/gateway/hono/routes/workspace.ts
20
20
  init_agent_scope();
21
21
  init_logger();
@@ -1,8 +1,8 @@
1
- import { createHash } from "node:crypto";
2
- import fs from "node:fs";
3
- import fs$1 from "node:fs/promises";
4
1
  import path from "node:path";
5
2
  import net from "node:net";
3
+ import fs from "node:fs";
4
+ import { createHash } from "node:crypto";
5
+ import fs$1 from "node:fs/promises";
6
6
  import { homedir } from "os";
7
7
  //#region src/gateway/lock.ts
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import fs from "node:fs";
4
3
  import net from "node:net";
4
+ import fs from "node:fs";
5
5
  import { execFileSync } from "node:child_process";
6
6
  //#region src/gateway/ports.ts
7
7
  /**
@@ -1,7 +1,7 @@
1
- import { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
3
1
  import { buildSessionKey, init_session_key, parseSessionKey } from "../../routing/session-key.js";
4
2
  import { getDefaultAgentId, init_resolve_route } from "../../routing/resolve-route.js";
3
+ import { createLogger } from "../../utils/logger/index.js";
4
+ import { init_logger } from "../../utils/logger.js";
5
5
  import { AgentRunRelay } from "../agent-run-relay.js";
6
6
  import { ClarifyBridge } from "../clarify-bridge.js";
7
7
  import { runGatewayAgent } from "./run-gateway-agent.js";
@@ -1,6 +1,6 @@
1
+ import { resolveStateDir } from "../../config/paths-state.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { resolveStateDir } from "../../config/paths-state.js";
4
4
  import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
5
5
  import { createSkillConfigManager } from "../../agent/skills/config.js";
6
6
  import { removeSkillsLockEntry } from "../../agent/skills/hub-lock.js";
@@ -11,8 +11,8 @@ import { installExtensionFromStoreZip, peekExtensionIdFromStoreZip } from "../..
11
11
  import { downloadExtensionStoreZipBuffer, fetchMarketplacePackageDetail, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
12
12
  import { getMarketplaceProviderDisplayName, resolveSkillsMarketplaceProvider } from "../../agent/skills/marketplace/resolve-adapter.js";
13
13
  import { downloadFromMarketplace, getMarketplacePackageDetail, listMarketplaceCategories, listMarketplacePackages } from "../../agent/skills/skills-marketplace.js";
14
- import { existsSync, mkdirSync, rmSync } from "node:fs";
15
14
  import { join } from "node:path";
15
+ import { existsSync, mkdirSync, rmSync } from "node:fs";
16
16
  //#region src/gateway/service/marketplace-service.ts
17
17
  /**
18
18
  * GatewayMarketplaceService — install / browse / remove for the two marketplaces
@@ -1,6 +1,7 @@
1
1
  import { AgentService } from '../agent/service.js';
2
2
  import { MessageBus } from '../infra/bus/index.js';
3
3
  import { CronService } from '../cron/index.js';
4
+ import { WorkflowRunService } from '../workflows/service/workflow-run-service.js';
4
5
  import { ExtensionLoader } from '../extensions/index.js';
5
6
  import { SessionIndex } from '../session/index.js';
6
7
  import type { Config } from '../config/schema.js';
@@ -43,6 +44,8 @@ export declare class GatewayService {
43
44
  private lastChannelConnectDeferSource;
44
45
  private readonly readiness;
45
46
  private startupTrace;
47
+ private workflowSessionBridge;
48
+ private workflowRunServiceInstance;
46
49
  /**
47
50
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
48
51
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -216,6 +219,8 @@ export declare class GatewayService {
216
219
  getEffectiveListenPort(): number;
217
220
  get cronServiceInstance(): CronService;
218
221
  get sessionIndexInstance(): SessionIndex;
222
+ /** Shared workflow run orchestrator + session bridge (one instance per gateway). */
223
+ createWorkflowRunService(): WorkflowRunService;
219
224
  /** Process a message directly through the agent (for CLI mode). */
220
225
  processDirect(content: string, sessionKey?: string): Promise<string>;
221
226
  subscribe(sessionId: string, listener: (event: ServiceEvent) => Promise<void> | void): () => void;
@@ -1,12 +1,12 @@
1
1
  import { __toCommonJS } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
3
+ import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
3
4
  import { getLogDir } from "../utils/logger/config.js";
4
5
  import { getLogStats } from "../utils/logger/stats.js";
5
6
  import { createLogger } from "../utils/logger/index.js";
6
7
  import { init_logger } from "../utils/logger.js";
7
8
  import { init_paths, resolveAgentDir, resolveConfigPath, resolveCronJobsPath, resolveExtensionsDir } from "../config/paths.js";
8
9
  import { loadConfig, saveConfig } from "../config/loader.js";
9
- import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
10
10
  import { prewarmModelRegistry } from "../providers/model-registry.js";
11
11
  import { init_providers, providers_exports } from "../providers/index.js";
12
12
  import { resolveEffectiveGatewayPort } from "./host.js";
@@ -30,6 +30,9 @@ import "../config/index.js";
30
30
  import { CronService } from "../cron/service.js";
31
31
  import "../cron/index.js";
32
32
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
33
+ import { buildWorkflowChildTools } from "../agent/workflow/workflow-child-tools.js";
34
+ import { WorkflowRunService } from "../workflows/service/workflow-run-service.js";
35
+ import { WorkflowSessionBridge } from "../workflows/service/workflow-session-bridge.js";
33
36
  import { HeartbeatService, heartbeatRunnerConfigFromConfig } from "./heartbeat/service.js";
34
37
  import "./heartbeat/index.js";
35
38
  import { wireTunnelEventsToGateway } from "../tunnel/gateway-lifecycle.js";
@@ -90,6 +93,8 @@ var GatewayService = class {
90
93
  lastChannelConnectDeferSource = "off";
91
94
  readiness = new GatewayReadiness();
92
95
  startupTrace = null;
96
+ workflowSessionBridge = null;
97
+ workflowRunServiceInstance = null;
93
98
  /**
94
99
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
95
100
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -222,6 +227,7 @@ var GatewayService = class {
222
227
  },
223
228
  extensionRegistry: this.extensionLoader?.getRegistry(),
224
229
  getCronService: () => cronRef.service,
230
+ getWorkflowRunService: () => this.createWorkflowRunService(),
225
231
  gatewayClarify: { requestClarification: (sessionKey, request) => this.agentRunner.requestClarification({
226
232
  sessionKey,
227
233
  request,
@@ -240,7 +246,8 @@ var GatewayService = class {
240
246
  messageBus: this.bus,
241
247
  heartbeatService: this.ensureHeartbeatService(),
242
248
  sessionStore: this.sessionIndex.getStore(),
243
- getDefaultCronAgentId: () => getDefaultAgentId(this.config)
249
+ getDefaultCronAgentId: () => getDefaultAgentId(this.config),
250
+ workflowRunService: this.createWorkflowRunService()
244
251
  });
245
252
  cronRef.service = this.cronService;
246
253
  this._agentService.persistentGoals.setWebchatContinuationScheduler((sessionKey, message) => {
@@ -453,7 +460,8 @@ var GatewayService = class {
453
460
  messageBus: this.bus,
454
461
  heartbeatService: this.ensureHeartbeatService(),
455
462
  sessionStore: this.sessionIndex.getStore(),
456
- getDefaultCronAgentId: () => getDefaultAgentId(this.config)
463
+ getDefaultCronAgentId: () => getDefaultAgentId(this.config),
464
+ workflowRunService: this.createWorkflowRunService()
457
465
  });
458
466
  this.sessionIndex.on("sessionUpdated", (data) => {
459
467
  this.emit("session.updated", {
@@ -920,6 +928,18 @@ var GatewayService = class {
920
928
  get sessionIndexInstance() {
921
929
  return this.sessionIndex;
922
930
  }
931
+ /** Shared workflow run orchestrator + session bridge (one instance per gateway). */
932
+ createWorkflowRunService() {
933
+ if (!this.workflowRunServiceInstance) {
934
+ this.workflowSessionBridge = new WorkflowSessionBridge(this);
935
+ this.workflowRunServiceInstance = new WorkflowRunService({
936
+ service: this,
937
+ sessionBridge: this.workflowSessionBridge,
938
+ buildChildTools: buildWorkflowChildTools
939
+ });
940
+ }
941
+ return this.workflowRunServiceInstance;
942
+ }
923
943
  /** Process a message directly through the agent (for CLI mode). */
924
944
  async processDirect(content, sessionKey = "agent:main:main") {
925
945
  return this.agentService.turnDispatcher.processDirect(content, sessionKey);