@desplega.ai/agent-swarm 1.158.0 → 1.160.0

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 (378) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-2mjwcsfh.js} +124 -27
  3. package/dist/{actions-p9hz5yat.js → actions-e43rxskr.js} +35 -30
  4. package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-5qx80j9k.js} +106 -16
  5. package/dist/{app-g26wdcz6.js → app-mc7xfagn.js} +12 -10
  6. package/dist/{assistant-wydfqkb3.js → assistant-sedkzv3b.js} +42 -31
  7. package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-nfb21z9a.js} +13 -14
  8. package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-cqz9swn5.js} +13 -12
  9. package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-m3656j2n.js} +14 -13
  10. package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-xbxf5d7w.js} +11 -9
  11. package/dist/boot-seeds-gsetbs5y.js +28 -0
  12. package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-dc6289mc.js} +28 -23
  13. package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-naaw51me.js} +4 -3
  14. package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-eacvchx0.js} +12 -3
  15. package/dist/claude-sdk-session-bqp2xvym.js +29722 -0
  16. package/dist/{cli-987hg0aa.js → cli-0jwe9034.js} +2 -2
  17. package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
  18. package/dist/{cli-c07r9a2m.js → cli-0q3avq3s.js} +12 -11
  19. package/dist/{cli-19jenss3.js → cli-0wgxmwf6.js} +31 -10
  20. package/dist/cli-0x01kwrd.js +491 -0
  21. package/dist/cli-0xqde53b.js +176 -0
  22. package/dist/cli-10nhj6xq.js +8355 -0
  23. package/dist/{cli-tt9k8r35.js → cli-12tszpk9.js} +479 -910
  24. package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
  25. package/dist/{cli-cqt19wg6.js → cli-1a2j50m0.js} +11 -2
  26. package/dist/{cli-xberxa1r.js → cli-25fcq4b4.js} +2 -2
  27. package/dist/{cli-npssxgaz.js → cli-2pdaysab.js} +52 -2
  28. package/dist/cli-3qhyh31j.js +166 -0
  29. package/dist/cli-447dt1h3.js +3828 -0
  30. package/dist/cli-4derpgyk.js +115 -0
  31. package/dist/{cli-00w2c66p.js → cli-523679eh.js} +13 -2
  32. package/dist/{cli-y95wp3tg.js → cli-58e8yr0d.js} +1 -1
  33. package/dist/{cli-24k806sc.js → cli-5nbmpy8w.js} +3 -3
  34. package/dist/{cli-53sz8gkz.js → cli-6cs6wzxt.js} +1 -1
  35. package/dist/cli-741yb0xx.js +1027 -0
  36. package/dist/cli-74h9hscv.js +69 -0
  37. package/dist/cli-7cxw8b60.js +14910 -0
  38. package/dist/{cli-xhaeg2nc.js → cli-7e398j1h.js} +1 -1
  39. package/dist/cli-7kyk9jr3.js +22 -0
  40. package/dist/cli-89s4ngw3.js +183 -0
  41. package/dist/{cli-9b13ggd1.js → cli-89v6kyq7.js} +1 -0
  42. package/dist/{cli-ftfvggzx.js → cli-9hsgwz4w.js} +1045 -581
  43. package/dist/{cli-rqz8qbw7.js → cli-a8dvhzrt.js} +59 -20
  44. package/dist/{cli-j57qkrpq.js → cli-azhgzetg.js} +395 -56
  45. package/dist/cli-br0qdrnp.js +2150 -0
  46. package/dist/{cli-rj19hc34.js → cli-btfv8y88.js} +1 -1
  47. package/dist/{cli-8qmme6vd.js → cli-c8a36vcc.js} +2 -2
  48. package/dist/cli-cpvsaqsw.js +333 -0
  49. package/dist/cli-d5czme6m.js +17805 -0
  50. package/dist/{cli-h38x0qhg.js → cli-et8m9xsv.js} +4 -3
  51. package/dist/{cli-x24pshtq.js → cli-evvtk35y.js} +6 -6
  52. package/dist/{cli-7s3syk22.js → cli-f8gy6r2r.js} +5 -5
  53. package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
  54. package/dist/{cli-9httdpyq.js → cli-g2whhdrf.js} +1 -1
  55. package/dist/cli-gt4hxb8p.js +99 -0
  56. package/dist/{cli-s8eet254.js → cli-jajnsm8q.js} +37184 -53838
  57. package/dist/{cli-7gtvvpbh.js → cli-jayjpjmb.js} +21 -12
  58. package/dist/{cli-68w09sjw.js → cli-jyk0ynw2.js} +27 -89
  59. package/dist/{cli-aehm1rbq.js → cli-jz4w45qt.js} +1152 -61
  60. package/dist/cli-kmcpfwn2.js +333856 -0
  61. package/dist/{cli-4198qc9v.js → cli-ktmyrtpn.js} +19 -3
  62. package/dist/{cli-j55n64b6.js → cli-mfe5btp9.js} +505 -189
  63. package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
  64. package/dist/{cli-1hkrch3k.js → cli-pm1rst0h.js} +46 -7
  65. package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
  66. package/dist/{cli-ggm92wcn.js → cli-ptr8h7kp.js} +20 -1
  67. package/dist/{cli-s8s499xy.js → cli-qbksc292.js} +3 -2
  68. package/dist/{cli-47m6dkd3.js → cli-qydf22qq.js} +597 -346
  69. package/dist/{cli-3gmcwfyx.js → cli-r1mxd1xh.js} +13 -6
  70. package/dist/cli-rb9m6rpe.js +4980 -0
  71. package/dist/cli-rykfmgwg.js +102 -0
  72. package/dist/{cli-5d10vd2m.js → cli-shkxm1vn.js} +6 -5
  73. package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
  74. package/dist/cli-tfky2838.js +756 -0
  75. package/dist/{cli-g8djp6qe.js → cli-tmqt7dpj.js} +40 -0
  76. package/dist/{cli-fgqxwrpv.js → cli-tpq83z89.js} +1631 -127
  77. package/dist/cli-trc24wk2.js +143 -0
  78. package/dist/{cli-aky8tctm.js → cli-tzx2ke1v.js} +3 -3
  79. package/dist/cli-v7fn5gms.js +1425 -0
  80. package/dist/{cli-wscdvcqz.js → cli-vctdqs5h.js} +1 -1
  81. package/dist/{cli-cw9zck8j.js → cli-xjcywfsf.js} +8 -4
  82. package/dist/{cli-k0g1sjzm.js → cli-ybgv4kw2.js} +18 -11
  83. package/dist/{cli-rjehvrts.js → cli-ydmcgve1.js} +8 -8
  84. package/dist/{cli-vhjwh6cz.js → cli-ygwm91nt.js} +1 -1
  85. package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
  86. package/dist/{cli-de1396j2.js → cli-ywybs5as.js} +7 -1
  87. package/dist/cli-zpep9q5e.js +491 -0
  88. package/dist/cli.js +41 -32
  89. package/dist/cloudflare-workers-ai-system-one-k6fbxw9d.js +46 -0
  90. package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-nmxcatww.js} +26 -17
  91. package/dist/{codex-hook-9hptmdhj.js → codex-hook-20me6byw.js} +2 -2
  92. package/dist/{codex-login-x3jk4etn.js → codex-login-w6fz4xbz.js} +50 -5
  93. package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-90aa80ev.js} +24 -17
  94. package/dist/{commands-e3bn0p75.js → commands-8wcq1kn7.js} +11 -9
  95. package/dist/{db-03v9kzr2.js → db-j40kc4se.js} +25 -11
  96. package/dist/{devin-adapter-8vgkwh29.js → devin-adapter-dpsv6hd9.js} +1 -1
  97. package/dist/{dispatcher-nrmg8yht.js → dispatcher-4zqy768d.js} +34 -29
  98. package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-mpnzgztj.js} +3 -3
  99. package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
  100. package/dist/execute-6e7qeyk4.js +1017 -0
  101. package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-k6n5nbpp.js} +6 -5
  102. package/dist/{google-vertex-809af514.js → google-vertex-44xxtcvp.js} +6 -5
  103. package/dist/{handlers-aqcedbyb.js → handlers-kjdce1w5.js} +37 -32
  104. package/dist/{hook-ybvmrmhq.js → hook-czx13n12.js} +19 -15
  105. package/dist/{hook-7vkskkre.js → hook-r2t4bqfg.js} +18 -14
  106. package/dist/{http-2eqa8t24.js → http-3bbb19be.js} +900 -145
  107. package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
  108. package/dist/{index-x71bvq0p.js → index-668me3f0.js} +35 -30
  109. package/dist/{index-c6zsv1bd.js → index-7aj368tw.js} +13 -12
  110. package/dist/{index-1yks3qcr.js → index-fg0dsp6c.js} +34 -29
  111. package/dist/{index-chgdkq36.js → index-kkv84jq9.js} +34 -29
  112. package/dist/{index-a3vn96n8.js → index-zg7vp46x.js} +198 -54
  113. package/dist/{keepalive-vtkf5n99.js → keepalive-yra8dy57.js} +13 -11
  114. package/dist/{lead-h3sp357x.js → lead-va0pad2c.js} +54 -49
  115. package/dist/llama-cpp-classify-tgj35k8d.js +335 -0
  116. package/dist/{maintenance-jzeqtk3q.js → maintenance-hqewtmyg.js} +14 -13
  117. package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-pc3ntnxt.js} +14 -17
  118. package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-7rdt1m9n.js} +12 -10
  119. package/dist/{onboard-tmsp0qbz.js → onboard-j6ms6d0x.js} +6 -5
  120. package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-bbancrr0.js} +21 -8
  121. package/dist/{openai-completions-9hjrqbw8.js → openai-completions-jpaj5g2b.js} +9 -12
  122. package/dist/{openai-responses-7b1pn0xt.js → openai-responses-200k1wx4.js} +23 -18
  123. package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-89rabkw2.js} +8 -7
  124. package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-8yx3487g.js} +5 -7
  125. package/dist/{otel-impl-9mz73q65.js → otel-impl-a792rjz0.js} +1 -1
  126. package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
  127. package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-g7qzvr3v.js} +295 -70
  128. package/dist/pricing-refresh-wx0tp7cb.js +39 -0
  129. package/dist/quickjs-r1pq2107.wasm +0 -0
  130. package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-8tzawacv.js} +12 -10
  131. package/dist/{render-v2-gryrh9h8.js → render-v2-mm7zswb8.js} +12 -10
  132. package/dist/runtime-zyssgse0.js +24 -0
  133. package/dist/{setup-q9720bt6.js → setup-8y70ys6t.js} +6 -5
  134. package/dist/typesafe-system-one-2ef30pec.js +27 -0
  135. package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-6nmk7h3n.js} +22 -13
  136. package/dist/{work-objects-b76x7deb.js → work-objects-fg6xkb0n.js} +37 -32
  137. package/dist/{worker-6vrxbv41.js → worker-wmwhxsph.js} +54 -49
  138. package/openapi.json +1314 -91
  139. package/package.json +12 -11
  140. package/src/be/db/agents.ts +20 -0
  141. package/src/be/db/api-keys.ts +70 -0
  142. package/src/be/db/tasks/human-free.ts +442 -0
  143. package/src/be/db/tasks/read.ts +56 -1
  144. package/src/be/db/tasks/write.ts +107 -11
  145. package/src/be/db.ts +274 -188
  146. package/src/be/harness-model-support.ts +182 -0
  147. package/src/be/human-free-drain.ts +67 -0
  148. package/src/be/memory/providers/sqlite-store.ts +51 -15
  149. package/src/be/migrations/182_task_human_free_flag.sql +63 -0
  150. package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
  151. package/src/be/migrations/184_model_catalog.sql +120 -0
  152. package/src/be/migrations/185_api_key_auth_failures.sql +6 -0
  153. package/src/be/migrations/186_api_key_seat_mismatch.sql +8 -0
  154. package/src/be/model-catalog-store.ts +644 -0
  155. package/src/be/model-tier-keys.ts +46 -0
  156. package/src/be/model-tier-resolution.ts +534 -0
  157. package/src/be/model-validation.ts +188 -0
  158. package/src/be/models-catalog.ts +61 -7
  159. package/src/be/modelsdev-cache.json +82 -0
  160. package/src/be/modelsdev-cache.ts +2 -0
  161. package/src/be/pricing-refresh.ts +154 -12
  162. package/src/be/scripts/typecheck.ts +15 -0
  163. package/src/be/seed/runner.ts +18 -12
  164. package/src/be/seed/types.ts +1 -0
  165. package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
  166. package/src/be/swarm-config-guard.ts +8 -0
  167. package/src/cli.tsx +10 -0
  168. package/src/commands/claude-managed-setup.ts +3 -1
  169. package/src/commands/codex-login.ts +67 -0
  170. package/src/commands/credential-outcome-report.ts +191 -0
  171. package/src/commands/rate-limit-outcome.ts +34 -4
  172. package/src/commands/runner.ts +357 -186
  173. package/src/commands/seat-mismatch-report.ts +46 -0
  174. package/src/extensions/apply-task-create.ts +27 -1
  175. package/src/extensions/contract-types.generated.ts +1 -1
  176. package/src/heartbeat/heartbeat.ts +79 -17
  177. package/src/heartbeat/templates.ts +2 -2
  178. package/src/http/agents.ts +62 -1
  179. package/src/http/api-keys.ts +140 -2
  180. package/src/http/codex-oauth-keep-warm.ts +3 -5
  181. package/src/http/index.ts +8 -0
  182. package/src/http/memory.ts +12 -5
  183. package/src/http/models-catalog.ts +357 -8
  184. package/src/http/poll.ts +54 -3
  185. package/src/http/schedules.ts +51 -6
  186. package/src/http/script-runs.ts +12 -0
  187. package/src/http/session-data.ts +2 -5
  188. package/src/http/stats.ts +6 -8
  189. package/src/http/status.ts +15 -1
  190. package/src/http/tasks.ts +90 -7
  191. package/src/http/usage-cache.ts +56 -15
  192. package/src/http/workflows.ts +46 -8
  193. package/src/mcp-client/http-client.ts +5 -0
  194. package/src/memory/recall-query.ts +74 -0
  195. package/src/prompts/base-prompt.ts +15 -4
  196. package/src/prompts/session-templates.ts +23 -1
  197. package/src/providers/acp-adapter.ts +1 -0
  198. package/src/providers/claude-adapter.ts +14 -5
  199. package/src/providers/claude-managed-adapter.ts +1 -0
  200. package/src/providers/claude-managed-models.ts +47 -161
  201. package/src/providers/claude-sdk-session.ts +3 -1
  202. package/src/providers/codex-adapter.ts +14 -14
  203. package/src/providers/codex-models.ts +65 -198
  204. package/src/providers/devin-adapter.ts +1 -0
  205. package/src/providers/dsh-adapter.ts +2 -1
  206. package/src/providers/harness-version.ts +83 -7
  207. package/src/providers/opencode-adapter.ts +53 -1
  208. package/src/providers/pi-binary-root/src/extensions/codemode/worker.ts +11 -0
  209. package/src/providers/pi-codemode-runtime.ts +17 -0
  210. package/src/providers/pi-mono-adapter.ts +361 -83
  211. package/src/providers/pi-mono-extension.ts +16 -1
  212. package/src/providers/reasoning-effort.ts +44 -140
  213. package/src/providers/types.ts +8 -0
  214. package/src/rbac/legacy-policy.ts +43 -0
  215. package/src/rbac/permissions.ts +15 -0
  216. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  217. package/src/scripts-runtime/types/stdlib.d.ts +15 -0
  218. package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
  219. package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
  220. package/src/server.ts +6 -0
  221. package/src/slack/assistant.ts +13 -0
  222. package/src/slack/message-text.ts +56 -2
  223. package/src/slack/render-v2.ts +87 -37
  224. package/src/slack/session-status.ts +541 -0
  225. package/src/slack/thread-buffer.ts +10 -2
  226. package/src/tasks/sibling-awareness.ts +3 -2
  227. package/src/telemetry.ts +5 -4
  228. package/src/templates.d.ts +6 -0
  229. package/src/tests/agents-list-model-display.test.ts +4 -6
  230. package/src/tests/api-key-auth-failure-route.test.ts +142 -0
  231. package/src/tests/api-key-tracking.test.ts +368 -1
  232. package/src/tests/base-prompt.test.ts +43 -2
  233. package/src/tests/claude-adapter.test.ts +68 -0
  234. package/src/tests/claude-managed-adapter.test.ts +12 -18
  235. package/src/tests/codex-adapter.test.ts +2 -1
  236. package/src/tests/codex-auth-failure.test.ts +52 -0
  237. package/src/tests/codex-gpt6-release.test.ts +66 -5
  238. package/src/tests/codex-login.test.ts +116 -0
  239. package/src/tests/context-window.test.ts +7 -5
  240. package/src/tests/credential-exhaustion-policy.test.ts +118 -3
  241. package/src/tests/credential-outcome-report.test.ts +171 -0
  242. package/src/tests/credential-status-api.test.ts +103 -2
  243. package/src/tests/db-extraction-contract.test.ts +1 -0
  244. package/src/tests/db-task-read-contract.test.ts +10 -1
  245. package/src/tests/db-task-write-contract.test.ts +535 -2
  246. package/src/tests/docs-index-footprint.test.js +3 -3
  247. package/src/tests/dokploy-deploy.test.ts +315 -0
  248. package/src/tests/dsh-adapter.test.ts +1 -1
  249. package/src/tests/explicit-model-validation.test.ts +583 -0
  250. package/src/tests/extensions-pre-task.test.ts +73 -0
  251. package/src/tests/fetch-resolved-env.test.ts +46 -0
  252. package/src/tests/hang-watchdog-worker.ts +47 -0
  253. package/src/tests/hang-watchdog.test.ts +45 -0
  254. package/src/tests/hang-watchdog.ts +30 -0
  255. package/src/tests/harness-model-guard.test.ts +123 -0
  256. package/src/tests/harness-model-support.test.ts +374 -0
  257. package/src/tests/harness-version.test.ts +70 -3
  258. package/src/tests/heartbeat-checklist-config.test.ts +71 -0
  259. package/src/tests/heartbeat-checklist.test.ts +4 -2
  260. package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
  261. package/src/tests/http-task-write-ownership.test.ts +172 -0
  262. package/src/tests/human-free-flag.test.ts +279 -0
  263. package/src/tests/human-free-oracle.ts +57 -0
  264. package/src/tests/human-free-reclassify.test.ts +669 -0
  265. package/src/tests/memory-fts-populate.test.ts +139 -0
  266. package/src/tests/memory-http-recall-gating.test.ts +125 -1
  267. package/src/tests/migration-046-budgets.test.ts +3 -3
  268. package/src/tests/model-catalog-migration.test.ts +134 -0
  269. package/src/tests/model-catalog-table.test.ts +249 -0
  270. package/src/tests/model-catalog-write-access.test.ts +387 -0
  271. package/src/tests/model-rate-limit-windows.test.ts +19 -0
  272. package/src/tests/model-tier-resolution.test.ts +611 -0
  273. package/src/tests/models-catalog.test.ts +1 -1
  274. package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
  275. package/src/tests/opencode-adapter.test.ts +157 -2
  276. package/src/tests/package-publish.test.ts +137 -36
  277. package/src/tests/pi-codemode.test.ts +246 -0
  278. package/src/tests/pi-mono-adapter.test.ts +3 -0
  279. package/src/tests/pi-native-mcp.test.ts +193 -0
  280. package/src/tests/pi-tool-exposure.test.ts +374 -0
  281. package/src/tests/preload.ts +3 -0
  282. package/src/tests/pricing-routes.test.ts +2 -2
  283. package/src/tests/prompt-template-session.test.ts +5 -3
  284. package/src/tests/rate-limit-event.test.ts +65 -0
  285. package/src/tests/rate-limit-outcome.test.ts +90 -0
  286. package/src/tests/rbac-engine.test.ts +77 -3
  287. package/src/tests/reasoning-effort.test.ts +109 -0
  288. package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
  289. package/src/tests/runner-key-completion-outcome.test.ts +112 -0
  290. package/src/tests/runner-key-outcome-late-reset.test.ts +224 -0
  291. package/src/tests/runner-registration-retry.test.ts +149 -0
  292. package/src/tests/runtime-model-catalog.test.ts +86 -0
  293. package/src/tests/script-connections.test.ts +9 -0
  294. package/src/tests/seat-mismatch-report.test.ts +85 -0
  295. package/src/tests/seed-scripts.test.ts +138 -0
  296. package/src/tests/seed.test.ts +25 -0
  297. package/src/tests/session-costs.test.ts +14 -11
  298. package/src/tests/slack-message-text.test.ts +101 -0
  299. package/src/tests/slack-render-v2.test.ts +96 -0
  300. package/src/tests/slack-session-status.test.ts +626 -0
  301. package/src/tests/slack-thread-buffer-context.test.ts +93 -0
  302. package/src/tests/status.test.ts +29 -0
  303. package/src/tests/steering-promotion.test.ts +51 -0
  304. package/src/tests/store-progress-ownership.test.ts +136 -0
  305. package/src/tests/subscription-plans.test.ts +28 -0
  306. package/src/tests/task-cascade-fail.test.ts +148 -2
  307. package/src/tests/task-citations.test.ts +3 -2
  308. package/src/tests/tool-annotations.test.ts +1 -1
  309. package/src/tests/usage-cache.test.ts +166 -0
  310. package/src/tests/workflow-agent-task.test.ts +30 -0
  311. package/src/tests/workflow-executors.test.ts +5 -2
  312. package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
  313. package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
  314. package/src/tests/workflow-system-one-decision.test.ts +2063 -0
  315. package/src/tests/workflow-triggers-v2.test.ts +320 -0
  316. package/src/tools/model-catalog/index.ts +137 -0
  317. package/src/tools/schedules/create-schedule.ts +17 -2
  318. package/src/tools/schedules/patch-schedule.ts +31 -1
  319. package/src/tools/schedules/update-schedule.ts +31 -1
  320. package/src/tools/send-task.ts +18 -1
  321. package/src/tools/store-progress.ts +49 -4
  322. package/src/tools/task-action.ts +14 -1
  323. package/src/tools/tool-config.ts +3 -1
  324. package/src/tools/workflows/create-workflow.ts +17 -4
  325. package/src/tools/workflows/patch-workflow-node.ts +17 -7
  326. package/src/tools/workflows/patch-workflow.ts +9 -2
  327. package/src/tools/workflows/update-workflow.ts +17 -4
  328. package/src/types.ts +41 -1
  329. package/src/utils/codex-auth-failure.ts +34 -0
  330. package/src/utils/context-window.ts +47 -53
  331. package/src/utils/credentials.ts +72 -30
  332. package/src/utils/error-tracker.ts +80 -0
  333. package/src/utils/harness-cli-version.ts +115 -0
  334. package/src/utils/harness-model-error.ts +33 -0
  335. package/src/utils/model-rate-limit-windows.ts +12 -0
  336. package/src/utils/runtime-model-catalog.ts +152 -0
  337. package/src/utils/spawn-model-guard.ts +43 -0
  338. package/src/utils/subscription-plans.ts +22 -0
  339. package/src/workflows/approval-resolution.ts +39 -0
  340. package/src/workflows/definition.ts +7 -0
  341. package/src/workflows/engine.ts +69 -1
  342. package/src/workflows/executors/agent-task.ts +16 -6
  343. package/src/workflows/executors/base.ts +53 -0
  344. package/src/workflows/executors/human-in-the-loop.ts +8 -8
  345. package/src/workflows/executors/index.ts +1 -0
  346. package/src/workflows/executors/registry.ts +2 -0
  347. package/src/workflows/executors/system-one-decision.ts +1232 -0
  348. package/src/workflows/executors/system-one-providers.ts +301 -0
  349. package/src/workflows/executors/workflow-llm.ts +13 -1
  350. package/src/workflows/model-validation.ts +45 -0
  351. package/src/workflows/patch-definition.ts +5 -0
  352. package/src/workflows/readiness.ts +86 -0
  353. package/src/workflows/recovery.ts +12 -12
  354. package/src/workflows/resume.ts +23 -9
  355. package/src/workflows/triggers.ts +85 -0
  356. package/templates/schedules/daily-blocker-digest/content.md +4 -5
  357. package/templates/skills/agent-browser/SKILL.md +6 -5
  358. package/templates/skills/agent-browser/content.md +6 -5
  359. package/templates/skills/heartbeat-runbook/config.json +1 -1
  360. package/templates/skills/heartbeat-runbook/content.md +2 -2
  361. package/templates/skills/swarm-scripts/SKILL.md +1 -1
  362. package/templates/skills/swarm-scripts/content.md +1 -1
  363. package/templates/skills/workflow-iterate/content.md +82 -1
  364. package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
  365. package/templates/workflows/pr-review-status-sweep/content.md +2 -0
  366. package/dist/boot-seeds-s3q01xj3.js +0 -26
  367. package/dist/claude-sdk-session-t442qz6f.js +0 -39108
  368. package/dist/cli-0xjkj1j7.js +0 -61
  369. package/dist/cli-20cj37vt.js +0 -335561
  370. package/dist/cli-2djtr51b.js +0 -48
  371. package/dist/cli-65hjmev5.js +0 -1141
  372. package/dist/cli-aw1jwp1r.js +0 -14075
  373. package/dist/cli-h967nb6r.js +0 -6603
  374. package/dist/cli-vapyk8sw.js +0 -20
  375. package/dist/cli-ws6rqycm.js +0 -247
  376. package/dist/pricing-refresh-v1cbr9te.js +0 -27
  377. package/src/providers/modelsdev-reasoning.json +0 -6453
  378. package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
@@ -1,7 +1,12 @@
1
+ import {
2
+ ALL_TOOLS,
3
+ init_tool_config
4
+ } from "./cli-3qhyh31j.js";
1
5
  import {
2
6
  AgentAvatarSchema,
3
7
  CreateTaskOptionsSchema,
4
8
  FollowUpConfigSchema,
9
+ MODEL_TIERS,
5
10
  PROVIDER_STEER_CAPABILITIES,
6
11
  ProviderNameSchema,
7
12
  ReasoningEffortSchema,
@@ -17,7 +22,7 @@ import {
17
22
  normalizeAssetKey,
18
23
  parseAssetKey,
19
24
  parseModelTier
20
- } from "./cli-4198qc9v.js";
25
+ } from "./cli-ktmyrtpn.js";
21
26
  import {
22
27
  IdentityFieldBudgetError,
23
28
  checkIdentityFieldBudget,
@@ -30,7 +35,11 @@ import {
30
35
  init_templates,
31
36
  matchesDefaultClaudeMd,
32
37
  matchesDefaultIdentityMd
33
- } from "./cli-3gmcwfyx.js";
38
+ } from "./cli-r1mxd1xh.js";
39
+ import {
40
+ init_config,
41
+ isSlackConfigured
42
+ } from "./cli-n7h1kqpf.js";
34
43
  import {
35
44
  configureDbResolver,
36
45
  getAllTemplateDefinitions,
@@ -40,28 +49,33 @@ import {
40
49
  init_steering_enabled,
41
50
  isSteeringEnabled,
42
51
  registerTemplate
43
- } from "./cli-ggm92wcn.js";
52
+ } from "./cli-ptr8h7kp.js";
53
+ import {
54
+ SUBSCRIPTION_KEY_TYPES,
55
+ estimateClaudePlan,
56
+ init_subscription_plans,
57
+ planAllowsModelFamily
58
+ } from "./cli-1a2j50m0.js";
44
59
  import {
45
60
  deriveProviderFromKeyType,
46
61
  init_credentials
47
- } from "./cli-19jenss3.js";
48
- import {
49
- init_config,
50
- isSlackConfigured
51
- } from "./cli-n7h1kqpf.js";
62
+ } from "./cli-0wgxmwf6.js";
52
63
  import {
53
64
  activeModelBlock,
54
65
  init_model_rate_limit_windows
55
- } from "./cli-de1396j2.js";
56
- import {
57
- SUBSCRIPTION_KEY_TYPES,
58
- estimateClaudePlan,
59
- init_subscription_plans
60
- } from "./cli-cqt19wg6.js";
66
+ } from "./cli-ywybs5as.js";
61
67
  import {
62
68
  init_env_flag,
63
69
  isEnvFlagEnabled
64
70
  } from "./cli-ej6gbxfb.js";
71
+ import {
72
+ harnessModelMismatch,
73
+ init_runtime_model_catalog,
74
+ init_src,
75
+ isAlias,
76
+ parseAlias,
77
+ runtimeHarnessSections
78
+ } from "./cli-kmcpfwn2.js";
65
79
  import {
66
80
  init_zod
67
81
  } from "./cli-sd0mxa3c.js";
@@ -77,7 +91,7 @@ import {
77
91
  import {
78
92
  init_package,
79
93
  package_default
80
- } from "./cli-c07r9a2m.js";
94
+ } from "./cli-0q3avq3s.js";
81
95
  import {
82
96
  init_secret_scrubber,
83
97
  registerVolatileSecret,
@@ -355,7 +369,7 @@ var init_slack_routing = __esm(() => {
355
369
 
356
370
  // src/telemetry.ts
357
371
  import { randomUUID } from "node:crypto";
358
- function isEnabled() {
372
+ function isTelemetryEnabled() {
359
373
  return isEnvFlagEnabled("ANONYMIZED_TELEMETRY", true);
360
374
  }
361
375
  function isCloudHostname(hostname) {
@@ -426,7 +440,7 @@ function _hasEmailChannel(env = process.env) {
426
440
  return !!env.AGENTMAIL_WEBHOOK_SECRET && !isEnvFlagEnabled("AGENTMAIL_DISABLE", false, env);
427
441
  }
428
442
  async function initTelemetry(sourceId, getConfig, setConfig, options = {}) {
429
- if (!isEnabled())
443
+ if (!isTelemetryEnabled())
430
444
  return;
431
445
  source = sourceId;
432
446
  const generateIfMissing = options.generateIfMissing === true;
@@ -489,7 +503,7 @@ function getTelemetryEnvironment() {
489
503
  return "production";
490
504
  }
491
505
  function track(options) {
492
- if (!isEnabled() || !installationId)
506
+ if (!isTelemetryEnabled() || !installationId)
493
507
  return;
494
508
  try {
495
509
  const payload = {
@@ -530,7 +544,7 @@ function track(options) {
530
544
  } catch {}
531
545
  }
532
546
  function emitIntegrationConnected(type, providerSlug, firstOfType) {
533
- if (!isEnabled() || !installationId)
547
+ if (!isTelemetryEnabled() || !installationId)
534
548
  return false;
535
549
  const provider = _resolveIntegrationProvider(providerSlug);
536
550
  telemetry.integration("connected", {
@@ -652,6 +666,27 @@ var init_telemetry = __esm(() => {
652
666
  };
653
667
  });
654
668
 
669
+ // src/utils/codex-auth-failure.ts
670
+ function isCodexAuthFailureReason(failureReason) {
671
+ if (!failureReason || !failureReason.includes("[auth-error]"))
672
+ return false;
673
+ const lower = failureReason.toLowerCase();
674
+ return !TRANSIENT_AUTH_ERROR_MARKERS.some((m) => lower.includes(m));
675
+ }
676
+ var CODEX_AUTH_FAILURE_BENCH_THRESHOLD = 2, CODEX_AUTH_FAILURE_BENCH_MS, CODEX_AUTH_WATCH_NAMESPACE = "codex-auth-watch", codexAuthBenchMarkerKey = (keySuffix) => `bench:${keySuffix}`, TRANSIENT_AUTH_ERROR_MARKERS;
677
+ var init_codex_auth_failure = __esm(() => {
678
+ CODEX_AUTH_FAILURE_BENCH_MS = 365 * 24 * 60 * 60 * 1000;
679
+ TRANSIENT_AUTH_ERROR_MARKERS = [
680
+ "waiting for the refresh lock",
681
+ "refresh rejected (429",
682
+ "refresh rejected (5",
683
+ "refresh rejected (unknown status",
684
+ "out of credits",
685
+ "no credentials found in config store",
686
+ "not a confirmed auth rejection"
687
+ ];
688
+ });
689
+
655
690
  // src/utils/github-pull-request.ts
656
691
  function parseGitHubPullRequestToken(token) {
657
692
  const candidate = token.replace(TRAILING_PROSE_PUNCTUATION_RE, "");
@@ -2501,6 +2536,17 @@ async function getAllAgents(opts) {
2501
2536
  const rows = await getDbClient().query(opts?.includeExtensions ? "SELECT * FROM agents ORDER BY name" : `SELECT * FROM agents WHERE ${NOT_EXTENSION_AGENT_SQL} ORDER BY name`);
2502
2537
  return rows.map((row) => rowToAgent(row, opts?.slim ?? false));
2503
2538
  }
2539
+ async function getAgentStatusCounts() {
2540
+ const rows = await getDbClient().query(`SELECT status, COUNT(*) AS count FROM agents WHERE ${NOT_EXTENSION_AGENT_SQL} GROUP BY status`);
2541
+ const counts = { total: 0, idle: 0, busy: 0, offline: 0 };
2542
+ for (const { status, count } of rows) {
2543
+ counts.total += count;
2544
+ if (status === "idle" || status === "busy" || status === "offline") {
2545
+ counts[status] = count;
2546
+ }
2547
+ }
2548
+ return counts;
2549
+ }
2504
2550
  async function getLeadAgent() {
2505
2551
  const leads = (await getAllAgents()).filter((a) => a.isLead);
2506
2552
  return leads.find((a) => a.status !== "offline") ?? leads[0] ?? null;
@@ -2789,6 +2835,199 @@ var init_context_versions = __esm(() => {
2789
2835
  init_runtime();
2790
2836
  });
2791
2837
 
2838
+ // src/be/db/tasks/human-free.ts
2839
+ function humanFreeCase(parentFlag) {
2840
+ return `CASE
2841
+ WHEN ${HUMAN_FREE_BASE_SQL} THEN 1
2842
+ WHEN ${parentFlag} = 1 AND ${UNATTRIBUTED_SQL} THEN 1
2843
+ ELSE 0
2844
+ END`;
2845
+ }
2846
+ function carriesHumanFreeTag(tagsJson) {
2847
+ const haystack = (tagsJson ?? "[]").toLowerCase();
2848
+ return HUMAN_FREE_TAGS.some((tag) => haystack.includes(`"${tag}"`));
2849
+ }
2850
+ function tagWriteChangesHumanFree(previousTagsJson, nextTagsJson) {
2851
+ return carriesHumanFreeTag(previousTagsJson) !== carriesHumanFreeTag(nextTagsJson);
2852
+ }
2853
+ async function classifyTaskHumanFree(input) {
2854
+ const row = await getDbClient().get(`WITH task(taskType, tags, source, requestedByUserId, requestedByUserIdInherited, parentTaskId, workflowRunId) AS (
2855
+ VALUES (?, ?, ?, ?, ?, ?, ?)
2856
+ )
2857
+ SELECT ${humanFreeCase("parent.isHumanFree")} AS humanFree
2858
+ FROM task
2859
+ LEFT JOIN agent_tasks parent ON parent.id = task.parentTaskId`, [
2860
+ input.taskType ?? null,
2861
+ input.tags ?? null,
2862
+ input.source ?? null,
2863
+ input.requestedByUserId ?? null,
2864
+ input.requestedByUserIdInherited ? 1 : 0,
2865
+ input.parentTaskId ?? null,
2866
+ input.workflowRunId ?? null
2867
+ ]);
2868
+ return row?.humanFree === 1;
2869
+ }
2870
+ function setHumanFreeQueueListener(listener) {
2871
+ queueListener = listener;
2872
+ }
2873
+ async function enqueueHumanFreeWork(taskIds, scope, hops) {
2874
+ if (taskIds.length === 0)
2875
+ return;
2876
+ if (hops > HUMAN_FREE_MAX_CONTINUATION_HOPS) {
2877
+ console.error(`[human-free] dropping ${taskIds.length} ${scope} continuation(s) past ${HUMAN_FREE_MAX_CONTINUATION_HOPS} hops; the task graph likely has a parent cycle`);
2878
+ return;
2879
+ }
2880
+ await getDbClient().run(`INSERT INTO human_free_reclassify_queue (taskId, scope, afterRowid, hops)
2881
+ SELECT value, ?, 0, ? FROM json_each(?) WHERE true
2882
+ ON CONFLICT (taskId, scope) DO UPDATE SET
2883
+ afterRowid = 0,
2884
+ hops = MAX(hops, excluded.hops)`, [scope, hops, JSON.stringify(taskIds)]);
2885
+ getDbClient().afterCommit(() => queueListener?.());
2886
+ }
2887
+ async function reclassifyBatch(seedTaskIds, batchSize, hops) {
2888
+ const client = getDbClient();
2889
+ const affected = (await client.query(`WITH RECURSIVE affected(id) AS (
2890
+ SELECT value FROM json_each(?)
2891
+
2892
+ UNION
2893
+
2894
+ SELECT task.id
2895
+ FROM affected
2896
+ JOIN agent_tasks task ON task.parentTaskId = affected.id
2897
+ LIMIT ?
2898
+ )
2899
+ SELECT id FROM affected`, [JSON.stringify(seedTaskIds), batchSize])).map((row) => row.id);
2900
+ const result = await client.run(`WITH RECURSIVE affected(id) AS (
2901
+ SELECT value FROM json_each(?)
2902
+ ),
2903
+ free(id) AS (
2904
+ SELECT task.id
2905
+ FROM agent_tasks task
2906
+ LEFT JOIN agent_tasks parent ON parent.id = task.parentTaskId
2907
+ WHERE task.id IN (SELECT id FROM affected)
2908
+ AND (
2909
+ ${HUMAN_FREE_BASE_SQL}
2910
+ OR (
2911
+ parent.isHumanFree = 1
2912
+ AND parent.id NOT IN (SELECT id FROM affected)
2913
+ AND ${UNATTRIBUTED_SQL}
2914
+ )
2915
+ )
2916
+
2917
+ UNION
2918
+
2919
+ SELECT task.id
2920
+ FROM free
2921
+ JOIN agent_tasks task ON task.parentTaskId = free.id
2922
+ WHERE +task.id IN (SELECT id FROM affected)
2923
+ AND ${UNATTRIBUTED_SQL}
2924
+ )
2925
+ UPDATE agent_tasks
2926
+ SET isHumanFree = CASE WHEN id IN (SELECT id FROM free) THEN 1 ELSE 0 END
2927
+ WHERE id IN (SELECT id FROM affected)
2928
+ AND isHumanFree != CASE WHEN id IN (SELECT id FROM free) THEN 1 ELSE 0 END`, [JSON.stringify(affected)]);
2929
+ if (affected.length >= batchSize) {
2930
+ const unfinished = await client.query(`WITH batch(id) AS (
2931
+ SELECT value FROM json_each(?)
2932
+ )
2933
+ SELECT batch.id
2934
+ FROM batch
2935
+ WHERE EXISTS (
2936
+ SELECT 1
2937
+ FROM agent_tasks child
2938
+ WHERE child.parentTaskId = batch.id
2939
+ AND child.id NOT IN (SELECT id FROM batch)
2940
+ )`, [JSON.stringify(affected)]);
2941
+ await enqueueHumanFreeWork(unfinished.map((row) => row.id), "children", hops);
2942
+ }
2943
+ return result.changes;
2944
+ }
2945
+ async function reclassifyTaskHumanFree(seedTaskIds, options = {}) {
2946
+ const batchSize = options.batchSize ?? HUMAN_FREE_RECLASSIFY_BATCH;
2947
+ const seeds = [...new Set(seedTaskIds)];
2948
+ if (seeds.length === 0)
2949
+ return 0;
2950
+ await enqueueHumanFreeWork(seeds.slice(batchSize), "self", 1);
2951
+ return await reclassifyBatch(seeds.slice(0, batchSize), batchSize, 1);
2952
+ }
2953
+ async function drainOneBatch(batchSize) {
2954
+ return await getDbClient().transaction(async (tx) => {
2955
+ const head = await tx.get("SELECT * FROM human_free_reclassify_queue ORDER BY seq LIMIT 1");
2956
+ if (!head)
2957
+ return null;
2958
+ if (head.scope === "self") {
2959
+ const rows = await tx.query("SELECT * FROM human_free_reclassify_queue WHERE scope = 'self' ORDER BY seq LIMIT ?", [batchSize]);
2960
+ const seeds = rows.map((row) => row.taskId);
2961
+ const hops = Math.max(...rows.map((row) => row.hops)) + 1;
2962
+ await tx.run("DELETE FROM human_free_reclassify_queue WHERE seq IN (SELECT value FROM json_each(?))", [JSON.stringify(rows.map((row) => row.seq))]);
2963
+ return await reclassifyBatch(seeds, batchSize, hops);
2964
+ }
2965
+ const page = await tx.query(`SELECT id, rowid AS position
2966
+ FROM agent_tasks
2967
+ WHERE parentTaskId = ? AND rowid > ?
2968
+ ORDER BY rowid
2969
+ LIMIT ?`, [head.taskId, head.afterRowid, batchSize]);
2970
+ if (page.length < batchSize) {
2971
+ await tx.run("DELETE FROM human_free_reclassify_queue WHERE seq = ?", [head.seq]);
2972
+ } else {
2973
+ await tx.run("UPDATE human_free_reclassify_queue SET afterRowid = ? WHERE seq = ?", [
2974
+ page[page.length - 1]?.position ?? head.afterRowid,
2975
+ head.seq
2976
+ ]);
2977
+ }
2978
+ if (page.length === 0)
2979
+ return 0;
2980
+ return await reclassifyBatch(page.map((row) => row.id), batchSize, head.hops + 1);
2981
+ });
2982
+ }
2983
+ async function pendingHumanFreeReclassifications() {
2984
+ const row = await getDbClient().get("SELECT COUNT(*) AS count FROM human_free_reclassify_queue");
2985
+ return row?.count ?? 0;
2986
+ }
2987
+ async function drainHumanFreeReclassifyQueue(options = {}) {
2988
+ const batchSize = options.batchSize ?? HUMAN_FREE_RECLASSIFY_BATCH;
2989
+ const maxBatches = options.maxBatches ?? Number.POSITIVE_INFINITY;
2990
+ let batches = 0;
2991
+ let changed = 0;
2992
+ while (batches < maxBatches) {
2993
+ const batchChanged = await drainOneBatch(batchSize);
2994
+ if (batchChanged === null)
2995
+ break;
2996
+ batches += 1;
2997
+ changed += batchChanged;
2998
+ }
2999
+ return { batches, changed, remaining: await pendingHumanFreeReclassifications() };
3000
+ }
3001
+ var HUMAN_FREE_TAGS, HUMAN_FREE_TAG_SQL, HUMAN_FREE_BASE_SQL, UNATTRIBUTED_SQL = "(task.requestedByUserId IS NULL OR task.requestedByUserIdInherited = 1)", HUMAN_FREE_RECLASSIFY_BATCH = 500, HUMAN_FREE_MAX_CONTINUATION_HOPS = 1e4, queueListener;
3002
+ var init_human_free = __esm(() => {
3003
+ init_runtime();
3004
+ HUMAN_FREE_TAGS = ["heartbeat"];
3005
+ HUMAN_FREE_TAG_SQL = HUMAN_FREE_TAGS.map((tag) => `COALESCE(task.tags, '[]') LIKE '%"${tag}"%'`).join(`
3006
+ OR `);
3007
+ HUMAN_FREE_BASE_SQL = `(
3008
+ COALESCE(task.taskType, '') IN ('heartbeat', 'heartbeat-checklist', 'boot-triage')
3009
+ OR ${HUMAN_FREE_TAG_SQL}
3010
+ OR (COALESCE(task.source, '') = 'schedule' AND task.requestedByUserId IS NULL)
3011
+ OR (
3012
+ task.parentTaskId IS NULL
3013
+ AND COALESCE(task.source, '') = 'workflow'
3014
+ AND task.requestedByUserId IS NULL
3015
+ AND EXISTS (
3016
+ SELECT 1
3017
+ FROM workflow_runs run
3018
+ WHERE run.id = task.workflowRunId
3019
+ AND run.triggerType = 'schedule'
3020
+ AND run.created_by IS NULL
3021
+ )
3022
+ )
3023
+ OR (
3024
+ COALESCE(task.source, '') = 'system'
3025
+ AND parent.id IS NOT NULL
3026
+ AND parent.requestedByUserId IS NULL
3027
+ )
3028
+ )`;
3029
+ });
3030
+
2792
3031
  // src/utils/provider-metadata.ts
2793
3032
  function parseProviderMeta(rawProvider, rawMeta) {
2794
3033
  if (!rawMeta || !rawProvider)
@@ -2882,6 +3121,9 @@ function rowToAgentTask(row) {
2882
3121
  claudeSessionId: row.claudeSessionId ?? undefined,
2883
3122
  model: row.model ?? undefined,
2884
3123
  modelTier: parseModelTier(row.modelTier) ?? undefined,
3124
+ resolvedModel: row.resolvedModel ?? undefined,
3125
+ modelSource: row.modelSource ?? undefined,
3126
+ modelAlias: row.modelAlias ?? undefined,
2885
3127
  effort: ReasoningEffortSchema.safeParse(row.effort).success ? row.effort : undefined,
2886
3128
  scheduleId: row.scheduleId ?? undefined,
2887
3129
  workflowRunId: row.workflowRunId ?? undefined,
@@ -2935,6 +3177,9 @@ function rowToAgentTaskSummary(row) {
2935
3177
  scheduleId: row.scheduleId ?? undefined,
2936
3178
  model: row.model ?? undefined,
2937
3179
  modelTier: parseModelTier(row.modelTier) ?? undefined,
3180
+ resolvedModel: row.resolvedModel ?? undefined,
3181
+ modelSource: row.modelSource ?? undefined,
3182
+ modelAlias: row.modelAlias ?? undefined,
2938
3183
  effort: ReasoningEffortSchema.safeParse(row.effort).success ? row.effort : undefined,
2939
3184
  provider: row.provider ?? undefined,
2940
3185
  requestedByUserId: row.requestedByUserId ?? undefined,
@@ -2989,6 +3234,24 @@ async function getSupersededTasksWithoutResume(finishedBefore, finishedAfter) {
2989
3234
  ORDER BY t.finishedAt ASC`, [finishedBefore, finishedAfter]);
2990
3235
  return rows.map(rowToAgentTask);
2991
3236
  }
3237
+ async function getSupersededTasksWithUnsettledDependents(finishedBefore, finishedAfter) {
3238
+ const placeholders = NEVER_STARTED_TASK_STATUSES.map(() => "?").join(", ");
3239
+ return getDbClient().query(`SELECT taskId, resumeTaskId FROM (
3240
+ SELECT t.id AS taskId, t.finishedAt AS finishedAt,
3241
+ (SELECT c.id FROM agent_tasks c
3242
+ WHERE c.parentTaskId = t.id AND c.taskType = 'resume'
3243
+ ORDER BY c.createdAt DESC LIMIT 1) AS resumeTaskId
3244
+ FROM agent_tasks t
3245
+ WHERE t.status = 'superseded'
3246
+ AND t.finishedAt < ?
3247
+ AND t.finishedAt > ?
3248
+ AND EXISTS (
3249
+ SELECT 1 FROM agent_tasks d, json_each(d.dependsOn) AS j
3250
+ WHERE j.value = t.id AND d.status IN (${placeholders})
3251
+ ))
3252
+ WHERE resumeTaskId IS NOT NULL
3253
+ ORDER BY finishedAt ASC`, [finishedBefore, finishedAfter, ...NEVER_STARTED_TASK_STATUSES]);
3254
+ }
2992
3255
  async function hasNonTerminalRerouteDecisionChild(parentId) {
2993
3256
  const row = await getDbClient().get(`SELECT 1 FROM agent_tasks
2994
3257
  WHERE parentTaskId = ?
@@ -3482,7 +3745,7 @@ async function findRecentCancelledTaskInThread(channelId, threadTs, windowMinute
3482
3745
  LIMIT 1`, [channelId, threadTs, since]);
3483
3746
  return row ? rowToAgentTask(row) : null;
3484
3747
  }
3485
- var dependencies2, TASK_PREVIEW_LENGTH = 300, TASK_PREVIEW_BYTES, TASK_PREVIEW_SQL, taskPreviewDecoder, LIST_COLUMNS, findTaskByGitHub, LINEAR_TRACKER_CONTEXT_KEY_PREFIX = "task:trackers:linear:";
3748
+ var dependencies2, TASK_PREVIEW_LENGTH = 300, TASK_PREVIEW_BYTES, TASK_PREVIEW_SQL, taskPreviewDecoder, LIST_COLUMNS, NEVER_STARTED_TASK_STATUSES, findTaskByGitHub, LINEAR_TRACKER_CONTEXT_KEY_PREFIX = "task:trackers:linear:";
3486
3749
  var init_read = __esm(() => {
3487
3750
  init_key();
3488
3751
  init_types();
@@ -3498,7 +3761,8 @@ var init_read = __esm(() => {
3498
3761
  ${TASK_PREVIEW_SQL}, agent_tasks.title, agent_tasks.status, agent_tasks.source,
3499
3762
  agent_tasks.taskType, agent_tasks.tags, agent_tasks.priority, agent_tasks.dependsOn,
3500
3763
  agent_tasks.offeredTo, agent_tasks.acceptedAt, agent_tasks.parentTaskId,
3501
- agent_tasks.scheduleId, agent_tasks.model, agent_tasks.modelTier, agent_tasks.effort,
3764
+ agent_tasks.scheduleId, agent_tasks.model, agent_tasks.modelTier,
3765
+ agent_tasks.resolvedModel, agent_tasks.modelSource, agent_tasks.modelAlias, agent_tasks.effort,
3502
3766
  agent_tasks.provider, agent_tasks.requestedByUserId, agent_tasks.progress,
3503
3767
  agent_tasks.createdAt, agent_tasks.lastUpdatedAt, agent_tasks.finishedAt,
3504
3768
  agent_tasks.peakContextPercent`,
@@ -3506,6 +3770,14 @@ var init_read = __esm(() => {
3506
3770
  agent_tasks.title, agent_tasks.status, agent_tasks.createdAt, agent_tasks.lastUpdatedAt,
3507
3771
  agent_tasks.finishedAt, agent_tasks.peakContextTokens`
3508
3772
  };
3773
+ NEVER_STARTED_TASK_STATUSES = [
3774
+ "draft",
3775
+ "backlog",
3776
+ "unassigned",
3777
+ "offered",
3778
+ "reviewing",
3779
+ "pending"
3780
+ ];
3509
3781
  findTaskByGitHub = findTaskByVcs;
3510
3782
  });
3511
3783
 
@@ -3535,8 +3807,9 @@ function configureTaskWriteDependencies(value) {
3535
3807
  async function createTask(agentId, task, options) {
3536
3808
  const id = crypto.randomUUID();
3537
3809
  const source2 = options?.source ?? "mcp";
3538
- const row = await getDbClient().get(`INSERT INTO agent_tasks (id, "key", agentId, task, status, source, slackChannelId, slackThreadTs, slackUserId, swarmVersion, createdAt, lastUpdatedAt)
3539
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) RETURNING *`, [
3810
+ const isHumanFree = await classifyTaskHumanFree({ source: source2 });
3811
+ const row = await getDbClient().get(`INSERT INTO agent_tasks (id, "key", agentId, task, status, source, slackChannelId, slackThreadTs, slackUserId, swarmVersion, isHumanFree, createdAt, lastUpdatedAt)
3812
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) RETURNING *`, [
3540
3813
  id,
3541
3814
  defaultAssetKey("task", id),
3542
3815
  agentId,
@@ -3546,7 +3819,8 @@ async function createTask(agentId, task, options) {
3546
3819
  options?.slackChannelId ?? null,
3547
3820
  options?.slackThreadTs ?? null,
3548
3821
  options?.slackUserId ?? null,
3549
- package_default.version
3822
+ package_default.version,
3823
+ isHumanFree ? 1 : 0
3550
3824
  ]);
3551
3825
  if (!row)
3552
3826
  throw new Error("Failed to create task");
@@ -3719,7 +3993,12 @@ async function completeTask(id, output, options) {
3719
3993
  if (completed && options?.addTags?.length) {
3720
3994
  const existingTags = completed.tags ? JSON.parse(completed.tags) : [];
3721
3995
  const nextTags = Array.from(new Set([...existingTags, ...options.addTags]));
3722
- completed = await getDbClient().get("UPDATE agent_tasks SET tags = ?, lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ? RETURNING *", [JSON.stringify(nextTags), id]);
3996
+ const previousTagsJson = completed.tags;
3997
+ const nextTagsJson = JSON.stringify(nextTags);
3998
+ completed = await getDbClient().get("UPDATE agent_tasks SET tags = ?, lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ? RETURNING *", [nextTagsJson, id]);
3999
+ if (tagWriteChangesHumanFree(previousTagsJson, nextTagsJson)) {
4000
+ await reclassifyTaskHumanFree([id]);
4001
+ }
3723
4002
  }
3724
4003
  if (completed && options?.deferredAt) {
3725
4004
  completed = await getDbClient().get("UPDATE agent_tasks SET deferredAt = ?, lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ? RETURNING *", [options.deferredAt, id]);
@@ -3950,15 +4229,52 @@ async function supersedeTask(id, args) {
3950
4229
  });
3951
4230
  }).catch((err) => console.error("[db] task.superseded event not emitted:", scrubSecrets(err instanceof Error ? err.message : String(err))));
3952
4231
  });
3953
- try {
3954
- await dependencies3.cascadeFailDependents(id, "superseded");
3955
- } catch (err) {
3956
- console.error("[supersedeTask] cascade-fail dependents error:", err);
3957
- }
4232
+ if (args.resumeTaskId)
4233
+ await settleSupersededTaskDependents(id, args.resumeTaskId);
3958
4234
  }
3959
4235
  return row ? rowToAgentTask(row) : null;
3960
4236
  }
4237
+ async function settleSupersededTaskDependents(supersededId, resumeTaskId) {
4238
+ try {
4239
+ if (resumeTaskId) {
4240
+ const placeholders = NEVER_STARTED_TASK_STATUSES.map(() => "?").join(", ");
4241
+ const repointed = await getDbClient().query(`UPDATE agent_tasks
4242
+ SET dependsOn = (
4243
+ SELECT json_group_array(value ORDER BY k) FROM (
4244
+ SELECT CASE WHEN j.value = ? THEN ? ELSE j.value END AS value,
4245
+ MIN(j.key) AS k
4246
+ FROM json_each(agent_tasks.dependsOn) AS j
4247
+ GROUP BY 1)),
4248
+ lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
4249
+ WHERE status IN (${placeholders})
4250
+ AND EXISTS (SELECT 1 FROM json_each(agent_tasks.dependsOn) WHERE value = ?)
4251
+ RETURNING id, agentId`, [supersededId, resumeTaskId, ...NEVER_STARTED_TASK_STATUSES, supersededId]);
4252
+ for (const dep of repointed) {
4253
+ try {
4254
+ await dependencies3.createLogEntry({
4255
+ eventType: "task_dependency_repointed",
4256
+ taskId: dep.id,
4257
+ agentId: dep.agentId ?? undefined,
4258
+ oldValue: supersededId,
4259
+ newValue: resumeTaskId,
4260
+ metadata: { reason: "supersede_resume" }
4261
+ });
4262
+ } catch {}
4263
+ }
4264
+ const resume = await getTaskById(resumeTaskId);
4265
+ if (repointed.length > 0 && (resume?.status === "failed" || resume?.status === "cancelled")) {
4266
+ await dependencies3.cascadeFailDependents(resumeTaskId, resume.status);
4267
+ }
4268
+ }
4269
+ await dependencies3.cascadeFailDependents(supersededId, "superseded");
4270
+ } catch (err) {
4271
+ console.error("[supersedeTask] settling dependents error:", err);
4272
+ }
4273
+ }
3961
4274
  async function backfillSupersedeTaskResumeTaskId(taskId, resumeTaskId) {
4275
+ if ((await getTaskById(taskId))?.status === "superseded") {
4276
+ await settleSupersededTaskDependents(taskId, resumeTaskId);
4277
+ }
3962
4278
  const row = await getDbClient().get(`SELECT id, metadata
3963
4279
  FROM agent_log
3964
4280
  WHERE taskId = ? AND eventType = 'task_superseded'
@@ -4091,8 +4407,12 @@ async function getRecentlyCancelledTasksForAgent(agentId) {
4091
4407
  return rows.map(rowToAgentTask);
4092
4408
  }
4093
4409
  async function deleteTask(id) {
4094
- const result = await getDbClient().run("DELETE FROM agent_tasks WHERE id = ?", [id]);
4095
- return result.changes > 0;
4410
+ return await getDbClient().transaction(async (tx) => {
4411
+ const childIds = (await tx.query("SELECT id FROM agent_tasks WHERE parentTaskId = ?", [id])).map((row) => row.id);
4412
+ const result = await tx.run("DELETE FROM agent_tasks WHERE id = ?", [id]);
4413
+ await reclassifyTaskHumanFree(childIds);
4414
+ return result.changes > 0;
4415
+ });
4096
4416
  }
4097
4417
  async function updateTaskProgress(id, progress) {
4098
4418
  const scrubbedProgress = scrubSecrets(progress);
@@ -4130,6 +4450,7 @@ var init_write = __esm(() => {
4130
4450
  init_task_lifecycle_events();
4131
4451
  init_agents();
4132
4452
  init_runtime();
4453
+ init_human_free();
4133
4454
  init_read();
4134
4455
  AFFINITY_DISPATCH_SKIP_LOG_COOLDOWN_MS = 5 * 60 * 1000;
4135
4456
  lastAffinityDispatchSkipLoggedAt = new Map;
@@ -4336,165 +4657,6 @@ var init_reaction_shortcode = __esm(() => {
4336
4657
  SLACK_REACTION_SHORTCODE_PATTERN = /^[a-z0-9_+'-]+(::skin-tone-[2-6])?$/;
4337
4658
  });
4338
4659
 
4339
- // src/tools/tool-config.ts
4340
- var CORE_TOOLS, DEFERRED_TOOLS, ALL_TOOLS;
4341
- var init_tool_config = __esm(() => {
4342
- CORE_TOOLS = new Set([
4343
- "join-swarm",
4344
- "my-agent-info",
4345
- "poll-task",
4346
- "get-task-details",
4347
- "store-progress",
4348
- "task-action",
4349
- "send-task",
4350
- "get-tasks",
4351
- "defer-task",
4352
- "memory-search",
4353
- "memory-get",
4354
- "memory-store",
4355
- "memory-delete",
4356
- "memory_rate",
4357
- "get-swarm",
4358
- "script-run",
4359
- "db-query",
4360
- "kv-get",
4361
- "script-query-types",
4362
- "get-repos",
4363
- "accept-steer",
4364
- "memory-edit",
4365
- "script-search",
4366
- "steer-task",
4367
- "kv-list",
4368
- "get-config"
4369
- ]);
4370
- DEFERRED_TOOLS = new Set([
4371
- "list-schedules",
4372
- "create-schedule",
4373
- "update-schedule",
4374
- "patch-schedule",
4375
- "delete-schedule",
4376
- "run-schedule-now",
4377
- "create-workflow",
4378
- "list-workflows",
4379
- "get-workflow",
4380
- "update-workflow",
4381
- "patch-workflow",
4382
- "patch-workflow-node",
4383
- "delete-workflow",
4384
- "trigger-workflow",
4385
- "list-workflow-runs",
4386
- "get-workflow-run",
4387
- "retry-workflow-run",
4388
- "cancel-workflow-run",
4389
- "register-service",
4390
- "unregister-service",
4391
- "list-services",
4392
- "update-service-status",
4393
- "set-config",
4394
- "list-config",
4395
- "delete-config",
4396
- "credential-bindings",
4397
- "script-connections",
4398
- "update-repo",
4399
- "update-profile",
4400
- "context-history",
4401
- "context-diff",
4402
- "read-messages",
4403
- "post-message",
4404
- "slack-reply",
4405
- "slack-read",
4406
- "slack-upload-file",
4407
- "slack-download-file",
4408
- "slack-list-channels",
4409
- "slack-post",
4410
- "slack-start-thread",
4411
- "slack-create-channel",
4412
- "slack-invite-to-channel",
4413
- "slack-archive-channel",
4414
- "slack-delete",
4415
- "slack-update",
4416
- "create-channel",
4417
- "delete-channel",
4418
- "list-channels",
4419
- "register-agentmail-inbox",
4420
- "register-kapso-number",
4421
- "unregister-kapso-number",
4422
- "send-whatsapp-message",
4423
- "reply-whatsapp-message",
4424
- "tracker-status",
4425
- "get-oauth-access-token",
4426
- "tracker-link-task",
4427
- "tracker-unlink",
4428
- "tracker-sync-status",
4429
- "tracker-map-agent",
4430
- "list-prompt-templates",
4431
- "get-prompt-template",
4432
- "set-prompt-template",
4433
- "delete-prompt-template",
4434
- "preview-prompt-template",
4435
- "create_metric",
4436
- "request-human-input",
4437
- "cancel-approval-request",
4438
- "skill-create",
4439
- "skill-update",
4440
- "skill-delete",
4441
- "skill-get",
4442
- "skill-get-file",
4443
- "skill-list",
4444
- "skill-search",
4445
- "skill-install",
4446
- "skill-uninstall",
4447
- "skill-install-remote",
4448
- "skill-sync-remote",
4449
- "skill-publish",
4450
- "mcp-server-create",
4451
- "mcp-server-delete",
4452
- "mcp-server-get",
4453
- "mcp-server-install",
4454
- "mcp-server-list",
4455
- "mcp-server-uninstall",
4456
- "mcp-server-update",
4457
- "resolve-user",
4458
- "manage-user",
4459
- "app-get",
4460
- "app-list",
4461
- "app-patch",
4462
- "app-query",
4463
- "app-sync",
4464
- "app-upsert",
4465
- "app-history",
4466
- "app-diff",
4467
- "app-rollback",
4468
- "create_page",
4469
- "delete-page",
4470
- "kv-set",
4471
- "kv-delete",
4472
- "kv-incr",
4473
- "room-get",
4474
- "room-change",
4475
- "room-reset",
4476
- "room-decode",
4477
- "script-upsert",
4478
- "script-delete",
4479
- "script-apis",
4480
- "launch-script-run",
4481
- "get-script-run",
4482
- "list-script-runs",
4483
- "extension-delete",
4484
- "extension-enable",
4485
- "extension-disable",
4486
- "extension-activate-version",
4487
- "extension-catalog",
4488
- "extension-install",
4489
- "extension-list",
4490
- "swarm_x",
4491
- "cancel-task",
4492
- "inject-learning",
4493
- "get-metrics"
4494
- ]);
4495
- ALL_TOOLS = new Set([...CORE_TOOLS, ...DEFERRED_TOOLS]);
4496
- });
4497
-
4498
4660
  // src/utils/task-tool-manifest.ts
4499
4661
  function parseTaskToolManifest(value) {
4500
4662
  return taskToolManifestSchema.parse(JSON.parse(value));
@@ -4515,6 +4677,42 @@ var init_task_tool_manifest = __esm(() => {
4515
4677
  });
4516
4678
  });
4517
4679
 
4680
+ // src/be/model-tier-keys.ts
4681
+ function tierConfigKey(provider, tier) {
4682
+ return `MODEL_TIER_${provider.toUpperCase().replace(/-/g, "_")}_${tier.toUpperCase()}`;
4683
+ }
4684
+ function isTierConfigKey(key) {
4685
+ return TIER_CONFIG_KEY_RE.test(key.toUpperCase());
4686
+ }
4687
+ function tierConfigKeyProvider(key) {
4688
+ const match = TIER_CONFIG_KEY_RE.exec(key.toUpperCase());
4689
+ if (!match)
4690
+ return null;
4691
+ return ProviderNameSchema.options.find((p) => p.toUpperCase().replace(/-/g, "_") === match[1]) ?? null;
4692
+ }
4693
+ function validateTierConfigValue(key, value) {
4694
+ const message = `Invalid ${key} (expected a model id, a CLI alias such as "opus", or latest:<anthropic|openai|openrouter>/<target>[@stable|@any])`;
4695
+ if (typeof value !== "string")
4696
+ return message;
4697
+ const trimmed = value.trim();
4698
+ if (trimmed.length === 0 || /\s/.test(trimmed) || trimmed.length > 200)
4699
+ return message;
4700
+ if (isAlias(trimmed) && !parseAlias(trimmed))
4701
+ return message;
4702
+ const provider = tierConfigKeyProvider(key);
4703
+ if (provider && harnessModelMismatch(trimmed, provider, runtimeHarnessSections())) {
4704
+ return `Invalid ${key}: model "${trimmed}" does not run on the ${provider} harness.`;
4705
+ }
4706
+ return null;
4707
+ }
4708
+ var TIER_CONFIG_KEY_RE;
4709
+ var init_model_tier_keys = __esm(() => {
4710
+ init_src();
4711
+ init_types();
4712
+ init_runtime_model_catalog();
4713
+ TIER_CONFIG_KEY_RE = new RegExp(`^MODEL_TIER_(${ProviderNameSchema.options.map((p) => p.toUpperCase().replace(/-/g, "_")).join("|")})_(${MODEL_TIERS.map((t) => t.toUpperCase()).join("|")})$`);
4714
+ });
4715
+
4518
4716
  // src/be/swarm-config-guard.ts
4519
4717
  function isInternalConfigKey(key) {
4520
4718
  return INTERNAL_CONFIG_KEYS.has(key.toLowerCase());
@@ -4596,6 +4794,8 @@ function validateFloatRange(key, value, min, max, expectation) {
4596
4794
  return null;
4597
4795
  }
4598
4796
  function validateConfigValue(key, value) {
4797
+ if (isTierConfigKey(key))
4798
+ return validateTierConfigValue(key.toUpperCase(), value);
4599
4799
  const validator = VALIDATED_KEYS[key.toUpperCase()];
4600
4800
  return validator ? validator(value) : null;
4601
4801
  }
@@ -4604,6 +4804,7 @@ var init_swarm_config_guard = __esm(() => {
4604
4804
  init_reaction_shortcode();
4605
4805
  init_types();
4606
4806
  init_task_tool_manifest();
4807
+ init_model_tier_keys();
4607
4808
  RESERVED_KEYS = new Set([
4608
4809
  "API_KEY",
4609
4810
  "SECRETS_ENCRYPTION_KEY",
@@ -4697,6 +4898,7 @@ var init_swarm_config_guard = __esm(() => {
4697
4898
  return null;
4698
4899
  },
4699
4900
  ...booleanValidators([
4901
+ "SWARM_DEV_MODE",
4700
4902
  "MULTI_RUNTIME_ENABLED",
4701
4903
  "STEERING_ENABLED",
4702
4904
  "MEMORY_HYBRID_SEARCH",
@@ -4706,6 +4908,8 @@ var init_swarm_config_guard = __esm(() => {
4706
4908
  "POOL_AFFINITY_ENFORCEMENT",
4707
4909
  "SCRIPTS_ONLY_MCP",
4708
4910
  "TASK_TOOL_PRELOAD_ENABLED",
4911
+ "PI_TOOL_DEFERRAL",
4912
+ "PI_CODEMODE",
4709
4913
  "SLACK_DISABLE",
4710
4914
  "SLACK_RENDER_V2",
4711
4915
  "SLACK_RENDER_V2_DELEGATION",
@@ -4726,7 +4930,8 @@ var init_swarm_config_guard = __esm(() => {
4726
4930
  "ANONYMIZED_TELEMETRY",
4727
4931
  "SWARM_HIDE_CLOUD_PROMO",
4728
4932
  "DB_QUERY_BOUNDED_ENABLED",
4729
- "DB_RETENTION_DRY_RUN"
4933
+ "DB_RETENTION_DRY_RUN",
4934
+ "MODEL_AUTO_UPGRADE"
4730
4935
  ]),
4731
4936
  ...enumValidator("SLACK_MODE", ["socket", "http"]),
4732
4937
  ...enumValidator("SLACK_THREAD_STEERING", ["off", "lead", "all"]),
@@ -4767,6 +4972,7 @@ var init_swarm_config_guard = __esm(() => {
4767
4972
  ...boundedIntegerValidatorsFor(DB_RETENTION_TUNING_BOUNDS),
4768
4973
  ...boundedIntegerValidators(["SESSION_LOG_RETENTION_DAYS", "AGENT_LOG_RETENTION_DAYS", "EVENTS_RETENTION_DAYS"], 1, MAX_DB_RETENTION_DAYS),
4769
4974
  ...integerValidators(["HEARTBEAT_MAX_AUTO_ASSIGN"], 0),
4975
+ ...integerValidators(["MODEL_LATEST_SOAK_DAYS"], 0),
4770
4976
  ...integerValidators(["APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS"], 0),
4771
4977
  ...boundedIntegerValidators(["CONTEXT_PREAMBLE_MAX_TOKENS"], 100, 20000),
4772
4978
  MEMORY_MIN_SIMILARITY: (value) => validateFloatRange("MEMORY_MIN_SIMILARITY", value, 0, 1, "between 0 and 1 inclusive"),
@@ -4774,6 +4980,43 @@ var init_swarm_config_guard = __esm(() => {
4774
4980
  };
4775
4981
  });
4776
4982
 
4983
+ // src/be/db/api-keys.ts
4984
+ async function recordKeySeatMismatch(keyType, keySuffix, keyIndex, model, scope = "global", scopeId = null) {
4985
+ const now = new Date().toISOString();
4986
+ const effectiveScopeId = scopeId ?? "";
4987
+ const provider = deriveProviderFromKeyType(keyType);
4988
+ return getDbClient().transaction(async (tx) => {
4989
+ await tx.run(`INSERT INTO api_key_status (keyType, keySuffix, keyIndex, scope, scopeId, provider, updatedAt)
4990
+ VALUES (?, ?, ?, ?, ?, ?, ?)
4991
+ ON CONFLICT(keyType, keySuffix, scope, scopeId)
4992
+ DO UPDATE SET
4993
+ keyIndex = excluded.keyIndex,
4994
+ provider = excluded.provider,
4995
+ updatedAt = excluded.updatedAt`, [keyType, keySuffix, keyIndex, scope, effectiveScopeId, provider, now]);
4996
+ await tx.run(`UPDATE api_key_status SET lastSeatMismatchAt = ?, lastSeatMismatchModel = ?
4997
+ WHERE keyType = ? AND keySuffix = ?`, [now, model, keyType, keySuffix]);
4998
+ let planChanged = false;
4999
+ if (keyType === "CLAUDE_CODE_OAUTH_TOKEN" && !planAllowsModelFamily("claude_team_standard", model)) {
5000
+ const result = await tx.run(`UPDATE api_key_status SET plan = 'claude_team_standard', planSource = 'detected'
5001
+ WHERE keyType = ? AND keySuffix = ? AND COALESCE(planSource, '') != 'manual'`, [keyType, keySuffix]);
5002
+ planChanged = result.changes > 0;
5003
+ }
5004
+ if (!planChanged) {
5005
+ const stored = await tx.get(`SELECT plan FROM api_key_status
5006
+ WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?`, [keyType, keySuffix, scope, effectiveScopeId]);
5007
+ if (planAllowsModelFamily(stored?.plan, model)) {
5008
+ console.warn(`[api-keys] seat mismatch: key ...${keySuffix} (${keyType}) has plan ${stored?.plan ?? "none"} but cannot run ${model}`);
5009
+ }
5010
+ }
5011
+ return { planChanged };
5012
+ });
5013
+ }
5014
+ var init_api_keys = __esm(() => {
5015
+ init_credentials();
5016
+ init_subscription_plans();
5017
+ init_runtime();
5018
+ });
5019
+
4777
5020
  // src/be/db.ts
4778
5021
  var exports_db = {};
4779
5022
  __export(exports_db, {
@@ -4910,6 +5153,7 @@ __export(exports_db, {
4910
5153
  getAgentMailInboxMappingsByAgent: () => getAgentMailInboxMappingsByAgent,
4911
5154
  getAgentMcpServers: () => getAgentMcpServers,
4912
5155
  getAgentSkills: () => getAgentSkills,
5156
+ getAgentStatusCounts: () => getAgentStatusCounts,
4913
5157
  getAgentWithTasks: () => getAgentWithTasks,
4914
5158
  getAgentWorkingOnThread: () => getAgentWorkingOnThread,
4915
5159
  getAllAgentMailInboxMappings: () => getAllAgentMailInboxMappings,
@@ -5064,6 +5308,7 @@ __export(exports_db, {
5064
5308
  getStuckApprovalRuns: () => getStuckApprovalRuns,
5065
5309
  getStuckWaitRuns: () => getStuckWaitRuns,
5066
5310
  getStuckWorkflowRuns: () => getStuckWorkflowRuns,
5311
+ getSupersededTasksWithUnsettledDependents: () => getSupersededTasksWithUnsettledDependents,
5067
5312
  getSupersededTasksWithoutResume: () => getSupersededTasksWithoutResume,
5068
5313
  getSwarmConfigById: () => getSwarmConfigById,
5069
5314
  getSwarmConfigLookupById: () => getSwarmConfigLookupById,
@@ -5087,7 +5332,6 @@ __export(exports_db, {
5087
5332
  getUnassignedTasksCount: () => getUnassignedTasksCount,
5088
5333
  getUnreadInboxMessages: () => getUnreadInboxMessages,
5089
5334
  getUnreadMessages: () => getUnreadMessages,
5090
- getUsageDataVersion: () => getUsageDataVersion,
5091
5335
  getUserById: () => getUserById,
5092
5336
  getWaitStateById: () => getWaitStateById,
5093
5337
  getWaitStateByStepId: () => getWaitStateByStepId,
@@ -5120,6 +5364,7 @@ __export(exports_db, {
5120
5364
  isPendingSlackMessage: () => isPendingSlackMessage,
5121
5365
  isPoolAffinityEnforcementEnabled: () => isPoolAffinityEnforcementEnabled,
5122
5366
  isSettledSlackMessage: () => isSettledSlackMessage,
5367
+ isSlackThreadAwaitingHuman: () => isSlackThreadAwaitingHuman,
5123
5368
  isSqliteVecAvailable: () => isSqliteVecAvailable,
5124
5369
  kvPrefixUpperBound: () => kvPrefixUpperBound,
5125
5370
  listAgentsWithCredStatusByProvider: () => listAgentsWithCredStatusByProvider,
@@ -5141,6 +5386,7 @@ __export(exports_db, {
5141
5386
  listScriptRuns: () => listScriptRuns,
5142
5387
  listSkillFileManifest: () => listSkillFileManifest,
5143
5388
  listSkills: () => listSkills,
5389
+ listSlackThreadsAwaitingHuman: () => listSlackThreadsAwaitingHuman,
5144
5390
  listTaskTemplates: () => listTaskTemplates,
5145
5391
  listUserFavorites: () => listUserFavorites,
5146
5392
  listWorkflowRuns: () => listWorkflowRuns,
@@ -5174,7 +5420,9 @@ __export(exports_db, {
5174
5420
  reassociateSessionLogs: () => reassociateSessionLogs,
5175
5421
  recordBudgetRefusalNotification: () => recordBudgetRefusalNotification,
5176
5422
  recordInlineScriptRun: () => recordInlineScriptRun,
5423
+ recordKeyAuthFailure: () => recordKeyAuthFailure,
5177
5424
  recordKeyRateLimitWindows: () => recordKeyRateLimitWindows,
5425
+ recordKeySeatMismatch: () => recordKeySeatMismatch,
5178
5426
  recordKeyUsage: () => recordKeyUsage,
5179
5427
  recordSlackMessage: () => recordSlackMessage,
5180
5428
  recordTaskPullRequestAttachments: () => recordTaskPullRequestAttachments,
@@ -5207,6 +5455,7 @@ __export(exports_db, {
5207
5455
  setFavorite: () => setFavorite,
5208
5456
  setSlackMessageTracking: () => setSlackMessageTracking,
5209
5457
  setUserFavorite: () => setUserFavorite,
5458
+ settleSupersededTaskDependents: () => settleSupersededTaskDependents,
5210
5459
  shouldBlockPolling: () => shouldBlockPolling,
5211
5460
  startTask: () => startTask,
5212
5461
  supersedeTask: () => supersedeTask,
@@ -5583,6 +5832,26 @@ async function getSlackTasksInThread(channelId, threadTs) {
5583
5832
  ORDER BY createdAt ASC, rowid ASC`, [channelId, threadTs]);
5584
5833
  return rows.map(rowToAgentTask);
5585
5834
  }
5835
+ async function listSlackThreadsAwaitingHuman() {
5836
+ return getDbClient().query(`SELECT DISTINCT task.slackChannelId AS channelId, task.slackThreadTs AS threadTs
5837
+ FROM approval_requests request
5838
+ JOIN agent_tasks task ON task.id = request.sourceTaskId
5839
+ WHERE request.status = 'pending'
5840
+ AND (request.expiresAt IS NULL OR request.expiresAt > strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
5841
+ AND task.slackChannelId IS NOT NULL
5842
+ AND task.slackThreadTs IS NOT NULL`);
5843
+ }
5844
+ async function isSlackThreadAwaitingHuman(channelId, threadTs) {
5845
+ const row = await getDbClient().get(`SELECT 1 AS waiting
5846
+ FROM approval_requests request
5847
+ JOIN agent_tasks task ON task.id = request.sourceTaskId
5848
+ WHERE request.status = 'pending'
5849
+ AND (request.expiresAt IS NULL OR request.expiresAt > strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
5850
+ AND task.slackChannelId = ?
5851
+ AND task.slackThreadTs = ?
5852
+ LIMIT 1`, [channelId, threadTs]);
5853
+ return !!row;
5854
+ }
5586
5855
  async function markTaskSlackReplySent(taskId) {
5587
5856
  await getDbClient().run(`UPDATE agent_tasks SET slackReplySent = 1 WHERE id = ?`, [taskId]);
5588
5857
  }
@@ -6612,6 +6881,15 @@ async function createTaskExtended(task, options) {
6612
6881
  } catch (error) {
6613
6882
  logRoutingDecisionFailure(id, "capture", error);
6614
6883
  }
6884
+ const isHumanFree = await classifyTaskHumanFree({
6885
+ taskType: options?.taskType,
6886
+ tags: JSON.stringify(options?.tags ?? []),
6887
+ source: options?.source ?? "mcp",
6888
+ requestedByUserId: options?.requestedByUserId,
6889
+ requestedByUserIdInherited,
6890
+ parentTaskId: options?.parentTaskId,
6891
+ workflowRunId: options?.workflowRunId
6892
+ });
6615
6893
  const inserted = await getDbClient().get(`INSERT INTO agent_tasks (
6616
6894
  id, "key", agentId, creatorAgentId, task, status, source, routing_reason, routing_source, routing_note,
6617
6895
  taskType, tags, priority, dependsOn, offeredTo, offeredAt,
@@ -6620,8 +6898,8 @@ async function createTaskExtended(task, options) {
6620
6898
  vcsInstallationId, vcsNodeId,
6621
6899
  agentmailInboxId, agentmailMessageId, agentmailThreadId,
6622
6900
  mentionMessageId, mentionChannelId, dir, parentTaskId, model, modelTier, effort, scheduleId,
6623
- workflowRunId, workflowRunStepId, outputSchema, followUpConfig, requestedByUserId, requestedByUserIdInherited, contextKey, routingAffinity, swarmVersion, createdAt, lastUpdatedAt, created_by, updated_by
6624
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`, [
6901
+ workflowRunId, workflowRunStepId, outputSchema, followUpConfig, requestedByUserId, requestedByUserIdInherited, contextKey, routingAffinity, swarmVersion, createdAt, lastUpdatedAt, created_by, updated_by, isHumanFree
6902
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`, [
6625
6903
  id,
6626
6904
  assetKey,
6627
6905
  options?.agentId ?? null,
@@ -6674,7 +6952,8 @@ async function createTaskExtended(task, options) {
6674
6952
  now,
6675
6953
  now,
6676
6954
  auditUserId,
6677
- auditUserId
6955
+ auditUserId,
6956
+ isHumanFree ? 1 : 0
6678
6957
  ]);
6679
6958
  if (!inserted)
6680
6959
  throw new Error("Failed to create task");
@@ -7019,7 +7298,7 @@ async function getUnassignedTaskIds(limit = 10) {
7019
7298
  const rows = await getDbClient().query("SELECT id FROM agent_tasks WHERE status = 'unassigned' ORDER BY priority DESC, createdAt ASC, rowid ASC LIMIT ?", [limit]);
7020
7299
  return rows.map((r) => r.id);
7021
7300
  }
7022
- async function getUnassignedTaskIdsForAgent(agentId, limit = 10) {
7301
+ async function getUnassignedTaskIdsForAgent(agentId, limit = 10, accept) {
7023
7302
  const agent = await getAgentById(agentId);
7024
7303
  if (!agent)
7025
7304
  return [];
@@ -7032,7 +7311,7 @@ async function getUnassignedTaskIdsForAgent(agentId, limit = 10) {
7032
7311
  break;
7033
7312
  for (const row of rows) {
7034
7313
  const task = rowToAgentTask(row);
7035
- if (isAgentEligibleForTask(agent, task)) {
7314
+ if (isAgentEligibleForTask(agent, task) && (!accept || await accept(task))) {
7036
7315
  eligible.push(task.id);
7037
7316
  if (eligible.length >= limit)
7038
7317
  break;
@@ -7855,8 +8134,8 @@ async function getSessionCostsFiltered(opts) {
7855
8134
  return rows.map(rowToSessionCost);
7856
8135
  }
7857
8136
  async function getSessionCostSummary(opts) {
7858
- const from = "FROM session_costs sc LEFT JOIN agent_tasks t ON t.id = sc.taskId";
7859
- const fromHf = `${from} LEFT JOIN human_free_tasks hf ON hf.id = t.id`;
8137
+ const from = "FROM session_costs sc LEFT JOIN agent_tasks t INDEXED BY idx_agent_tasks_usage_cover ON t.id = sc.taskId";
8138
+ const agentFrom = opts.userId === undefined ? "FROM session_costs sc" : from;
7860
8139
  const conditions = [];
7861
8140
  const params = [];
7862
8141
  if (opts.startDate) {
@@ -7878,12 +8157,8 @@ async function getSessionCostSummary(opts) {
7878
8157
  params.push(opts.userId);
7879
8158
  }
7880
8159
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
7881
- const classify = opts.userId !== undefined;
7882
- const withHf = classify ? `WITH RECURSIVE ${HUMAN_FREE_TASKS_CTE}` : "";
7883
- const scopedFrom = classify ? fromHf : from;
7884
8160
  const subscriptionSql = `t.credentialKeyType IN (${SUBSCRIPTION_KEY_TYPES.map((k) => `'${k}'`).join(", ")})`;
7885
- const totalsRow = await getDbClient().get(`WITH RECURSIVE ${HUMAN_FREE_TASKS_CTE}
7886
- SELECT
8161
+ const totalsRow = await getDbClient().get(`SELECT
7887
8162
  COALESCE(SUM(sc.totalCostUsd), 0) as totalCostUsd,
7888
8163
  COALESCE(SUM(sc.inputTokens), 0) as totalInputTokens,
7889
8164
  COALESCE(SUM(sc.outputTokens), 0) as totalOutputTokens,
@@ -7900,7 +8175,7 @@ async function getSessionCostSummary(opts) {
7900
8175
  COUNT(DISTINCT CASE WHEN ${HUMAN_FREE_SQL} THEN t.id END) as excludedTaskCount,
7901
8176
  COALESCE(SUM(CASE WHEN ${subscriptionSql}
7902
8177
  THEN sc.totalCostUsd ELSE 0 END), 0) as subscriptionCostUsd
7903
- ${fromHf} ${where}`, params);
8178
+ ${from} ${where}`, params);
7904
8179
  const totals = totalsRow ? {
7905
8180
  ...totalsRow,
7906
8181
  avgCostPerSession: totalsRow.totalSessions > 0 ? totalsRow.totalCostUsd / totalsRow.totalSessions : 0
@@ -7922,8 +8197,7 @@ async function getSessionCostSummary(opts) {
7922
8197
  const groupBy = opts.groupBy ?? "both";
7923
8198
  let daily = [];
7924
8199
  if (groupBy === "day" || groupBy === "both") {
7925
- daily = await getDbClient().query(`${withHf}
7926
- SELECT
8200
+ daily = await getDbClient().query(`SELECT
7927
8201
  DATE(sc.createdAt) as date,
7928
8202
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7929
8203
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
@@ -7931,42 +8205,39 @@ async function getSessionCostSummary(opts) {
7931
8205
  COUNT(*) as sessions,
7932
8206
  COALESCE(SUM(CASE WHEN ${subscriptionSql} THEN sc.totalCostUsd ELSE 0 END), 0)
7933
8207
  as subscriptionCostUsd
7934
- ${scopedFrom} ${where}
8208
+ ${from} ${where}
7935
8209
  GROUP BY DATE(sc.createdAt)
7936
8210
  ORDER BY date ASC`, params);
7937
8211
  }
7938
8212
  let byAgent = [];
7939
8213
  if (groupBy === "agent" || groupBy === "both") {
7940
- byAgent = await getDbClient().query(`${withHf}
7941
- SELECT
8214
+ byAgent = await getDbClient().query(`SELECT
7942
8215
  sc.agentId as agentId,
7943
8216
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7944
8217
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
7945
8218
  COALESCE(SUM(sc.outputTokens), 0) as outputTokens,
7946
8219
  COUNT(*) as sessions,
7947
8220
  COALESCE(SUM(sc.durationMs), 0) as durationMs
7948
- ${scopedFrom} ${where}
8221
+ ${agentFrom} ${where}
7949
8222
  GROUP BY sc.agentId
7950
8223
  ORDER BY costUsd DESC`, params);
7951
8224
  }
7952
8225
  let byUser = [];
7953
8226
  if (groupBy === "user" || groupBy === "both") {
7954
- byUser = await getDbClient().query(`WITH RECURSIVE ${HUMAN_FREE_TASKS_CTE}
7955
- SELECT
8227
+ byUser = await getDbClient().query(`SELECT
7956
8228
  CASE WHEN ${HUMAN_FREE_SQL} THEN NULL ELSE t.requestedByUserId END as userId,
7957
8229
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7958
8230
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
7959
8231
  COALESCE(SUM(sc.outputTokens), 0) as outputTokens,
7960
8232
  COUNT(DISTINCT sc.taskId) as tasks,
7961
8233
  COALESCE(SUM(sc.durationMs), 0) as durationMs
7962
- ${fromHf} ${where}
8234
+ ${from} ${where}
7963
8235
  GROUP BY CASE WHEN ${HUMAN_FREE_SQL} THEN NULL ELSE t.requestedByUserId END
7964
8236
  ORDER BY costUsd DESC`, params);
7965
8237
  }
7966
8238
  let byCredential = [];
7967
8239
  if (groupBy === "both") {
7968
- const rows = await getDbClient().query(`${withHf}
7969
- SELECT
8240
+ const rows = await getDbClient().query(`SELECT
7970
8241
  t.credentialKeyType as keyType,
7971
8242
  t.credentialKeySuffix as keySuffix,
7972
8243
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
@@ -7975,7 +8246,7 @@ async function getSessionCostSummary(opts) {
7975
8246
  COUNT(*) as sessions,
7976
8247
  MIN(sc.createdAt) as firstSessionAt,
7977
8248
  MAX(sc.createdAt) as lastSessionAt
7978
- ${scopedFrom} ${where}
8249
+ ${from} ${where}
7979
8250
  GROUP BY t.credentialKeyType, t.credentialKeySuffix
7980
8251
  ORDER BY costUsd DESC`, params);
7981
8252
  const labels = await getCredentialLabels();
@@ -8011,11 +8282,6 @@ async function getCredentialLabels() {
8011
8282
  }
8012
8283
  return labels;
8013
8284
  }
8014
- async function getUsageDataVersion() {
8015
- const row = await getDbClient().get(`SELECT COALESCE((SELECT MAX(rowid) FROM session_costs), 0) || ':' ||
8016
- COALESCE((SELECT MAX(rowid) FROM agent_tasks), 0) as version`);
8017
- return row?.version ?? "0:0";
8018
- }
8019
8285
  async function getAttributionByPerson(opts) {
8020
8286
  const conditions = ["t.requestedByUserId IS NOT NULL"];
8021
8287
  const params = [];
@@ -8035,18 +8301,20 @@ async function getAttributionByPerson(opts) {
8035
8301
  }
8036
8302
  }
8037
8303
  const where = `WHERE ${conditions.join(" AND ")}`;
8038
- const rootRows = await getDbClient().query(`WITH RECURSIVE selected_roots(id, requestedByUserId, status, output) AS (
8039
- SELECT t.id, t.requestedByUserId, t.status, t.output
8304
+ const rootRows = await getDbClient().query(`WITH RECURSIVE selected_roots(id, requestedByUserId, status) AS (
8305
+ SELECT t.id, t.requestedByUserId, t.status
8040
8306
  FROM agent_tasks t
8041
- ${where} AND t.parentTaskId IS NULL AND NOT ${ROOT_HUMAN_FREE_SQL}
8307
+ ${where} AND t.parentTaskId IS NULL AND t.isHumanFree = 0
8042
8308
  ),
8043
- task_tree(rootId, taskId, output) AS (
8044
- SELECT id, id, output
8309
+ -- Ids only: carrying each descendant's \`output\` through the recursion copied
8310
+ -- every task's text into the queue. The output fallback below reads it by id.
8311
+ task_tree(rootId, taskId) AS (
8312
+ SELECT id, id
8045
8313
  FROM selected_roots
8046
8314
 
8047
8315
  UNION ALL
8048
8316
 
8049
- SELECT tree.rootId, child.id, child.output
8317
+ SELECT tree.rootId, child.id
8050
8318
  FROM agent_tasks child
8051
8319
  JOIN task_tree tree ON child.parentTaskId = tree.taskId
8052
8320
  ),
@@ -8079,8 +8347,11 @@ async function getAttributionByPerson(opts) {
8079
8347
 
8080
8348
  SELECT tree.rootId
8081
8349
  FROM task_tree tree
8082
- WHERE tree.output LIKE '%github.com/%/pull/%'
8083
- OR tree.output LIKE '%/-/merge_requests/%'
8350
+ -- CROSS JOIN pins the order (tree outer, task by id). Left to itself the
8351
+ -- planner scans every task's output and probes the tree instead.
8352
+ CROSS JOIN agent_tasks described ON described.id = tree.taskId
8353
+ WHERE described.output LIKE '%github.com/%/pull/%'
8354
+ OR described.output LIKE '%/-/merge_requests/%'
8084
8355
  )
8085
8356
  SELECT
8086
8357
  t.requestedByUserId as userId,
@@ -8089,65 +8360,13 @@ async function getAttributionByPerson(opts) {
8089
8360
  FROM selected_roots t
8090
8361
  LEFT JOIN shipped_roots s ON s.rootId = t.id
8091
8362
  GROUP BY t.requestedByUserId`, params);
8092
- const reachRows = await getDbClient().query(`WITH RECURSIVE report_tasks AS (
8093
- -- Only the columns read below: a task row carries its full prompt and output.
8094
- SELECT t.id, t.agentId, t.vcsRepo, t.source, t.parentTaskId, t.requestedByUserId,
8095
- t.requestedByUserIdInherited, t.taskType, t.tags, t.workflowRunId
8096
- FROM agent_tasks t
8097
- ${where}
8098
- ),
8099
- task_ancestry(
8100
- taskId, id, parentTaskId, requestedByUserId, requestedByUserIdInherited,
8101
- taskType, tags, source, workflowRunId
8102
- ) AS (
8103
- SELECT
8104
- id, id, parentTaskId, requestedByUserId, requestedByUserIdInherited,
8105
- taskType, tags, source, workflowRunId
8106
- FROM report_tasks
8107
-
8108
- UNION ALL
8109
-
8110
- SELECT
8111
- child.taskId, parent.id, parent.parentTaskId, parent.requestedByUserId,
8112
- parent.requestedByUserIdInherited, parent.taskType, parent.tags,
8113
- parent.source, parent.workflowRunId
8114
- FROM agent_tasks parent
8115
- JOIN task_ancestry child ON parent.id = child.parentTaskId
8116
- WHERE child.requestedByUserId IS NULL
8117
- OR child.requestedByUserIdInherited = 1
8118
- ),
8119
- human_free_report_tasks(id) AS (
8120
- SELECT DISTINCT ancestor.taskId
8121
- FROM task_ancestry ancestor
8122
- LEFT JOIN agent_tasks parent ON parent.id = ancestor.parentTaskId
8123
- WHERE COALESCE(ancestor.taskType, '') IN ('heartbeat', 'heartbeat-checklist', 'boot-triage')
8124
- OR COALESCE(ancestor.tags, '[]') LIKE '%"heartbeat"%'
8125
- OR (COALESCE(ancestor.source, '') = 'schedule' AND ancestor.requestedByUserId IS NULL)
8126
- OR (
8127
- ancestor.parentTaskId IS NULL
8128
- AND COALESCE(ancestor.source, '') = 'workflow'
8129
- AND ancestor.requestedByUserId IS NULL
8130
- AND EXISTS (
8131
- SELECT 1
8132
- FROM workflow_runs run
8133
- WHERE run.id = ancestor.workflowRunId
8134
- AND run.triggerType = 'schedule'
8135
- AND run.created_by IS NULL
8136
- )
8137
- )
8138
- OR (
8139
- COALESCE(ancestor.source, '') = 'system'
8140
- AND parent.id IS NOT NULL
8141
- AND parent.requestedByUserId IS NULL
8142
- )
8143
- )
8144
- SELECT
8363
+ const reachRows = await getDbClient().query(`SELECT
8145
8364
  t.requestedByUserId as userId,
8146
8365
  COUNT(DISTINCT t.agentId) as agentsReached,
8147
8366
  COUNT(DISTINCT t.vcsRepo) as reposReached,
8148
8367
  COUNT(DISTINCT t.source) as surfacesReached
8149
- FROM report_tasks t
8150
- WHERE NOT EXISTS (SELECT 1 FROM human_free_report_tasks WHERE id = t.id)
8368
+ FROM agent_tasks t
8369
+ ${where} AND t.isHumanFree = 0
8151
8370
  GROUP BY t.requestedByUserId`, params);
8152
8371
  const byUser = new Map;
8153
8372
  for (const r of rootRows) {
@@ -9310,10 +9529,15 @@ async function updateWorkflow(id, data) {
9310
9529
  return row ? rowToWorkflow(row) : null;
9311
9530
  }
9312
9531
  async function deleteWorkflow(id, source2) {
9532
+ return await getDbClient().transaction(() => deleteWorkflowRows(id, source2));
9533
+ }
9534
+ async function deleteWorkflowRows(id, source2) {
9313
9535
  const client = getDbClient();
9536
+ const linkedTaskIds = (await client.query(`SELECT id FROM agent_tasks WHERE workflowRunId IN (SELECT id FROM workflow_runs WHERE workflowId = ?)`, [id])).map((row) => row.id);
9314
9537
  await client.run(`UPDATE agent_tasks SET workflowRunId = NULL, workflowRunStepId = NULL WHERE workflowRunId IN (SELECT id FROM workflow_runs WHERE workflowId = ?)`, [id]);
9315
9538
  await client.run(`DELETE FROM workflow_run_steps WHERE runId IN (SELECT id FROM workflow_runs WHERE workflowId = ?)`, [id]);
9316
9539
  await client.run("DELETE FROM workflow_runs WHERE workflowId = ?", [id]);
9540
+ await reclassifyTaskHumanFree(linkedTaskIds);
9317
9541
  const result = await client.run("DELETE FROM workflows WHERE id = ?", [id]);
9318
9542
  const deleted = result.changes > 0;
9319
9543
  if (deleted) {
@@ -11368,8 +11592,8 @@ async function getAvailableKeyIndices(keyType, totalKeys, scope = "global", scop
11368
11592
  await client.run(`UPDATE api_key_status
11369
11593
  SET status = 'available', rateLimitedUntil = NULL, updatedAt = ?
11370
11594
  WHERE keyType = ? AND scope = ? AND scopeId = ?
11371
- AND status = 'rate_limited' AND rateLimitedUntil IS NOT NULL AND rateLimitedUntil <= ?`, [now, keyType, scope, effectiveScopeId, now]);
11372
- const rows = await client.query(`SELECT keyIndex, status, rateLimitWindows FROM api_key_status
11595
+ AND status = 'rate_limited' AND rateLimitedUntil <= ? AND consecutiveAuthFailures < ?`, [now, keyType, scope, effectiveScopeId, now, CODEX_AUTH_FAILURE_BENCH_THRESHOLD]);
11596
+ const rows = await client.query(`SELECT keyIndex, status, rateLimitWindows, plan, authFailureSeq FROM api_key_status
11373
11597
  WHERE keyType = ? AND scope = ? AND scopeId = ?`, [keyType, scope, effectiveScopeId]);
11374
11598
  const blockedIndices = new Set(rows.filter((r) => r.status === "rate_limited").map((r) => r.keyIndex));
11375
11599
  const modelBlockedIndices = [];
@@ -11388,16 +11612,26 @@ async function getAvailableKeyIndices(keyType, totalKeys, scope = "global", scop
11388
11612
  }
11389
11613
  }
11390
11614
  const modelBlockedSet = new Set(modelBlockedIndices);
11615
+ const seatBlockedIndices = [];
11616
+ if (modelFamily) {
11617
+ for (const row of rows) {
11618
+ if (!planAllowsModelFamily(row.plan, modelFamily))
11619
+ seatBlockedIndices.push(row.keyIndex);
11620
+ }
11621
+ }
11622
+ const seatBlockedSet = new Set(seatBlockedIndices);
11391
11623
  const availableIndices = [];
11392
11624
  for (let i = 0;i < totalKeys; i++) {
11393
- if (blockedIndices.has(i) || modelBlockedSet.has(i))
11625
+ if (blockedIndices.has(i) || modelBlockedSet.has(i) || seatBlockedSet.has(i))
11394
11626
  continue;
11395
11627
  availableIndices.push(i);
11396
11628
  }
11397
11629
  return {
11398
11630
  availableIndices,
11399
11631
  modelBlockedIndices,
11400
- earliestModelResetAt: earliestModelResetsAtSec !== undefined ? new Date(earliestModelResetsAtSec * 1000).toISOString() : null
11632
+ seatBlockedIndices,
11633
+ earliestModelResetAt: earliestModelResetsAtSec !== undefined ? new Date(earliestModelResetsAtSec * 1000).toISOString() : null,
11634
+ authFailureFence: Math.max(0, ...rows.map((r) => r.authFailureSeq))
11401
11635
  };
11402
11636
  }
11403
11637
  async function recordKeyUsage(keyType, keySuffix, keyIndex, taskId, scope = "global", scopeId = null, plan = null) {
@@ -11444,12 +11678,50 @@ async function markKeyRateLimited(keyType, keySuffix, keyIndex, rateLimitedUntil
11444
11678
  ON CONFLICT(keyType, keySuffix, scope, scopeId)
11445
11679
  DO UPDATE SET
11446
11680
  status = 'rate_limited',
11447
- rateLimitedUntil = excluded.rateLimitedUntil,
11681
+ rateLimitedUntil = CASE WHEN status = 'rate_limited' AND consecutiveAuthFailures >= ${CODEX_AUTH_FAILURE_BENCH_THRESHOLD} THEN MAX(COALESCE(rateLimitedUntil, ''), excluded.rateLimitedUntil) ELSE excluded.rateLimitedUntil END,
11448
11682
  lastRateLimitAt = excluded.lastRateLimitAt,
11449
11683
  rateLimitCount = rateLimitCount + 1,
11450
11684
  keyIndex = excluded.keyIndex,
11451
11685
  updatedAt = excluded.updatedAt`, [keyType, keySuffix, keyIndex, scope, effectiveScopeId, rateLimitedUntil, now, provider, now]);
11452
11686
  }
11687
+ async function recordKeyAuthFailure(keyType, keySuffix, keyIndex, scope = "global", scopeId = null) {
11688
+ const effectiveScopeId = scopeId ?? "";
11689
+ const provider = deriveProviderFromKeyType(keyType);
11690
+ return await getDbClient().transaction(async (tx) => {
11691
+ const now = new Date().toISOString();
11692
+ const source2 = "report-auth-failure";
11693
+ const row = await tx.get(`INSERT INTO api_key_status (keyType, keySuffix, keyIndex, scope, scopeId, status, consecutiveAuthFailures, lastAuthFailureAt, authFailureSeq, provider, updatedAt)
11694
+ VALUES (?, ?, ?, ?, ?, 'available', 1, ?, (SELECT COALESCE(MAX(authFailureSeq), 0) + 1 FROM api_key_status), ?, ?)
11695
+ ON CONFLICT(keyType, keySuffix, scope, scopeId)
11696
+ DO UPDATE SET
11697
+ consecutiveAuthFailures = consecutiveAuthFailures + 1,
11698
+ lastAuthFailureAt = excluded.lastAuthFailureAt, authFailureSeq = excluded.authFailureSeq,
11699
+ keyIndex = excluded.keyIndex, updatedAt = excluded.updatedAt
11700
+ RETURNING consecutiveAuthFailures, rateLimitedUntil`, [keyType, keySuffix, keyIndex, scope, effectiveScopeId, now, provider, now]);
11701
+ if (!row)
11702
+ throw new Error("Failed to record auth failure");
11703
+ const { consecutiveAuthFailures } = row;
11704
+ if (consecutiveAuthFailures < CODEX_AUTH_FAILURE_BENCH_THRESHOLD) {
11705
+ return { consecutiveAuthFailures, benched: false, rateLimitedUntil: row.rateLimitedUntil };
11706
+ }
11707
+ let benchedUntil = new Date(Date.parse(now) + CODEX_AUTH_FAILURE_BENCH_MS).toISOString();
11708
+ if (row.rateLimitedUntil && Date.parse(row.rateLimitedUntil) > Date.parse(benchedUntil)) {
11709
+ benchedUntil = row.rateLimitedUntil;
11710
+ }
11711
+ await tx.run(`UPDATE api_key_status
11712
+ SET status = 'rate_limited', rateLimitedUntil = ?, lastRateLimitAt = ?,
11713
+ rateLimitCount = rateLimitCount + 1, updatedAt = ?
11714
+ WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?`, [benchedUntil, now, now, keyType, keySuffix, scope, effectiveScopeId]);
11715
+ await upsertKv({
11716
+ namespace: CODEX_AUTH_WATCH_NAMESPACE,
11717
+ key: codexAuthBenchMarkerKey(keySuffix),
11718
+ valueType: "json",
11719
+ value: { keyIndex, keyType, benchedAt: now, benchedUntil, lastFailAt: now, source: source2 },
11720
+ expiresAt: Date.parse(benchedUntil) + 86400000
11721
+ });
11722
+ return { consecutiveAuthFailures, benched: true, rateLimitedUntil: benchedUntil };
11723
+ });
11724
+ }
11453
11725
  function mergeRateLimitWindowTelemetry(stored, reported) {
11454
11726
  const merged = { ...stored };
11455
11727
  for (const [type, entry] of Object.entries(reported)) {
@@ -11516,14 +11788,32 @@ async function setApiKeyName(keyType, keySuffix, name, scope = "global", scopeId
11516
11788
  WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?`, [name, new Date().toISOString(), keyType, keySuffix, scope, scopeId ?? ""]);
11517
11789
  return result.changes > 0;
11518
11790
  }
11519
- async function clearKeyRateLimit(keyType, keySuffix, scope = "global", scopeId = null) {
11791
+ async function clearKeyRateLimit(keyType, keySuffix, scope = "global", scopeId = null, opts = {}) {
11520
11792
  const now = new Date().toISOString();
11521
11793
  const effectiveScopeId = scopeId ?? "";
11522
- const result = await getDbClient().run(`UPDATE api_key_status
11523
- SET status = 'available', rateLimitedUntil = NULL, updatedAt = ?
11524
- WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?
11525
- AND status = 'rate_limited'`, [now, keyType, keySuffix, scope, effectiveScopeId]);
11526
- return result.changes > 0;
11794
+ const { keyIndex = -1, authFence = null } = opts;
11795
+ const clearAuthBench = opts.clearAuthBench === true && authFence !== null;
11796
+ const key = [keyType, keySuffix, scope, effectiveScopeId];
11797
+ return await getDbClient().transaction(async (tx) => {
11798
+ const result = await tx.run(`UPDATE api_key_status
11799
+ SET status = 'available', rateLimitedUntil = NULL, updatedAt = ?
11800
+ WHERE keyType = ? AND keySuffix = ? AND scope = ? AND scopeId = ?
11801
+ AND status = 'rate_limited' AND ((? AND authFailureSeq <= ?) OR consecutiveAuthFailures < ?)`, [now, ...key, clearAuthBench ? 1 : 0, authFence, CODEX_AUTH_FAILURE_BENCH_THRESHOLD]);
11802
+ const cleared = result.changes > 0;
11803
+ if (!clearAuthBench)
11804
+ return cleared;
11805
+ const lifted = await tx.query(`UPDATE api_key_status SET consecutiveAuthFailures = 0, updatedAt = ?1,
11806
+ status = CASE WHEN keySuffix = ?2 THEN status ELSE 'available' END, rateLimitedUntil = CASE WHEN keySuffix = ?2 THEN rateLimitedUntil END
11807
+ WHERE keyType = ?3 AND scope = ?4 AND scopeId = ?5 AND (consecutiveAuthFailures > 0 OR status = 'rate_limited')
11808
+ AND ((keySuffix = ?2 AND authFailureSeq <= ?7) OR (keySuffix != ?2 AND keyIndex = ?6)) RETURNING keySuffix`, [now, keySuffix, keyType, scope, effectiveScopeId, keyIndex, authFence]);
11809
+ const retired = lifted.filter((row) => row.keySuffix !== keySuffix);
11810
+ if (keyType === "CODEX_OAUTH") {
11811
+ for (const suffix of [...cleared ? [keySuffix] : [], ...retired.map((r) => r.keySuffix)]) {
11812
+ await deleteKv(CODEX_AUTH_WATCH_NAMESPACE, codexAuthBenchMarkerKey(suffix));
11813
+ }
11814
+ }
11815
+ return cleared || retired.length > 0;
11816
+ });
11527
11817
  }
11528
11818
  async function getKeyStatuses(keyType, scope, scopeId) {
11529
11819
  const conditions = [];
@@ -11700,6 +11990,10 @@ async function deleteUser(id, replacementUserId) {
11700
11990
  AND foreign_keys."table" = 'users'
11701
11991
  )`);
11702
11992
  const replacement = replacementUserId ?? null;
11993
+ const reclassifySeedIds = replacementUserId ? [] : (await tx.query(`SELECT id FROM agent_tasks WHERE requestedByUserId = ?
11994
+ UNION
11995
+ SELECT id FROM agent_tasks
11996
+ WHERE workflowRunId IN (SELECT id FROM workflow_runs WHERE created_by = ?)`, [id, id])).map((row) => row.id);
11703
11997
  for (const reference of references) {
11704
11998
  const table = quoteSqlIdentifier(reference.tableName);
11705
11999
  const column = quoteSqlIdentifier(reference.columnName);
@@ -11716,6 +12010,7 @@ async function deleteUser(id, replacementUserId) {
11716
12010
  WHERE json_valid(context)
11717
12011
  AND json_extract(context, '$.swarm.requestedByUserId') = ?`, [id]);
11718
12012
  }
12013
+ await reclassifyTaskHumanFree(reclassifySeedIds);
11719
12014
  const result = await tx.run("DELETE FROM users WHERE id = ?", [id]);
11720
12015
  return result.changes > 0;
11721
12016
  });
@@ -12702,54 +12997,7 @@ var VERSIONABLE_FIELDS2, BUDGETED_IDENTITY_FIELDS, PENDING_SLACK_MESSAGE_TS_PREF
12702
12997
  LEFT JOIN agents a ON m.created_by_kind = 'agent' AND a.id = m.created_by_agent_id`, ROUTING_HOLDER_SQL = `CASE
12703
12998
  WHEN status IN ('draft', 'offered', 'reviewing') AND offeredTo IS NOT NULL THEN offeredTo
12704
12999
  ELSE COALESCE(agentId, offeredTo)
12705
- END`, ELIGIBILITY_SCAN_BATCH_SIZE, ELIGIBILITY_SCAN_CAP, UNATTRIBUTED_USER_ID = "unattributed", HUMAN_FREE_TASKS_CTE = `human_free_tasks(id) AS (
12706
- SELECT task.id
12707
- FROM agent_tasks task
12708
- LEFT JOIN agent_tasks parent ON parent.id = task.parentTaskId
12709
- WHERE COALESCE(task.taskType, '') IN ('heartbeat', 'heartbeat-checklist', 'boot-triage')
12710
- OR COALESCE(task.tags, '[]') LIKE '%"heartbeat"%'
12711
- OR (COALESCE(task.source, '') = 'schedule' AND task.requestedByUserId IS NULL)
12712
- OR (
12713
- task.parentTaskId IS NULL
12714
- AND COALESCE(task.source, '') = 'workflow'
12715
- AND task.requestedByUserId IS NULL
12716
- AND EXISTS (
12717
- SELECT 1
12718
- FROM workflow_runs run
12719
- WHERE run.id = task.workflowRunId
12720
- AND run.triggerType = 'schedule'
12721
- AND run.created_by IS NULL
12722
- )
12723
- )
12724
- OR (
12725
- COALESCE(task.source, '') = 'system'
12726
- AND parent.id IS NOT NULL
12727
- AND parent.requestedByUserId IS NULL
12728
- )
12729
-
12730
- UNION
12731
-
12732
- SELECT child.id
12733
- FROM agent_tasks child
12734
- JOIN human_free_tasks parent ON child.parentTaskId = parent.id
12735
- WHERE child.requestedByUserId IS NULL
12736
- OR child.requestedByUserIdInherited = 1
12737
- )`, HUMAN_FREE_SQL = "hf.id IS NOT NULL", ROOT_HUMAN_FREE_SQL = `(
12738
- COALESCE(t.taskType, '') IN ('heartbeat', 'heartbeat-checklist', 'boot-triage')
12739
- OR COALESCE(t.tags, '[]') LIKE '%"heartbeat"%'
12740
- OR (COALESCE(t.source, '') = 'schedule' AND t.requestedByUserId IS NULL)
12741
- OR (
12742
- COALESCE(t.source, '') = 'workflow'
12743
- AND t.requestedByUserId IS NULL
12744
- AND EXISTS (
12745
- SELECT 1
12746
- FROM workflow_runs run
12747
- WHERE run.id = t.workflowRunId
12748
- AND run.triggerType = 'schedule'
12749
- AND run.created_by IS NULL
12750
- )
12751
- )
12752
- )`, SCHEDULE_TEMPLATE_PREVIEW_LENGTH = 280, RESERVED_CONFIG_PLACEHOLDER = "[reserved key stored in swarm_config; delete this row]", WORKFLOW_RUN_SUMMARY_COLUMNS = "id, workflowId, status, triggerType, triggerData, error, created_by, startedAt, lastUpdatedAt, finishedAt", SKILL_FILE_LIMITS, BINARY_SKILL_FILE_PLACEHOLDER = "[binary file - not synced]", SKILL_SLIM_COLUMNS = "id, name, description, type, scope, ownerAgentId, sourceUrl, sourceRepo, sourcePath, sourceBranch, sourceHash, isComplex, allowedTools, model, effort, context, agent, disableModelInvocation, userInvocable, version, isEnabled, systemDefault, createdAt, lastUpdatedAt, lastFetchedAt, '' as content", WEEK_SECONDS, KvTypeCollisionError;
13000
+ END`, ELIGIBILITY_SCAN_BATCH_SIZE, ELIGIBILITY_SCAN_CAP, UNATTRIBUTED_USER_ID = "unattributed", HUMAN_FREE_SQL = "(COALESCE(t.isHumanFree, 0) = 1)", SCHEDULE_TEMPLATE_PREVIEW_LENGTH = 280, RESERVED_CONFIG_PLACEHOLDER = "[reserved key stored in swarm_config; delete this row]", WORKFLOW_RUN_SUMMARY_COLUMNS = "id, workflowId, status, triggerType, triggerData, error, created_by, startedAt, lastUpdatedAt, finishedAt", SKILL_FILE_LIMITS, BINARY_SKILL_FILE_PLACEHOLDER = "[binary file - not synced]", SKILL_SLIM_COLUMNS = "id, name, description, type, scope, ownerAgentId, sourceUrl, sourceRepo, sourcePath, sourceBranch, sourceHash, isComplex, allowedTools, model, effort, context, agent, disableModelInvocation, userInvocable, version, isEnabled, systemDefault, createdAt, lastUpdatedAt, lastFetchedAt, '' as content", WEEK_SECONDS, KvTypeCollisionError;
12753
13001
  var init_db = __esm(() => {
12754
13002
  init_package();
12755
13003
  init_key();
@@ -12758,6 +13006,7 @@ var init_db = __esm(() => {
12758
13006
  init_slack_routing();
12759
13007
  init_telemetry();
12760
13008
  init_types();
13009
+ init_codex_auth_failure();
12761
13010
  init_credentials();
12762
13011
  init_github_pull_request();
12763
13012
  init_heartbeat_expiry();
@@ -12773,12 +13022,14 @@ var init_db = __esm(() => {
12773
13022
  init_approvals();
12774
13023
  init_context_versions();
12775
13024
  init_runtime();
13025
+ init_human_free();
12776
13026
  init_read();
12777
13027
  init_write();
12778
13028
  init_steering();
12779
13029
  init_swarm_config_guard();
12780
13030
  init_task_lifecycle_events();
12781
13031
  init_agents();
13032
+ init_api_keys();
12782
13033
  init_approvals();
12783
13034
  init_context_versions();
12784
13035
  init_runtime();
@@ -12835,4 +13086,4 @@ var init_db = __esm(() => {
12835
13086
  };
12836
13087
  });
12837
13088
 
12838
- export { slackContextKey, agentmailContextKey, githubContextKey, gitlabContextKey, linearContextKey, buildJiraContextKey, scheduleContextKey, workflowContextKey, agentContextKey, pageContextKey, init_context_key, checkSlackRoutingCoherence, init_slack_routing, _resolveIntegrationType, _resolveIntegrationProvider, initTelemetry, telemetry, emitIntegrationConnected, init_telemetry, HeartbeatExpiryError, init_heartbeat_expiry, beginRequestAuthScope, setRequestAuth, getRequestAuth, getCurrentRequestAuth, runWithoutRequestAuth, init_request_auth_context, auditAssetKeys, init_asset_key_audit, encryptSecret, decryptSecret, getEncryptionKey, init_crypto, normalizeDate, normalizeDateRequired, init_date_utils, CredentialBindingSchema, placeholderForConfigKey, CredentialBroker, DEFAULT_CREDENTIAL_BINDINGS, init_credential_broker, isInTransaction, init_db_client, getPromptTemplateDefaultDrift, init_default_drift, init_templates2 as init_templates, isSqliteVecAvailable, resolveSqliteVecExtensionPath, __resetSqliteVecExtensionPathCacheForTests, initDb, getDb, closeDb, getDbClient, updateAgentCredentialState, updateAgentCredentialMissing, createAgent, getAgentById, EXTENSION_AGENT_ROLE, NOT_EXTENSION_AGENT_SQL, isExtensionAgent, extensionAgentAssignmentError, ReservedAgentRoleError, reservedRoleViolation, ExtensionAgentAssignmentError, getAllAgents, getLeadAgent, updateAgentStatus, updateAgentMaxTasks, updateAgentProvider, setAgentHarnessProvider, updateAgentCredStatus, listAgentsWithCredStatusByProvider, getAgentHarnessProviders, updateAgentActivity, MAX_EMPTY_POLLS, incrementEmptyPollCount, resetEmptyPollCount, shouldBlockPolling, deleteAgent, getActiveTaskCount, hasCapacity, getRemainingCapacity, updateAgentStatusFromCapacity, isPoolAffinityEnforcementEnabled, buildRoutingAffinityFromAgent, isAgentEligibleForTask, getAgentDailyTaskCounts, listApprovalRequestSummaries, computeContentHash, createContextVersion, getLatestContextVersion, getContextVersion, getContextVersionHistory, getTaskById, getChildTasks, hasNonTerminalResumeChild, getSupersededTasksWithoutResume, hasNonTerminalRerouteDecisionChild, getTasksByAgentId, getAgentCurrentTask, getTasksByStatus, findTaskByVcs, findTaskByGitHub, getAllTasks, getTasksCount, getTaskStats, getCompletedSlackTasks, getPendingSlackRelayTasks, markSlackRelayAttempted, markSlackRelayDelivered, markFinalizedSlackRelaysDelivered, getRecentlyFinishedWorkerTasks, markTasksNotified, resetTasksNotified, getInProgressSlackTasks, getSlackTasksMissingTree, getInProgressTasksByContextKey, findExistingLinearTrackerContextWork, getLatestTaskByContextKey, getLatestScriptRunStepTaskByContextKey, getAgentWorkingOnThread, getLatestActiveTaskInThread, getLatestLeadTaskInThread, getMostRecentTaskInThread, findCompletedTaskInThread, findRecentCancelledTaskInThread, onTaskStarted, init_task_lifecycle_events, createTask, getPendingTaskForAgent, assignUnassignedTaskPending, startTask, updateTaskClaudeSessionId, updateTaskTitle, completeTask, failTask, overwriteTerminalTaskResultText, cancelTask, supersedeTask, backfillSupersedeTaskResumeTaskId, pauseTask, resumeTask, getPausedTasksForAgent, getOrphanedInProgressTasksForAgent, resetOrphanedInProgressTasksForAgent, getRecentlyCancelledTasksForAgent, deleteTask, updateTaskProgress, SteeringRequestError, isSteeringEnabled2 as isSteeringEnabled, getTaskSteeringFields, getTaskSteeringFieldsForTasks, promotePendingSteeringForTask, markSteeringUndeliverable, requestSteering, init_steering, SLACK_REACTION_DEFAULTS, SLACK_REACTION_CONFIG_KEYS, reactionName, init_reaction_shortcode, parseTaskToolManifest, selectTaskTools, init_task_tool_manifest, isInternalConfigKey, internalConfigKeyError, isReservedConfigKey, reservedKeyError, MAX_DB_RETENTION_DAYS, DB_RETENTION_TUNING_BOUNDS, validateConfigValue, init_swarm_config_guard, getSlackRenderV2ActivatedAt, ensureSlackRenderV2Activation, getSlackDelegationActivatedAt, ensureSlackDelegationActivation, isPendingSlackMessage, isSettledSlackMessage, recordSlackMessage, reserveSlackMessage, bindSlackMessageTimestamp, updateSlackMessageRecord, markSlackTreeRendered, deleteSlackMessageRecord, getSlackTreeMessage, getSlackTreeMessageByThread, getSlackOutcomeMessage, getResolvableDeferralOutcomes, markSlackDeferralResolved, noteSlackOutcomeDeliveryFailure, abandonSlackOutcomeDelivery, getSlackTreeMessages, getSlackMessageByChannelTs, getSlackTasksInThread, markTaskSlackReplySent, setSlackMessageTracking, updateTaskVcs, insertTaskAttachment, recordTaskPullRequestAttachments, getAssetKeyMappingByProvider, upsertAssetKeyMapping, getAssetKeyMapping, listAssetSummaries, moveAssetKey, deleteTaskAttachment, replaceTaskAttachment, getTaskAttachments, createSteeringMessage, getSteeringMessagesForTask, getSteeringMessageById, getPendingSteeringForTask, getPendingSteeringForAgent, markSteeringDelivered, markSteeringHandled, markSteeringPromoted, cancelPendingSteeringForTask, hasPendingSteering, getAgentWithTasks, getAllAgentsWithTasks, createLogEntry, getLogsByAgentId, getLogsByTaskId, getLogsByTaskIdAndEventType, getLogsByTaskIdChronological, getLogsByEventType, getAllLogs, findRecentSimilarTasks, createTaskExtended, claimTask, releaseTask, acceptTask, rejectTask, moveTaskToBacklog, moveTaskFromBacklog, promoteDraftTask, refreshDraftTaskLease, promoteAbandonedDraftTasks, releaseStaleReviewingTasks, releaseStaleOfferedTasksForOfflineAgents, getOfferedTasksForAgent, claimOfferedTask, getUnassignedTasksCount, getUnassignedTaskIds, getUnassignedTaskIdsForAgent, checkDependencies, getDependentTasks, cascadeFailDependents, updateAgentProfile, updateAgentName, createChannel, getMessageById, getChannelById, getChannelByName, getAllChannels, deleteChannel, postMessage, getChannelMessages, updateReadState, getLastReadAt, getUnreadMessages, getMentionsForAgent, getInboxSummary, claimMentions, releaseMentionProcessing, releaseStaleMentionProcessing, createService, getServiceById, getServiceByAgentAndName, getServicesByAgentId, getAllServices, updateServiceStatus, deleteService, upsertService, deleteServicesByAgentId, createSessionLogs, getSessionLogsByTaskId, getSessionLogsBySession, createSessionCost, getSessionCostsByTaskId, getSessionCostsByAgentId, getAllSessionCosts, getSessionCostsFiltered, UNATTRIBUTED_USER_ID, getSessionCostSummary, getUsageDataVersion, getAttributionByPerson, getDashboardCostSummary, createInboxMessage, getInboxMessageById, getUnreadInboxMessages, claimInboxMessages, markInboxMessageRead, markInboxMessageResponded, markInboxMessageDelegated, releaseStaleProcessingInbox, getConcurrentContext, getScheduledTasks, getScheduledTaskById, getScheduledTaskByName, createScheduledTask, updateScheduledTask, deleteScheduledTask, getDueScheduledTasks, autoEncryptLegacyPlaintextSecrets, maskSecrets, getSwarmConfigs, getInjectableGlobalConfigs, getSwarmConfigById, getSwarmConfigLookupById, upsertSwarmConfig, emitBuiltInIntegrationConnectedOnce, deleteSwarmConfig, deleteSwarmConfigByKey, getResolvedConfig, getSwarmRepos, getSwarmRepoById, getSwarmRepoByName, getSwarmRepoByUrl, createSwarmRepo, updateSwarmRepo, deleteSwarmRepo, getAgentMailInboxMapping, getAgentMailInboxMappingsByAgent, getAllAgentMailInboxMappings, createAgentMailInboxMapping, deleteAgentMailInboxMapping, findTaskByAgentMailThread, insertActiveSession, deleteActiveSession, deleteActiveSessionById, getActiveSessions, heartbeatActiveSession, cleanupStaleSessions, cleanupAgentSessions, updateActiveSessionProviderSessionId, getActiveSessionForTask, reassociateSessionLogs, getStalledInProgressTasks, getStalePinnedResumes, failPendingResumeIfUnclaimed, getIdleWorkersWithCapacity, getUnassignedPoolTasks, getStaleUnassignedAffinityTasks, getRecentFailedTasks, getRecentCompletedCount, getRecentFailedCount, createWorkflow, getWorkflow, listWorkflows, updateWorkflow, deleteWorkflow, getWorkflowsByScheduleId, createWorkflowRun, getWorkflowRun, updateWorkflowRun, listWorkflowRuns, countWorkflowRuns, listWorkflowRunsPage, createWorkflowRunStep, getWorkflowRunStep, updateWorkflowRunStep, getWorkflowRunStepsByRunId, getStuckWorkflowRuns, getLastSuccessfulRun, getLastRunStart, getRetryableSteps, getCompletedStepNodeIds, getTaskByWorkflowRunStepId, detachTaskFromWorkflowRunStep, getStepByIdempotencyKey, getStepCountForNode, getLatestStepForNode, getCurrentStepForNode, createWorkflowVersion, getWorkflowVersions, getWorkflowVersion, createAppVersion, getAppVersions, getAppVersion, createPage, getPage, getPageBySlug, getLatestPageBySlug, listPagesByAgent, listAllPages, countAllPages, countPagesByAgent, updatePage, deletePage, incrementPageViewCount, createPageVersion, getPageVersions, getPageVersion, createMetric, getMetric, getMetricBySlug, listMetricsByAgent, listAllMetrics, countAllMetrics, countMetricsByAgent, updateMetric, deleteMetric, createMetricVersion, getMetricVersions, getMetricVersion, getPromptTemplates, getPromptTemplateById, upsertPromptTemplate, deletePromptTemplate, resetPromptTemplateToDefault, getPromptTemplateHistory, resolvePromptTemplate, checkoutPromptTemplate, getAllChannelActivityCursors, getChannelActivityCursor, upsertChannelActivityCursor, createApprovalRequest, getApprovalRequestById, resolveApprovalRequest, cancelApprovalRequestById, cancelPendingApprovalRequestsForRun, listCancelledApprovalRequestsForRun, listCancelledApprovalRequestsForStep, claimApprovalCancellationNotification, completeApprovalCancellationNotificationClaim, releaseApprovalCancellationNotificationClaim, updateApprovalRequestNotifications, listApprovalRequests, getStuckApprovalRuns, getApprovalRequestByStepId, getExpiredPendingApprovals, getStaleApprovalRequests, createWaitState, getWaitStateById, getWaitStateByStepId, getDueWaitStates, getPendingEventWaitNames, getPendingWaitsByEvent, resolveWaitState, getStuckWaitRuns, SKILL_FILE_LIMITS, normalizeSkillFilePath, createSkill, updateSkill, listSkillFileManifest, getSkillFiles, getSkillFile, upsertSkillFile, upsertSkillFiles, deleteSkillFile, deleteSkill, getSkillById, getSkillByName, listSkills, searchSkills, installSkill, getSystemDefaultSkills, installSystemDefaultSkillsForAgent, uninstallSkill, getAgentSkills, toggleAgentSkill, createMcpServer, emitMcpServerConnectedTelemetry, updateMcpServer, deleteMcpServer, getMcpServerById, getMcpServerByName, listMcpServers, installMcpServer, uninstallMcpServer, getAgentMcpServers, createContextSnapshot, getContextSnapshotsByTaskId, getContextSnapshotsBySessionId, getContextSummaryByTaskId, getAvailableKeyIndices, recordKeyUsage, setApiKeyPlan, markKeyRateLimited, recordKeyRateLimitWindows, setApiKeyName, clearKeyRateLimit, getKeyStatuses, getKeyCostSummary, getUserById, getAllUsers, createUser, updateUser, deleteUser, listInboxState, upsertInboxState, listFavorites, listUserFavorites, getFavoriteItemIdSet, setFavorite, setUserFavorite, withFavoriteFlags, listTaskTemplates, getRootTaskChain, listRecentSessions, countSessions, getBudget, getBudgets, upsertBudget, deleteBudget, getAllPricingRows, getPricingRows, getActivePricingRow, insertPricingRow, deletePricingRow, getDailySpendForAgent, getDailySpendGlobal, getDailySpendForUser, recordBudgetRefusalNotification, getBudgetRefusalNotification, getRecentBudgetRefusalNotifications, hasBudgetRefusalNotificationToday, setBudgetRefusalFollowUpTaskId, getLiveAgentCounts, getReadyAgentCounts, getInstanceActivity, getSwarmMetrics, hasFirstCompletedTask, getKv, sweepExpiredKv, sweepExpiredKvPrefix, upsertKv, claimKv, deleteKv, KvTypeCollisionError, incrKv, kvPrefixUpperBound, listKv, countKv, createScriptRun, recordInlineScriptRun, getScriptRun, getScriptRunByIdempotencyKey, listScriptRuns, countScriptRuns, countActiveScriptRuns, updateScriptRun, updateScriptRunIfNotTerminal, updateScriptRunIfRunning, getRunningScriptRuns, getScriptRunJournalStep, upsertScriptRunJournalStep, listScriptRunJournalSteps, countScriptRunJournalSteps, countScriptRunJournalAgentTaskSteps, exports_db, init_db };
13089
+ export { slackContextKey, agentmailContextKey, githubContextKey, gitlabContextKey, linearContextKey, buildJiraContextKey, scheduleContextKey, workflowContextKey, agentContextKey, pageContextKey, init_context_key, checkSlackRoutingCoherence, init_slack_routing, isTelemetryEnabled, _resolveIntegrationType, _resolveIntegrationProvider, initTelemetry, telemetry, emitIntegrationConnected, init_telemetry, CODEX_AUTH_WATCH_NAMESPACE, codexAuthBenchMarkerKey, isCodexAuthFailureReason, init_codex_auth_failure, HeartbeatExpiryError, init_heartbeat_expiry, beginRequestAuthScope, setRequestAuth, getRequestAuth, getCurrentRequestAuth, runWithoutRequestAuth, init_request_auth_context, auditAssetKeys, init_asset_key_audit, encryptSecret, decryptSecret, getEncryptionKey, init_crypto, normalizeDate, normalizeDateRequired, init_date_utils, CredentialBindingSchema, placeholderForConfigKey, CredentialBroker, DEFAULT_CREDENTIAL_BINDINGS, init_credential_broker, isInTransaction, init_db_client, getPromptTemplateDefaultDrift, init_default_drift, init_templates2 as init_templates, isSqliteVecAvailable, resolveSqliteVecExtensionPath, __resetSqliteVecExtensionPathCacheForTests, initDb, getDb, closeDb, getDbClient, updateAgentCredentialState, updateAgentCredentialMissing, createAgent, getAgentById, EXTENSION_AGENT_ROLE, NOT_EXTENSION_AGENT_SQL, isExtensionAgent, extensionAgentAssignmentError, ReservedAgentRoleError, reservedRoleViolation, ExtensionAgentAssignmentError, getAllAgents, getAgentStatusCounts, getLeadAgent, updateAgentStatus, updateAgentMaxTasks, updateAgentProvider, setAgentHarnessProvider, updateAgentCredStatus, listAgentsWithCredStatusByProvider, getAgentHarnessProviders, updateAgentActivity, MAX_EMPTY_POLLS, incrementEmptyPollCount, resetEmptyPollCount, shouldBlockPolling, deleteAgent, getActiveTaskCount, hasCapacity, getRemainingCapacity, updateAgentStatusFromCapacity, isPoolAffinityEnforcementEnabled, buildRoutingAffinityFromAgent, isAgentEligibleForTask, getAgentDailyTaskCounts, listApprovalRequestSummaries, computeContentHash, createContextVersion, getLatestContextVersion, getContextVersion, getContextVersionHistory, setHumanFreeQueueListener, drainHumanFreeReclassifyQueue, init_human_free, getTaskById, getChildTasks, hasNonTerminalResumeChild, getSupersededTasksWithoutResume, getSupersededTasksWithUnsettledDependents, hasNonTerminalRerouteDecisionChild, getTasksByAgentId, getAgentCurrentTask, getTasksByStatus, findTaskByVcs, findTaskByGitHub, getAllTasks, getTasksCount, getTaskStats, getCompletedSlackTasks, getPendingSlackRelayTasks, markSlackRelayAttempted, markSlackRelayDelivered, markFinalizedSlackRelaysDelivered, getRecentlyFinishedWorkerTasks, markTasksNotified, resetTasksNotified, getInProgressSlackTasks, getSlackTasksMissingTree, getInProgressTasksByContextKey, findExistingLinearTrackerContextWork, getLatestTaskByContextKey, getLatestScriptRunStepTaskByContextKey, getAgentWorkingOnThread, getLatestActiveTaskInThread, getLatestLeadTaskInThread, getMostRecentTaskInThread, findCompletedTaskInThread, findRecentCancelledTaskInThread, onTaskStarted, init_task_lifecycle_events, createTask, getPendingTaskForAgent, assignUnassignedTaskPending, startTask, updateTaskClaudeSessionId, updateTaskTitle, completeTask, failTask, overwriteTerminalTaskResultText, cancelTask, supersedeTask, settleSupersededTaskDependents, backfillSupersedeTaskResumeTaskId, pauseTask, resumeTask, getPausedTasksForAgent, getOrphanedInProgressTasksForAgent, resetOrphanedInProgressTasksForAgent, getRecentlyCancelledTasksForAgent, deleteTask, updateTaskProgress, SteeringRequestError, isSteeringEnabled2 as isSteeringEnabled, getTaskSteeringFields, getTaskSteeringFieldsForTasks, promotePendingSteeringForTask, markSteeringUndeliverable, requestSteering, init_steering, SLACK_REACTION_DEFAULTS, SLACK_REACTION_CONFIG_KEYS, reactionName, init_reaction_shortcode, parseTaskToolManifest, selectTaskTools, init_task_tool_manifest, tierConfigKey, init_model_tier_keys, isInternalConfigKey, internalConfigKeyError, isReservedConfigKey, reservedKeyError, MAX_DB_RETENTION_DAYS, DB_RETENTION_TUNING_BOUNDS, validateConfigValue, init_swarm_config_guard, recordKeySeatMismatch, getSlackRenderV2ActivatedAt, ensureSlackRenderV2Activation, getSlackDelegationActivatedAt, ensureSlackDelegationActivation, isPendingSlackMessage, isSettledSlackMessage, recordSlackMessage, reserveSlackMessage, bindSlackMessageTimestamp, updateSlackMessageRecord, markSlackTreeRendered, deleteSlackMessageRecord, getSlackTreeMessage, getSlackTreeMessageByThread, getSlackOutcomeMessage, getResolvableDeferralOutcomes, markSlackDeferralResolved, noteSlackOutcomeDeliveryFailure, abandonSlackOutcomeDelivery, getSlackTreeMessages, getSlackMessageByChannelTs, getSlackTasksInThread, listSlackThreadsAwaitingHuman, isSlackThreadAwaitingHuman, markTaskSlackReplySent, setSlackMessageTracking, updateTaskVcs, insertTaskAttachment, recordTaskPullRequestAttachments, getAssetKeyMappingByProvider, upsertAssetKeyMapping, getAssetKeyMapping, listAssetSummaries, moveAssetKey, deleteTaskAttachment, replaceTaskAttachment, getTaskAttachments, createSteeringMessage, getSteeringMessagesForTask, getSteeringMessageById, getPendingSteeringForTask, getPendingSteeringForAgent, markSteeringDelivered, markSteeringHandled, markSteeringPromoted, cancelPendingSteeringForTask, hasPendingSteering, getAgentWithTasks, getAllAgentsWithTasks, createLogEntry, getLogsByAgentId, getLogsByTaskId, getLogsByTaskIdAndEventType, getLogsByTaskIdChronological, getLogsByEventType, getAllLogs, findRecentSimilarTasks, createTaskExtended, claimTask, releaseTask, acceptTask, rejectTask, moveTaskToBacklog, moveTaskFromBacklog, promoteDraftTask, refreshDraftTaskLease, promoteAbandonedDraftTasks, releaseStaleReviewingTasks, releaseStaleOfferedTasksForOfflineAgents, getOfferedTasksForAgent, claimOfferedTask, getUnassignedTasksCount, getUnassignedTaskIds, getUnassignedTaskIdsForAgent, checkDependencies, getDependentTasks, cascadeFailDependents, updateAgentProfile, updateAgentName, createChannel, getMessageById, getChannelById, getChannelByName, getAllChannels, deleteChannel, postMessage, getChannelMessages, updateReadState, getLastReadAt, getUnreadMessages, getMentionsForAgent, getInboxSummary, claimMentions, releaseMentionProcessing, releaseStaleMentionProcessing, createService, getServiceById, getServiceByAgentAndName, getServicesByAgentId, getAllServices, updateServiceStatus, deleteService, upsertService, deleteServicesByAgentId, createSessionLogs, getSessionLogsByTaskId, getSessionLogsBySession, createSessionCost, getSessionCostsByTaskId, getSessionCostsByAgentId, getAllSessionCosts, getSessionCostsFiltered, UNATTRIBUTED_USER_ID, getSessionCostSummary, getAttributionByPerson, getDashboardCostSummary, createInboxMessage, getInboxMessageById, getUnreadInboxMessages, claimInboxMessages, markInboxMessageRead, markInboxMessageResponded, markInboxMessageDelegated, releaseStaleProcessingInbox, getConcurrentContext, getScheduledTasks, getScheduledTaskById, getScheduledTaskByName, createScheduledTask, updateScheduledTask, deleteScheduledTask, getDueScheduledTasks, autoEncryptLegacyPlaintextSecrets, maskSecrets, getSwarmConfigs, getInjectableGlobalConfigs, getSwarmConfigById, getSwarmConfigLookupById, upsertSwarmConfig, emitBuiltInIntegrationConnectedOnce, deleteSwarmConfig, deleteSwarmConfigByKey, getResolvedConfig, getSwarmRepos, getSwarmRepoById, getSwarmRepoByName, getSwarmRepoByUrl, createSwarmRepo, updateSwarmRepo, deleteSwarmRepo, getAgentMailInboxMapping, getAgentMailInboxMappingsByAgent, getAllAgentMailInboxMappings, createAgentMailInboxMapping, deleteAgentMailInboxMapping, findTaskByAgentMailThread, insertActiveSession, deleteActiveSession, deleteActiveSessionById, getActiveSessions, heartbeatActiveSession, cleanupStaleSessions, cleanupAgentSessions, updateActiveSessionProviderSessionId, getActiveSessionForTask, reassociateSessionLogs, getStalledInProgressTasks, getStalePinnedResumes, failPendingResumeIfUnclaimed, getIdleWorkersWithCapacity, getUnassignedPoolTasks, getStaleUnassignedAffinityTasks, getRecentFailedTasks, getRecentCompletedCount, getRecentFailedCount, createWorkflow, getWorkflow, listWorkflows, updateWorkflow, deleteWorkflow, getWorkflowsByScheduleId, createWorkflowRun, getWorkflowRun, updateWorkflowRun, listWorkflowRuns, countWorkflowRuns, listWorkflowRunsPage, createWorkflowRunStep, getWorkflowRunStep, updateWorkflowRunStep, getWorkflowRunStepsByRunId, getStuckWorkflowRuns, getLastSuccessfulRun, getLastRunStart, getRetryableSteps, getCompletedStepNodeIds, getTaskByWorkflowRunStepId, detachTaskFromWorkflowRunStep, getStepByIdempotencyKey, getStepCountForNode, getLatestStepForNode, getCurrentStepForNode, createWorkflowVersion, getWorkflowVersions, getWorkflowVersion, createAppVersion, getAppVersions, getAppVersion, createPage, getPage, getPageBySlug, getLatestPageBySlug, listPagesByAgent, listAllPages, countAllPages, countPagesByAgent, updatePage, deletePage, incrementPageViewCount, createPageVersion, getPageVersions, getPageVersion, createMetric, getMetric, getMetricBySlug, listMetricsByAgent, listAllMetrics, countAllMetrics, countMetricsByAgent, updateMetric, deleteMetric, createMetricVersion, getMetricVersions, getMetricVersion, getPromptTemplates, getPromptTemplateById, upsertPromptTemplate, deletePromptTemplate, resetPromptTemplateToDefault, getPromptTemplateHistory, resolvePromptTemplate, checkoutPromptTemplate, getAllChannelActivityCursors, getChannelActivityCursor, upsertChannelActivityCursor, createApprovalRequest, getApprovalRequestById, resolveApprovalRequest, cancelApprovalRequestById, cancelPendingApprovalRequestsForRun, listCancelledApprovalRequestsForRun, listCancelledApprovalRequestsForStep, claimApprovalCancellationNotification, completeApprovalCancellationNotificationClaim, releaseApprovalCancellationNotificationClaim, updateApprovalRequestNotifications, listApprovalRequests, getStuckApprovalRuns, getApprovalRequestByStepId, getExpiredPendingApprovals, getStaleApprovalRequests, createWaitState, getWaitStateById, getWaitStateByStepId, getDueWaitStates, getPendingEventWaitNames, getPendingWaitsByEvent, resolveWaitState, getStuckWaitRuns, SKILL_FILE_LIMITS, normalizeSkillFilePath, createSkill, updateSkill, listSkillFileManifest, getSkillFiles, getSkillFile, upsertSkillFile, upsertSkillFiles, deleteSkillFile, deleteSkill, getSkillById, getSkillByName, listSkills, searchSkills, installSkill, getSystemDefaultSkills, installSystemDefaultSkillsForAgent, uninstallSkill, getAgentSkills, toggleAgentSkill, createMcpServer, emitMcpServerConnectedTelemetry, updateMcpServer, deleteMcpServer, getMcpServerById, getMcpServerByName, listMcpServers, installMcpServer, uninstallMcpServer, getAgentMcpServers, createContextSnapshot, getContextSnapshotsByTaskId, getContextSnapshotsBySessionId, getContextSummaryByTaskId, getAvailableKeyIndices, recordKeyUsage, setApiKeyPlan, markKeyRateLimited, recordKeyAuthFailure, recordKeyRateLimitWindows, setApiKeyName, clearKeyRateLimit, getKeyStatuses, getKeyCostSummary, getUserById, getAllUsers, createUser, updateUser, deleteUser, listInboxState, upsertInboxState, listFavorites, listUserFavorites, getFavoriteItemIdSet, setFavorite, setUserFavorite, withFavoriteFlags, listTaskTemplates, getRootTaskChain, listRecentSessions, countSessions, getBudget, getBudgets, upsertBudget, deleteBudget, getAllPricingRows, getPricingRows, getActivePricingRow, insertPricingRow, deletePricingRow, getDailySpendForAgent, getDailySpendGlobal, getDailySpendForUser, recordBudgetRefusalNotification, getBudgetRefusalNotification, getRecentBudgetRefusalNotifications, hasBudgetRefusalNotificationToday, setBudgetRefusalFollowUpTaskId, getLiveAgentCounts, getReadyAgentCounts, getInstanceActivity, getSwarmMetrics, hasFirstCompletedTask, getKv, sweepExpiredKv, sweepExpiredKvPrefix, upsertKv, claimKv, deleteKv, KvTypeCollisionError, incrKv, kvPrefixUpperBound, listKv, countKv, createScriptRun, recordInlineScriptRun, getScriptRun, getScriptRunByIdempotencyKey, listScriptRuns, countScriptRuns, countActiveScriptRuns, updateScriptRun, updateScriptRunIfNotTerminal, updateScriptRunIfRunning, getRunningScriptRuns, getScriptRunJournalStep, upsertScriptRunJournalStep, listScriptRunJournalSteps, countScriptRunJournalSteps, countScriptRunJournalAgentTaskSteps, exports_db, init_db };