@desplega.ai/agent-swarm 1.158.0 → 1.159.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 (272) hide show
  1. package/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-qhch0n2v.js} +1 -1
  2. package/dist/{actions-p9hz5yat.js → actions-dtsh1mfb.js} +33 -29
  3. package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
  4. package/dist/{app-g26wdcz6.js → app-y1b9srva.js} +10 -9
  5. package/dist/{assistant-wydfqkb3.js → assistant-31hwy5xj.js} +34 -30
  6. package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
  7. package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-48d2qpkt.js} +11 -11
  8. package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-w0bryhkr.js} +12 -12
  9. package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-t65wbrn7.js} +9 -8
  10. package/dist/{boot-seeds-s3q01xj3.js → boot-seeds-h7c32hvm.js} +12 -11
  11. package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-1t6611ne.js} +26 -21
  12. package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-werp659j.js} +4 -2
  13. package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
  14. package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
  15. package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
  16. package/dist/{cli-wscdvcqz.js → cli-0n2e4x49.js} +1 -1
  17. package/dist/cli-0xqde53b.js +176 -0
  18. package/dist/{cli-xberxa1r.js → cli-10ym38qc.js} +2 -2
  19. package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
  20. package/dist/{cli-rqz8qbw7.js → cli-20035trh.js} +50 -18
  21. package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
  22. package/dist/cli-3gvrr8vj.js +1422 -0
  23. package/dist/{cli-c07r9a2m.js → cli-48527fpw.js} +9 -8
  24. package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
  25. package/dist/{cli-7gtvvpbh.js → cli-4tvgz99m.js} +7 -7
  26. package/dist/cli-503ya656.js +455 -0
  27. package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
  28. package/dist/{cli-s8eet254.js → cli-68bmme5p.js} +11078 -27833
  29. package/dist/{cli-ftfvggzx.js → cli-79aq9cgb.js} +794 -563
  30. package/dist/cli-7cxw8b60.js +14910 -0
  31. package/dist/cli-7kyk9jr3.js +22 -0
  32. package/dist/cli-7zttzetj.js +324 -0
  33. package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
  34. package/dist/{cli-g8djp6qe.js → cli-9yg65c1j.js} +22 -0
  35. package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
  36. package/dist/{cli-7s3syk22.js → cli-b6thtzac.js} +5 -5
  37. package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
  38. package/dist/{cli-j55n64b6.js → cli-bv0a38v9.js} +163 -44
  39. package/dist/cli-ca2w7zv7.js +115 -0
  40. package/dist/cli-cpvsaqsw.js +333 -0
  41. package/dist/cli-cygyqj3b.js +754 -0
  42. package/dist/{cli-x24pshtq.js → cli-dvjpkkjd.js} +6 -6
  43. package/dist/{cli-5d10vd2m.js → cli-e0ndxhtk.js} +4 -4
  44. package/dist/{cli-4198qc9v.js → cli-e4xnc0qp.js} +15 -3
  45. package/dist/{cli-rjehvrts.js → cli-eg7cdg68.js} +8 -8
  46. package/dist/cli-ejpygnqz.js +3815 -0
  47. package/dist/{cli-fgqxwrpv.js → cli-fjtp3463.js} +1631 -127
  48. package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
  49. package/dist/{cli-47m6dkd3.js → cli-g9df2m37.js} +409 -168
  50. package/dist/cli-gzyh0j0g.js +8455 -0
  51. package/dist/cli-hgqfttfc.js +183 -0
  52. package/dist/cli-hj65wsts.js +17755 -0
  53. package/dist/cli-j9z8mfx3.js +476 -0
  54. package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
  55. package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
  56. package/dist/{cli-20cj37vt.js → cli-m4excttz.js} +136 -2216
  57. package/dist/{cli-8qmme6vd.js → cli-mg24hkt4.js} +2 -2
  58. package/dist/{cli-xhaeg2nc.js → cli-mzkqpxee.js} +1 -1
  59. package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
  60. package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
  61. package/dist/{cli-rj19hc34.js → cli-qjxy52w7.js} +1 -1
  62. package/dist/{cli-53sz8gkz.js → cli-qv4jv8bx.js} +1 -1
  63. package/dist/cli-qvnnx4ct.js +1051 -0
  64. package/dist/cli-rb9m6rpe.js +4980 -0
  65. package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
  66. package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
  67. package/dist/{cli-9httdpyq.js → cli-rrqmqr1s.js} +1 -1
  68. package/dist/cli-rykfmgwg.js +102 -0
  69. package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
  70. package/dist/{cli-68w09sjw.js → cli-vn0qv9cj.js} +25 -88
  71. package/dist/{cli-987hg0aa.js → cli-vwbbaecp.js} +2 -2
  72. package/dist/cli-wd9hz40d.js +69 -0
  73. package/dist/{cli-j57qkrpq.js → cli-wgjx0q33.js} +13 -13
  74. package/dist/cli-xgpf00sk.js +2149 -0
  75. package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
  76. package/dist/{cli-aky8tctm.js → cli-z9x0sh1t.js} +3 -3
  77. package/dist/{cli-1hkrch3k.js → cli-zw65mab6.js} +5 -5
  78. package/dist/cli.js +38 -29
  79. package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
  80. package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-jqfqqa21.js} +21 -14
  81. package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
  82. package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-zd341dsm.js} +21 -14
  83. package/dist/{commands-e3bn0p75.js → commands-vfsysz4s.js} +9 -8
  84. package/dist/{db-03v9kzr2.js → db-s3znhvbn.js} +15 -10
  85. package/dist/{dispatcher-nrmg8yht.js → dispatcher-5xn0c7rf.js} +32 -28
  86. package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-894mgfvs.js} +3 -3
  87. package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
  88. package/dist/execute-71ysgv35.js +965 -0
  89. package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
  90. package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
  91. package/dist/{handlers-aqcedbyb.js → handlers-5w4jwycr.js} +35 -31
  92. package/dist/{hook-7vkskkre.js → hook-853bxrr6.js} +16 -13
  93. package/dist/{hook-ybvmrmhq.js → hook-z0hbxj85.js} +16 -13
  94. package/dist/{http-2eqa8t24.js → http-akc3wy3m.js} +600 -123
  95. package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
  96. package/dist/{index-a3vn96n8.js → index-5sz16ksh.js} +187 -47
  97. package/dist/{index-c6zsv1bd.js → index-bjmjh9h4.js} +11 -11
  98. package/dist/{index-chgdkq36.js → index-cd151qkq.js} +32 -28
  99. package/dist/{index-x71bvq0p.js → index-k661dzzr.js} +33 -29
  100. package/dist/{index-1yks3qcr.js → index-ttpbhnjg.js} +32 -28
  101. package/dist/{keepalive-vtkf5n99.js → keepalive-8p9rpvz5.js} +11 -10
  102. package/dist/{lead-h3sp357x.js → lead-jp69z5h3.js} +49 -45
  103. package/dist/llama-cpp-classify-t2tccams.js +335 -0
  104. package/dist/{maintenance-jzeqtk3q.js → maintenance-fwx4ev0k.js} +12 -12
  105. package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
  106. package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
  107. package/dist/{onboard-tmsp0qbz.js → onboard-2b4q0t84.js} +6 -5
  108. package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
  109. package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
  110. package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
  111. package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-zz7xvjj6.js} +6 -4
  112. package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
  113. package/dist/{otel-impl-9mz73q65.js → otel-impl-g8rs4vwr.js} +1 -1
  114. package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
  115. package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-n0me28wt.js} +29 -17
  116. package/dist/pricing-refresh-0v77385v.js +39 -0
  117. package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-krjyazbj.js} +10 -9
  118. package/dist/{render-v2-gryrh9h8.js → render-v2-3wjsp9aw.js} +10 -9
  119. package/dist/runtime-ktjysacx.js +24 -0
  120. package/dist/{setup-q9720bt6.js → setup-yeqryke6.js} +6 -5
  121. package/dist/typesafe-system-one-96960jxp.js +27 -0
  122. package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-dzdeq1sf.js} +21 -13
  123. package/dist/{work-objects-b76x7deb.js → work-objects-3pakpkw0.js} +35 -31
  124. package/dist/{worker-6vrxbv41.js → worker-85testgj.js} +49 -45
  125. package/openapi.json +863 -14
  126. package/package.json +9 -8
  127. package/src/be/db/agents.ts +20 -0
  128. package/src/be/db/tasks/human-free.ts +442 -0
  129. package/src/be/db/tasks/read.ts +56 -1
  130. package/src/be/db/tasks/write.ts +107 -11
  131. package/src/be/db.ts +89 -165
  132. package/src/be/harness-model-support.ts +182 -0
  133. package/src/be/human-free-drain.ts +67 -0
  134. package/src/be/migrations/182_task_human_free_flag.sql +63 -0
  135. package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
  136. package/src/be/migrations/184_model_catalog.sql +120 -0
  137. package/src/be/model-catalog-store.ts +644 -0
  138. package/src/be/model-tier-keys.ts +31 -0
  139. package/src/be/model-tier-resolution.ts +489 -0
  140. package/src/be/model-validation.ts +112 -0
  141. package/src/be/models-catalog.ts +61 -7
  142. package/src/be/modelsdev-cache.json +82 -0
  143. package/src/be/modelsdev-cache.ts +2 -0
  144. package/src/be/pricing-refresh.ts +154 -12
  145. package/src/be/scripts/typecheck.ts +15 -0
  146. package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
  147. package/src/be/swarm-config-guard.ts +6 -0
  148. package/src/cli.tsx +10 -0
  149. package/src/commands/claude-managed-setup.ts +3 -1
  150. package/src/commands/runner.ts +76 -2
  151. package/src/extensions/contract-types.generated.ts +1 -1
  152. package/src/heartbeat/heartbeat.ts +64 -15
  153. package/src/heartbeat/templates.ts +2 -2
  154. package/src/http/agents.ts +49 -1
  155. package/src/http/index.ts +8 -0
  156. package/src/http/models-catalog.ts +357 -8
  157. package/src/http/poll.ts +45 -2
  158. package/src/http/schedules.ts +36 -6
  159. package/src/http/session-data.ts +2 -5
  160. package/src/http/stats.ts +6 -8
  161. package/src/http/tasks.ts +26 -1
  162. package/src/http/usage-cache.ts +56 -15
  163. package/src/http/workflows.ts +35 -8
  164. package/src/prompts/session-templates.ts +1 -0
  165. package/src/providers/claude-managed-models.ts +47 -161
  166. package/src/providers/codex-adapter.ts +4 -4
  167. package/src/providers/codex-models.ts +65 -198
  168. package/src/providers/reasoning-effort.ts +44 -140
  169. package/src/rbac/legacy-policy.ts +25 -0
  170. package/src/rbac/permissions.ts +10 -0
  171. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  172. package/src/scripts-runtime/types/stdlib.d.ts +15 -0
  173. package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
  174. package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
  175. package/src/server.ts +6 -0
  176. package/src/slack/message-text.ts +56 -2
  177. package/src/slack/thread-buffer.ts +10 -2
  178. package/src/tests/agents-list-model-display.test.ts +4 -6
  179. package/src/tests/base-prompt.test.ts +3 -0
  180. package/src/tests/claude-adapter.test.ts +10 -0
  181. package/src/tests/claude-managed-adapter.test.ts +12 -18
  182. package/src/tests/codex-adapter.test.ts +2 -1
  183. package/src/tests/codex-gpt6-release.test.ts +66 -5
  184. package/src/tests/context-window.test.ts +7 -5
  185. package/src/tests/db-extraction-contract.test.ts +1 -0
  186. package/src/tests/db-task-read-contract.test.ts +5 -1
  187. package/src/tests/db-task-write-contract.test.ts +4 -1
  188. package/src/tests/docs-index-footprint.test.js +3 -3
  189. package/src/tests/explicit-model-validation.test.ts +332 -0
  190. package/src/tests/harness-model-support.test.ts +374 -0
  191. package/src/tests/heartbeat-checklist-config.test.ts +71 -0
  192. package/src/tests/heartbeat-checklist.test.ts +4 -2
  193. package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
  194. package/src/tests/human-free-flag.test.ts +279 -0
  195. package/src/tests/human-free-oracle.ts +57 -0
  196. package/src/tests/human-free-reclassify.test.ts +669 -0
  197. package/src/tests/migration-046-budgets.test.ts +3 -3
  198. package/src/tests/model-catalog-migration.test.ts +134 -0
  199. package/src/tests/model-catalog-table.test.ts +249 -0
  200. package/src/tests/model-catalog-write-access.test.ts +387 -0
  201. package/src/tests/model-tier-resolution.test.ts +519 -0
  202. package/src/tests/models-catalog.test.ts +1 -1
  203. package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
  204. package/src/tests/package-publish.test.ts +137 -36
  205. package/src/tests/pricing-routes.test.ts +2 -2
  206. package/src/tests/rbac-engine.test.ts +42 -2
  207. package/src/tests/reasoning-effort.test.ts +109 -0
  208. package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
  209. package/src/tests/runtime-model-catalog.test.ts +86 -0
  210. package/src/tests/script-connections.test.ts +5 -0
  211. package/src/tests/seed-scripts.test.ts +89 -0
  212. package/src/tests/session-costs.test.ts +14 -11
  213. package/src/tests/slack-message-text.test.ts +101 -0
  214. package/src/tests/slack-thread-buffer-context.test.ts +93 -0
  215. package/src/tests/task-cascade-fail.test.ts +148 -2
  216. package/src/tests/tool-annotations.test.ts +1 -1
  217. package/src/tests/usage-cache.test.ts +166 -0
  218. package/src/tests/workflow-executors.test.ts +5 -2
  219. package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
  220. package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
  221. package/src/tests/workflow-system-one-decision.test.ts +2063 -0
  222. package/src/tools/model-catalog/index.ts +137 -0
  223. package/src/tools/schedules/create-schedule.ts +16 -1
  224. package/src/tools/schedules/patch-schedule.ts +17 -0
  225. package/src/tools/schedules/update-schedule.ts +17 -0
  226. package/src/tools/send-task.ts +14 -0
  227. package/src/tools/task-action.ts +12 -0
  228. package/src/tools/tool-config.ts +3 -1
  229. package/src/tools/workflows/create-workflow.ts +9 -2
  230. package/src/tools/workflows/patch-workflow-node.ts +17 -7
  231. package/src/tools/workflows/patch-workflow.ts +9 -2
  232. package/src/tools/workflows/update-workflow.ts +9 -2
  233. package/src/types.ts +30 -1
  234. package/src/utils/context-window.ts +47 -53
  235. package/src/utils/harness-cli-version.ts +115 -0
  236. package/src/utils/harness-model-error.ts +33 -0
  237. package/src/utils/runtime-model-catalog.ts +137 -0
  238. package/src/workflows/approval-resolution.ts +39 -0
  239. package/src/workflows/definition.ts +7 -0
  240. package/src/workflows/engine.ts +69 -1
  241. package/src/workflows/executors/agent-task.ts +9 -0
  242. package/src/workflows/executors/base.ts +53 -0
  243. package/src/workflows/executors/human-in-the-loop.ts +8 -8
  244. package/src/workflows/executors/index.ts +1 -0
  245. package/src/workflows/executors/registry.ts +2 -0
  246. package/src/workflows/executors/system-one-decision.ts +1232 -0
  247. package/src/workflows/executors/system-one-providers.ts +301 -0
  248. package/src/workflows/executors/workflow-llm.ts +13 -1
  249. package/src/workflows/readiness.ts +86 -0
  250. package/src/workflows/recovery.ts +12 -12
  251. package/src/workflows/resume.ts +23 -9
  252. package/templates/schedules/daily-blocker-digest/content.md +4 -5
  253. package/templates/skills/agent-browser/SKILL.md +6 -5
  254. package/templates/skills/agent-browser/content.md +6 -5
  255. package/templates/skills/heartbeat-runbook/config.json +1 -1
  256. package/templates/skills/heartbeat-runbook/content.md +2 -2
  257. package/templates/skills/swarm-scripts/SKILL.md +1 -1
  258. package/templates/skills/swarm-scripts/content.md +1 -1
  259. package/templates/skills/workflow-iterate/content.md +81 -1
  260. package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
  261. package/templates/workflows/pr-review-status-sweep/content.md +2 -0
  262. package/dist/claude-sdk-session-t442qz6f.js +0 -39108
  263. package/dist/cli-0xjkj1j7.js +0 -61
  264. package/dist/cli-65hjmev5.js +0 -1141
  265. package/dist/cli-aw1jwp1r.js +0 -14075
  266. package/dist/cli-h967nb6r.js +0 -6603
  267. package/dist/cli-vapyk8sw.js +0 -20
  268. package/dist/cli-ws6rqycm.js +0 -247
  269. package/dist/pricing-refresh-v1cbr9te.js +0 -27
  270. package/src/providers/modelsdev-reasoning.json +0 -6453
  271. package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
  272. package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
@@ -2,6 +2,7 @@ import {
2
2
  AgentAvatarSchema,
3
3
  CreateTaskOptionsSchema,
4
4
  FollowUpConfigSchema,
5
+ MODEL_TIERS,
5
6
  PROVIDER_STEER_CAPABILITIES,
6
7
  ProviderNameSchema,
7
8
  ReasoningEffortSchema,
@@ -17,7 +18,7 @@ import {
17
18
  normalizeAssetKey,
18
19
  parseAssetKey,
19
20
  parseModelTier
20
- } from "./cli-4198qc9v.js";
21
+ } from "./cli-e4xnc0qp.js";
21
22
  import {
22
23
  IdentityFieldBudgetError,
23
24
  checkIdentityFieldBudget,
@@ -30,7 +31,11 @@ import {
30
31
  init_templates,
31
32
  matchesDefaultClaudeMd,
32
33
  matchesDefaultIdentityMd
33
- } from "./cli-3gmcwfyx.js";
34
+ } from "./cli-ardpzhjm.js";
35
+ import {
36
+ init_config,
37
+ isSlackConfigured
38
+ } from "./cli-n7h1kqpf.js";
34
39
  import {
35
40
  configureDbResolver,
36
41
  getAllTemplateDefinitions,
@@ -40,28 +45,29 @@ import {
40
45
  init_steering_enabled,
41
46
  isSteeringEnabled,
42
47
  registerTemplate
43
- } from "./cli-ggm92wcn.js";
48
+ } from "./cli-rgjprct3.js";
49
+ import {
50
+ SUBSCRIPTION_KEY_TYPES,
51
+ estimateClaudePlan,
52
+ init_subscription_plans
53
+ } from "./cli-cqt19wg6.js";
44
54
  import {
45
55
  deriveProviderFromKeyType,
46
56
  init_credentials
47
57
  } from "./cli-19jenss3.js";
48
- import {
49
- init_config,
50
- isSlackConfigured
51
- } from "./cli-n7h1kqpf.js";
52
58
  import {
53
59
  activeModelBlock,
54
60
  init_model_rate_limit_windows
55
61
  } from "./cli-de1396j2.js";
56
- import {
57
- SUBSCRIPTION_KEY_TYPES,
58
- estimateClaudePlan,
59
- init_subscription_plans
60
- } from "./cli-cqt19wg6.js";
61
62
  import {
62
63
  init_env_flag,
63
64
  isEnvFlagEnabled
64
65
  } from "./cli-ej6gbxfb.js";
66
+ import {
67
+ init_src,
68
+ isAlias,
69
+ parseAlias
70
+ } from "./cli-7zttzetj.js";
65
71
  import {
66
72
  init_zod
67
73
  } from "./cli-sd0mxa3c.js";
@@ -77,7 +83,7 @@ import {
77
83
  import {
78
84
  init_package,
79
85
  package_default
80
- } from "./cli-c07r9a2m.js";
86
+ } from "./cli-48527fpw.js";
81
87
  import {
82
88
  init_secret_scrubber,
83
89
  registerVolatileSecret,
@@ -2501,6 +2507,17 @@ async function getAllAgents(opts) {
2501
2507
  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
2508
  return rows.map((row) => rowToAgent(row, opts?.slim ?? false));
2503
2509
  }
2510
+ async function getAgentStatusCounts() {
2511
+ const rows = await getDbClient().query(`SELECT status, COUNT(*) AS count FROM agents WHERE ${NOT_EXTENSION_AGENT_SQL} GROUP BY status`);
2512
+ const counts = { total: 0, idle: 0, busy: 0, offline: 0 };
2513
+ for (const { status, count } of rows) {
2514
+ counts.total += count;
2515
+ if (status === "idle" || status === "busy" || status === "offline") {
2516
+ counts[status] = count;
2517
+ }
2518
+ }
2519
+ return counts;
2520
+ }
2504
2521
  async function getLeadAgent() {
2505
2522
  const leads = (await getAllAgents()).filter((a) => a.isLead);
2506
2523
  return leads.find((a) => a.status !== "offline") ?? leads[0] ?? null;
@@ -2789,6 +2806,199 @@ var init_context_versions = __esm(() => {
2789
2806
  init_runtime();
2790
2807
  });
2791
2808
 
2809
+ // src/be/db/tasks/human-free.ts
2810
+ function humanFreeCase(parentFlag) {
2811
+ return `CASE
2812
+ WHEN ${HUMAN_FREE_BASE_SQL} THEN 1
2813
+ WHEN ${parentFlag} = 1 AND ${UNATTRIBUTED_SQL} THEN 1
2814
+ ELSE 0
2815
+ END`;
2816
+ }
2817
+ function carriesHumanFreeTag(tagsJson) {
2818
+ const haystack = (tagsJson ?? "[]").toLowerCase();
2819
+ return HUMAN_FREE_TAGS.some((tag) => haystack.includes(`"${tag}"`));
2820
+ }
2821
+ function tagWriteChangesHumanFree(previousTagsJson, nextTagsJson) {
2822
+ return carriesHumanFreeTag(previousTagsJson) !== carriesHumanFreeTag(nextTagsJson);
2823
+ }
2824
+ async function classifyTaskHumanFree(input) {
2825
+ const row = await getDbClient().get(`WITH task(taskType, tags, source, requestedByUserId, requestedByUserIdInherited, parentTaskId, workflowRunId) AS (
2826
+ VALUES (?, ?, ?, ?, ?, ?, ?)
2827
+ )
2828
+ SELECT ${humanFreeCase("parent.isHumanFree")} AS humanFree
2829
+ FROM task
2830
+ LEFT JOIN agent_tasks parent ON parent.id = task.parentTaskId`, [
2831
+ input.taskType ?? null,
2832
+ input.tags ?? null,
2833
+ input.source ?? null,
2834
+ input.requestedByUserId ?? null,
2835
+ input.requestedByUserIdInherited ? 1 : 0,
2836
+ input.parentTaskId ?? null,
2837
+ input.workflowRunId ?? null
2838
+ ]);
2839
+ return row?.humanFree === 1;
2840
+ }
2841
+ function setHumanFreeQueueListener(listener) {
2842
+ queueListener = listener;
2843
+ }
2844
+ async function enqueueHumanFreeWork(taskIds, scope, hops) {
2845
+ if (taskIds.length === 0)
2846
+ return;
2847
+ if (hops > HUMAN_FREE_MAX_CONTINUATION_HOPS) {
2848
+ 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`);
2849
+ return;
2850
+ }
2851
+ await getDbClient().run(`INSERT INTO human_free_reclassify_queue (taskId, scope, afterRowid, hops)
2852
+ SELECT value, ?, 0, ? FROM json_each(?) WHERE true
2853
+ ON CONFLICT (taskId, scope) DO UPDATE SET
2854
+ afterRowid = 0,
2855
+ hops = MAX(hops, excluded.hops)`, [scope, hops, JSON.stringify(taskIds)]);
2856
+ getDbClient().afterCommit(() => queueListener?.());
2857
+ }
2858
+ async function reclassifyBatch(seedTaskIds, batchSize, hops) {
2859
+ const client = getDbClient();
2860
+ const affected = (await client.query(`WITH RECURSIVE affected(id) AS (
2861
+ SELECT value FROM json_each(?)
2862
+
2863
+ UNION
2864
+
2865
+ SELECT task.id
2866
+ FROM affected
2867
+ JOIN agent_tasks task ON task.parentTaskId = affected.id
2868
+ LIMIT ?
2869
+ )
2870
+ SELECT id FROM affected`, [JSON.stringify(seedTaskIds), batchSize])).map((row) => row.id);
2871
+ const result = await client.run(`WITH RECURSIVE affected(id) AS (
2872
+ SELECT value FROM json_each(?)
2873
+ ),
2874
+ free(id) AS (
2875
+ SELECT task.id
2876
+ FROM agent_tasks task
2877
+ LEFT JOIN agent_tasks parent ON parent.id = task.parentTaskId
2878
+ WHERE task.id IN (SELECT id FROM affected)
2879
+ AND (
2880
+ ${HUMAN_FREE_BASE_SQL}
2881
+ OR (
2882
+ parent.isHumanFree = 1
2883
+ AND parent.id NOT IN (SELECT id FROM affected)
2884
+ AND ${UNATTRIBUTED_SQL}
2885
+ )
2886
+ )
2887
+
2888
+ UNION
2889
+
2890
+ SELECT task.id
2891
+ FROM free
2892
+ JOIN agent_tasks task ON task.parentTaskId = free.id
2893
+ WHERE +task.id IN (SELECT id FROM affected)
2894
+ AND ${UNATTRIBUTED_SQL}
2895
+ )
2896
+ UPDATE agent_tasks
2897
+ SET isHumanFree = CASE WHEN id IN (SELECT id FROM free) THEN 1 ELSE 0 END
2898
+ WHERE id IN (SELECT id FROM affected)
2899
+ AND isHumanFree != CASE WHEN id IN (SELECT id FROM free) THEN 1 ELSE 0 END`, [JSON.stringify(affected)]);
2900
+ if (affected.length >= batchSize) {
2901
+ const unfinished = await client.query(`WITH batch(id) AS (
2902
+ SELECT value FROM json_each(?)
2903
+ )
2904
+ SELECT batch.id
2905
+ FROM batch
2906
+ WHERE EXISTS (
2907
+ SELECT 1
2908
+ FROM agent_tasks child
2909
+ WHERE child.parentTaskId = batch.id
2910
+ AND child.id NOT IN (SELECT id FROM batch)
2911
+ )`, [JSON.stringify(affected)]);
2912
+ await enqueueHumanFreeWork(unfinished.map((row) => row.id), "children", hops);
2913
+ }
2914
+ return result.changes;
2915
+ }
2916
+ async function reclassifyTaskHumanFree(seedTaskIds, options = {}) {
2917
+ const batchSize = options.batchSize ?? HUMAN_FREE_RECLASSIFY_BATCH;
2918
+ const seeds = [...new Set(seedTaskIds)];
2919
+ if (seeds.length === 0)
2920
+ return 0;
2921
+ await enqueueHumanFreeWork(seeds.slice(batchSize), "self", 1);
2922
+ return await reclassifyBatch(seeds.slice(0, batchSize), batchSize, 1);
2923
+ }
2924
+ async function drainOneBatch(batchSize) {
2925
+ return await getDbClient().transaction(async (tx) => {
2926
+ const head = await tx.get("SELECT * FROM human_free_reclassify_queue ORDER BY seq LIMIT 1");
2927
+ if (!head)
2928
+ return null;
2929
+ if (head.scope === "self") {
2930
+ const rows = await tx.query("SELECT * FROM human_free_reclassify_queue WHERE scope = 'self' ORDER BY seq LIMIT ?", [batchSize]);
2931
+ const seeds = rows.map((row) => row.taskId);
2932
+ const hops = Math.max(...rows.map((row) => row.hops)) + 1;
2933
+ await tx.run("DELETE FROM human_free_reclassify_queue WHERE seq IN (SELECT value FROM json_each(?))", [JSON.stringify(rows.map((row) => row.seq))]);
2934
+ return await reclassifyBatch(seeds, batchSize, hops);
2935
+ }
2936
+ const page = await tx.query(`SELECT id, rowid AS position
2937
+ FROM agent_tasks
2938
+ WHERE parentTaskId = ? AND rowid > ?
2939
+ ORDER BY rowid
2940
+ LIMIT ?`, [head.taskId, head.afterRowid, batchSize]);
2941
+ if (page.length < batchSize) {
2942
+ await tx.run("DELETE FROM human_free_reclassify_queue WHERE seq = ?", [head.seq]);
2943
+ } else {
2944
+ await tx.run("UPDATE human_free_reclassify_queue SET afterRowid = ? WHERE seq = ?", [
2945
+ page[page.length - 1]?.position ?? head.afterRowid,
2946
+ head.seq
2947
+ ]);
2948
+ }
2949
+ if (page.length === 0)
2950
+ return 0;
2951
+ return await reclassifyBatch(page.map((row) => row.id), batchSize, head.hops + 1);
2952
+ });
2953
+ }
2954
+ async function pendingHumanFreeReclassifications() {
2955
+ const row = await getDbClient().get("SELECT COUNT(*) AS count FROM human_free_reclassify_queue");
2956
+ return row?.count ?? 0;
2957
+ }
2958
+ async function drainHumanFreeReclassifyQueue(options = {}) {
2959
+ const batchSize = options.batchSize ?? HUMAN_FREE_RECLASSIFY_BATCH;
2960
+ const maxBatches = options.maxBatches ?? Number.POSITIVE_INFINITY;
2961
+ let batches = 0;
2962
+ let changed = 0;
2963
+ while (batches < maxBatches) {
2964
+ const batchChanged = await drainOneBatch(batchSize);
2965
+ if (batchChanged === null)
2966
+ break;
2967
+ batches += 1;
2968
+ changed += batchChanged;
2969
+ }
2970
+ return { batches, changed, remaining: await pendingHumanFreeReclassifications() };
2971
+ }
2972
+ 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;
2973
+ var init_human_free = __esm(() => {
2974
+ init_runtime();
2975
+ HUMAN_FREE_TAGS = ["heartbeat"];
2976
+ HUMAN_FREE_TAG_SQL = HUMAN_FREE_TAGS.map((tag) => `COALESCE(task.tags, '[]') LIKE '%"${tag}"%'`).join(`
2977
+ OR `);
2978
+ HUMAN_FREE_BASE_SQL = `(
2979
+ COALESCE(task.taskType, '') IN ('heartbeat', 'heartbeat-checklist', 'boot-triage')
2980
+ OR ${HUMAN_FREE_TAG_SQL}
2981
+ OR (COALESCE(task.source, '') = 'schedule' AND task.requestedByUserId IS NULL)
2982
+ OR (
2983
+ task.parentTaskId IS NULL
2984
+ AND COALESCE(task.source, '') = 'workflow'
2985
+ AND task.requestedByUserId IS NULL
2986
+ AND EXISTS (
2987
+ SELECT 1
2988
+ FROM workflow_runs run
2989
+ WHERE run.id = task.workflowRunId
2990
+ AND run.triggerType = 'schedule'
2991
+ AND run.created_by IS NULL
2992
+ )
2993
+ )
2994
+ OR (
2995
+ COALESCE(task.source, '') = 'system'
2996
+ AND parent.id IS NOT NULL
2997
+ AND parent.requestedByUserId IS NULL
2998
+ )
2999
+ )`;
3000
+ });
3001
+
2792
3002
  // src/utils/provider-metadata.ts
2793
3003
  function parseProviderMeta(rawProvider, rawMeta) {
2794
3004
  if (!rawMeta || !rawProvider)
@@ -2882,6 +3092,9 @@ function rowToAgentTask(row) {
2882
3092
  claudeSessionId: row.claudeSessionId ?? undefined,
2883
3093
  model: row.model ?? undefined,
2884
3094
  modelTier: parseModelTier(row.modelTier) ?? undefined,
3095
+ resolvedModel: row.resolvedModel ?? undefined,
3096
+ modelSource: row.modelSource ?? undefined,
3097
+ modelAlias: row.modelAlias ?? undefined,
2885
3098
  effort: ReasoningEffortSchema.safeParse(row.effort).success ? row.effort : undefined,
2886
3099
  scheduleId: row.scheduleId ?? undefined,
2887
3100
  workflowRunId: row.workflowRunId ?? undefined,
@@ -2935,6 +3148,9 @@ function rowToAgentTaskSummary(row) {
2935
3148
  scheduleId: row.scheduleId ?? undefined,
2936
3149
  model: row.model ?? undefined,
2937
3150
  modelTier: parseModelTier(row.modelTier) ?? undefined,
3151
+ resolvedModel: row.resolvedModel ?? undefined,
3152
+ modelSource: row.modelSource ?? undefined,
3153
+ modelAlias: row.modelAlias ?? undefined,
2938
3154
  effort: ReasoningEffortSchema.safeParse(row.effort).success ? row.effort : undefined,
2939
3155
  provider: row.provider ?? undefined,
2940
3156
  requestedByUserId: row.requestedByUserId ?? undefined,
@@ -2989,6 +3205,24 @@ async function getSupersededTasksWithoutResume(finishedBefore, finishedAfter) {
2989
3205
  ORDER BY t.finishedAt ASC`, [finishedBefore, finishedAfter]);
2990
3206
  return rows.map(rowToAgentTask);
2991
3207
  }
3208
+ async function getSupersededTasksWithUnsettledDependents(finishedBefore, finishedAfter) {
3209
+ const placeholders = NEVER_STARTED_TASK_STATUSES.map(() => "?").join(", ");
3210
+ return getDbClient().query(`SELECT taskId, resumeTaskId FROM (
3211
+ SELECT t.id AS taskId, t.finishedAt AS finishedAt,
3212
+ (SELECT c.id FROM agent_tasks c
3213
+ WHERE c.parentTaskId = t.id AND c.taskType = 'resume'
3214
+ ORDER BY c.createdAt DESC LIMIT 1) AS resumeTaskId
3215
+ FROM agent_tasks t
3216
+ WHERE t.status = 'superseded'
3217
+ AND t.finishedAt < ?
3218
+ AND t.finishedAt > ?
3219
+ AND EXISTS (
3220
+ SELECT 1 FROM agent_tasks d, json_each(d.dependsOn) AS j
3221
+ WHERE j.value = t.id AND d.status IN (${placeholders})
3222
+ ))
3223
+ WHERE resumeTaskId IS NOT NULL
3224
+ ORDER BY finishedAt ASC`, [finishedBefore, finishedAfter, ...NEVER_STARTED_TASK_STATUSES]);
3225
+ }
2992
3226
  async function hasNonTerminalRerouteDecisionChild(parentId) {
2993
3227
  const row = await getDbClient().get(`SELECT 1 FROM agent_tasks
2994
3228
  WHERE parentTaskId = ?
@@ -3482,7 +3716,7 @@ async function findRecentCancelledTaskInThread(channelId, threadTs, windowMinute
3482
3716
  LIMIT 1`, [channelId, threadTs, since]);
3483
3717
  return row ? rowToAgentTask(row) : null;
3484
3718
  }
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:";
3719
+ 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
3720
  var init_read = __esm(() => {
3487
3721
  init_key();
3488
3722
  init_types();
@@ -3498,7 +3732,8 @@ var init_read = __esm(() => {
3498
3732
  ${TASK_PREVIEW_SQL}, agent_tasks.title, agent_tasks.status, agent_tasks.source,
3499
3733
  agent_tasks.taskType, agent_tasks.tags, agent_tasks.priority, agent_tasks.dependsOn,
3500
3734
  agent_tasks.offeredTo, agent_tasks.acceptedAt, agent_tasks.parentTaskId,
3501
- agent_tasks.scheduleId, agent_tasks.model, agent_tasks.modelTier, agent_tasks.effort,
3735
+ agent_tasks.scheduleId, agent_tasks.model, agent_tasks.modelTier,
3736
+ agent_tasks.resolvedModel, agent_tasks.modelSource, agent_tasks.modelAlias, agent_tasks.effort,
3502
3737
  agent_tasks.provider, agent_tasks.requestedByUserId, agent_tasks.progress,
3503
3738
  agent_tasks.createdAt, agent_tasks.lastUpdatedAt, agent_tasks.finishedAt,
3504
3739
  agent_tasks.peakContextPercent`,
@@ -3506,6 +3741,14 @@ var init_read = __esm(() => {
3506
3741
  agent_tasks.title, agent_tasks.status, agent_tasks.createdAt, agent_tasks.lastUpdatedAt,
3507
3742
  agent_tasks.finishedAt, agent_tasks.peakContextTokens`
3508
3743
  };
3744
+ NEVER_STARTED_TASK_STATUSES = [
3745
+ "draft",
3746
+ "backlog",
3747
+ "unassigned",
3748
+ "offered",
3749
+ "reviewing",
3750
+ "pending"
3751
+ ];
3509
3752
  findTaskByGitHub = findTaskByVcs;
3510
3753
  });
3511
3754
 
@@ -3535,8 +3778,9 @@ function configureTaskWriteDependencies(value) {
3535
3778
  async function createTask(agentId, task, options) {
3536
3779
  const id = crypto.randomUUID();
3537
3780
  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 *`, [
3781
+ const isHumanFree = await classifyTaskHumanFree({ source: source2 });
3782
+ const row = await getDbClient().get(`INSERT INTO agent_tasks (id, "key", agentId, task, status, source, slackChannelId, slackThreadTs, slackUserId, swarmVersion, isHumanFree, createdAt, lastUpdatedAt)
3783
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) RETURNING *`, [
3540
3784
  id,
3541
3785
  defaultAssetKey("task", id),
3542
3786
  agentId,
@@ -3546,7 +3790,8 @@ async function createTask(agentId, task, options) {
3546
3790
  options?.slackChannelId ?? null,
3547
3791
  options?.slackThreadTs ?? null,
3548
3792
  options?.slackUserId ?? null,
3549
- package_default.version
3793
+ package_default.version,
3794
+ isHumanFree ? 1 : 0
3550
3795
  ]);
3551
3796
  if (!row)
3552
3797
  throw new Error("Failed to create task");
@@ -3719,7 +3964,12 @@ async function completeTask(id, output, options) {
3719
3964
  if (completed && options?.addTags?.length) {
3720
3965
  const existingTags = completed.tags ? JSON.parse(completed.tags) : [];
3721
3966
  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]);
3967
+ const previousTagsJson = completed.tags;
3968
+ const nextTagsJson = JSON.stringify(nextTags);
3969
+ completed = await getDbClient().get("UPDATE agent_tasks SET tags = ?, lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ? RETURNING *", [nextTagsJson, id]);
3970
+ if (tagWriteChangesHumanFree(previousTagsJson, nextTagsJson)) {
3971
+ await reclassifyTaskHumanFree([id]);
3972
+ }
3723
3973
  }
3724
3974
  if (completed && options?.deferredAt) {
3725
3975
  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 +4200,52 @@ async function supersedeTask(id, args) {
3950
4200
  });
3951
4201
  }).catch((err) => console.error("[db] task.superseded event not emitted:", scrubSecrets(err instanceof Error ? err.message : String(err))));
3952
4202
  });
3953
- try {
3954
- await dependencies3.cascadeFailDependents(id, "superseded");
3955
- } catch (err) {
3956
- console.error("[supersedeTask] cascade-fail dependents error:", err);
3957
- }
4203
+ if (args.resumeTaskId)
4204
+ await settleSupersededTaskDependents(id, args.resumeTaskId);
3958
4205
  }
3959
4206
  return row ? rowToAgentTask(row) : null;
3960
4207
  }
4208
+ async function settleSupersededTaskDependents(supersededId, resumeTaskId) {
4209
+ try {
4210
+ if (resumeTaskId) {
4211
+ const placeholders = NEVER_STARTED_TASK_STATUSES.map(() => "?").join(", ");
4212
+ const repointed = await getDbClient().query(`UPDATE agent_tasks
4213
+ SET dependsOn = (
4214
+ SELECT json_group_array(value ORDER BY k) FROM (
4215
+ SELECT CASE WHEN j.value = ? THEN ? ELSE j.value END AS value,
4216
+ MIN(j.key) AS k
4217
+ FROM json_each(agent_tasks.dependsOn) AS j
4218
+ GROUP BY 1)),
4219
+ lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
4220
+ WHERE status IN (${placeholders})
4221
+ AND EXISTS (SELECT 1 FROM json_each(agent_tasks.dependsOn) WHERE value = ?)
4222
+ RETURNING id, agentId`, [supersededId, resumeTaskId, ...NEVER_STARTED_TASK_STATUSES, supersededId]);
4223
+ for (const dep of repointed) {
4224
+ try {
4225
+ await dependencies3.createLogEntry({
4226
+ eventType: "task_dependency_repointed",
4227
+ taskId: dep.id,
4228
+ agentId: dep.agentId ?? undefined,
4229
+ oldValue: supersededId,
4230
+ newValue: resumeTaskId,
4231
+ metadata: { reason: "supersede_resume" }
4232
+ });
4233
+ } catch {}
4234
+ }
4235
+ const resume = await getTaskById(resumeTaskId);
4236
+ if (repointed.length > 0 && (resume?.status === "failed" || resume?.status === "cancelled")) {
4237
+ await dependencies3.cascadeFailDependents(resumeTaskId, resume.status);
4238
+ }
4239
+ }
4240
+ await dependencies3.cascadeFailDependents(supersededId, "superseded");
4241
+ } catch (err) {
4242
+ console.error("[supersedeTask] settling dependents error:", err);
4243
+ }
4244
+ }
3961
4245
  async function backfillSupersedeTaskResumeTaskId(taskId, resumeTaskId) {
4246
+ if ((await getTaskById(taskId))?.status === "superseded") {
4247
+ await settleSupersededTaskDependents(taskId, resumeTaskId);
4248
+ }
3962
4249
  const row = await getDbClient().get(`SELECT id, metadata
3963
4250
  FROM agent_log
3964
4251
  WHERE taskId = ? AND eventType = 'task_superseded'
@@ -4091,8 +4378,12 @@ async function getRecentlyCancelledTasksForAgent(agentId) {
4091
4378
  return rows.map(rowToAgentTask);
4092
4379
  }
4093
4380
  async function deleteTask(id) {
4094
- const result = await getDbClient().run("DELETE FROM agent_tasks WHERE id = ?", [id]);
4095
- return result.changes > 0;
4381
+ return await getDbClient().transaction(async (tx) => {
4382
+ const childIds = (await tx.query("SELECT id FROM agent_tasks WHERE parentTaskId = ?", [id])).map((row) => row.id);
4383
+ const result = await tx.run("DELETE FROM agent_tasks WHERE id = ?", [id]);
4384
+ await reclassifyTaskHumanFree(childIds);
4385
+ return result.changes > 0;
4386
+ });
4096
4387
  }
4097
4388
  async function updateTaskProgress(id, progress) {
4098
4389
  const scrubbedProgress = scrubSecrets(progress);
@@ -4130,6 +4421,7 @@ var init_write = __esm(() => {
4130
4421
  init_task_lifecycle_events();
4131
4422
  init_agents();
4132
4423
  init_runtime();
4424
+ init_human_free();
4133
4425
  init_read();
4134
4426
  AFFINITY_DISPATCH_SKIP_LOG_COOLDOWN_MS = 5 * 60 * 1000;
4135
4427
  lastAffinityDispatchSkipLoggedAt = new Map;
@@ -4395,6 +4687,8 @@ var init_tool_config = __esm(() => {
4395
4687
  "delete-config",
4396
4688
  "credential-bindings",
4397
4689
  "script-connections",
4690
+ "model-catalog-refresh",
4691
+ "model-catalog-overlay-upsert",
4398
4692
  "update-repo",
4399
4693
  "update-profile",
4400
4694
  "context-history",
@@ -4515,6 +4809,31 @@ var init_task_tool_manifest = __esm(() => {
4515
4809
  });
4516
4810
  });
4517
4811
 
4812
+ // src/be/model-tier-keys.ts
4813
+ function tierConfigKey(provider, tier) {
4814
+ return `MODEL_TIER_${provider.toUpperCase().replace(/-/g, "_")}_${tier.toUpperCase()}`;
4815
+ }
4816
+ function isTierConfigKey(key) {
4817
+ return TIER_CONFIG_KEY_RE.test(key.toUpperCase());
4818
+ }
4819
+ function validateTierConfigValue(key, value) {
4820
+ const message = `Invalid ${key} (expected a model id, a CLI alias such as "opus", or latest:<anthropic|openai|openrouter>/<target>[@stable|@any])`;
4821
+ if (typeof value !== "string")
4822
+ return message;
4823
+ const trimmed = value.trim();
4824
+ if (trimmed.length === 0 || /\s/.test(trimmed) || trimmed.length > 200)
4825
+ return message;
4826
+ if (isAlias(trimmed) && !parseAlias(trimmed))
4827
+ return message;
4828
+ return null;
4829
+ }
4830
+ var TIER_CONFIG_KEY_RE;
4831
+ var init_model_tier_keys = __esm(() => {
4832
+ init_src();
4833
+ init_types();
4834
+ TIER_CONFIG_KEY_RE = new RegExp(`^MODEL_TIER_(${ProviderNameSchema.options.map((p) => p.toUpperCase().replace(/-/g, "_")).join("|")})_(${MODEL_TIERS.map((t) => t.toUpperCase()).join("|")})$`);
4835
+ });
4836
+
4518
4837
  // src/be/swarm-config-guard.ts
4519
4838
  function isInternalConfigKey(key) {
4520
4839
  return INTERNAL_CONFIG_KEYS.has(key.toLowerCase());
@@ -4596,6 +4915,8 @@ function validateFloatRange(key, value, min, max, expectation) {
4596
4915
  return null;
4597
4916
  }
4598
4917
  function validateConfigValue(key, value) {
4918
+ if (isTierConfigKey(key))
4919
+ return validateTierConfigValue(key.toUpperCase(), value);
4599
4920
  const validator = VALIDATED_KEYS[key.toUpperCase()];
4600
4921
  return validator ? validator(value) : null;
4601
4922
  }
@@ -4604,6 +4925,7 @@ var init_swarm_config_guard = __esm(() => {
4604
4925
  init_reaction_shortcode();
4605
4926
  init_types();
4606
4927
  init_task_tool_manifest();
4928
+ init_model_tier_keys();
4607
4929
  RESERVED_KEYS = new Set([
4608
4930
  "API_KEY",
4609
4931
  "SECRETS_ENCRYPTION_KEY",
@@ -4697,6 +5019,7 @@ var init_swarm_config_guard = __esm(() => {
4697
5019
  return null;
4698
5020
  },
4699
5021
  ...booleanValidators([
5022
+ "SWARM_DEV_MODE",
4700
5023
  "MULTI_RUNTIME_ENABLED",
4701
5024
  "STEERING_ENABLED",
4702
5025
  "MEMORY_HYBRID_SEARCH",
@@ -4726,7 +5049,8 @@ var init_swarm_config_guard = __esm(() => {
4726
5049
  "ANONYMIZED_TELEMETRY",
4727
5050
  "SWARM_HIDE_CLOUD_PROMO",
4728
5051
  "DB_QUERY_BOUNDED_ENABLED",
4729
- "DB_RETENTION_DRY_RUN"
5052
+ "DB_RETENTION_DRY_RUN",
5053
+ "MODEL_AUTO_UPGRADE"
4730
5054
  ]),
4731
5055
  ...enumValidator("SLACK_MODE", ["socket", "http"]),
4732
5056
  ...enumValidator("SLACK_THREAD_STEERING", ["off", "lead", "all"]),
@@ -4767,6 +5091,7 @@ var init_swarm_config_guard = __esm(() => {
4767
5091
  ...boundedIntegerValidatorsFor(DB_RETENTION_TUNING_BOUNDS),
4768
5092
  ...boundedIntegerValidators(["SESSION_LOG_RETENTION_DAYS", "AGENT_LOG_RETENTION_DAYS", "EVENTS_RETENTION_DAYS"], 1, MAX_DB_RETENTION_DAYS),
4769
5093
  ...integerValidators(["HEARTBEAT_MAX_AUTO_ASSIGN"], 0),
5094
+ ...integerValidators(["MODEL_LATEST_SOAK_DAYS"], 0),
4770
5095
  ...integerValidators(["APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS"], 0),
4771
5096
  ...boundedIntegerValidators(["CONTEXT_PREAMBLE_MAX_TOKENS"], 100, 20000),
4772
5097
  MEMORY_MIN_SIMILARITY: (value) => validateFloatRange("MEMORY_MIN_SIMILARITY", value, 0, 1, "between 0 and 1 inclusive"),
@@ -4910,6 +5235,7 @@ __export(exports_db, {
4910
5235
  getAgentMailInboxMappingsByAgent: () => getAgentMailInboxMappingsByAgent,
4911
5236
  getAgentMcpServers: () => getAgentMcpServers,
4912
5237
  getAgentSkills: () => getAgentSkills,
5238
+ getAgentStatusCounts: () => getAgentStatusCounts,
4913
5239
  getAgentWithTasks: () => getAgentWithTasks,
4914
5240
  getAgentWorkingOnThread: () => getAgentWorkingOnThread,
4915
5241
  getAllAgentMailInboxMappings: () => getAllAgentMailInboxMappings,
@@ -5064,6 +5390,7 @@ __export(exports_db, {
5064
5390
  getStuckApprovalRuns: () => getStuckApprovalRuns,
5065
5391
  getStuckWaitRuns: () => getStuckWaitRuns,
5066
5392
  getStuckWorkflowRuns: () => getStuckWorkflowRuns,
5393
+ getSupersededTasksWithUnsettledDependents: () => getSupersededTasksWithUnsettledDependents,
5067
5394
  getSupersededTasksWithoutResume: () => getSupersededTasksWithoutResume,
5068
5395
  getSwarmConfigById: () => getSwarmConfigById,
5069
5396
  getSwarmConfigLookupById: () => getSwarmConfigLookupById,
@@ -5087,7 +5414,6 @@ __export(exports_db, {
5087
5414
  getUnassignedTasksCount: () => getUnassignedTasksCount,
5088
5415
  getUnreadInboxMessages: () => getUnreadInboxMessages,
5089
5416
  getUnreadMessages: () => getUnreadMessages,
5090
- getUsageDataVersion: () => getUsageDataVersion,
5091
5417
  getUserById: () => getUserById,
5092
5418
  getWaitStateById: () => getWaitStateById,
5093
5419
  getWaitStateByStepId: () => getWaitStateByStepId,
@@ -5207,6 +5533,7 @@ __export(exports_db, {
5207
5533
  setFavorite: () => setFavorite,
5208
5534
  setSlackMessageTracking: () => setSlackMessageTracking,
5209
5535
  setUserFavorite: () => setUserFavorite,
5536
+ settleSupersededTaskDependents: () => settleSupersededTaskDependents,
5210
5537
  shouldBlockPolling: () => shouldBlockPolling,
5211
5538
  startTask: () => startTask,
5212
5539
  supersedeTask: () => supersedeTask,
@@ -6612,6 +6939,15 @@ async function createTaskExtended(task, options) {
6612
6939
  } catch (error) {
6613
6940
  logRoutingDecisionFailure(id, "capture", error);
6614
6941
  }
6942
+ const isHumanFree = await classifyTaskHumanFree({
6943
+ taskType: options?.taskType,
6944
+ tags: JSON.stringify(options?.tags ?? []),
6945
+ source: options?.source ?? "mcp",
6946
+ requestedByUserId: options?.requestedByUserId,
6947
+ requestedByUserIdInherited,
6948
+ parentTaskId: options?.parentTaskId,
6949
+ workflowRunId: options?.workflowRunId
6950
+ });
6615
6951
  const inserted = await getDbClient().get(`INSERT INTO agent_tasks (
6616
6952
  id, "key", agentId, creatorAgentId, task, status, source, routing_reason, routing_source, routing_note,
6617
6953
  taskType, tags, priority, dependsOn, offeredTo, offeredAt,
@@ -6620,8 +6956,8 @@ async function createTaskExtended(task, options) {
6620
6956
  vcsInstallationId, vcsNodeId,
6621
6957
  agentmailInboxId, agentmailMessageId, agentmailThreadId,
6622
6958
  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 *`, [
6959
+ workflowRunId, workflowRunStepId, outputSchema, followUpConfig, requestedByUserId, requestedByUserIdInherited, contextKey, routingAffinity, swarmVersion, createdAt, lastUpdatedAt, created_by, updated_by, isHumanFree
6960
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`, [
6625
6961
  id,
6626
6962
  assetKey,
6627
6963
  options?.agentId ?? null,
@@ -6674,7 +7010,8 @@ async function createTaskExtended(task, options) {
6674
7010
  now,
6675
7011
  now,
6676
7012
  auditUserId,
6677
- auditUserId
7013
+ auditUserId,
7014
+ isHumanFree ? 1 : 0
6678
7015
  ]);
6679
7016
  if (!inserted)
6680
7017
  throw new Error("Failed to create task");
@@ -7855,8 +8192,8 @@ async function getSessionCostsFiltered(opts) {
7855
8192
  return rows.map(rowToSessionCost);
7856
8193
  }
7857
8194
  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`;
8195
+ const from = "FROM session_costs sc LEFT JOIN agent_tasks t INDEXED BY idx_agent_tasks_usage_cover ON t.id = sc.taskId";
8196
+ const agentFrom = opts.userId === undefined ? "FROM session_costs sc" : from;
7860
8197
  const conditions = [];
7861
8198
  const params = [];
7862
8199
  if (opts.startDate) {
@@ -7878,12 +8215,8 @@ async function getSessionCostSummary(opts) {
7878
8215
  params.push(opts.userId);
7879
8216
  }
7880
8217
  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
8218
  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
8219
+ const totalsRow = await getDbClient().get(`SELECT
7887
8220
  COALESCE(SUM(sc.totalCostUsd), 0) as totalCostUsd,
7888
8221
  COALESCE(SUM(sc.inputTokens), 0) as totalInputTokens,
7889
8222
  COALESCE(SUM(sc.outputTokens), 0) as totalOutputTokens,
@@ -7900,7 +8233,7 @@ async function getSessionCostSummary(opts) {
7900
8233
  COUNT(DISTINCT CASE WHEN ${HUMAN_FREE_SQL} THEN t.id END) as excludedTaskCount,
7901
8234
  COALESCE(SUM(CASE WHEN ${subscriptionSql}
7902
8235
  THEN sc.totalCostUsd ELSE 0 END), 0) as subscriptionCostUsd
7903
- ${fromHf} ${where}`, params);
8236
+ ${from} ${where}`, params);
7904
8237
  const totals = totalsRow ? {
7905
8238
  ...totalsRow,
7906
8239
  avgCostPerSession: totalsRow.totalSessions > 0 ? totalsRow.totalCostUsd / totalsRow.totalSessions : 0
@@ -7922,8 +8255,7 @@ async function getSessionCostSummary(opts) {
7922
8255
  const groupBy = opts.groupBy ?? "both";
7923
8256
  let daily = [];
7924
8257
  if (groupBy === "day" || groupBy === "both") {
7925
- daily = await getDbClient().query(`${withHf}
7926
- SELECT
8258
+ daily = await getDbClient().query(`SELECT
7927
8259
  DATE(sc.createdAt) as date,
7928
8260
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7929
8261
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
@@ -7931,42 +8263,39 @@ async function getSessionCostSummary(opts) {
7931
8263
  COUNT(*) as sessions,
7932
8264
  COALESCE(SUM(CASE WHEN ${subscriptionSql} THEN sc.totalCostUsd ELSE 0 END), 0)
7933
8265
  as subscriptionCostUsd
7934
- ${scopedFrom} ${where}
8266
+ ${from} ${where}
7935
8267
  GROUP BY DATE(sc.createdAt)
7936
8268
  ORDER BY date ASC`, params);
7937
8269
  }
7938
8270
  let byAgent = [];
7939
8271
  if (groupBy === "agent" || groupBy === "both") {
7940
- byAgent = await getDbClient().query(`${withHf}
7941
- SELECT
8272
+ byAgent = await getDbClient().query(`SELECT
7942
8273
  sc.agentId as agentId,
7943
8274
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7944
8275
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
7945
8276
  COALESCE(SUM(sc.outputTokens), 0) as outputTokens,
7946
8277
  COUNT(*) as sessions,
7947
8278
  COALESCE(SUM(sc.durationMs), 0) as durationMs
7948
- ${scopedFrom} ${where}
8279
+ ${agentFrom} ${where}
7949
8280
  GROUP BY sc.agentId
7950
8281
  ORDER BY costUsd DESC`, params);
7951
8282
  }
7952
8283
  let byUser = [];
7953
8284
  if (groupBy === "user" || groupBy === "both") {
7954
- byUser = await getDbClient().query(`WITH RECURSIVE ${HUMAN_FREE_TASKS_CTE}
7955
- SELECT
8285
+ byUser = await getDbClient().query(`SELECT
7956
8286
  CASE WHEN ${HUMAN_FREE_SQL} THEN NULL ELSE t.requestedByUserId END as userId,
7957
8287
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
7958
8288
  COALESCE(SUM(sc.inputTokens), 0) as inputTokens,
7959
8289
  COALESCE(SUM(sc.outputTokens), 0) as outputTokens,
7960
8290
  COUNT(DISTINCT sc.taskId) as tasks,
7961
8291
  COALESCE(SUM(sc.durationMs), 0) as durationMs
7962
- ${fromHf} ${where}
8292
+ ${from} ${where}
7963
8293
  GROUP BY CASE WHEN ${HUMAN_FREE_SQL} THEN NULL ELSE t.requestedByUserId END
7964
8294
  ORDER BY costUsd DESC`, params);
7965
8295
  }
7966
8296
  let byCredential = [];
7967
8297
  if (groupBy === "both") {
7968
- const rows = await getDbClient().query(`${withHf}
7969
- SELECT
8298
+ const rows = await getDbClient().query(`SELECT
7970
8299
  t.credentialKeyType as keyType,
7971
8300
  t.credentialKeySuffix as keySuffix,
7972
8301
  COALESCE(SUM(sc.totalCostUsd), 0) as costUsd,
@@ -7975,7 +8304,7 @@ async function getSessionCostSummary(opts) {
7975
8304
  COUNT(*) as sessions,
7976
8305
  MIN(sc.createdAt) as firstSessionAt,
7977
8306
  MAX(sc.createdAt) as lastSessionAt
7978
- ${scopedFrom} ${where}
8307
+ ${from} ${where}
7979
8308
  GROUP BY t.credentialKeyType, t.credentialKeySuffix
7980
8309
  ORDER BY costUsd DESC`, params);
7981
8310
  const labels = await getCredentialLabels();
@@ -8011,11 +8340,6 @@ async function getCredentialLabels() {
8011
8340
  }
8012
8341
  return labels;
8013
8342
  }
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
8343
  async function getAttributionByPerson(opts) {
8020
8344
  const conditions = ["t.requestedByUserId IS NOT NULL"];
8021
8345
  const params = [];
@@ -8035,18 +8359,20 @@ async function getAttributionByPerson(opts) {
8035
8359
  }
8036
8360
  }
8037
8361
  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
8362
+ const rootRows = await getDbClient().query(`WITH RECURSIVE selected_roots(id, requestedByUserId, status) AS (
8363
+ SELECT t.id, t.requestedByUserId, t.status
8040
8364
  FROM agent_tasks t
8041
- ${where} AND t.parentTaskId IS NULL AND NOT ${ROOT_HUMAN_FREE_SQL}
8365
+ ${where} AND t.parentTaskId IS NULL AND t.isHumanFree = 0
8042
8366
  ),
8043
- task_tree(rootId, taskId, output) AS (
8044
- SELECT id, id, output
8367
+ -- Ids only: carrying each descendant's \`output\` through the recursion copied
8368
+ -- every task's text into the queue. The output fallback below reads it by id.
8369
+ task_tree(rootId, taskId) AS (
8370
+ SELECT id, id
8045
8371
  FROM selected_roots
8046
8372
 
8047
8373
  UNION ALL
8048
8374
 
8049
- SELECT tree.rootId, child.id, child.output
8375
+ SELECT tree.rootId, child.id
8050
8376
  FROM agent_tasks child
8051
8377
  JOIN task_tree tree ON child.parentTaskId = tree.taskId
8052
8378
  ),
@@ -8079,8 +8405,11 @@ async function getAttributionByPerson(opts) {
8079
8405
 
8080
8406
  SELECT tree.rootId
8081
8407
  FROM task_tree tree
8082
- WHERE tree.output LIKE '%github.com/%/pull/%'
8083
- OR tree.output LIKE '%/-/merge_requests/%'
8408
+ -- CROSS JOIN pins the order (tree outer, task by id). Left to itself the
8409
+ -- planner scans every task's output and probes the tree instead.
8410
+ CROSS JOIN agent_tasks described ON described.id = tree.taskId
8411
+ WHERE described.output LIKE '%github.com/%/pull/%'
8412
+ OR described.output LIKE '%/-/merge_requests/%'
8084
8413
  )
8085
8414
  SELECT
8086
8415
  t.requestedByUserId as userId,
@@ -8089,65 +8418,13 @@ async function getAttributionByPerson(opts) {
8089
8418
  FROM selected_roots t
8090
8419
  LEFT JOIN shipped_roots s ON s.rootId = t.id
8091
8420
  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
8421
+ const reachRows = await getDbClient().query(`SELECT
8145
8422
  t.requestedByUserId as userId,
8146
8423
  COUNT(DISTINCT t.agentId) as agentsReached,
8147
8424
  COUNT(DISTINCT t.vcsRepo) as reposReached,
8148
8425
  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)
8426
+ FROM agent_tasks t
8427
+ ${where} AND t.isHumanFree = 0
8151
8428
  GROUP BY t.requestedByUserId`, params);
8152
8429
  const byUser = new Map;
8153
8430
  for (const r of rootRows) {
@@ -9310,10 +9587,15 @@ async function updateWorkflow(id, data) {
9310
9587
  return row ? rowToWorkflow(row) : null;
9311
9588
  }
9312
9589
  async function deleteWorkflow(id, source2) {
9590
+ return await getDbClient().transaction(() => deleteWorkflowRows(id, source2));
9591
+ }
9592
+ async function deleteWorkflowRows(id, source2) {
9313
9593
  const client = getDbClient();
9594
+ 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
9595
  await client.run(`UPDATE agent_tasks SET workflowRunId = NULL, workflowRunStepId = NULL WHERE workflowRunId IN (SELECT id FROM workflow_runs WHERE workflowId = ?)`, [id]);
9315
9596
  await client.run(`DELETE FROM workflow_run_steps WHERE runId IN (SELECT id FROM workflow_runs WHERE workflowId = ?)`, [id]);
9316
9597
  await client.run("DELETE FROM workflow_runs WHERE workflowId = ?", [id]);
9598
+ await reclassifyTaskHumanFree(linkedTaskIds);
9317
9599
  const result = await client.run("DELETE FROM workflows WHERE id = ?", [id]);
9318
9600
  const deleted = result.changes > 0;
9319
9601
  if (deleted) {
@@ -11700,6 +11982,10 @@ async function deleteUser(id, replacementUserId) {
11700
11982
  AND foreign_keys."table" = 'users'
11701
11983
  )`);
11702
11984
  const replacement = replacementUserId ?? null;
11985
+ const reclassifySeedIds = replacementUserId ? [] : (await tx.query(`SELECT id FROM agent_tasks WHERE requestedByUserId = ?
11986
+ UNION
11987
+ SELECT id FROM agent_tasks
11988
+ WHERE workflowRunId IN (SELECT id FROM workflow_runs WHERE created_by = ?)`, [id, id])).map((row) => row.id);
11703
11989
  for (const reference of references) {
11704
11990
  const table = quoteSqlIdentifier(reference.tableName);
11705
11991
  const column = quoteSqlIdentifier(reference.columnName);
@@ -11716,6 +12002,7 @@ async function deleteUser(id, replacementUserId) {
11716
12002
  WHERE json_valid(context)
11717
12003
  AND json_extract(context, '$.swarm.requestedByUserId') = ?`, [id]);
11718
12004
  }
12005
+ await reclassifyTaskHumanFree(reclassifySeedIds);
11719
12006
  const result = await tx.run("DELETE FROM users WHERE id = ?", [id]);
11720
12007
  return result.changes > 0;
11721
12008
  });
@@ -12702,54 +12989,7 @@ var VERSIONABLE_FIELDS2, BUDGETED_IDENTITY_FIELDS, PENDING_SLACK_MESSAGE_TS_PREF
12702
12989
  LEFT JOIN agents a ON m.created_by_kind = 'agent' AND a.id = m.created_by_agent_id`, ROUTING_HOLDER_SQL = `CASE
12703
12990
  WHEN status IN ('draft', 'offered', 'reviewing') AND offeredTo IS NOT NULL THEN offeredTo
12704
12991
  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;
12992
+ 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
12993
  var init_db = __esm(() => {
12754
12994
  init_package();
12755
12995
  init_key();
@@ -12773,6 +13013,7 @@ var init_db = __esm(() => {
12773
13013
  init_approvals();
12774
13014
  init_context_versions();
12775
13015
  init_runtime();
13016
+ init_human_free();
12776
13017
  init_read();
12777
13018
  init_write();
12778
13019
  init_steering();
@@ -12835,4 +13076,4 @@ var init_db = __esm(() => {
12835
13076
  };
12836
13077
  });
12837
13078
 
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 };
13079
+ 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, 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, 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, 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 };