@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 +1 @@
1
- {"version":3,"file":"model.js","names":[],"sources":["../../../../../src/cli/commands/onboard/model.ts"],"sourcesContent":["/**\n * Model Configuration for Onboarding\n */\n\nimport { input, select, confirm } from '@inquirer/prompts';\nimport type { Config } from '../../../config/schema.js';\nimport type { CLIContext } from '../../registry.js';\nimport { colors } from '../../utils/colors.js';\nimport {\n getModelsByProvider,\n getSortedProviders,\n getProviderDisplayName,\n providerSupportsOAuth,\n providerSupportsApiKey,\n} from '../../../providers/index.js';\nimport { listProfilesForProvider } from '../../../auth/profiles/index.js';\nimport { upsertAuthProfile } from '../../../auth/profiles/index.js';\nimport { getOAuthProvider } from '../../utils/oauth-providers.js';\nimport type { OAuthLoginCallbacks } from '../../../auth/index.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { getApiKeyFromEnv } from '../../../providers/env-keys.js';\n\n/**\n * Get available models for a provider\n */\nasync function getModelsForProvider(provider: string): Promise<{ value: string; name: string }[]> {\n const models = getModelsByProvider(provider);\n return models.map((m) => ({\n value: `${m.provider}/${m.id}`,\n name: m.name || m.id,\n }));\n}\n\n/**\n * Perform OAuth login for a provider\n */\nasync function doOAuthLogin(provider: string): Promise<boolean> {\n const config = getOAuthProvider(provider);\n if (!config) {\n console.error(`OAuth not supported for provider: ${provider}`);\n return false;\n }\n\n console.log(`\\n🔐 Starting ${config.displayName} OAuth login...`);\n\n const callbacks: OAuthLoginCallbacks = {\n onAuth: (info) => {\n console.log(`\\n${config.urlPrompt}`);\n console.log(info.url);\n if (info.instructions) {\n console.log('\\n' + info.instructions);\n }\n console.log('\\n');\n },\n onPrompt: async (prompt) => {\n return input({ message: prompt.message });\n },\n onProgress: (message) => {\n console.log(' →', message);\n },\n };\n\n try {\n const creds = await config.provider.login(callbacks);\n upsertAuthProfile({\n profileId: config.profileId,\n credential: {\n type: 'oauth',\n provider,\n ...creds,\n },\n });\n return true;\n } catch (error) {\n console.error('❌ OAuth login failed:', error);\n return false;\n }\n}\n\n/**\n * Configure AI model provider and model\n */\nexport async function setupModel(\n existingConfig: Config | null,\n ctx: CLIContext\n): Promise<Config> {\n console.log('\\n🤖 Step: AI Model\\n');\n\n const config = existingConfig || ({} as Config);\n const currentModelConfig = config?.agents?.defaults?.model;\n const currentModel =\n typeof currentModelConfig === 'string' ? currentModelConfig : currentModelConfig?.primary;\n\n if (currentModel) {\n console.log('Current model:', currentModel);\n const keepCurrent = await confirm({\n message: 'Keep using this model?',\n default: true,\n });\n if (keepCurrent) {\n console.log('✅ Keeping:', currentModel);\n return config;\n }\n }\n\n // Get sorted providers with metadata\n const sortedProviders = getSortedProviders();\n\n const choices = sortedProviders.map((p) => ({\n value: p,\n name: getProviderDisplayName(p),\n }));\n\n const provider = await select({\n message: 'Select provider:',\n choices,\n });\n\n const providerName = getProviderDisplayName(provider);\n\n // Check if provider has existing profiles\n const existingProfiles = listProfilesForProvider(provider);\n if (existingProfiles.length > 0) {\n console.log(`\\n${colors.green('✓')} Found existing credentials for ${providerName}`);\n const useExisting = await confirm({\n message: 'Use existing credentials?',\n default: true,\n });\n\n if (useExisting) {\n // Get available models\n const modelChoices = await getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n console.log(`\\n⚠️ No models found for ${providerName}. Please check your credentials.`);\n } else {\n const model = await select({\n message: 'Select model:',\n choices: modelChoices,\n });\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: model, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: model, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', model);\n return config;\n }\n }\n }\n\n let apiKey: string | undefined;\n let useOAuth = false;\n\n apiKey = getApiKeyFromEnv(provider);\n if (apiKey) {\n console.log(`\\n${colors.green('✓')} Found API key for ${providerName} in environment`);\n }\n\n if (!apiKey) {\n // Check auth support from metadata\n const supportsOAuth = providerSupportsOAuth(provider);\n const supportsApiKey = providerSupportsApiKey(provider);\n const isOAuthOnly = supportsOAuth && !supportsApiKey;\n\n if (isOAuthOnly) {\n // OAuth only - no choice\n const success = await doOAuthLogin(provider);\n if (success) {\n useOAuth = true;\n console.log('\\n✅ OAuth login successful!');\n } else {\n console.error('\\n❌ OAuth login failed. This provider requires OAuth.');\n return config;\n }\n } else if (supportsOAuth && supportsApiKey) {\n // Dual auth - let user choose\n const authMethod = await select({\n message: `How would you like to authenticate with ${providerName}?`,\n choices: [\n { value: 'api_key', name: 'API Key (enter manually)' },\n { value: 'oauth', name: 'OAuth Login (browser-based)' },\n ],\n });\n\n if (authMethod === 'oauth') {\n const success = await doOAuthLogin(provider);\n if (success) {\n useOAuth = true;\n console.log('\\n✅ OAuth login successful!');\n } else {\n console.log('\\n⚠️ OAuth login failed. Please enter API key manually.');\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n useOAuth = false;\n }\n } else {\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n }\n } else {\n // API key only\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n }\n }\n\n // Get available models\n const modelChoices = await getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n console.log(`\\n⚠️ No built-in models found for ${providerName}.`);\n console.log(' You can still use custom model names.');\n const model = await input({\n message: 'Model name:',\n validate: (v: string) => v.length > 0 || 'Required',\n });\n\n // Store API key in new credential system\n if (apiKey) {\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey, { profileName: 'default' });\n }\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: `${provider}/${model}`, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: `${provider}/${model}`, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', `${provider}/${model}`);\n return config;\n }\n\n console.log(`\\n📋 Available models for ${providerName}:`);\n const model = await select({\n message: 'Select model:',\n choices: modelChoices,\n });\n\n // Store in new credential system\n if (!useOAuth && apiKey) {\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey, { profileName: 'default' });\n }\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: model, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: model, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', model);\n return config;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"model.js","names":[],"sources":["../../../../../src/cli/commands/onboard/model.ts"],"sourcesContent":["/**\n * Model Configuration for Onboarding\n */\n\nimport { input, select, confirm } from '@inquirer/prompts';\nimport type { Config } from '../../../config/schema.js';\nimport type { CLIContext } from '../../registry.js';\nimport { colors } from '../../utils/colors.js';\nimport {\n getModelsByProvider,\n getSortedProviders,\n getProviderDisplayName,\n providerSupportsOAuth,\n providerSupportsApiKey,\n} from '../../../providers/index.js';\nimport { listProfilesForProvider } from '../../../auth/profiles/index.js';\nimport { upsertAuthProfile } from '../../../auth/profiles/index.js';\nimport { getOAuthProvider } from '../../utils/oauth-providers.js';\nimport type { OAuthLoginCallbacks } from '../../../auth/index.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { getApiKeyFromEnv } from '../../../providers/env-keys.js';\n\n/**\n * Get available models for a provider\n */\nasync function getModelsForProvider(provider: string): Promise<{ value: string; name: string }[]> {\n const models = getModelsByProvider(provider);\n return models.map((m) => ({\n value: `${m.provider}/${m.id}`,\n name: m.name || m.id,\n }));\n}\n\n/**\n * Perform OAuth login for a provider\n */\nasync function doOAuthLogin(provider: string): Promise<boolean> {\n const config = getOAuthProvider(provider);\n if (!config) {\n console.error(`OAuth not supported for provider: ${provider}`);\n return false;\n }\n\n console.log(`\\n🔐 Starting ${config.displayName} OAuth login...`);\n\n const callbacks: OAuthLoginCallbacks = {\n onAuth: (info) => {\n console.log(`\\n${config.urlPrompt}`);\n console.log(info.url);\n if (info.instructions) {\n console.log('\\n' + info.instructions);\n }\n console.log('\\n');\n },\n onDeviceCode: (info) => {\n console.log(`\\nOpen ${info.verificationUri} and enter code ${info.userCode}\\n`);\n },\n onPrompt: async (prompt) => {\n return input({ message: prompt.message });\n },\n onProgress: (message) => {\n console.log(' →', message);\n },\n onSelect: async (prompt) => {\n const browserOption = prompt.options.find((option) => option.id === 'browser');\n return browserOption?.id ?? prompt.options[0]?.id;\n },\n };\n\n try {\n const creds = await config.provider.login(callbacks);\n upsertAuthProfile({\n profileId: config.profileId,\n credential: {\n type: 'oauth',\n provider,\n ...creds,\n },\n });\n return true;\n } catch (error) {\n console.error('❌ OAuth login failed:', error);\n return false;\n }\n}\n\n/**\n * Configure AI model provider and model\n */\nexport async function setupModel(\n existingConfig: Config | null,\n ctx: CLIContext\n): Promise<Config> {\n console.log('\\n🤖 Step: AI Model\\n');\n\n const config = existingConfig || ({} as Config);\n const currentModelConfig = config?.agents?.defaults?.model;\n const currentModel =\n typeof currentModelConfig === 'string' ? currentModelConfig : currentModelConfig?.primary;\n\n if (currentModel) {\n console.log('Current model:', currentModel);\n const keepCurrent = await confirm({\n message: 'Keep using this model?',\n default: true,\n });\n if (keepCurrent) {\n console.log('✅ Keeping:', currentModel);\n return config;\n }\n }\n\n // Get sorted providers with metadata\n const sortedProviders = getSortedProviders();\n\n const choices = sortedProviders.map((p) => ({\n value: p,\n name: getProviderDisplayName(p),\n }));\n\n const provider = await select({\n message: 'Select provider:',\n choices,\n });\n\n const providerName = getProviderDisplayName(provider);\n\n // Check if provider has existing profiles\n const existingProfiles = listProfilesForProvider(provider);\n if (existingProfiles.length > 0) {\n console.log(`\\n${colors.green('✓')} Found existing credentials for ${providerName}`);\n const useExisting = await confirm({\n message: 'Use existing credentials?',\n default: true,\n });\n\n if (useExisting) {\n // Get available models\n const modelChoices = await getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n console.log(`\\n⚠️ No models found for ${providerName}. Please check your credentials.`);\n } else {\n const model = await select({\n message: 'Select model:',\n choices: modelChoices,\n });\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: model, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: model, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', model);\n return config;\n }\n }\n }\n\n let apiKey: string | undefined;\n let useOAuth = false;\n\n apiKey = getApiKeyFromEnv(provider);\n if (apiKey) {\n console.log(`\\n${colors.green('✓')} Found API key for ${providerName} in environment`);\n }\n\n if (!apiKey) {\n // Check auth support from metadata\n const supportsOAuth = providerSupportsOAuth(provider);\n const supportsApiKey = providerSupportsApiKey(provider);\n const isOAuthOnly = supportsOAuth && !supportsApiKey;\n\n if (isOAuthOnly) {\n // OAuth only - no choice\n const success = await doOAuthLogin(provider);\n if (success) {\n useOAuth = true;\n console.log('\\n✅ OAuth login successful!');\n } else {\n console.error('\\n❌ OAuth login failed. This provider requires OAuth.');\n return config;\n }\n } else if (supportsOAuth && supportsApiKey) {\n // Dual auth - let user choose\n const authMethod = await select({\n message: `How would you like to authenticate with ${providerName}?`,\n choices: [\n { value: 'api_key', name: 'API Key (enter manually)' },\n { value: 'oauth', name: 'OAuth Login (browser-based)' },\n ],\n });\n\n if (authMethod === 'oauth') {\n const success = await doOAuthLogin(provider);\n if (success) {\n useOAuth = true;\n console.log('\\n✅ OAuth login successful!');\n } else {\n console.log('\\n⚠️ OAuth login failed. Please enter API key manually.');\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n useOAuth = false;\n }\n } else {\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n }\n } else {\n // API key only\n apiKey = await input({\n message: `API Key for ${providerName}:`,\n validate: (v: string) => v.length > 0 || 'Required',\n });\n }\n }\n\n // Get available models\n const modelChoices = await getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n console.log(`\\n⚠️ No built-in models found for ${providerName}.`);\n console.log(' You can still use custom model names.');\n const model = await input({\n message: 'Model name:',\n validate: (v: string) => v.length > 0 || 'Required',\n });\n\n // Store API key in new credential system\n if (apiKey) {\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey, { profileName: 'default' });\n }\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: `${provider}/${model}`, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: `${provider}/${model}`, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', `${provider}/${model}`);\n return config;\n }\n\n console.log(`\\n📋 Available models for ${providerName}:`);\n const model = await select({\n message: 'Select model:',\n choices: modelChoices,\n });\n\n // Store in new credential system\n if (!useOAuth && apiKey) {\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey, { profileName: 'default' });\n }\n\n config.agents = config.agents || {};\n config.agents.defaults = config.agents.defaults || {\n workspace: ctx.workspacePath,\n model: { primary: model, fallbacks: [] },\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n };\n config.agents.defaults.model = { primary: model, fallbacks: [] };\n config.agents.defaults.workspace = ctx.workspacePath;\n\n console.log('\\n✅ Model configured:', model);\n return config;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { ConfigSchema, init_schema } from "../../config/schema.js";
1
2
  import { init_agent_scope, resolveAgentProfileDir, resolveDefaultAgentId } from "../../agent/agent-scope.js";
2
3
  import { WORKSPACE_FILES, init_paths } from "../../config/paths.js";
3
- import { ConfigSchema, init_schema } from "../../config/schema.js";
4
4
  import { saveConfig } from "../../config/loader.js";
5
5
  import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
6
6
  import { isWeixinOnboardConfigured } from "../../../extensions/weixin/src/adapters/onboard-cli.js";
@@ -1,8 +1,8 @@
1
1
  import { ConfigSchema, init_schema } from "../../config/schema.js";
2
2
  import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
3
- import { randomBytes } from "node:crypto";
4
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
5
3
  import { dirname, join } from "node:path";
4
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
5
+ import { randomBytes } from "node:crypto";
6
6
  //#region src/cli/utils/init-workspace-core.ts
7
7
  init_schema();
8
8
  init_loader();
@@ -1,5 +1,5 @@
1
- import { init_agent_scope, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
2
1
  import { getAgentDefaultModelRef, init_schema } from "./schema.js";
2
+ import { init_agent_scope, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
3
3
  import { init_session_key, parseSessionKey } from "../routing/session-key.js";
4
4
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
5
5
  //#region src/config/agent-profile.ts
@@ -1,5 +1,5 @@
1
- import { init_agent_scope, listAgentEntries } from "../agent/agent-scope.js";
2
1
  import { init_schema, parseModelRef } from "./schema.js";
2
+ import { init_agent_scope, listAgentEntries } from "../agent/agent-scope.js";
3
3
  //#region src/config/agent-typed-models.ts
4
4
  init_agent_scope();
5
5
  init_schema();
@@ -1,7 +1,7 @@
1
1
  import { getTailnetIPv4Sync } from "../infra/tailscale.js";
2
2
  import { isLoopbackHost } from "../gateway/host.js";
3
- import { existsSync } from "node:fs";
4
3
  import net from "node:net";
4
+ import { existsSync } from "node:fs";
5
5
  //#region src/config/gateway-bind.ts
6
6
  function resolveGatewayBindMode(cfg, bindOverride) {
7
7
  if (bindOverride) return bindOverride;
@@ -1,15 +1,15 @@
1
+ import { TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema } from "../../extensions/telegram/src/config-schema.js";
2
+ import { WeixinAccountConfigSchema, WeixinConfigSchema } from "../../extensions/weixin/src/config-schema.js";
3
+ import { AgentConfigSchema, AgentDefaultsSchema, AgentImageGenerationModelSchema, AgentModelRefSchema, AgentTypedModelSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigSchema, CronConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GoalsConfigSchema, HeartbeatConfigSchema, McpConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelsDevConfigSchema, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, getAgentDefaultModelRef, init_schema, parseModelRef } from "./schema.js";
4
+ import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
1
5
  import { ENV_VARS, resolveHomeDir, resolveStateDir } from "./paths-state.js";
2
6
  import { expandWorkspacePathString, init_workspace_path, normalizeWorkspaceDir, resolveWorkspaceRoot } from "./workspace-path.js";
3
7
  import { resolveDefaultAgentWorkspaceDir } from "./workspace-defaults.js";
4
8
  import { resolveAgentDir as resolveAgentDir$1, resolveAgentHomeDir as resolveAgentHomeDir$1, resolveAgentWorkspaceDir, resolveSessionsDir as resolveSessionsDir$1 } from "../agent/agent-scope.js";
9
+ import { extractProfileAgentId, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
5
10
  import { resolveSessionFilePath, resolveSessionTranscriptPathInDir } from "../session/parity/transcript-paths.js";
6
11
  import { FILENAMES, WORKSPACE_FILES, existsSync, init_paths, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentHomeDir, resolveAgentMetadataPath, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveCredentialsDir, resolveCronDir, resolveCronJobsPath, resolveCronLogPath, resolveCronLogsDir, resolveCronRunsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMemoryDir, resolveMemoryPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveSessionTranscriptPath, resolveSessionsArchiveDir, resolveSessionsDir, resolveSessionsMapPath, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath } from "./paths.js";
7
- import { TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema } from "../../extensions/telegram/src/config-schema.js";
8
- import { WeixinAccountConfigSchema, WeixinConfigSchema } from "../../extensions/weixin/src/config-schema.js";
9
- import { AgentConfigSchema, AgentDefaultsSchema, AgentImageGenerationModelSchema, AgentModelRefSchema, AgentTypedModelSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigSchema, CronConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GoalsConfigSchema, HeartbeatConfigSchema, McpConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelsDevConfigSchema, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, getAgentDefaultModelRef, init_schema, parseModelRef } from "./schema.js";
10
12
  import { init_loader, loadConfig, registerChannelConfigValidator, saveConfig } from "./loader.js";
11
- import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
12
- import { extractProfileAgentId, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
13
13
  import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
14
14
  import { CustomModelSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
15
15
  import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
@@ -1,9 +1,9 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
2
+ import { ConfigSchema, init_schema } from "./schema.js";
3
3
  import { createLogger } from "../utils/logger/index.js";
4
4
  import { init_logger } from "../utils/logger.js";
5
5
  import { init_paths, resolveConfigPath } from "./paths.js";
6
- import { ConfigSchema, init_schema } from "./schema.js";
6
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
7
7
  import { dirname } from "path";
8
8
  import { existsSync, mkdirSync, promises, readFileSync } from "fs";
9
9
  import { config } from "dotenv";
@@ -1,8 +1,8 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
3
2
  import { init_paths, resolveModelsJsonPath } from "./paths.js";
4
- import { existsSync, readFileSync } from "fs";
3
+ import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
5
4
  import { z } from "zod";
5
+ import { existsSync, readFileSync } from "fs";
6
6
  //#region src/config/models-json.ts
7
7
  /**
8
8
  * Models.json configuration types and schema
@@ -1,6 +1,6 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { join } from "node:path";
3
2
  import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
4
  //#region src/config/paths-state.ts
5
5
  function resolveHomeDir(env = process.env) {
6
6
  return env[ENV_VARS.HOME] || homedir();
@@ -1,9 +1,9 @@
1
+ import { ENV_VARS, init_paths_state, resolveHomeDir } from "./paths-state.js";
1
2
  import { createLogger } from "../utils/logger/index.js";
2
3
  import { init_logger } from "../utils/logger.js";
3
- import { ENV_VARS, init_paths_state, resolveHomeDir } from "./paths-state.js";
4
- import { mkdir, readdir, rm, stat } from "fs/promises";
5
4
  import { join } from "path";
6
5
  import { existsSync } from "fs";
6
+ import { mkdir, readdir, rm, stat } from "fs/promises";
7
7
  //#region src/config/profile.ts
8
8
  init_logger();
9
9
  init_paths_state();
@@ -1,6 +1,6 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { parse, resolve } from "node:path";
3
2
  import { homedir } from "node:os";
3
+ import { parse, resolve } from "node:path";
4
4
  //#region src/config/workspace-path.ts
5
5
  /** Expand leading `~` to the user home directory. */
6
6
  function expandWorkspacePathString(raw) {
@@ -9,6 +9,7 @@ export declare class DefaultJobExecutor implements JobExecutor {
9
9
  private sessionStore;
10
10
  private runLogStore;
11
11
  private getDefaultCronAgentId;
12
+ private workflowRunService;
12
13
  setRunLogStore(store: CronRunLogStore | null): void;
13
14
  setDeps(deps: JobExecutorDeps): void;
14
15
  private buildCronOutboundMessage;
@@ -17,6 +18,7 @@ export declare class DefaultJobExecutor implements JobExecutor {
17
18
  * Perform the actual job work - integrate with AgentService
18
19
  */
19
20
  protected performJob(job: JobData, signal: AbortSignal): Promise<CronRunOutcome>;
21
+ private executeWorkflowRun;
20
22
  /**
21
23
  * Execute in main session - sends system event
22
24
  */
@@ -1,11 +1,11 @@
1
- import { createLogger } from "../utils/logger/index.js";
2
- import { init_logger } from "../utils/logger.js";
3
1
  import { init_agent_scope, normalizeAgentId } from "../agent/agent-scope.js";
4
2
  import { buildSessionKey, init_session_key } from "../routing/session-key.js";
3
+ import { createLogger } from "../utils/logger/index.js";
4
+ import { init_logger } from "../utils/logger.js";
5
+ import { getCronPayloadText } from "./job-content.js";
5
6
  import { bundledChannelPlugins } from "../generated/bundled-channel-plugins.js";
6
7
  import { shouldSilence, stripHeartbeatToken } from "../heartbeat/tokens.js";
7
8
  import { getChannelPlugin, listChannelPlugins, syncChannelPluginsFromManager } from "../channels/plugins/registry.js";
8
- import { getCronPayloadText } from "./job-content.js";
9
9
  //#region src/cron/executor.ts
10
10
  init_logger();
11
11
  init_agent_scope();
@@ -39,6 +39,7 @@ var DefaultJobExecutor = class {
39
39
  sessionStore;
40
40
  runLogStore = null;
41
41
  getDefaultCronAgentId = null;
42
+ workflowRunService = null;
42
43
  setRunLogStore(store) {
43
44
  this.runLogStore = store;
44
45
  }
@@ -48,6 +49,7 @@ var DefaultJobExecutor = class {
48
49
  this.heartbeatService = deps.heartbeatService ?? null;
49
50
  if (deps.sessionStore !== void 0) this.sessionStore = deps.sessionStore;
50
51
  this.getDefaultCronAgentId = deps.getDefaultCronAgentId ?? null;
52
+ this.workflowRunService = deps.workflowRunService ?? null;
51
53
  }
52
54
  async buildCronOutboundMessage(channel, to, content) {
53
55
  if (listChannelPlugins().length === 0) syncChannelPluginsFromManager(bundledChannelPlugins);
@@ -103,6 +105,7 @@ var DefaultJobExecutor = class {
103
105
  execution.sessionKey = result.sessionKey;
104
106
  execution.sessionType = result.sessionType;
105
107
  execution.model = result.model;
108
+ execution.workflowRunId = result.workflowRunId;
106
109
  if (result.status === "ok") log.info({
107
110
  jobId: job.id,
108
111
  executionId,
@@ -155,11 +158,12 @@ var DefaultJobExecutor = class {
155
158
  status: "skipped",
156
159
  error: "Job was aborted before execution"
157
160
  };
158
- if (!this.agentService || !this.messageBus) {
159
- log.warn({ jobId: job.id }, "No agent service configured, using basic execution");
160
- return this.basicExecute(job, signal, timeout);
161
- }
162
161
  try {
162
+ if (job.payload.kind === "workflowRun") return await this.executeWorkflowRun(job, signal);
163
+ if (!this.agentService || !this.messageBus) {
164
+ log.warn({ jobId: job.id }, "No agent service configured, using basic execution");
165
+ return this.basicExecute(job, signal, timeout);
166
+ }
163
167
  if (sessionTarget === "main") return await this.executeMainSession(job, signal, timeout);
164
168
  else return await this.executeIsolated(job, signal, timeout);
165
169
  } catch (error) {
@@ -169,6 +173,56 @@ var DefaultJobExecutor = class {
169
173
  };
170
174
  }
171
175
  }
176
+ async executeWorkflowRun(job, signal) {
177
+ if (signal.aborted) return {
178
+ status: "skipped",
179
+ error: "Job was aborted before workflow run start"
180
+ };
181
+ if (job.payload.kind !== "workflowRun") return {
182
+ status: "error",
183
+ error: "Cron job payload is not workflowRun"
184
+ };
185
+ if (!this.workflowRunService) return {
186
+ status: "error",
187
+ error: "Workflow run service is not configured for cron"
188
+ };
189
+ const fallbackAgentId = this.getDefaultCronAgentId?.() ?? "main";
190
+ const agentId = normalizeAgentId(job.payload.agentId || job.agentId || fallbackAgentId);
191
+ const fireId = job.payload.source?.fireId || crypto.randomUUID();
192
+ const source = {
193
+ kind: "cron",
194
+ scheduleId: job.payload.source?.scheduleId || job.id,
195
+ fireId,
196
+ scheduledAtMs: job.payload.source?.scheduledAtMs ?? Date.now()
197
+ };
198
+ const result = await this.workflowRunService.startWorkflowRun({
199
+ agentId,
200
+ definitionId: job.payload.definitionId,
201
+ input: job.payload.input,
202
+ inputEnvelope: job.payload.inputEnvelope,
203
+ goal: job.payload.goal,
204
+ source,
205
+ idempotencyKey: `cron:${job.id}:${fireId}`
206
+ });
207
+ if (result.ok === false) return {
208
+ status: "error",
209
+ error: result.message
210
+ };
211
+ log.info({
212
+ jobId: job.id,
213
+ workflowRunId: result.runId,
214
+ definitionId: job.payload.definitionId,
215
+ sessionKey: result.sessionKey
216
+ }, "Workflow run started from cron");
217
+ return {
218
+ status: "ok",
219
+ summary: `Started workflow run ${result.runId}`,
220
+ sessionId: result.sessionKey,
221
+ sessionKey: result.sessionKey,
222
+ sessionType: "workflow",
223
+ workflowRunId: result.runId
224
+ };
225
+ }
172
226
  /**
173
227
  * Execute in main session - sends system event
174
228
  */
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","names":[],"sources":["../../../src/cron/executor.ts"],"sourcesContent":["// Cron job executor with timeout, retry logic and agent integration\nimport type {\n CronRunOutcome,\n HeartbeatWakeSink,\n JobData,\n JobExecution,\n JobExecutor,\n JobExecutorDeps,\n} from './types.js';\nimport type { OutboundMessage } from '../channels/transport-types.js';\nimport { createLogger } from '../utils/logger.js';\nimport {\n getChannelPlugin,\n listChannelPlugins,\n syncChannelPluginsFromManager,\n} from '../channels/plugins/registry.js';\nimport { bundledChannelPlugins } from '../generated/bundled-channel-plugins.js';\nimport { getCronPayloadText } from './job-content.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { CronRunLogStore } from './run-log-store.js';\nimport {\n DEFAULT_ACK_MAX_CHARS,\n NO_REPLY,\n shouldSilence,\n stripHeartbeatToken,\n} from '../heartbeat/tokens.js';\nimport { DEFAULT_AGENT_ID, normalizeAgentId } from '../agent/agent-scope.js';\nimport { buildSessionKey } from '../routing/session-key.js';\n\nconst log = createLogger('CronExecutor');\n\n// Error backoff schedule in ms\nconst ERROR_BACKOFF_MS = [\n 30_000, // 1st error → 30s\n 60_000, // 2nd error → 1min\n 5 * 60_000, // 3rd error → 5min\n 15 * 60_000, // 4th error → 15min\n 60 * 60_000, // 5th+ error → 60min\n];\n\nfunction errorBackoffMs(consecutiveErrors: number): number {\n const idx = Math.min(consecutiveErrors - 1, ERROR_BACKOFF_MS.length - 1);\n return ERROR_BACKOFF_MS[Math.max(0, idx)];\n}\n\nfunction resolveIsolatedCronJobModel(job: JobData): string | undefined {\n const fromJob = job.model?.trim();\n if (fromJob) return fromJob;\n if (job.payload?.kind === 'agentTurn') {\n const m = job.payload.model?.trim();\n if (m) return m;\n }\n return undefined;\n}\n\nexport class DefaultJobExecutor implements JobExecutor {\n private history: Map<string, JobExecution[]> = new Map();\n private runningJobs = new Map<string, AbortController>();\n private agentService: any = null;\n private messageBus: any = null;\n private heartbeatService: HeartbeatWakeSink | null = null;\n private sessionStore: SessionStore | undefined;\n private runLogStore: CronRunLogStore | null = null;\n private getDefaultCronAgentId: (() => string) | null = null;\n\n setRunLogStore(store: CronRunLogStore | null): void {\n this.runLogStore = store;\n }\n\n setDeps(deps: JobExecutorDeps): void {\n this.agentService = deps.agentService;\n this.messageBus = deps.messageBus;\n this.heartbeatService = deps.heartbeatService ?? null;\n if (deps.sessionStore !== undefined) {\n this.sessionStore = deps.sessionStore;\n }\n this.getDefaultCronAgentId = deps.getDefaultCronAgentId ?? null;\n }\n\n private async buildCronOutboundMessage(\n channel: string,\n to: string,\n content: string,\n ): Promise<OutboundMessage> {\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const plugin = getChannelPlugin(channel);\n if (plugin?.cronDelivery) {\n const { chatId, accountId, metadata } = await plugin.cronDelivery.normalizeDeliveryTarget(\n to,\n this.sessionStore,\n );\n const meta =\n accountId || metadata\n ? { ...(metadata ?? {}), ...(accountId ? { accountId } : {}) }\n : undefined;\n return {\n channel,\n chat_id: chatId,\n content,\n type: 'message',\n ...(meta && Object.keys(meta).length > 0 ? { metadata: meta } : {}),\n };\n }\n return {\n channel,\n chat_id: to,\n content,\n type: 'message',\n };\n }\n\n async execute(job: JobData, signal: AbortSignal, deps?: JobExecutorDeps): Promise<void> {\n // Set deps if provided\n if (deps) {\n this.setDeps(deps);\n }\n\n const executionId = crypto.randomUUID();\n const execution: JobExecution = {\n id: executionId,\n jobId: job.id,\n status: 'running',\n startedAt: new Date().toISOString(),\n retryCount: 0,\n };\n\n // Record execution start\n this.addToHistory(job.id, execution);\n this.runningJobs.set(job.id, new AbortController());\n\n log.info(\n { jobId: job.id, executionId, preview: getCronPayloadText(job).slice(0, 100) },\n 'Job executing'\n );\n\n let result: CronRunOutcome;\n\n try {\n // Check for cancellation\n if (signal.aborted) {\n throw new Error('Job was cancelled before execution');\n }\n\n // Execute the job\n result = await this.performJob(job, signal);\n\n // Mark as success/failed\n execution.status = result.status === 'ok' ? 'success' : result.status === 'skipped' ? 'cancelled' : 'failed';\n execution.endedAt = new Date().toISOString();\n execution.duration = Date.now() - new Date(execution.startedAt).getTime();\n execution.summary = result.summary;\n execution.error = result.error;\n execution.sessionId = result.sessionId;\n execution.sessionKey = result.sessionKey;\n execution.sessionType = result.sessionType;\n execution.model = result.model;\n\n if (result.status === 'ok') {\n log.info(\n { jobId: job.id, executionId, duration: execution.duration },\n 'Job completed'\n );\n } else if (result.status === 'skipped') {\n log.warn({ jobId: job.id, executionId, reason: result.error }, 'Job skipped');\n } else {\n log.error(\n { jobId: job.id, executionId, error: result.error },\n 'Job failed'\n );\n }\n\n if (result.status === 'ok' && this.heartbeatService) {\n try {\n this.heartbeatService.requestNow({ reason: `cron:${job.id}` });\n } catch (e) {\n log.warn({ jobId: job.id, err: e }, 'Heartbeat wake after cron failed');\n }\n }\n } catch (error) {\n execution.status = 'failed';\n execution.endedAt = new Date().toISOString();\n execution.duration = Date.now() - new Date(execution.startedAt).getTime();\n execution.error = error instanceof Error ? error.message : String(error);\n\n log.error(\n { jobId: job.id, executionId, error: execution.error },\n 'Job execution error'\n );\n\n result = {\n status: 'error',\n error: execution.error,\n };\n } finally {\n this.runningJobs.delete(job.id);\n }\n\n if (this.runLogStore) {\n await this.runLogStore.appendCompleted(execution);\n }\n\n return;\n }\n\n /**\n * Perform the actual job work - integrate with AgentService\n */\n protected async performJob(job: JobData, signal: AbortSignal): Promise<CronRunOutcome> {\n const timeout = job.timeout || 60000;\n const sessionTarget = job.sessionTarget || 'main';\n\n // Check for abort before starting\n if (signal.aborted) {\n return { status: 'skipped', error: 'Job was aborted before execution' };\n }\n\n // If no agent service, fall back to basic execution\n if (!this.agentService || !this.messageBus) {\n log.warn({ jobId: job.id }, 'No agent service configured, using basic execution');\n return this.basicExecute(job, signal, timeout);\n }\n\n try {\n if (sessionTarget === 'main') {\n return await this.executeMainSession(job, signal, timeout);\n } else {\n return await this.executeIsolated(job, signal, timeout);\n }\n } catch (error) {\n return {\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Execute in main session - sends system event\n */\n private async executeMainSession(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n const text = getCronPayloadText(job);\n\n if (!text || !text.trim()) {\n return { status: 'skipped', error: 'Main session job requires non-empty message' };\n }\n\n // Parse delivery from job config, or parse routing from payload text: \"channel:chat_id:content\"\n let channel: string;\n let to: string;\n let actualMessage: string;\n\n if (job.delivery?.channel === 'local') {\n channel = 'local';\n to = '';\n actualMessage = text;\n } else if (job.delivery?.channel && job.delivery?.to) {\n // Use explicit delivery config\n channel = job.delivery.channel;\n to = job.delivery.to;\n actualMessage = text;\n } else {\n // Parse from payload text: \"channel:chat_id:content\"\n const parts = text.split(':');\n const hasAtLeastThreeParts = parts.length >= 3;\n \n // Check if first part looks like a known channel\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const registeredChannelIds = listChannelPlugins().map((p) => p.id);\n const knownChannels = [...new Set([...registeredChannelIds, 'cli', 'gateway', 'local'])];\n const firstPartIsChannel = knownChannels.includes(parts[0]);\n \n if (hasAtLeastThreeParts && firstPartIsChannel) {\n channel = parts[0];\n to = parts[1];\n actualMessage = parts.slice(2).join(':');\n log.info(\n { jobId: job.id, channel, to, parsedFrom: 'message', originalLength: text.length },\n 'Parsed delivery from payload text'\n );\n } else {\n // Fallback to defaults\n channel = 'cli';\n to = 'cron';\n actualMessage = text;\n log.debug(\n { jobId: job.id, partsCount: parts.length, firstPart: parts[0], hasDelivery: !!job.delivery },\n 'Using default delivery - message format not recognized'\n );\n }\n }\n\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Job timed out after ${timeout}ms`)), timeout);\n });\n\n // Create execution promise\n const executePromise = (async () => {\n // Check for abort\n if (signal.aborted) {\n throw new Error('Job was aborted');\n }\n\n if (channel === 'local') {\n log.info(\n { jobId: job.id, messageLength: actualMessage.length },\n 'Cron main session: local channel — no outbound publish'\n );\n return {\n status: 'ok' as const,\n summary: actualMessage.slice(0, 200),\n };\n }\n\n const outbound = await this.buildCronOutboundMessage(channel, to, actualMessage);\n\n await this.messageBus.publishOutbound(outbound);\n\n log.info(\n { jobId: job.id, channel, to: outbound.chat_id, messageLength: actualMessage.length },\n 'Sent message to main session'\n );\n\n return {\n status: 'ok' as const,\n summary: actualMessage.slice(0, 200),\n };\n })();\n\n // Race against timeout\n return await Promise.race([executePromise, timeoutPromise]);\n }\n\n /**\n * Execute in isolated mode - runs agent independently\n */\n private async executeIsolated(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n const message = getCronPayloadText(job);\n\n if (!message || !message.trim()) {\n return { status: 'skipped', error: 'Isolated job requires non-empty message' };\n }\n\n const aid = job.agentId?.trim();\n const fallbackAgentId = this.getDefaultCronAgentId?.() ?? DEFAULT_AGENT_ID;\n const sessionKey = buildSessionKey({\n agentId: normalizeAgentId(aid || fallbackAgentId),\n source: 'cron',\n accountId: 'default',\n peerKind: 'dm',\n peerId: job.id,\n });\n\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Job timed out after ${timeout}ms`)), timeout);\n });\n\n // Create execution promise\n const executePromise = (async () => {\n // Check for abort\n if (signal.aborted) {\n throw new Error('Job was aborted');\n }\n\n await this.agentService.sessionConfig.applyCronJobWorkingDirectory(sessionKey, job.workingDirectory);\n\n const jobModel = resolveIsolatedCronJobModel(job);\n if (jobModel) {\n const ok = await this.agentService.switchModelForSession(sessionKey, jobModel);\n if (!ok) {\n log.warn({ jobId: job.id, sessionKey, model: jobModel }, 'Cron job model invalid; using agent default');\n await this.agentService.resetSessionModelToAgentDefault(sessionKey);\n }\n } else {\n await this.agentService.resetSessionModelToAgentDefault(sessionKey);\n }\n\n const response = await this.agentService.turnDispatcher.processDirect(message, sessionKey);\n\n const model = this.agentService.getModelForSession(sessionKey);\n\n log.info(\n { jobId: job.id, sessionKey, responseLength: response.length, model },\n 'Agent execution completed'\n );\n\n // Handle delivery (`local` channel or `mode: none` = no outbound; transcript in SessionStore)\n const delivery = job.delivery;\n const outboundChannel = delivery?.channel;\n const shouldPublish =\n delivery &&\n delivery.mode !== 'none' &&\n outboundChannel !== 'local' &&\n delivery.to;\n\n if (shouldPublish) {\n if (shouldSilence(response, DEFAULT_ACK_MAX_CHARS) || response.trim() === NO_REPLY) {\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n }\n const { stripped } = stripHeartbeatToken(response);\n const outboundText = stripped || response.trim();\n\n const targetChannel = outboundChannel || 'cli';\n const outbound = await this.buildCronOutboundMessage(targetChannel, delivery.to, outboundText);\n\n await this.messageBus.publishOutbound(outbound);\n\n log.info(\n { jobId: job.id, channel: targetChannel, to: outbound.chat_id },\n 'Delivered agent response'\n );\n\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n }\n\n // No outbound delivery: transcript is in SessionStore under `sessionKey`.\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n })();\n\n // Race against timeout\n try {\n return await Promise.race([executePromise, timeoutPromise]);\n } finally {\n const { retireSessionMcpRuntimeForSessionKey } = await import('../agent/mcp/bundle-mcp-tools.js');\n await retireSessionMcpRuntimeForSessionKey({\n sessionKey,\n reason: 'cron-isolated-end',\n }).catch(() => {});\n }\n }\n\n /**\n * Basic execution without agent service (fallback)\n */\n private async basicExecute(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Job timed out after ${timeout}ms`));\n }, timeout);\n\n // Listen for abort signal\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job was aborted'));\n };\n signal.addEventListener('abort', abortHandler);\n\n // Simulate basic work\n setTimeout(() => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n\n if (signal.aborted) {\n reject(new Error('Job was aborted'));\n } else {\n resolve({\n status: 'ok',\n summary: `Executed: ${getCronPayloadText(job).slice(0, 100)}`,\n });\n }\n }, 100);\n });\n }\n\n /**\n * Cancel a running job\n */\n cancelJob(jobId: string): boolean {\n const controller = this.runningJobs.get(jobId);\n if (controller) {\n controller.abort();\n this.runningJobs.delete(jobId);\n return true;\n }\n return false;\n }\n\n /**\n * Get execution history for a job\n */\n getHistory(jobId: string, limit = 10): JobExecution[] {\n const history = this.history.get(jobId) || [];\n return history.slice(-limit);\n }\n\n /**\n * Get currently running executions\n */\n getRunningExecutions(): JobExecution[] {\n const result: JobExecution[] = [];\n for (const [jobId] of this.runningJobs) {\n const history = this.history.get(jobId);\n if (history) {\n const running = history.find((e) => e.status === 'running');\n if (running) result.push(running);\n }\n }\n return result;\n }\n\n /**\n * Check if a job is currently running\n */\n isRunning(jobId: string): boolean {\n return this.runningJobs.has(jobId);\n }\n\n /**\n * Get consecutive error count for a job\n */\n getConsecutiveErrors(jobId: string): number {\n const history = this.history.get(jobId) || [];\n // Find last execution\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].status !== 'running') {\n if (history[i].status === 'failed' || history[i].status === 'cancelled') {\n // Count consecutive errors before this\n let count = 0;\n for (let j = i - 1; j >= 0; j--) {\n if (history[j].status === 'failed' || history[j].status === 'cancelled') {\n count++;\n } else {\n break;\n }\n }\n return count + 1;\n }\n return 0;\n }\n }\n return 0;\n }\n\n /**\n * Calculate backoff delay for a job\n */\n calculateBackoff(jobId: string): number {\n const errors = this.getConsecutiveErrors(jobId);\n return errorBackoffMs(errors);\n }\n\n /**\n * Clear old history entries\n */\n cleanupHistory(maxAgeDays = 7): void {\n const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;\n\n for (const [jobId, executions] of this.history) {\n this.history.set(\n jobId,\n executions.filter((e) => new Date(e.startedAt).getTime() > cutoff)\n );\n }\n }\n\n private addToHistory(jobId: string, execution: JobExecution): void {\n const existing = this.history.get(jobId) || [];\n existing.push(execution);\n // Keep last 100 executions per job\n if (existing.length > 100) {\n existing.shift();\n }\n this.history.set(jobId, existing);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"executor.js","names":[],"sources":["../../../src/cron/executor.ts"],"sourcesContent":["// Cron job executor with timeout, retry logic and agent integration\nimport type {\n CronRunOutcome,\n CronWorkflowRunStarter,\n HeartbeatWakeSink,\n JobData,\n JobExecution,\n JobExecutor,\n JobExecutorDeps,\n} from './types.js';\nimport type { OutboundMessage } from '../channels/transport-types.js';\nimport { createLogger } from '../utils/logger.js';\nimport {\n getChannelPlugin,\n listChannelPlugins,\n syncChannelPluginsFromManager,\n} from '../channels/plugins/registry.js';\nimport { bundledChannelPlugins } from '../generated/bundled-channel-plugins.js';\nimport { getCronPayloadText } from './job-content.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { CronRunLogStore } from './run-log-store.js';\nimport {\n DEFAULT_ACK_MAX_CHARS,\n NO_REPLY,\n shouldSilence,\n stripHeartbeatToken,\n} from '../heartbeat/tokens.js';\nimport { DEFAULT_AGENT_ID, normalizeAgentId } from '../agent/agent-scope.js';\nimport { buildSessionKey } from '../routing/session-key.js';\n\nconst log = createLogger('CronExecutor');\n\n// Error backoff schedule in ms\nconst ERROR_BACKOFF_MS = [\n 30_000, // 1st error → 30s\n 60_000, // 2nd error → 1min\n 5 * 60_000, // 3rd error → 5min\n 15 * 60_000, // 4th error → 15min\n 60 * 60_000, // 5th+ error → 60min\n];\n\nfunction errorBackoffMs(consecutiveErrors: number): number {\n const idx = Math.min(consecutiveErrors - 1, ERROR_BACKOFF_MS.length - 1);\n return ERROR_BACKOFF_MS[Math.max(0, idx)];\n}\n\nfunction resolveIsolatedCronJobModel(job: JobData): string | undefined {\n const fromJob = job.model?.trim();\n if (fromJob) return fromJob;\n if (job.payload?.kind === 'agentTurn') {\n const m = job.payload.model?.trim();\n if (m) return m;\n }\n return undefined;\n}\n\nexport class DefaultJobExecutor implements JobExecutor {\n private history: Map<string, JobExecution[]> = new Map();\n private runningJobs = new Map<string, AbortController>();\n private agentService: any = null;\n private messageBus: any = null;\n private heartbeatService: HeartbeatWakeSink | null = null;\n private sessionStore: SessionStore | undefined;\n private runLogStore: CronRunLogStore | null = null;\n private getDefaultCronAgentId: (() => string) | null = null;\n private workflowRunService: CronWorkflowRunStarter | null = null;\n\n setRunLogStore(store: CronRunLogStore | null): void {\n this.runLogStore = store;\n }\n\n setDeps(deps: JobExecutorDeps): void {\n this.agentService = deps.agentService;\n this.messageBus = deps.messageBus;\n this.heartbeatService = deps.heartbeatService ?? null;\n if (deps.sessionStore !== undefined) {\n this.sessionStore = deps.sessionStore;\n }\n this.getDefaultCronAgentId = deps.getDefaultCronAgentId ?? null;\n this.workflowRunService = deps.workflowRunService ?? null;\n }\n\n private async buildCronOutboundMessage(\n channel: string,\n to: string,\n content: string,\n ): Promise<OutboundMessage> {\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const plugin = getChannelPlugin(channel);\n if (plugin?.cronDelivery) {\n const { chatId, accountId, metadata } = await plugin.cronDelivery.normalizeDeliveryTarget(\n to,\n this.sessionStore,\n );\n const meta =\n accountId || metadata\n ? { ...(metadata ?? {}), ...(accountId ? { accountId } : {}) }\n : undefined;\n return {\n channel,\n chat_id: chatId,\n content,\n type: 'message',\n ...(meta && Object.keys(meta).length > 0 ? { metadata: meta } : {}),\n };\n }\n return {\n channel,\n chat_id: to,\n content,\n type: 'message',\n };\n }\n\n async execute(job: JobData, signal: AbortSignal, deps?: JobExecutorDeps): Promise<void> {\n // Set deps if provided\n if (deps) {\n this.setDeps(deps);\n }\n\n const executionId = crypto.randomUUID();\n const execution: JobExecution = {\n id: executionId,\n jobId: job.id,\n status: 'running',\n startedAt: new Date().toISOString(),\n retryCount: 0,\n };\n\n // Record execution start\n this.addToHistory(job.id, execution);\n this.runningJobs.set(job.id, new AbortController());\n\n log.info(\n { jobId: job.id, executionId, preview: getCronPayloadText(job).slice(0, 100) },\n 'Job executing'\n );\n\n let result: CronRunOutcome;\n\n try {\n // Check for cancellation\n if (signal.aborted) {\n throw new Error('Job was cancelled before execution');\n }\n\n // Execute the job\n result = await this.performJob(job, signal);\n\n // Mark as success/failed\n execution.status = result.status === 'ok' ? 'success' : result.status === 'skipped' ? 'cancelled' : 'failed';\n execution.endedAt = new Date().toISOString();\n execution.duration = Date.now() - new Date(execution.startedAt).getTime();\n execution.summary = result.summary;\n execution.error = result.error;\n execution.sessionId = result.sessionId;\n execution.sessionKey = result.sessionKey;\n execution.sessionType = result.sessionType;\n execution.model = result.model;\n execution.workflowRunId = result.workflowRunId;\n\n if (result.status === 'ok') {\n log.info(\n { jobId: job.id, executionId, duration: execution.duration },\n 'Job completed'\n );\n } else if (result.status === 'skipped') {\n log.warn({ jobId: job.id, executionId, reason: result.error }, 'Job skipped');\n } else {\n log.error(\n { jobId: job.id, executionId, error: result.error },\n 'Job failed'\n );\n }\n\n if (result.status === 'ok' && this.heartbeatService) {\n try {\n this.heartbeatService.requestNow({ reason: `cron:${job.id}` });\n } catch (e) {\n log.warn({ jobId: job.id, err: e }, 'Heartbeat wake after cron failed');\n }\n }\n } catch (error) {\n execution.status = 'failed';\n execution.endedAt = new Date().toISOString();\n execution.duration = Date.now() - new Date(execution.startedAt).getTime();\n execution.error = error instanceof Error ? error.message : String(error);\n\n log.error(\n { jobId: job.id, executionId, error: execution.error },\n 'Job execution error'\n );\n\n result = {\n status: 'error',\n error: execution.error,\n };\n } finally {\n this.runningJobs.delete(job.id);\n }\n\n if (this.runLogStore) {\n await this.runLogStore.appendCompleted(execution);\n }\n\n return;\n }\n\n /**\n * Perform the actual job work - integrate with AgentService\n */\n protected async performJob(job: JobData, signal: AbortSignal): Promise<CronRunOutcome> {\n const timeout = job.timeout || 60000;\n const sessionTarget = job.sessionTarget || 'main';\n\n // Check for abort before starting\n if (signal.aborted) {\n return { status: 'skipped', error: 'Job was aborted before execution' };\n }\n\n try {\n if (job.payload.kind === 'workflowRun') {\n return await this.executeWorkflowRun(job, signal);\n }\n\n // If no agent service, fall back to basic execution\n if (!this.agentService || !this.messageBus) {\n log.warn({ jobId: job.id }, 'No agent service configured, using basic execution');\n return this.basicExecute(job, signal, timeout);\n }\n\n if (sessionTarget === 'main') {\n return await this.executeMainSession(job, signal, timeout);\n } else {\n return await this.executeIsolated(job, signal, timeout);\n }\n } catch (error) {\n return {\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n private async executeWorkflowRun(job: JobData, signal: AbortSignal): Promise<CronRunOutcome> {\n if (signal.aborted) {\n return { status: 'skipped', error: 'Job was aborted before workflow run start' };\n }\n\n if (job.payload.kind !== 'workflowRun') {\n return { status: 'error', error: 'Cron job payload is not workflowRun' };\n }\n\n if (!this.workflowRunService) {\n return { status: 'error', error: 'Workflow run service is not configured for cron' };\n }\n\n const fallbackAgentId = this.getDefaultCronAgentId?.() ?? DEFAULT_AGENT_ID;\n const agentId = normalizeAgentId(job.payload.agentId || job.agentId || fallbackAgentId);\n const fireId = job.payload.source?.fireId || crypto.randomUUID();\n const source = {\n kind: 'cron' as const,\n scheduleId: job.payload.source?.scheduleId || job.id,\n fireId,\n scheduledAtMs: job.payload.source?.scheduledAtMs ?? Date.now(),\n };\n const result = await this.workflowRunService.startWorkflowRun({\n agentId,\n definitionId: job.payload.definitionId,\n input: job.payload.input,\n inputEnvelope: job.payload.inputEnvelope,\n goal: job.payload.goal,\n source,\n idempotencyKey: `cron:${job.id}:${fireId}`,\n });\n\n if (result.ok === false) {\n return {\n status: 'error',\n error: result.message,\n };\n }\n\n log.info(\n {\n jobId: job.id,\n workflowRunId: result.runId,\n definitionId: job.payload.definitionId,\n sessionKey: result.sessionKey,\n },\n 'Workflow run started from cron',\n );\n\n return {\n status: 'ok',\n summary: `Started workflow run ${result.runId}`,\n sessionId: result.sessionKey,\n sessionKey: result.sessionKey,\n sessionType: 'workflow',\n workflowRunId: result.runId,\n };\n }\n\n /**\n * Execute in main session - sends system event\n */\n private async executeMainSession(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n const text = getCronPayloadText(job);\n\n if (!text || !text.trim()) {\n return { status: 'skipped', error: 'Main session job requires non-empty message' };\n }\n\n // Parse delivery from job config, or parse routing from payload text: \"channel:chat_id:content\"\n let channel: string;\n let to: string;\n let actualMessage: string;\n\n if (job.delivery?.channel === 'local') {\n channel = 'local';\n to = '';\n actualMessage = text;\n } else if (job.delivery?.channel && job.delivery?.to) {\n // Use explicit delivery config\n channel = job.delivery.channel;\n to = job.delivery.to;\n actualMessage = text;\n } else {\n // Parse from payload text: \"channel:chat_id:content\"\n const parts = text.split(':');\n const hasAtLeastThreeParts = parts.length >= 3;\n \n // Check if first part looks like a known channel\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n const registeredChannelIds = listChannelPlugins().map((p) => p.id);\n const knownChannels = [...new Set([...registeredChannelIds, 'cli', 'gateway', 'local'])];\n const firstPartIsChannel = knownChannels.includes(parts[0]);\n \n if (hasAtLeastThreeParts && firstPartIsChannel) {\n channel = parts[0];\n to = parts[1];\n actualMessage = parts.slice(2).join(':');\n log.info(\n { jobId: job.id, channel, to, parsedFrom: 'message', originalLength: text.length },\n 'Parsed delivery from payload text'\n );\n } else {\n // Fallback to defaults\n channel = 'cli';\n to = 'cron';\n actualMessage = text;\n log.debug(\n { jobId: job.id, partsCount: parts.length, firstPart: parts[0], hasDelivery: !!job.delivery },\n 'Using default delivery - message format not recognized'\n );\n }\n }\n\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Job timed out after ${timeout}ms`)), timeout);\n });\n\n // Create execution promise\n const executePromise = (async () => {\n // Check for abort\n if (signal.aborted) {\n throw new Error('Job was aborted');\n }\n\n if (channel === 'local') {\n log.info(\n { jobId: job.id, messageLength: actualMessage.length },\n 'Cron main session: local channel — no outbound publish'\n );\n return {\n status: 'ok' as const,\n summary: actualMessage.slice(0, 200),\n };\n }\n\n const outbound = await this.buildCronOutboundMessage(channel, to, actualMessage);\n\n await this.messageBus.publishOutbound(outbound);\n\n log.info(\n { jobId: job.id, channel, to: outbound.chat_id, messageLength: actualMessage.length },\n 'Sent message to main session'\n );\n\n return {\n status: 'ok' as const,\n summary: actualMessage.slice(0, 200),\n };\n })();\n\n // Race against timeout\n return await Promise.race([executePromise, timeoutPromise]);\n }\n\n /**\n * Execute in isolated mode - runs agent independently\n */\n private async executeIsolated(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n const message = getCronPayloadText(job);\n\n if (!message || !message.trim()) {\n return { status: 'skipped', error: 'Isolated job requires non-empty message' };\n }\n\n const aid = job.agentId?.trim();\n const fallbackAgentId = this.getDefaultCronAgentId?.() ?? DEFAULT_AGENT_ID;\n const sessionKey = buildSessionKey({\n agentId: normalizeAgentId(aid || fallbackAgentId),\n source: 'cron',\n accountId: 'default',\n peerKind: 'dm',\n peerId: job.id,\n });\n\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Job timed out after ${timeout}ms`)), timeout);\n });\n\n // Create execution promise\n const executePromise = (async () => {\n // Check for abort\n if (signal.aborted) {\n throw new Error('Job was aborted');\n }\n\n await this.agentService.sessionConfig.applyCronJobWorkingDirectory(sessionKey, job.workingDirectory);\n\n const jobModel = resolveIsolatedCronJobModel(job);\n if (jobModel) {\n const ok = await this.agentService.switchModelForSession(sessionKey, jobModel);\n if (!ok) {\n log.warn({ jobId: job.id, sessionKey, model: jobModel }, 'Cron job model invalid; using agent default');\n await this.agentService.resetSessionModelToAgentDefault(sessionKey);\n }\n } else {\n await this.agentService.resetSessionModelToAgentDefault(sessionKey);\n }\n\n const response = await this.agentService.turnDispatcher.processDirect(message, sessionKey);\n\n const model = this.agentService.getModelForSession(sessionKey);\n\n log.info(\n { jobId: job.id, sessionKey, responseLength: response.length, model },\n 'Agent execution completed'\n );\n\n // Handle delivery (`local` channel or `mode: none` = no outbound; transcript in SessionStore)\n const delivery = job.delivery;\n const outboundChannel = delivery?.channel;\n const shouldPublish =\n delivery &&\n delivery.mode !== 'none' &&\n outboundChannel !== 'local' &&\n delivery.to;\n\n if (shouldPublish) {\n if (shouldSilence(response, DEFAULT_ACK_MAX_CHARS) || response.trim() === NO_REPLY) {\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n }\n const { stripped } = stripHeartbeatToken(response);\n const outboundText = stripped || response.trim();\n\n const targetChannel = outboundChannel || 'cli';\n const outbound = await this.buildCronOutboundMessage(targetChannel, delivery.to, outboundText);\n\n await this.messageBus.publishOutbound(outbound);\n\n log.info(\n { jobId: job.id, channel: targetChannel, to: outbound.chat_id },\n 'Delivered agent response'\n );\n\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n }\n\n // No outbound delivery: transcript is in SessionStore under `sessionKey`.\n return {\n status: 'ok' as const,\n summary: response.slice(0, 200),\n sessionId: sessionKey,\n sessionKey,\n sessionType: 'cron',\n model,\n };\n })();\n\n // Race against timeout\n try {\n return await Promise.race([executePromise, timeoutPromise]);\n } finally {\n const { retireSessionMcpRuntimeForSessionKey } = await import('../agent/mcp/bundle-mcp-tools.js');\n await retireSessionMcpRuntimeForSessionKey({\n sessionKey,\n reason: 'cron-isolated-end',\n }).catch(() => {});\n }\n }\n\n /**\n * Basic execution without agent service (fallback)\n */\n private async basicExecute(\n job: JobData,\n signal: AbortSignal,\n timeout: number\n ): Promise<CronRunOutcome> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Job timed out after ${timeout}ms`));\n }, timeout);\n\n // Listen for abort signal\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job was aborted'));\n };\n signal.addEventListener('abort', abortHandler);\n\n // Simulate basic work\n setTimeout(() => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n\n if (signal.aborted) {\n reject(new Error('Job was aborted'));\n } else {\n resolve({\n status: 'ok',\n summary: `Executed: ${getCronPayloadText(job).slice(0, 100)}`,\n });\n }\n }, 100);\n });\n }\n\n /**\n * Cancel a running job\n */\n cancelJob(jobId: string): boolean {\n const controller = this.runningJobs.get(jobId);\n if (controller) {\n controller.abort();\n this.runningJobs.delete(jobId);\n return true;\n }\n return false;\n }\n\n /**\n * Get execution history for a job\n */\n getHistory(jobId: string, limit = 10): JobExecution[] {\n const history = this.history.get(jobId) || [];\n return history.slice(-limit);\n }\n\n /**\n * Get currently running executions\n */\n getRunningExecutions(): JobExecution[] {\n const result: JobExecution[] = [];\n for (const [jobId] of this.runningJobs) {\n const history = this.history.get(jobId);\n if (history) {\n const running = history.find((e) => e.status === 'running');\n if (running) result.push(running);\n }\n }\n return result;\n }\n\n /**\n * Check if a job is currently running\n */\n isRunning(jobId: string): boolean {\n return this.runningJobs.has(jobId);\n }\n\n /**\n * Get consecutive error count for a job\n */\n getConsecutiveErrors(jobId: string): number {\n const history = this.history.get(jobId) || [];\n // Find last execution\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].status !== 'running') {\n if (history[i].status === 'failed' || history[i].status === 'cancelled') {\n // Count consecutive errors before this\n let count = 0;\n for (let j = i - 1; j >= 0; j--) {\n if (history[j].status === 'failed' || history[j].status === 'cancelled') {\n count++;\n } else {\n break;\n }\n }\n return count + 1;\n }\n return 0;\n }\n }\n return 0;\n }\n\n /**\n * Calculate backoff delay for a job\n */\n calculateBackoff(jobId: string): number {\n const errors = this.getConsecutiveErrors(jobId);\n return errorBackoffMs(errors);\n }\n\n /**\n * Clear old history entries\n */\n cleanupHistory(maxAgeDays = 7): void {\n const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;\n\n for (const [jobId, executions] of this.history) {\n this.history.set(\n jobId,\n executions.filter((e) => new Date(e.startedAt).getTime() > cutoff)\n );\n }\n }\n\n private addToHistory(jobId: string, execution: JobExecution): void {\n const existing = this.history.get(jobId) || [];\n existing.push(execution);\n // Keep last 100 executions per job\n if (existing.length > 100) {\n existing.shift();\n }\n this.history.set(jobId, existing);\n }\n}\n"],"mappings":"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"}
@@ -5,7 +5,8 @@
5
5
  function getCronPayloadText(job) {
6
6
  const p = job.payload;
7
7
  if (p.kind === "systemEvent") return p.text;
8
- return p.message;
8
+ if (p.kind === "agentTurn") return p.message;
9
+ return p.goal || p.definitionId;
9
10
  }
10
11
  //#endregion
11
12
  export { getCronPayloadText };
@@ -1 +1 @@
1
- {"version":3,"file":"job-content.js","names":[],"sources":["../../../src/cron/job-content.ts"],"sourcesContent":["import type { JobData } from './types.js';\n\n/**\n * Executable body text from a cron job (`payload` only).\n */\nexport function getCronPayloadText(job: Pick<JobData, 'payload'>): string {\n const p = job.payload;\n if (p.kind === 'systemEvent') return p.text;\n return p.message;\n}\n"],"mappings":";;;;AAKA,SAAgB,mBAAmB,KAAuC;CACxE,MAAM,IAAI,IAAI;AACd,KAAI,EAAE,SAAS,cAAe,QAAO,EAAE;AACvC,QAAO,EAAE"}
1
+ {"version":3,"file":"job-content.js","names":[],"sources":["../../../src/cron/job-content.ts"],"sourcesContent":["import type { JobData } from './types.js';\n\n/**\n * Executable body text from a cron job (`payload` only).\n */\nexport function getCronPayloadText(job: Pick<JobData, 'payload'>): string {\n const p = job.payload;\n if (p.kind === 'systemEvent') return p.text;\n if (p.kind === 'agentTurn') return p.message;\n return p.goal || p.definitionId;\n}\n"],"mappings":";;;;AAKA,SAAgB,mBAAmB,KAAuC;CACxE,MAAM,IAAI,IAAI;AACd,KAAI,EAAE,SAAS,cAAe,QAAO,EAAE;AACvC,KAAI,EAAE,SAAS,YAAa,QAAO,EAAE;AACrC,QAAO,EAAE,QAAQ,EAAE"}
@@ -1,6 +1,6 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
2
1
  import { createLogger } from "../utils/logger/index.js";
3
2
  import { init_logger } from "../utils/logger.js";
3
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
4
4
  import { JobDataSchema } from "./validation.js";
5
5
  import { access, readFile } from "fs/promises";
6
6
  //#region src/cron/persistence.ts
@@ -1,8 +1,8 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_paths, resolveCronRunsDir } from "../config/paths.js";
4
- import { appendFile, mkdir, readFile, readdir, unlink, writeFile } from "fs/promises";
5
4
  import { join } from "path";
5
+ import { appendFile, mkdir, readFile, readdir, unlink, writeFile } from "fs/promises";
6
6
  //#region src/cron/run-log-store.ts
7
7
  init_paths();
8
8
  init_logger();
@@ -1,4 +1,6 @@
1
1
  import type { SessionStore } from '../session/store.js';
2
+ import type { WorkflowRunInputEnvelope, WorkflowRunSource } from '../workflows/domain/index.js';
3
+ import type { StartWorkflowRunServiceParams, WorkflowRunServiceResult } from '../workflows/service/workflow-run-service.types.js';
2
4
  export type CronDeliveryMode = 'none' | 'announce' | 'direct';
3
5
  export interface CronDelivery {
4
6
  mode: CronDeliveryMode;
@@ -14,7 +16,19 @@ export type CronPayload = {
14
16
  message: string;
15
17
  model?: string;
16
18
  timeoutSeconds?: number;
17
- };
19
+ } | CronWorkflowRunPayload;
20
+ export interface CronWorkflowRunPayload {
21
+ kind: 'workflowRun';
22
+ definitionId: string;
23
+ input?: unknown;
24
+ inputEnvelope?: WorkflowRunInputEnvelope;
25
+ goal?: string;
26
+ agentId?: string;
27
+ sessionKey?: string;
28
+ source?: Partial<Extract<WorkflowRunSource, {
29
+ kind: 'cron';
30
+ }>>;
31
+ }
18
32
  export type CronSessionTarget = 'main' | 'isolated';
19
33
  export interface JobData {
20
34
  id: string;
@@ -67,6 +81,7 @@ export interface JobExecution {
67
81
  model?: string;
68
82
  provider?: string;
69
83
  usage?: CronUsageSummary;
84
+ workflowRunId?: string;
70
85
  }
71
86
  export interface CronUsageSummary {
72
87
  input_tokens?: number;
@@ -88,6 +103,10 @@ export interface CronRunOutcome {
88
103
  model?: string;
89
104
  provider?: string;
90
105
  usage?: CronUsageSummary;
106
+ workflowRunId?: string;
107
+ }
108
+ export interface CronWorkflowRunStarter {
109
+ startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult>;
91
110
  }
92
111
  /** Optional hook after a successful cron run (e.g. wake gateway heartbeat). */
93
112
  export interface HeartbeatWakeSink {
@@ -106,6 +125,7 @@ export interface JobExecutorDeps {
106
125
  * (same as {@link JobData.agentId} set to the default agent). Typically `getDefaultAgentId(config)`.
107
126
  */
108
127
  getDefaultCronAgentId?: () => string;
128
+ workflowRunService?: CronWorkflowRunStarter;
109
129
  }
110
130
  export interface JobExecutor {
111
131
  execute(job: JobData, signal: AbortSignal, deps?: JobExecutorDeps): Promise<void>;