@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.
- package/README.md +1 -1
- package/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-2mjwcsfh.js} +124 -27
- package/dist/{actions-p9hz5yat.js → actions-e43rxskr.js} +35 -30
- package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-5qx80j9k.js} +106 -16
- package/dist/{app-g26wdcz6.js → app-mc7xfagn.js} +12 -10
- package/dist/{assistant-wydfqkb3.js → assistant-sedkzv3b.js} +42 -31
- package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-nfb21z9a.js} +13 -14
- package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-cqz9swn5.js} +13 -12
- package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-m3656j2n.js} +14 -13
- package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-xbxf5d7w.js} +11 -9
- package/dist/boot-seeds-gsetbs5y.js +28 -0
- package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-dc6289mc.js} +28 -23
- package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-naaw51me.js} +4 -3
- package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-eacvchx0.js} +12 -3
- package/dist/claude-sdk-session-bqp2xvym.js +29722 -0
- package/dist/{cli-987hg0aa.js → cli-0jwe9034.js} +2 -2
- package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
- package/dist/{cli-c07r9a2m.js → cli-0q3avq3s.js} +12 -11
- package/dist/{cli-19jenss3.js → cli-0wgxmwf6.js} +31 -10
- package/dist/cli-0x01kwrd.js +491 -0
- package/dist/cli-0xqde53b.js +176 -0
- package/dist/cli-10nhj6xq.js +8355 -0
- package/dist/{cli-tt9k8r35.js → cli-12tszpk9.js} +479 -910
- package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
- package/dist/{cli-cqt19wg6.js → cli-1a2j50m0.js} +11 -2
- package/dist/{cli-xberxa1r.js → cli-25fcq4b4.js} +2 -2
- package/dist/{cli-npssxgaz.js → cli-2pdaysab.js} +52 -2
- package/dist/cli-3qhyh31j.js +166 -0
- package/dist/cli-447dt1h3.js +3828 -0
- package/dist/cli-4derpgyk.js +115 -0
- package/dist/{cli-00w2c66p.js → cli-523679eh.js} +13 -2
- package/dist/{cli-y95wp3tg.js → cli-58e8yr0d.js} +1 -1
- package/dist/{cli-24k806sc.js → cli-5nbmpy8w.js} +3 -3
- package/dist/{cli-53sz8gkz.js → cli-6cs6wzxt.js} +1 -1
- package/dist/cli-741yb0xx.js +1027 -0
- package/dist/cli-74h9hscv.js +69 -0
- package/dist/cli-7cxw8b60.js +14910 -0
- package/dist/{cli-xhaeg2nc.js → cli-7e398j1h.js} +1 -1
- package/dist/cli-7kyk9jr3.js +22 -0
- package/dist/cli-89s4ngw3.js +183 -0
- package/dist/{cli-9b13ggd1.js → cli-89v6kyq7.js} +1 -0
- package/dist/{cli-ftfvggzx.js → cli-9hsgwz4w.js} +1045 -581
- package/dist/{cli-rqz8qbw7.js → cli-a8dvhzrt.js} +59 -20
- package/dist/{cli-j57qkrpq.js → cli-azhgzetg.js} +395 -56
- package/dist/cli-br0qdrnp.js +2150 -0
- package/dist/{cli-rj19hc34.js → cli-btfv8y88.js} +1 -1
- package/dist/{cli-8qmme6vd.js → cli-c8a36vcc.js} +2 -2
- package/dist/cli-cpvsaqsw.js +333 -0
- package/dist/cli-d5czme6m.js +17805 -0
- package/dist/{cli-h38x0qhg.js → cli-et8m9xsv.js} +4 -3
- package/dist/{cli-x24pshtq.js → cli-evvtk35y.js} +6 -6
- package/dist/{cli-7s3syk22.js → cli-f8gy6r2r.js} +5 -5
- package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
- package/dist/{cli-9httdpyq.js → cli-g2whhdrf.js} +1 -1
- package/dist/cli-gt4hxb8p.js +99 -0
- package/dist/{cli-s8eet254.js → cli-jajnsm8q.js} +37184 -53838
- package/dist/{cli-7gtvvpbh.js → cli-jayjpjmb.js} +21 -12
- package/dist/{cli-68w09sjw.js → cli-jyk0ynw2.js} +27 -89
- package/dist/{cli-aehm1rbq.js → cli-jz4w45qt.js} +1152 -61
- package/dist/cli-kmcpfwn2.js +333856 -0
- package/dist/{cli-4198qc9v.js → cli-ktmyrtpn.js} +19 -3
- package/dist/{cli-j55n64b6.js → cli-mfe5btp9.js} +505 -189
- package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
- package/dist/{cli-1hkrch3k.js → cli-pm1rst0h.js} +46 -7
- package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
- package/dist/{cli-ggm92wcn.js → cli-ptr8h7kp.js} +20 -1
- package/dist/{cli-s8s499xy.js → cli-qbksc292.js} +3 -2
- package/dist/{cli-47m6dkd3.js → cli-qydf22qq.js} +597 -346
- package/dist/{cli-3gmcwfyx.js → cli-r1mxd1xh.js} +13 -6
- package/dist/cli-rb9m6rpe.js +4980 -0
- package/dist/cli-rykfmgwg.js +102 -0
- package/dist/{cli-5d10vd2m.js → cli-shkxm1vn.js} +6 -5
- package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
- package/dist/cli-tfky2838.js +756 -0
- package/dist/{cli-g8djp6qe.js → cli-tmqt7dpj.js} +40 -0
- package/dist/{cli-fgqxwrpv.js → cli-tpq83z89.js} +1631 -127
- package/dist/cli-trc24wk2.js +143 -0
- package/dist/{cli-aky8tctm.js → cli-tzx2ke1v.js} +3 -3
- package/dist/cli-v7fn5gms.js +1425 -0
- package/dist/{cli-wscdvcqz.js → cli-vctdqs5h.js} +1 -1
- package/dist/{cli-cw9zck8j.js → cli-xjcywfsf.js} +8 -4
- package/dist/{cli-k0g1sjzm.js → cli-ybgv4kw2.js} +18 -11
- package/dist/{cli-rjehvrts.js → cli-ydmcgve1.js} +8 -8
- package/dist/{cli-vhjwh6cz.js → cli-ygwm91nt.js} +1 -1
- package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
- package/dist/{cli-de1396j2.js → cli-ywybs5as.js} +7 -1
- package/dist/cli-zpep9q5e.js +491 -0
- package/dist/cli.js +41 -32
- package/dist/cloudflare-workers-ai-system-one-k6fbxw9d.js +46 -0
- package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-nmxcatww.js} +26 -17
- package/dist/{codex-hook-9hptmdhj.js → codex-hook-20me6byw.js} +2 -2
- package/dist/{codex-login-x3jk4etn.js → codex-login-w6fz4xbz.js} +50 -5
- package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-90aa80ev.js} +24 -17
- package/dist/{commands-e3bn0p75.js → commands-8wcq1kn7.js} +11 -9
- package/dist/{db-03v9kzr2.js → db-j40kc4se.js} +25 -11
- package/dist/{devin-adapter-8vgkwh29.js → devin-adapter-dpsv6hd9.js} +1 -1
- package/dist/{dispatcher-nrmg8yht.js → dispatcher-4zqy768d.js} +34 -29
- package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-mpnzgztj.js} +3 -3
- package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
- package/dist/execute-6e7qeyk4.js +1017 -0
- package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-k6n5nbpp.js} +6 -5
- package/dist/{google-vertex-809af514.js → google-vertex-44xxtcvp.js} +6 -5
- package/dist/{handlers-aqcedbyb.js → handlers-kjdce1w5.js} +37 -32
- package/dist/{hook-ybvmrmhq.js → hook-czx13n12.js} +19 -15
- package/dist/{hook-7vkskkre.js → hook-r2t4bqfg.js} +18 -14
- package/dist/{http-2eqa8t24.js → http-3bbb19be.js} +900 -145
- package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
- package/dist/{index-x71bvq0p.js → index-668me3f0.js} +35 -30
- package/dist/{index-c6zsv1bd.js → index-7aj368tw.js} +13 -12
- package/dist/{index-1yks3qcr.js → index-fg0dsp6c.js} +34 -29
- package/dist/{index-chgdkq36.js → index-kkv84jq9.js} +34 -29
- package/dist/{index-a3vn96n8.js → index-zg7vp46x.js} +198 -54
- package/dist/{keepalive-vtkf5n99.js → keepalive-yra8dy57.js} +13 -11
- package/dist/{lead-h3sp357x.js → lead-va0pad2c.js} +54 -49
- package/dist/llama-cpp-classify-tgj35k8d.js +335 -0
- package/dist/{maintenance-jzeqtk3q.js → maintenance-hqewtmyg.js} +14 -13
- package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-pc3ntnxt.js} +14 -17
- package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-7rdt1m9n.js} +12 -10
- package/dist/{onboard-tmsp0qbz.js → onboard-j6ms6d0x.js} +6 -5
- package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-bbancrr0.js} +21 -8
- package/dist/{openai-completions-9hjrqbw8.js → openai-completions-jpaj5g2b.js} +9 -12
- package/dist/{openai-responses-7b1pn0xt.js → openai-responses-200k1wx4.js} +23 -18
- package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-89rabkw2.js} +8 -7
- package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-8yx3487g.js} +5 -7
- package/dist/{otel-impl-9mz73q65.js → otel-impl-a792rjz0.js} +1 -1
- package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
- package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-g7qzvr3v.js} +295 -70
- package/dist/pricing-refresh-wx0tp7cb.js +39 -0
- package/dist/quickjs-r1pq2107.wasm +0 -0
- package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-8tzawacv.js} +12 -10
- package/dist/{render-v2-gryrh9h8.js → render-v2-mm7zswb8.js} +12 -10
- package/dist/runtime-zyssgse0.js +24 -0
- package/dist/{setup-q9720bt6.js → setup-8y70ys6t.js} +6 -5
- package/dist/typesafe-system-one-2ef30pec.js +27 -0
- package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-6nmk7h3n.js} +22 -13
- package/dist/{work-objects-b76x7deb.js → work-objects-fg6xkb0n.js} +37 -32
- package/dist/{worker-6vrxbv41.js → worker-wmwhxsph.js} +54 -49
- package/openapi.json +1314 -91
- package/package.json +12 -11
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/api-keys.ts +70 -0
- package/src/be/db/tasks/human-free.ts +442 -0
- package/src/be/db/tasks/read.ts +56 -1
- package/src/be/db/tasks/write.ts +107 -11
- package/src/be/db.ts +274 -188
- package/src/be/harness-model-support.ts +182 -0
- package/src/be/human-free-drain.ts +67 -0
- package/src/be/memory/providers/sqlite-store.ts +51 -15
- package/src/be/migrations/182_task_human_free_flag.sql +63 -0
- package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
- package/src/be/migrations/184_model_catalog.sql +120 -0
- package/src/be/migrations/185_api_key_auth_failures.sql +6 -0
- package/src/be/migrations/186_api_key_seat_mismatch.sql +8 -0
- package/src/be/model-catalog-store.ts +644 -0
- package/src/be/model-tier-keys.ts +46 -0
- package/src/be/model-tier-resolution.ts +534 -0
- package/src/be/model-validation.ts +188 -0
- package/src/be/models-catalog.ts +61 -7
- package/src/be/modelsdev-cache.json +82 -0
- package/src/be/modelsdev-cache.ts +2 -0
- package/src/be/pricing-refresh.ts +154 -12
- package/src/be/scripts/typecheck.ts +15 -0
- package/src/be/seed/runner.ts +18 -12
- package/src/be/seed/types.ts +1 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
- package/src/be/swarm-config-guard.ts +8 -0
- package/src/cli.tsx +10 -0
- package/src/commands/claude-managed-setup.ts +3 -1
- package/src/commands/codex-login.ts +67 -0
- package/src/commands/credential-outcome-report.ts +191 -0
- package/src/commands/rate-limit-outcome.ts +34 -4
- package/src/commands/runner.ts +357 -186
- package/src/commands/seat-mismatch-report.ts +46 -0
- package/src/extensions/apply-task-create.ts +27 -1
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +79 -17
- package/src/heartbeat/templates.ts +2 -2
- package/src/http/agents.ts +62 -1
- package/src/http/api-keys.ts +140 -2
- package/src/http/codex-oauth-keep-warm.ts +3 -5
- package/src/http/index.ts +8 -0
- package/src/http/memory.ts +12 -5
- package/src/http/models-catalog.ts +357 -8
- package/src/http/poll.ts +54 -3
- package/src/http/schedules.ts +51 -6
- package/src/http/script-runs.ts +12 -0
- package/src/http/session-data.ts +2 -5
- package/src/http/stats.ts +6 -8
- package/src/http/status.ts +15 -1
- package/src/http/tasks.ts +90 -7
- package/src/http/usage-cache.ts +56 -15
- package/src/http/workflows.ts +46 -8
- package/src/mcp-client/http-client.ts +5 -0
- package/src/memory/recall-query.ts +74 -0
- package/src/prompts/base-prompt.ts +15 -4
- package/src/prompts/session-templates.ts +23 -1
- package/src/providers/acp-adapter.ts +1 -0
- package/src/providers/claude-adapter.ts +14 -5
- package/src/providers/claude-managed-adapter.ts +1 -0
- package/src/providers/claude-managed-models.ts +47 -161
- package/src/providers/claude-sdk-session.ts +3 -1
- package/src/providers/codex-adapter.ts +14 -14
- package/src/providers/codex-models.ts +65 -198
- package/src/providers/devin-adapter.ts +1 -0
- package/src/providers/dsh-adapter.ts +2 -1
- package/src/providers/harness-version.ts +83 -7
- package/src/providers/opencode-adapter.ts +53 -1
- package/src/providers/pi-binary-root/src/extensions/codemode/worker.ts +11 -0
- package/src/providers/pi-codemode-runtime.ts +17 -0
- package/src/providers/pi-mono-adapter.ts +361 -83
- package/src/providers/pi-mono-extension.ts +16 -1
- package/src/providers/reasoning-effort.ts +44 -140
- package/src/providers/types.ts +8 -0
- package/src/rbac/legacy-policy.ts +43 -0
- package/src/rbac/permissions.ts +15 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/types/stdlib.d.ts +15 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
- package/src/server.ts +6 -0
- package/src/slack/assistant.ts +13 -0
- package/src/slack/message-text.ts +56 -2
- package/src/slack/render-v2.ts +87 -37
- package/src/slack/session-status.ts +541 -0
- package/src/slack/thread-buffer.ts +10 -2
- package/src/tasks/sibling-awareness.ts +3 -2
- package/src/telemetry.ts +5 -4
- package/src/templates.d.ts +6 -0
- package/src/tests/agents-list-model-display.test.ts +4 -6
- package/src/tests/api-key-auth-failure-route.test.ts +142 -0
- package/src/tests/api-key-tracking.test.ts +368 -1
- package/src/tests/base-prompt.test.ts +43 -2
- package/src/tests/claude-adapter.test.ts +68 -0
- package/src/tests/claude-managed-adapter.test.ts +12 -18
- package/src/tests/codex-adapter.test.ts +2 -1
- package/src/tests/codex-auth-failure.test.ts +52 -0
- package/src/tests/codex-gpt6-release.test.ts +66 -5
- package/src/tests/codex-login.test.ts +116 -0
- package/src/tests/context-window.test.ts +7 -5
- package/src/tests/credential-exhaustion-policy.test.ts +118 -3
- package/src/tests/credential-outcome-report.test.ts +171 -0
- package/src/tests/credential-status-api.test.ts +103 -2
- package/src/tests/db-extraction-contract.test.ts +1 -0
- package/src/tests/db-task-read-contract.test.ts +10 -1
- package/src/tests/db-task-write-contract.test.ts +535 -2
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dokploy-deploy.test.ts +315 -0
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/explicit-model-validation.test.ts +583 -0
- package/src/tests/extensions-pre-task.test.ts +73 -0
- package/src/tests/fetch-resolved-env.test.ts +46 -0
- package/src/tests/hang-watchdog-worker.ts +47 -0
- package/src/tests/hang-watchdog.test.ts +45 -0
- package/src/tests/hang-watchdog.ts +30 -0
- package/src/tests/harness-model-guard.test.ts +123 -0
- package/src/tests/harness-model-support.test.ts +374 -0
- package/src/tests/harness-version.test.ts +70 -3
- package/src/tests/heartbeat-checklist-config.test.ts +71 -0
- package/src/tests/heartbeat-checklist.test.ts +4 -2
- package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
- package/src/tests/http-task-write-ownership.test.ts +172 -0
- package/src/tests/human-free-flag.test.ts +279 -0
- package/src/tests/human-free-oracle.ts +57 -0
- package/src/tests/human-free-reclassify.test.ts +669 -0
- package/src/tests/memory-fts-populate.test.ts +139 -0
- package/src/tests/memory-http-recall-gating.test.ts +125 -1
- package/src/tests/migration-046-budgets.test.ts +3 -3
- package/src/tests/model-catalog-migration.test.ts +134 -0
- package/src/tests/model-catalog-table.test.ts +249 -0
- package/src/tests/model-catalog-write-access.test.ts +387 -0
- package/src/tests/model-rate-limit-windows.test.ts +19 -0
- package/src/tests/model-tier-resolution.test.ts +611 -0
- package/src/tests/models-catalog.test.ts +1 -1
- package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
- package/src/tests/opencode-adapter.test.ts +157 -2
- package/src/tests/package-publish.test.ts +137 -36
- package/src/tests/pi-codemode.test.ts +246 -0
- package/src/tests/pi-mono-adapter.test.ts +3 -0
- package/src/tests/pi-native-mcp.test.ts +193 -0
- package/src/tests/pi-tool-exposure.test.ts +374 -0
- package/src/tests/preload.ts +3 -0
- package/src/tests/pricing-routes.test.ts +2 -2
- package/src/tests/prompt-template-session.test.ts +5 -3
- package/src/tests/rate-limit-event.test.ts +65 -0
- package/src/tests/rate-limit-outcome.test.ts +90 -0
- package/src/tests/rbac-engine.test.ts +77 -3
- package/src/tests/reasoning-effort.test.ts +109 -0
- package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
- package/src/tests/runner-key-completion-outcome.test.ts +112 -0
- package/src/tests/runner-key-outcome-late-reset.test.ts +224 -0
- package/src/tests/runner-registration-retry.test.ts +149 -0
- package/src/tests/runtime-model-catalog.test.ts +86 -0
- package/src/tests/script-connections.test.ts +9 -0
- package/src/tests/seat-mismatch-report.test.ts +85 -0
- package/src/tests/seed-scripts.test.ts +138 -0
- package/src/tests/seed.test.ts +25 -0
- package/src/tests/session-costs.test.ts +14 -11
- package/src/tests/slack-message-text.test.ts +101 -0
- package/src/tests/slack-render-v2.test.ts +96 -0
- package/src/tests/slack-session-status.test.ts +626 -0
- package/src/tests/slack-thread-buffer-context.test.ts +93 -0
- package/src/tests/status.test.ts +29 -0
- package/src/tests/steering-promotion.test.ts +51 -0
- package/src/tests/store-progress-ownership.test.ts +136 -0
- package/src/tests/subscription-plans.test.ts +28 -0
- package/src/tests/task-cascade-fail.test.ts +148 -2
- package/src/tests/task-citations.test.ts +3 -2
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/usage-cache.test.ts +166 -0
- package/src/tests/workflow-agent-task.test.ts +30 -0
- package/src/tests/workflow-executors.test.ts +5 -2
- package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
- package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
- package/src/tests/workflow-system-one-decision.test.ts +2063 -0
- package/src/tests/workflow-triggers-v2.test.ts +320 -0
- package/src/tools/model-catalog/index.ts +137 -0
- package/src/tools/schedules/create-schedule.ts +17 -2
- package/src/tools/schedules/patch-schedule.ts +31 -1
- package/src/tools/schedules/update-schedule.ts +31 -1
- package/src/tools/send-task.ts +18 -1
- package/src/tools/store-progress.ts +49 -4
- package/src/tools/task-action.ts +14 -1
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/workflows/create-workflow.ts +17 -4
- package/src/tools/workflows/patch-workflow-node.ts +17 -7
- package/src/tools/workflows/patch-workflow.ts +9 -2
- package/src/tools/workflows/update-workflow.ts +17 -4
- package/src/types.ts +41 -1
- package/src/utils/codex-auth-failure.ts +34 -0
- package/src/utils/context-window.ts +47 -53
- package/src/utils/credentials.ts +72 -30
- package/src/utils/error-tracker.ts +80 -0
- package/src/utils/harness-cli-version.ts +115 -0
- package/src/utils/harness-model-error.ts +33 -0
- package/src/utils/model-rate-limit-windows.ts +12 -0
- package/src/utils/runtime-model-catalog.ts +152 -0
- package/src/utils/spawn-model-guard.ts +43 -0
- package/src/utils/subscription-plans.ts +22 -0
- package/src/workflows/approval-resolution.ts +39 -0
- package/src/workflows/definition.ts +7 -0
- package/src/workflows/engine.ts +69 -1
- package/src/workflows/executors/agent-task.ts +16 -6
- package/src/workflows/executors/base.ts +53 -0
- package/src/workflows/executors/human-in-the-loop.ts +8 -8
- package/src/workflows/executors/index.ts +1 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/system-one-decision.ts +1232 -0
- package/src/workflows/executors/system-one-providers.ts +301 -0
- package/src/workflows/executors/workflow-llm.ts +13 -1
- package/src/workflows/model-validation.ts +45 -0
- package/src/workflows/patch-definition.ts +5 -0
- package/src/workflows/readiness.ts +86 -0
- package/src/workflows/recovery.ts +12 -12
- package/src/workflows/resume.ts +23 -9
- package/src/workflows/triggers.ts +85 -0
- package/templates/schedules/daily-blocker-digest/content.md +4 -5
- package/templates/skills/agent-browser/SKILL.md +6 -5
- package/templates/skills/agent-browser/content.md +6 -5
- package/templates/skills/heartbeat-runbook/config.json +1 -1
- package/templates/skills/heartbeat-runbook/content.md +2 -2
- package/templates/skills/swarm-scripts/SKILL.md +1 -1
- package/templates/skills/swarm-scripts/content.md +1 -1
- package/templates/skills/workflow-iterate/content.md +82 -1
- package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
- package/templates/workflows/pr-review-status-sweep/content.md +2 -0
- package/dist/boot-seeds-s3q01xj3.js +0 -26
- package/dist/claude-sdk-session-t442qz6f.js +0 -39108
- package/dist/cli-0xjkj1j7.js +0 -61
- package/dist/cli-20cj37vt.js +0 -335561
- package/dist/cli-2djtr51b.js +0 -48
- package/dist/cli-65hjmev5.js +0 -1141
- package/dist/cli-aw1jwp1r.js +0 -14075
- package/dist/cli-h967nb6r.js +0 -6603
- package/dist/cli-vapyk8sw.js +0 -20
- package/dist/cli-ws6rqycm.js +0 -247
- package/dist/pricing-refresh-v1cbr9te.js +0 -27
- package/src/providers/modelsdev-reasoning.json +0 -6453
- package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
package/src/tools/send-task.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
isExtensionAgent,
|
|
18
18
|
} from "@/be/db";
|
|
19
19
|
import { repointTrackerSyncBySwarmId } from "@/be/db-queries/tracker";
|
|
20
|
+
import { explicitModelErrorForAgent } from "@/be/model-validation";
|
|
20
21
|
import { applyPreTaskCreate } from "@/extensions/apply-task-create";
|
|
21
22
|
import { checkSlackRoutingCoherence } from "@/tasks/slack-routing";
|
|
22
23
|
import { findDuplicateTask } from "@/tools/task-dedup";
|
|
@@ -131,11 +132,17 @@ export const sendTaskInputSchema = z
|
|
|
131
132
|
.min(1)
|
|
132
133
|
.optional()
|
|
133
134
|
.describe(
|
|
134
|
-
"Concrete model override for this task, interpreted by the assignee's harness/provider. This does not switch providers. Prefer modelTier for portable intent.",
|
|
135
|
+
"Concrete model override for this task, interpreted by the assignee's harness/provider. This does not switch providers. Prefer modelTier for portable intent. The model must run on the assignee's harness (an Anthropic model on a Claude agent, an OpenAI model on a Codex agent); a mismatch is rejected.",
|
|
135
136
|
),
|
|
136
137
|
modelTier: ModelTierSchema.optional().describe(
|
|
137
138
|
"Portable model tier for this task: 'smol', 'regular', 'smart', or 'ultra'. Resolved at claim/run time using the assignee's harness/provider. Legacy model shortnames map as haiku→smol, sonnet→regular, opus→smart, fable→ultra.",
|
|
138
139
|
),
|
|
140
|
+
allowCustomModel: z
|
|
141
|
+
.boolean()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe(
|
|
144
|
+
"Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only for ids the catalog cannot know yet (a fresh launch, a private deployment).",
|
|
145
|
+
),
|
|
139
146
|
effort: ReasoningEffortSchema.optional().describe(
|
|
140
147
|
"Reasoning effort for this task: 'off', 'low', 'medium', 'high', 'xhigh', or 'max'. If omitted, the assignee's REASONING_EFFORT_OVERRIDE/default applies.",
|
|
141
148
|
),
|
|
@@ -268,6 +275,7 @@ export async function sendTaskHandler(
|
|
|
268
275
|
vcsRepo,
|
|
269
276
|
model,
|
|
270
277
|
modelTier,
|
|
278
|
+
allowCustomModel,
|
|
271
279
|
effort,
|
|
272
280
|
allowDuplicate,
|
|
273
281
|
slackChannelId,
|
|
@@ -380,6 +388,14 @@ export async function sendTaskHandler(
|
|
|
380
388
|
effectiveAgentId = effectiveParentTask.agentId;
|
|
381
389
|
}
|
|
382
390
|
}
|
|
391
|
+
// Judge the model against the harness that will actually run it, including the
|
|
392
|
+
// parent auto-route target.
|
|
393
|
+
const modelError = await explicitModelErrorForAgent({
|
|
394
|
+
model: normalizedModel.model,
|
|
395
|
+
allowCustomModel,
|
|
396
|
+
agentId: effectiveAgentId,
|
|
397
|
+
});
|
|
398
|
+
if (modelError) return toolErr(modelError, { data: { yourAgentId: creatorAgentId } });
|
|
383
399
|
const effectiveRoutingReason =
|
|
384
400
|
agentId !== undefined ? routingReason : effectiveAgentId ? "continuity" : undefined;
|
|
385
401
|
const effectiveRoutingNote = effectiveRoutingReason ? routingNote : undefined;
|
|
@@ -427,6 +443,7 @@ export async function sendTaskHandler(
|
|
|
427
443
|
options: requestedTaskOptions,
|
|
428
444
|
origin: "mcp",
|
|
429
445
|
requestInfo: ctx.kind === "owner" ? ctx.requestInfo : undefined,
|
|
446
|
+
allowCustomModel,
|
|
430
447
|
});
|
|
431
448
|
if (preCreate.kind === "blocked") {
|
|
432
449
|
return toolErr(preCreate.reason, {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
createLogEntry,
|
|
7
7
|
failTask,
|
|
8
8
|
getAgentById,
|
|
9
|
+
getAgentCurrentTask,
|
|
9
10
|
getDbClient,
|
|
10
11
|
getResolvedConfig,
|
|
11
12
|
getTaskById,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
upsertTaskCitations,
|
|
22
23
|
} from "@/be/task-citations";
|
|
23
24
|
import { AgentFsProvider } from "@/fs/agent-fs-provider";
|
|
25
|
+
import { can } from "@/rbac";
|
|
24
26
|
import { runTaskTerminalEffects } from "@/tasks/task-terminal-effects";
|
|
25
27
|
import {
|
|
26
28
|
getTaskOutputValidationError,
|
|
@@ -49,6 +51,36 @@ const BLOCKED_WAITING_PATTERN =
|
|
|
49
51
|
// noise and calling defer-task buys nothing over checking in again shortly.
|
|
50
52
|
const BLOCKED_WAITING_MIN_ELAPSED_MS = 3 * 60 * 1000;
|
|
51
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Only the assigned agent may write a task's progress, status, or artifacts
|
|
56
|
+
* (`task.progress.write`). Workflow siblings see each other's task ids in
|
|
57
|
+
* their prompt, and a worker once completed a sibling's task with its own
|
|
58
|
+
* report. Leads keep cross-task writes (the task-citations suite pins lead
|
|
59
|
+
* completion of a worker task); unassigned tasks stay writable, matching
|
|
60
|
+
* `POST /api/tasks/:id/finish`. Returns the refusal message, naming the
|
|
61
|
+
* caller's own task so it can retry.
|
|
62
|
+
*/
|
|
63
|
+
async function foreignTaskWriteError(
|
|
64
|
+
caller: { id: string; isLead?: boolean },
|
|
65
|
+
task: { id: string; agentId?: string | null },
|
|
66
|
+
sourceTaskId: string | undefined,
|
|
67
|
+
): Promise<string | undefined> {
|
|
68
|
+
const decision = can({
|
|
69
|
+
principal: { kind: "agent", agentId: caller.id, isLead: caller.isLead === true },
|
|
70
|
+
verb: "task.progress.write",
|
|
71
|
+
resource: { kind: "task", taskId: task.id, agentId: task.agentId },
|
|
72
|
+
source: "mcp",
|
|
73
|
+
});
|
|
74
|
+
if (decision.allow) return undefined;
|
|
75
|
+
const sourceTask = sourceTaskId ? await getTaskById(sourceTaskId) : null;
|
|
76
|
+
const ownTask =
|
|
77
|
+
sourceTask?.agentId === caller.id ? sourceTask : await getAgentCurrentTask(caller.id);
|
|
78
|
+
const retry = ownTask
|
|
79
|
+
? ` Your own task is "${ownTask.id}"; call store-progress with that taskId.`
|
|
80
|
+
: " You have no in-progress task.";
|
|
81
|
+
return `Task "${task.id}" is assigned to another agent; only its assignee may store progress on it. Nothing was written.${retry}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
52
84
|
export const storeProgressOutputSchema = swarmToolOutputSchema({
|
|
53
85
|
// Bounded confirmation only. The handler keeps the full task row internally
|
|
54
86
|
// for completion memory, raters, and follow-up creation, but never echoes it
|
|
@@ -227,14 +259,18 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
227
259
|
// Validate the caller and target before an agent-fs lookup. Otherwise a
|
|
228
260
|
// forged X-Agent-ID or unknown task could use this tool as a file-existence
|
|
229
261
|
// oracle through the API-owned agent-fs credential fallback.
|
|
230
|
-
|
|
262
|
+
const caller = await getAgentById(requestInfo.agentId);
|
|
263
|
+
if (!caller) {
|
|
231
264
|
return toolErr(
|
|
232
265
|
`Agent with ID "${requestInfo.agentId}" not found in the swarm, register before storing task progress.`,
|
|
233
266
|
);
|
|
234
267
|
}
|
|
235
|
-
|
|
268
|
+
const target = await getTaskById(taskId);
|
|
269
|
+
if (!target) {
|
|
236
270
|
return toolErr(`Task with ID "${taskId}" not found.`);
|
|
237
271
|
}
|
|
272
|
+
const foreignError = await foreignTaskWriteError(caller, target, requestInfo.sourceTaskId);
|
|
273
|
+
if (foreignError) return toolErr(foreignError);
|
|
238
274
|
|
|
239
275
|
const configs = await getResolvedConfig(requestInfo.agentId ?? undefined);
|
|
240
276
|
const configValue = (key: string) => configs.find((c) => c.key === key)?.value?.trim();
|
|
@@ -315,6 +351,15 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
315
351
|
};
|
|
316
352
|
}
|
|
317
353
|
|
|
354
|
+
const foreignError = await foreignTaskWriteError(
|
|
355
|
+
agent,
|
|
356
|
+
existingTask,
|
|
357
|
+
requestInfo.sourceTaskId,
|
|
358
|
+
);
|
|
359
|
+
if (foreignError) {
|
|
360
|
+
return { success: false, message: foreignError };
|
|
361
|
+
}
|
|
362
|
+
|
|
318
363
|
let updatedTask = existingTask;
|
|
319
364
|
const isTerminal = isTerminalTaskStatus(existingTask.status);
|
|
320
365
|
// This call's own status can finish the task even though existingTask
|
|
@@ -382,8 +427,8 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
382
427
|
}
|
|
383
428
|
}
|
|
384
429
|
|
|
385
|
-
//
|
|
386
|
-
// only the assigned agent may author sources. Check under the same
|
|
430
|
+
// A lead may update another agent's task (see foreignTaskWriteError),
|
|
431
|
+
// but only the assigned agent may author sources. Check under the same
|
|
387
432
|
// transaction as the upsert, including for terminal tasks. Ignore an
|
|
388
433
|
// unauthorized batch so citations never block the task update itself.
|
|
389
434
|
if (citations?.length && existingTask.agentId === agent.id) {
|
package/src/tools/task-action.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
releaseTask,
|
|
28
28
|
updateTaskClaudeSessionId,
|
|
29
29
|
} from "@/be/db";
|
|
30
|
+
import { explicitModelErrorForAgent } from "@/be/model-validation";
|
|
30
31
|
import { touchRuntimeInstance } from "@/be/multi-runtime";
|
|
31
32
|
import { applyPreTaskCreate } from "@/extensions/apply-task-create";
|
|
32
33
|
import { assertOwnsTask, ownerCtx, type ToolCtx } from "@/tools/task-tool-ctx";
|
|
@@ -93,11 +94,17 @@ export const taskActionInputSchema = z.object({
|
|
|
93
94
|
.min(1)
|
|
94
95
|
.optional()
|
|
95
96
|
.describe(
|
|
96
|
-
"Concrete model override for the created task, interpreted by the claiming worker's harness/provider. This does not switch providers. Only used with 'create' action.",
|
|
97
|
+
"Concrete model override for the created task, interpreted by the claiming worker's harness/provider. This does not switch providers. Only used with 'create' action. The model must run on the assignee's harness (an Anthropic model on a Claude agent, an OpenAI model on a Codex agent); a mismatch is rejected.",
|
|
97
98
|
),
|
|
98
99
|
modelTier: ModelTierSchema.optional().describe(
|
|
99
100
|
"Portable model tier for the created task: 'smol', 'regular', 'smart', or 'ultra'. Resolved when a worker claims/runs the task. Only used with 'create' action.",
|
|
100
101
|
),
|
|
102
|
+
allowCustomModel: z
|
|
103
|
+
.boolean()
|
|
104
|
+
.optional()
|
|
105
|
+
.describe(
|
|
106
|
+
"Accept a `model` the model catalog does not list. Without it an unknown model id is rejected. Only used with 'create' action.",
|
|
107
|
+
),
|
|
101
108
|
effort: ReasoningEffortSchema.optional().describe(
|
|
102
109
|
"Reasoning effort for the created task: 'off', 'low', 'medium', 'high', 'xhigh', or 'max'. Only used with 'create' action.",
|
|
103
110
|
),
|
|
@@ -275,6 +282,11 @@ export async function taskActionHandler(
|
|
|
275
282
|
agentId,
|
|
276
283
|
);
|
|
277
284
|
}
|
|
285
|
+
const modelError = await explicitModelErrorForAgent({
|
|
286
|
+
model: normalizedModel.model,
|
|
287
|
+
allowCustomModel: input.allowCustomModel,
|
|
288
|
+
});
|
|
289
|
+
if (modelError) return taskActionResult({ success: false, message: modelError }, agentId);
|
|
278
290
|
try {
|
|
279
291
|
assetKey = key
|
|
280
292
|
? await authorizeAssetKeyWrite(key, await resolveTaskAuditUserId(ctx.sourceTaskId, agentId))
|
|
@@ -310,6 +322,7 @@ export async function taskActionHandler(
|
|
|
310
322
|
},
|
|
311
323
|
origin: "mcp",
|
|
312
324
|
requestInfo: ctx.requestInfo,
|
|
325
|
+
allowCustomModel: input.allowCustomModel,
|
|
313
326
|
});
|
|
314
327
|
if (preCreate.kind === "blocked") {
|
|
315
328
|
return taskActionResult({ success: false, message: preCreate.reason }, agentId);
|
package/src/tools/tool-config.ts
CHANGED
|
@@ -78,12 +78,14 @@ export const DEFERRED_TOOLS = new Set([
|
|
|
78
78
|
"list-services",
|
|
79
79
|
"update-service-status",
|
|
80
80
|
|
|
81
|
-
// Config (
|
|
81
|
+
// Config (7)
|
|
82
82
|
"set-config",
|
|
83
83
|
"list-config",
|
|
84
84
|
"delete-config",
|
|
85
85
|
"credential-bindings",
|
|
86
86
|
"script-connections",
|
|
87
|
+
"model-catalog-refresh",
|
|
88
|
+
"model-catalog-overlay-upsert",
|
|
87
89
|
|
|
88
90
|
// Repos (1)
|
|
89
91
|
"update-repo",
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
} from "@/types";
|
|
20
20
|
import { getExecutorRegistry } from "@/workflows";
|
|
21
21
|
import { validateDefinition } from "@/workflows/definition";
|
|
22
|
+
import { workflowModelErrors } from "@/workflows/model-validation";
|
|
23
|
+
import { withSaveWarnings, workflowSaveWarnings } from "@/workflows/readiness";
|
|
22
24
|
|
|
23
25
|
export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
24
26
|
createToolRegistrar(server)(
|
|
@@ -49,7 +51,8 @@ export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
|
49
51
|
"- WEBHOOK VERIFICATION: Webhook triggers use hmacSecret for all verification formats. " +
|
|
50
52
|
"Omit verification for legacy HMAC-SHA256 over the raw body with fallback header scanning; " +
|
|
51
53
|
"or set verification to { format: 'hmac-sha256', header }, { format: 'timestamped-hmac-sha256', header, toleranceSeconds? }, " +
|
|
52
|
-
"
|
|
54
|
+
"{ format: 'token-equality', header }, or { format: 'standard-webhooks', toleranceSeconds? } " +
|
|
55
|
+
"(standardwebhooks.com: webhook-id/webhook-timestamp/webhook-signature headers, hmacSecret is the whsec_ signing secret). Example: { type: 'webhook', hmacSecret: 'secret.SUPERAGENT_WEBHOOK_SECRET', " +
|
|
53
56
|
"verification: { format: 'timestamped-hmac-sha256', header: 'X-Superagent-Signature', toleranceSeconds: 300 } }.\n" +
|
|
54
57
|
"- WAIT NODE: type 'wait' pauses a workflow for a duration or until a named workflowEventBus event arrives. " +
|
|
55
58
|
"See runbooks/workflows.md#wait-nodes for config shapes, ordering caveats, and built-in event names.",
|
|
@@ -66,7 +69,7 @@ export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
|
66
69
|
.array(TriggerConfigSchema)
|
|
67
70
|
.optional()
|
|
68
71
|
.describe(
|
|
69
|
-
"Optional trigger configurations (webhook, schedule, event). Webhook verification formats: legacy omitted verification, hmac-sha256, timestamped-hmac-sha256, token-equality.",
|
|
72
|
+
"Optional trigger configurations (webhook, schedule, event). Webhook verification formats: legacy omitted verification, hmac-sha256, timestamped-hmac-sha256, token-equality, standard-webhooks.",
|
|
70
73
|
),
|
|
71
74
|
cooldown: CooldownConfigSchema.optional().describe(
|
|
72
75
|
"Optional cooldown configuration to prevent re-triggering too frequently",
|
|
@@ -102,6 +105,7 @@ export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
|
102
105
|
outputSchema: swarmToolOutputSchema({
|
|
103
106
|
yourAgentId: z.string().optional(),
|
|
104
107
|
workflow: z.unknown().optional(),
|
|
108
|
+
warnings: z.array(z.string()).optional(),
|
|
105
109
|
}),
|
|
106
110
|
},
|
|
107
111
|
async (
|
|
@@ -128,6 +132,10 @@ export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
|
128
132
|
if (!validation.valid) {
|
|
129
133
|
return toolErr(`Invalid definition: ${validation.errors.join("; ")}`);
|
|
130
134
|
}
|
|
135
|
+
const modelErrors = await workflowModelErrors(definition);
|
|
136
|
+
if (modelErrors.length > 0) {
|
|
137
|
+
return toolErr(`Invalid definition: ${modelErrors.join("; ")}`);
|
|
138
|
+
}
|
|
131
139
|
|
|
132
140
|
const createdBy =
|
|
133
141
|
(await resolveTaskAuditUserId(requestInfo.sourceTaskId, requestInfo.agentId)) ??
|
|
@@ -152,11 +160,16 @@ export const registerCreateWorkflowTool = (server: McpServer) => {
|
|
|
152
160
|
"mcp",
|
|
153
161
|
);
|
|
154
162
|
const longScriptTimeoutHint = findLongScriptTimeoutHint(definition.nodes);
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
|
|
164
|
+
return toolOk(withSaveWarnings(`Created workflow "${workflow.name}".`, warnings), {
|
|
165
|
+
details: withSaveWarnings(
|
|
166
|
+
`Created workflow "${workflow.name}" (${workflow.id}).`,
|
|
167
|
+
warnings,
|
|
168
|
+
),
|
|
157
169
|
data: {
|
|
158
170
|
yourAgentId: requestInfo.agentId,
|
|
159
171
|
workflow,
|
|
172
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
160
173
|
...(longScriptTimeoutHint ? { longScriptTimeoutHint } : {}),
|
|
161
174
|
},
|
|
162
175
|
});
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { WorkflowNodePatchSchema } from "@/types";
|
|
12
12
|
import { getExecutorRegistry } from "@/workflows";
|
|
13
13
|
import { patchWorkflowDefinition } from "@/workflows/patch-definition";
|
|
14
|
+
import { withSaveWarnings, workflowSaveWarnings } from "@/workflows/readiness";
|
|
14
15
|
|
|
15
16
|
export const registerPatchWorkflowNodeTool = (server: McpServer) => {
|
|
16
17
|
createToolRegistrar(server)(
|
|
@@ -30,6 +31,7 @@ export const registerPatchWorkflowNodeTool = (server: McpServer) => {
|
|
|
30
31
|
outputSchema: swarmToolOutputSchema({
|
|
31
32
|
workflow: z.unknown().optional(),
|
|
32
33
|
versionCreated: z.number().optional(),
|
|
34
|
+
warnings: z.array(z.string()).optional(),
|
|
33
35
|
}),
|
|
34
36
|
},
|
|
35
37
|
async ({ id, nodeId, ...nodeFields }, requestInfo) => {
|
|
@@ -59,14 +61,22 @@ export const registerPatchWorkflowNodeTool = (server: McpServer) => {
|
|
|
59
61
|
{ id: nodeId, type: patchedNode?.type, config: nodeFields.config },
|
|
60
62
|
]);
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const warnings = await workflowSaveWarnings(result.definition, getExecutorRegistry());
|
|
65
|
+
return toolOk(
|
|
66
|
+
withSaveWarnings(`Patched node "${nodeId}" in workflow "${workflow.name}".`, warnings),
|
|
67
|
+
{
|
|
68
|
+
details: withSaveWarnings(
|
|
69
|
+
`Patched node "${nodeId}" in workflow "${workflow.name}" (${id}). Version ${version} snapshot created.`,
|
|
70
|
+
warnings,
|
|
71
|
+
),
|
|
72
|
+
data: {
|
|
73
|
+
workflow,
|
|
74
|
+
versionCreated: version ?? undefined,
|
|
75
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
76
|
+
...(longScriptTimeoutHint ? { longScriptTimeoutHint } : {}),
|
|
77
|
+
},
|
|
68
78
|
},
|
|
69
|
-
|
|
79
|
+
);
|
|
70
80
|
} catch (err) {
|
|
71
81
|
return toolErr(String(err));
|
|
72
82
|
}
|
|
@@ -14,6 +14,7 @@ import type { WorkflowPatch } from "@/types";
|
|
|
14
14
|
import { AssetKeySchema, WorkflowNodePatchSchema } from "@/types";
|
|
15
15
|
import { getExecutorRegistry } from "@/workflows";
|
|
16
16
|
import { patchWorkflowDefinition } from "@/workflows/patch-definition";
|
|
17
|
+
import { withSaveWarnings, workflowSaveWarnings } from "@/workflows/readiness";
|
|
17
18
|
|
|
18
19
|
export const registerPatchWorkflowTool = (server: McpServer) => {
|
|
19
20
|
createToolRegistrar(server)(
|
|
@@ -78,6 +79,7 @@ export const registerPatchWorkflowTool = (server: McpServer) => {
|
|
|
78
79
|
nodesCreated: z.number().optional(),
|
|
79
80
|
nodesUpdated: z.number().optional(),
|
|
80
81
|
nodesDeleted: z.number().optional(),
|
|
82
|
+
warnings: z.array(z.string()).optional(),
|
|
81
83
|
}),
|
|
82
84
|
},
|
|
83
85
|
async ({ id, key, update, delete: del, create, onNodeFailure, triggerSchema }, requestInfo) => {
|
|
@@ -133,14 +135,19 @@ export const registerPatchWorkflowTool = (server: McpServer) => {
|
|
|
133
135
|
);
|
|
134
136
|
const longScriptTimeoutHint = findLongScriptTimeoutHint(authoredFinalNodes);
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
const warnings = await workflowSaveWarnings(result.definition, getExecutorRegistry());
|
|
139
|
+
return toolOk(withSaveWarnings(`Patched workflow "${workflow.name}".`, warnings), {
|
|
140
|
+
details: withSaveWarnings(
|
|
141
|
+
`Patched workflow "${workflow.name}" (${id}). Version ${version} snapshot created.`,
|
|
142
|
+
warnings,
|
|
143
|
+
),
|
|
138
144
|
data: {
|
|
139
145
|
workflow,
|
|
140
146
|
versionCreated: version ?? undefined,
|
|
141
147
|
nodesCreated: create?.length ?? 0,
|
|
142
148
|
nodesUpdated: update?.length ?? 0,
|
|
143
149
|
nodesDeleted: del?.length ?? 0,
|
|
150
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
144
151
|
...(longScriptTimeoutHint ? { longScriptTimeoutHint } : {}),
|
|
145
152
|
},
|
|
146
153
|
});
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
} from "@/types";
|
|
20
20
|
import { getExecutorRegistry } from "@/workflows";
|
|
21
21
|
import { definitionNodeIds, validateDefinition } from "@/workflows/definition";
|
|
22
|
+
import { workflowModelErrors } from "@/workflows/model-validation";
|
|
23
|
+
import { withSaveWarnings, workflowSaveWarnings } from "@/workflows/readiness";
|
|
22
24
|
import { snapshotAndUpdateWorkflow } from "@/workflows/version";
|
|
23
25
|
|
|
24
26
|
export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
@@ -36,7 +38,8 @@ export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
|
36
38
|
"WEBHOOK VERIFICATION: webhook triggers use hmacSecret for all verification formats. " +
|
|
37
39
|
"Omit verification for legacy HMAC-SHA256 over the raw body with fallback header scanning; " +
|
|
38
40
|
"or set verification to { format: 'hmac-sha256', header }, { format: 'timestamped-hmac-sha256', header, toleranceSeconds? }, " +
|
|
39
|
-
"
|
|
41
|
+
"{ format: 'token-equality', header }, or { format: 'standard-webhooks', toleranceSeconds? } " +
|
|
42
|
+
"(standardwebhooks.com: webhook-id/webhook-timestamp/webhook-signature headers, hmacSecret is the whsec_ signing secret).",
|
|
40
43
|
inputSchema: z.object({
|
|
41
44
|
id: z.string().uuid().describe("Workflow ID to update"),
|
|
42
45
|
key: AssetKeySchema.optional().describe("Move to a logical namespace."),
|
|
@@ -47,7 +50,7 @@ export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
|
47
50
|
.array(TriggerConfigSchema)
|
|
48
51
|
.optional()
|
|
49
52
|
.describe(
|
|
50
|
-
"New trigger configurations. Webhook verification formats: legacy omitted verification, hmac-sha256, timestamped-hmac-sha256, token-equality.",
|
|
53
|
+
"New trigger configurations. Webhook verification formats: legacy omitted verification, hmac-sha256, timestamped-hmac-sha256, token-equality, standard-webhooks.",
|
|
51
54
|
),
|
|
52
55
|
cooldown: CooldownConfigSchema.optional()
|
|
53
56
|
.nullable()
|
|
@@ -84,6 +87,7 @@ export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
|
84
87
|
outputSchema: swarmToolOutputSchema({
|
|
85
88
|
workflow: z.unknown().optional(),
|
|
86
89
|
versionCreated: z.number().optional(),
|
|
90
|
+
warnings: z.array(z.string()).optional(),
|
|
87
91
|
}),
|
|
88
92
|
},
|
|
89
93
|
async (
|
|
@@ -118,6 +122,10 @@ export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
|
118
122
|
if (!validation.valid) {
|
|
119
123
|
return toolErr(`Invalid definition: ${validation.errors.join("; ")}`);
|
|
120
124
|
}
|
|
125
|
+
const modelErrors = await workflowModelErrors(definition);
|
|
126
|
+
if (modelErrors.length > 0) {
|
|
127
|
+
return toolErr(`Invalid definition: ${modelErrors.join("; ")}`);
|
|
128
|
+
}
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
const updatedBy =
|
|
@@ -152,11 +160,16 @@ export const registerUpdateWorkflowTool = (server: McpServer) => {
|
|
|
152
160
|
const longScriptTimeoutHint = definition
|
|
153
161
|
? findLongScriptTimeoutHint(definition.nodes)
|
|
154
162
|
: undefined;
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
|
|
164
|
+
return toolOk(withSaveWarnings(`Updated workflow "${workflow.name}".`, warnings), {
|
|
165
|
+
details: withSaveWarnings(
|
|
166
|
+
`Updated workflow "${workflow.name}" (${id}). Version ${version.version} snapshot created.`,
|
|
167
|
+
warnings,
|
|
168
|
+
),
|
|
157
169
|
data: {
|
|
158
170
|
workflow,
|
|
159
171
|
versionCreated: version.version,
|
|
172
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
160
173
|
...(longScriptTimeoutHint ? { longScriptTimeoutHint } : {}),
|
|
161
174
|
},
|
|
162
175
|
});
|
package/src/types.ts
CHANGED
|
@@ -231,6 +231,25 @@ export function resolveModelTier(opts: {
|
|
|
231
231
|
return DEFAULT_MODEL_TIER_MAP[opts.harnessProvider]?.[tier];
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
export type ModelTierOverrides = Partial<Record<string, Partial<Record<ModelTier, string>>>>;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The worker's own MODEL_TIER_<TIER> / MODEL_TIER_MAP overrides, keyed by its
|
|
238
|
+
* harness provider, in the shape the worker sends on register and poll so the
|
|
239
|
+
* server can apply them at claim time. Values only (model ids), never secrets.
|
|
240
|
+
*/
|
|
241
|
+
export function parseWorkerModelTierOverrides(
|
|
242
|
+
env: Record<string, string | undefined>,
|
|
243
|
+
harnessProvider: ProviderName,
|
|
244
|
+
): ModelTierOverrides {
|
|
245
|
+
const tiers: Partial<Record<ModelTier, string>> = { ...parseTierMapJson(env.MODEL_TIER_MAP) };
|
|
246
|
+
for (const tier of MODEL_TIERS) {
|
|
247
|
+
const direct = env[`MODEL_TIER_${tier.toUpperCase()}`]?.trim();
|
|
248
|
+
if (direct) tiers[tier] = direct;
|
|
249
|
+
}
|
|
250
|
+
return Object.keys(tiers).length > 0 ? { [harnessProvider]: tiers } : {};
|
|
251
|
+
}
|
|
252
|
+
|
|
234
253
|
export function resolveTaskModelSelection(opts: {
|
|
235
254
|
model?: string | null;
|
|
236
255
|
modelTier?: string | null;
|
|
@@ -612,6 +631,12 @@ export const AgentTaskSchema = z
|
|
|
612
631
|
model: z.string().optional(),
|
|
613
632
|
modelTier: ModelTierSchema.optional(),
|
|
614
633
|
effort: ReasoningEffortSchema.optional(),
|
|
634
|
+
// Claim-time model resolution (server-side, see runbooks/model-tiers.md).
|
|
635
|
+
// resolvedModel is what the worker runs; modelSource says which layer won;
|
|
636
|
+
// modelAlias is the `latest:` alias the value came from, when any.
|
|
637
|
+
resolvedModel: z.string().optional(),
|
|
638
|
+
modelSource: z.string().optional(),
|
|
639
|
+
modelAlias: z.string().optional(),
|
|
615
640
|
|
|
616
641
|
// Schedule linking (optional — set when task was created by a schedule).
|
|
617
642
|
// z.string(): also reachable verbatim from the create-task query param.
|
|
@@ -1996,7 +2021,7 @@ export const WorkflowNodeSchema = z
|
|
|
1996
2021
|
type: z
|
|
1997
2022
|
.string()
|
|
1998
2023
|
.describe(
|
|
1999
|
-
"Executor type: 'agent-task', 'script', 'swarm-script', 'raw-llm', 'validate', 'property-match'",
|
|
2024
|
+
"Executor type: 'agent-task', 'script', 'swarm-script', 'raw-llm', 'system-one-decision', 'validate', 'property-match'",
|
|
2000
2025
|
),
|
|
2001
2026
|
label: z.string().optional().describe("Human-readable label for UI display"),
|
|
2002
2027
|
config: z
|
|
@@ -2005,6 +2030,7 @@ export const WorkflowNodeSchema = z
|
|
|
2005
2030
|
"Executor-specific config. For agent-task: { template, outputSchema?, agentId?, routingReason?, routingNote?, tags?, priority?, dir?, vcsRepo?, model? }; configured agentId defaults routingReason to human_pinned. " +
|
|
2006
2031
|
"For script: { runtime, script, args?, timeout? }. " +
|
|
2007
2032
|
"For swarm-script: { scriptName, scope?, pinHash?, args?, fsMode?, timeoutMs? (1000-300000) }. " +
|
|
2033
|
+
"For system-one-decision (typed decisions, Jev by default): { provider? ('typesafe' default | 'openrouter' | 'laya'; a literal, never a {{token}}), state, questions: { <id>: { type: 'noul'|'choice'|'score', instructions, criteria? } }, returns: { <id>: { type } }, model? (provider-specific; unset = the provider's default, and laya has none so it sends no model and picks its own checkpoint), timeoutMs?, maxRetries? (0-3), humanReview? { band: { min, max } (0-1, inclusive), approvers: { users?, roles?, policy }, title?, timeout?, notifications? } }; each provider needs its own global secret (TYPESAFE_API_KEY, OPENROUTER_API_KEY, or LAYA_API_KEY; laya also needs the global config LAYA_URL), and a save warns and a run fails before any node executes when one is missing; system-one-decision nodes must not set retry or validation.retry. With humanReview, an answer whose confidence is inside the band waits for a person (human-in-the-loop approval), and next must map ports { approved, rejected?, timeout? }. " +
|
|
2008
2034
|
"Agent-task templates and ordinary config values support {{interpolation}} from the node's inputs context, including trigger and declared upstream aliases. " +
|
|
2009
2035
|
"SECURITY: executable source for script/swarm-script nodes does not interpolate trigger.* or upstream node outputs; only input/workflow/swarm/run values are allowed in inline script source, and named swarm-script source is not workflow-interpolated. " +
|
|
2010
2036
|
"Pass dynamic values through config.args instead (inline script receives them as argv; swarm-script receives its args object). " +
|
|
@@ -2127,6 +2153,8 @@ export interface PatchResult {
|
|
|
2127
2153
|
|
|
2128
2154
|
// Presets only: Slack-style separate timestamp headers, asymmetric signatures,
|
|
2129
2155
|
// and generic signature-template DSLs are intentionally out of scope for v1.
|
|
2156
|
+
// `standard-webhooks` follows https://www.standardwebhooks.com/ (symmetric v1 only):
|
|
2157
|
+
// fixed webhook-id / webhook-timestamp / webhook-signature headers, so no `header`.
|
|
2130
2158
|
export const WebhookVerificationSchema = z.discriminatedUnion("format", [
|
|
2131
2159
|
z.object({
|
|
2132
2160
|
format: z.literal("hmac-sha256"),
|
|
@@ -2161,6 +2189,15 @@ export const WebhookVerificationSchema = z.discriminatedUnion("format", [
|
|
|
2161
2189
|
format: z.literal("token-equality"),
|
|
2162
2190
|
header: z.string().min(1).describe("Header containing the shared token to compare"),
|
|
2163
2191
|
}),
|
|
2192
|
+
z.object({
|
|
2193
|
+
format: z.literal("standard-webhooks"),
|
|
2194
|
+
toleranceSeconds: z
|
|
2195
|
+
.number()
|
|
2196
|
+
.int()
|
|
2197
|
+
.positive()
|
|
2198
|
+
.default(300)
|
|
2199
|
+
.describe("Maximum allowed clock skew, in seconds, for the webhook-timestamp header"),
|
|
2200
|
+
}),
|
|
2164
2201
|
]);
|
|
2165
2202
|
export type WebhookVerification = z.infer<typeof WebhookVerificationSchema>;
|
|
2166
2203
|
|
|
@@ -2412,6 +2449,9 @@ export type AgentTaskSummary = Pick<
|
|
|
2412
2449
|
| "scheduleId"
|
|
2413
2450
|
| "model"
|
|
2414
2451
|
| "modelTier"
|
|
2452
|
+
| "resolvedModel"
|
|
2453
|
+
| "modelSource"
|
|
2454
|
+
| "modelAlias"
|
|
2415
2455
|
| "effort"
|
|
2416
2456
|
| "provider"
|
|
2417
2457
|
| "requestedByUserId"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex pool auth-failure benching: shared by the runner (classifies and
|
|
3
|
+
* reports failures) and the API (counts them and benches the login).
|
|
4
|
+
*
|
|
5
|
+
* Worker-side code imports this file, so it must never import `src/be/db`
|
|
6
|
+
* or `bun:sqlite`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Consecutive auth failures that bench a Codex pool login. */
|
|
10
|
+
export const CODEX_AUTH_FAILURE_BENCH_THRESHOLD = 2;
|
|
11
|
+
/** Bench length. Matches the codex-auth-expiry-watch bench (benchDays = 365). */
|
|
12
|
+
export const CODEX_AUTH_FAILURE_BENCH_MS = 365 * 24 * 60 * 60 * 1000;
|
|
13
|
+
/** KV namespace and key shared with codex-auth-expiry-watch and keep-warm. */
|
|
14
|
+
export const CODEX_AUTH_WATCH_NAMESPACE = "codex-auth-watch";
|
|
15
|
+
export const codexAuthBenchMarkerKey = (keySuffix: string) => `bench:${keySuffix}`;
|
|
16
|
+
|
|
17
|
+
/** Transient `[auth-error]` texts that must not count. */
|
|
18
|
+
const TRANSIENT_AUTH_ERROR_MARKERS = [
|
|
19
|
+
"waiting for the refresh lock",
|
|
20
|
+
"refresh rejected (429",
|
|
21
|
+
"refresh rejected (5",
|
|
22
|
+
"refresh rejected (unknown status",
|
|
23
|
+
"out of credits",
|
|
24
|
+
"no credentials found in config store",
|
|
25
|
+
// Revalidation threw something other than a refresh rejection (lock HTTP,
|
|
26
|
+
// network, or persistence failure). See buildPoolRevalidationFailureReason.
|
|
27
|
+
"not a confirmed auth rejection",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export function isCodexAuthFailureReason(failureReason: string | undefined | null): boolean {
|
|
31
|
+
if (!failureReason || !failureReason.includes("[auth-error]")) return false;
|
|
32
|
+
const lower = failureReason.toLowerCase();
|
|
33
|
+
return !TRANSIENT_AUTH_ERROR_MARKERS.some((m) => lower.includes(m));
|
|
34
|
+
}
|