@desplega.ai/agent-swarm 2.5.3 → 2.6.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 +2 -2
- package/dist/{acp-adapter-gr2fcyyj.js → acp-adapter-dgfakfpw.js} +9 -9
- package/dist/{actions-wv766ghf.js → actions-fbqma8aa.js} +21 -21
- package/dist/{amp-adapter-speb906t.js → amp-adapter-en0jy6hs.js} +4 -4
- package/dist/{app-ag29n14f.js → app-k8a5cgpp.js} +3 -3
- package/dist/{assistant-3x8bz3eg.js → assistant-a16433gr.js} +30 -26
- package/dist/{boot-reembed-jsmfrpzf.js → boot-reembed-6c1sjfnr.js} +1 -1
- package/dist/{boot-reembed-5b3d2eea.js → boot-reembed-f4nn561n.js} +1 -1
- package/dist/{boot-scrub-sweep-s73gerxy.js → boot-scrub-sweep-d4w9gajf.js} +4 -4
- package/dist/{boot-seeds-5zmax2wr.js → boot-seeds-9bmkspyw.js} +4 -4
- package/dist/{claude-adapter-hswdnm3t.js → claude-adapter-nys1kjxa.js} +9 -9
- package/dist/{claude-managed-adapter-cvbzj1h6.js → claude-managed-adapter-55207973.js} +3 -3
- package/dist/{claude-managed-setup-3k8m3hhc.js → claude-managed-setup-3cm35gey.js} +11 -4
- package/dist/{claude-sdk-session-fkbyk66x.js → claude-sdk-session-nw5yd8cp.js} +9313 -9260
- package/dist/{cli-210xd1f4.js → cli-03gg9pd1.js} +4 -4
- package/dist/{cli-kxpfx2xr.js → cli-0z1xjzwa.js} +2 -2
- package/dist/cli-1tem6ns9.js +894 -0
- package/dist/{cli-25j01dpj.js → cli-24j1jeeb.js} +3 -3
- package/dist/{cli-ta8bd7th.js → cli-2sjhpsns.js} +2 -2
- package/dist/{cli-p859hcc8.js → cli-39aet655.js} +2 -2
- package/dist/{cli-g1cw7xtt.js → cli-39rrw8yp.js} +1 -1
- package/dist/{cli-e2ar4bp1.js → cli-3aqd4jaa.js} +121 -47
- package/dist/{cli-jjznk3f7.js → cli-3fwqy71j.js} +69 -35
- package/dist/{cli-p9rafdrb.js → cli-3gfvmzht.js} +7 -7
- package/dist/{cli-03vpq45j.js → cli-3ndmpxxv.js} +2 -2
- package/dist/{cli-aecdcr77.js → cli-4hxrf0p4.js} +228 -74
- package/dist/{cli-mz9afxxf.js → cli-4rf0f5vg.js} +15 -3
- package/dist/{cli-qzme5949.js → cli-5rj83bam.js} +284 -202
- package/dist/{cli-fsdprwrg.js → cli-5sckpqcx.js} +2 -2
- package/dist/{cli-cz5nmdxt.js → cli-683y0b3a.js} +2 -2
- package/dist/{cli-3ngdk5te.js → cli-6y51ryva.js} +2 -2
- package/dist/{cli-n4c8e3s5.js → cli-708wdy32.js} +1 -1
- package/dist/{cli-pasyvjmm.js → cli-737pyqxr.js} +1 -1
- package/dist/{cli-gx4rm0qx.js → cli-7enjwya9.js} +1 -1
- package/dist/{cli-6x9ma5w5.js → cli-803188pb.js} +1 -1
- package/dist/{cli-avdvgcay.js → cli-9abdgn5t.js} +28 -9
- package/dist/{cli-99xgw26r.js → cli-a2rr0fmg.js} +1 -1
- package/dist/{cli-e5bxnjps.js → cli-a34pr3w1.js} +7 -7
- package/dist/{cli-502eqv93.js → cli-abkm71vr.js} +1 -1
- package/dist/{cli-mmhj8vd7.js → cli-ag2yrnt5.js} +11 -2
- package/dist/{cli-n45mr7zh.js → cli-aj8djyqt.js} +5 -5
- package/dist/{cli-1fc85mvt.js → cli-art7c1zh.js} +5 -5
- package/dist/{cli-40jsnrjm.js → cli-az25fn5f.js} +10 -8
- package/dist/{cli-9s05422w.js → cli-bqztfyve.js} +1 -1
- package/dist/{cli-bn0rewsy.js → cli-c081bj3b.js} +2 -2
- package/dist/{cli-svrj71pg.js → cli-c2habvsf.js} +12 -12
- package/dist/{cli-s49hpn37.js → cli-ca6banwz.js} +85 -19
- package/dist/{cli-hhxjnjzs.js → cli-cz37jqss.js} +12 -10
- package/dist/{cli-6n8axjv1.js → cli-d2dpf95n.js} +2 -2
- package/dist/{cli-tx00c0h6.js → cli-dqygeeh5.js} +17 -1
- package/dist/{cli-z21whrrg.js → cli-emhjcj2y.js} +17 -17
- package/dist/{cli-e8jyq7d8.js → cli-esakngh8.js} +7 -3
- package/dist/{cli-ha9rmwgq.js → cli-fb8m699c.js} +2 -2
- package/dist/{cli-35gtk1p6.js → cli-ffvsj2qw.js} +44 -13
- package/dist/{cli-ce0ak9ms.js → cli-g20jjwt4.js} +26 -26
- package/dist/{cli-kxawjrxg.js → cli-g8ka5j4j.js} +772 -194
- package/dist/{cli-vwn81jbs.js → cli-gf95q3bm.js} +5 -5
- package/dist/{cli-s53vp709.js → cli-gnsb1zxa.js} +2 -2
- package/dist/{cli-nwyw3zhg.js → cli-gxee0bqa.js} +1 -1
- package/dist/{cli-gpv60278.js → cli-hfeb68z4.js} +7 -7
- package/dist/{cli-0ebey9hg.js → cli-j6rktc91.js} +1 -1
- package/dist/{cli-ewm3pwbq.js → cli-k21gx5ht.js} +46 -23
- package/dist/{cli-egjggehm.js → cli-kf4jree9.js} +2 -2
- package/dist/{cli-dabehxhp.js → cli-kt907da6.js} +1 -1
- package/dist/{cli-p0rzjkya.js → cli-m5a9m0ak.js} +32 -13
- package/dist/{cli-fzcn3d87.js → cli-m70bajzr.js} +3 -3
- package/dist/{cli-w1zwctj2.js → cli-mtnj4fwa.js} +11 -5
- package/dist/{cli-gpsz7g88.js → cli-mvjz5an3.js} +16 -12
- package/dist/{cli-hcpj2xqz.js → cli-n7asmce6.js} +225 -3
- package/dist/{cli-y561h5a9.js → cli-nn6vx2mq.js} +5 -5
- package/dist/cli-nq677csy.js +140 -0
- package/dist/{cli-a5ebc95n.js → cli-pfk92eqz.js} +18 -15
- package/dist/{cli-p6zs9h4y.js → cli-rr7zx19j.js} +767 -249
- package/dist/{cli-qgf8emrn.js → cli-sqma6vw1.js} +10 -7
- package/dist/{cli-0xk505e8.js → cli-sxgtf5fw.js} +1 -1
- package/dist/{cli-nzfnt2gs.js → cli-tf1n0r0b.js} +1 -1
- package/dist/{cli-qqzmjxkf.js → cli-v49fkghp.js} +11 -6
- package/dist/{cli-x77gen2p.js → cli-w2656ka1.js} +7 -7
- package/dist/{cli-5kqnemen.js → cli-yvy48785.js} +1 -1
- package/dist/{cli-8s5wx3nz.js → cli-zqne1qcj.js} +44 -17
- package/dist/cli.js +22 -22
- package/dist/{codex-adapter-n8ka66vf.js → codex-adapter-d95q4qsn.js} +7 -7
- package/dist/{codex-hook-e2he7aca.js → codex-hook-brpnycn5.js} +1 -1
- package/dist/{codex-login-rn7c5gxt.js → codex-login-8cg0vhf2.js} +1 -1
- package/dist/{codex-session-runner-fsebts37.js → codex-session-runner-gdwd8h0c.js} +8 -8
- package/dist/{commands-t04rt2pc.js → commands-jqmgk54b.js} +2 -2
- package/dist/{controller-rgna04r2.js → controller-z3jq589f.js} +30 -4
- package/dist/{controllers-connect-bqm1rtft.js → controllers-connect-r2za39ef.js} +23 -23
- package/dist/{cursor-adapter-swr2k95y.js → cursor-adapter-4mr4jgkw.js} +2 -3
- package/dist/{db-a4m7haw0.js → db-ppv2tze7.js} +3 -3
- package/dist/{db-24ck09xy.js → db-w36wwb5g.js} +4 -2
- package/dist/{devin-adapter-4ycy4vrf.js → devin-adapter-byen2cxt.js} +1 -1
- package/dist/{dispatcher-nwf9ss0q.js → dispatcher-pv5h77vf.js} +20 -20
- package/dist/{docker-nfy2gc8t.js → docker-fdzyewpz.js} +4 -4
- package/dist/{dsh-adapter-kpdnhjst.js → dsh-adapter-d4pdpb3r.js} +2 -3
- package/dist/{e2b-9gkdhm3c.js → e2b-222hsajc.js} +2 -2
- package/dist/{e2b-cjtf8k1z.js → e2b-fn3zacvt.js} +2 -2
- package/dist/{easter-egg-3d-e4qv8dxj.js → easter-egg-3d-4sp4dvmc.js} +1 -1
- package/dist/{event-bus-3z78ep5n.js → event-bus-pghg8hqy.js} +1 -1
- package/dist/{execute-0xpz8950.js → execute-jev839y1.js} +1 -1
- package/dist/{external-channel-j1e2p34p.js → external-channel-y6nkzhnn.js} +2 -2
- package/dist/{grok-adapter-qtjz0whk.js → grok-adapter-t08b9ntm.js} +10 -10
- package/dist/handlers-eqsnmv95.js +41 -0
- package/dist/{heartbeat-vtesda5d.js → heartbeat-vn31xwdk.js} +23 -23
- package/dist/{hook-b2hhj6rd.js → hook-6d0zbvvt.js} +6 -5
- package/dist/{hook-8wqaszda.js → hook-cpjs8q51.js} +13 -7
- package/dist/{http-mxcqhhcs.js → http-9c6medda.js} +1085 -136
- package/dist/{index-spwxjgay.js → index-38t35h0n.js} +20 -20
- package/dist/{index-1r8wfpzs.js → index-g6k9tctj.js} +1 -1
- package/dist/{index-srg522m6.js → index-k0yt1tvq.js} +20 -20
- package/dist/{index-31ceyf42.js → index-pkma1yf8.js} +1 -1
- package/dist/{index-n1vbvta9.js → index-qhjf2htm.js} +29 -24
- package/dist/index-yqgbfgaj.js +43 -0
- package/dist/{keepalive-dsd8rtgx.js → keepalive-em0117bp.js} +4 -4
- package/dist/lead-23e7z59t.js +79 -0
- package/dist/{maintenance-jqmqwnet.js → maintenance-kbme3qy9.js} +1 -1
- package/dist/{oauth-refresh-sweep-q2c3bnvm.js → oauth-refresh-sweep-xysj4yse.js} +3 -3
- package/dist/{onboard-w4yd7s8t.js → onboard-p6q0vz97.js} +3 -3
- package/dist/{opencode-adapter-9tppvxar.js → opencode-adapter-esv3k9yn.js} +7 -7
- package/dist/{otel-impl-f36byzbd.js → otel-impl-54qhqh1z.js} +2 -2
- package/dist/{pi-mono-adapter-tqsge1ay.js → pi-mono-adapter-mymbwhj0.js} +41 -14
- package/dist/{pricing-refresh-xvak5p4v.js → pricing-refresh-yb75wv33.js} +3 -3
- package/dist/{rbac-roles-gfn30fb8.js → rbac-roles-1vp2mw4p.js} +2 -2
- package/dist/{rbac-roles-682k2mt5.js → rbac-roles-dexhc9x8.js} +1 -1
- package/dist/render-v2-tjay5hhf.js +16 -0
- package/dist/{resume-2dvq348g.js → resume-8ayf37g5.js} +11 -9
- package/dist/{runtime-bt5pkpm1.js → runtime-hqe5cqcd.js} +1 -1
- package/dist/{session-access-7f21ekq9.js → session-access-fdhp987s.js} +4 -4
- package/dist/session-source-backfill-qgtc86z1.js +110 -0
- package/dist/{setup-epffxtbk.js → setup-4rrmqcq3.js} +1 -1
- package/dist/{virtual-modules-mnfbh5mr.js → virtual-modules-52km00d6.js} +2 -2
- package/dist/{work-objects-xz1a5rqk.js → work-objects-p28fgd70.js} +23 -23
- package/dist/worker-e3w7vye1.js +79 -0
- package/dist/{x-pbpezr0s.js → x-wxrzvzx8.js} +2 -2
- package/openapi.json +1323 -16
- package/package.json +5 -5
- package/plugin/commands/create-pr.md +2 -2
- package/plugin/pi-skills/create-pr/SKILL.md +2 -2
- package/src/assets/source-key.ts +95 -0
- package/src/be/db/api-keys.ts +80 -0
- package/src/be/db/approvals.ts +48 -0
- package/src/be/db/session-labels.ts +28 -0
- package/src/be/db/session-moves.ts +5 -6
- package/src/be/db/session-tree.ts +153 -14
- package/src/be/db/tasks/read.ts +11 -0
- package/src/be/db/tasks/write.ts +21 -6
- package/src/be/db/workflow-idempotency.ts +183 -0
- package/src/be/db/workflow-runs.ts +500 -7
- package/src/be/db-retention.ts +61 -6
- package/src/be/db.ts +126 -131
- package/src/be/memory/providers/openai-embedding.ts +5 -1
- package/src/be/migrations/242_workflow_idempotency_keys.sql +40 -0
- package/src/be/migrations/244_api_key_validation.sql +4 -0
- package/src/be/onboarding.ts +4 -0
- package/src/be/scripts/typecheck.ts +1 -1
- package/src/be/sealed-json.ts +1 -0
- package/src/be/seed-scripts/catalog/compound-insights.inline.ts +2 -2
- package/src/be/seed-scripts/catalog/compound-insights.ts +2 -2
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/session-source-backfill.ts +163 -0
- package/src/be/sql-connections.ts +7 -1
- package/src/be/swarm-config-guard.ts +3 -0
- package/src/be/users.ts +9 -0
- package/src/comb/review-batch.ts +28 -1
- package/src/comb/templates.ts +7 -2
- package/src/commands/claude-managed-setup.ts +7 -1
- package/src/commands/controller.ts +33 -0
- package/src/commands/credential-refresh.ts +76 -1
- package/src/commands/credential-wait.ts +2 -2
- package/src/commands/provider-credentials.ts +210 -170
- package/src/commands/runner.ts +31 -6
- package/src/extensions/apply-task-create.ts +64 -11
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +30 -0
- package/src/extensions/dispatcher.ts +4 -0
- package/src/extensions/post-bridge.ts +8 -0
- package/src/hooks/context-bound-note.ts +196 -0
- package/src/hooks/hook.ts +12 -0
- package/src/http/all-routes.ts +2 -0
- package/src/http/api-keys.ts +53 -0
- package/src/http/assets.ts +15 -0
- package/src/http/codex-oauth-accounts.ts +191 -0
- package/src/http/comb.ts +15 -2
- package/src/http/config.ts +49 -17
- package/src/http/core.ts +6 -0
- package/src/http/fleet-benchmark.ts +5 -2
- package/src/http/idempotency-key.ts +117 -0
- package/src/http/index.ts +11 -0
- package/src/http/integrations.ts +5 -1
- package/src/http/kv.ts +8 -3
- package/src/http/onboarding.ts +6 -1
- package/src/http/pool-keys.ts +354 -0
- package/src/http/sessions.ts +37 -12
- package/src/http/stats.ts +1 -0
- package/src/http/status.ts +26 -12
- package/src/http/tasks.ts +3 -0
- package/src/http/used-by.ts +7 -2
- package/src/http/workflows.ts +207 -33
- package/src/integrations/chat-sdk/inbound.ts +27 -0
- package/src/kv-reserved-namespaces.ts +19 -0
- package/src/prompts/context-bound-note.ts +48 -0
- package/src/prompts/session-templates.ts +25 -1
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +30 -8
- package/src/providers/claude-adapter.ts +34 -5
- package/src/providers/claude-managed-adapter.ts +42 -9
- package/src/providers/claude-sdk-session.ts +10 -0
- package/src/providers/claude-session-events.ts +13 -0
- package/src/providers/codex-adapter.ts +83 -11
- package/src/providers/opencode-adapter.ts +18 -0
- package/src/providers/pi-mono-adapter.ts +35 -0
- package/src/runtime-providers/docker.ts +6 -2
- package/src/scheduler/scheduler.ts +3 -2
- package/src/scripts-runtime/swarm-sdk.ts +7 -1
- package/src/scripts-runtime/types/stdlib.d.ts +1 -1
- package/src/scripts-runtime/types/swarm-extension.d.ts +52 -8
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -1
- package/src/slack/assistant.ts +7 -0
- package/src/slack/channel-labels.ts +74 -0
- package/src/slack/handlers.ts +8 -0
- package/src/slack/inbound-files.ts +5 -2
- package/src/slack/thread-buffer.ts +4 -0
- package/src/tasks/sibling-awareness.ts +12 -3
- package/src/telemetry-context.ts +5 -6
- package/src/telemetry-identity.ts +3 -3
- package/src/tests/amp-adapter.test.ts +97 -0
- package/src/tests/api-keys-validation.test.ts +170 -0
- package/src/tests/approval-requests.test.ts +10 -7
- package/src/tests/approval-sweeps.test.ts +12 -6
- package/src/tests/base-prompt.test.ts +1 -1
- package/src/tests/claude-hook-output.test.ts +79 -1
- package/src/tests/claude-managed-adapter.test.ts +321 -0
- package/src/tests/claude-routes-e2e.test.ts +7 -2
- package/src/tests/codex-adapter.test.ts +163 -0
- package/src/tests/codex-credential-pools.test.ts +120 -0
- package/src/tests/codex-gateway-route.test.ts +165 -0
- package/src/tests/codex-oauth-accounts.test.ts +357 -0
- package/src/tests/comb-review-batch.test.ts +63 -2
- package/src/tests/config-pool-keys.test.ts +533 -0
- package/src/tests/context-bound-note.test.ts +269 -0
- package/src/tests/credential-check.test.ts +290 -2
- package/src/tests/credential-refresh.test.ts +172 -1
- package/src/tests/db-retention.test.ts +9 -3
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +1 -3
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/extensions-pre-task.test.ts +325 -0
- package/src/tests/fetch-resolved-env.test.ts +17 -0
- package/src/tests/fixtures/extensions/record-blocks/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/record-blocks/manifest.json +7 -0
- package/src/tests/fixtures/extensions/record-task-create/hooks.ts +9 -0
- package/src/tests/fixtures/extensions/record-task-create/manifest.json +7 -0
- package/src/tests/fixtures/fake-amp.ts +22 -8
- package/src/tests/fixtures/held-template-render.ts +42 -0
- package/src/tests/fixtures/workflow-idempotency-trigger.child.ts +73 -0
- package/src/tests/fleet-benchmark.test.ts +8 -0
- package/src/tests/get-workflow-run-tool.test.ts +98 -0
- package/src/tests/integrations-http.test.ts +32 -2
- package/src/tests/internal-ai/complete-structured.test.ts +37 -1
- package/src/tests/internal-ai/credentials.test.ts +23 -0
- package/src/tests/kv-http.test.ts +32 -0
- package/src/tests/kv-tool.test.ts +25 -0
- package/src/tests/multi-runtime-registration.test.ts +12 -12
- package/src/tests/onboarding.test.ts +108 -1
- package/src/tests/openai-embedding-credentials.test.ts +35 -0
- package/src/tests/openapi-route-headers.test.ts +2 -0
- package/src/tests/opencode-adapter.test.ts +134 -0
- package/src/tests/openrouter-attribution-call-sites.test.ts +2 -2
- package/src/tests/org-website.test.ts +36 -0
- package/src/tests/pi-mono-adapter.test.ts +105 -0
- package/src/tests/prompt-template-session.test.ts +4 -3
- package/src/tests/provider-key-probes.test.ts +181 -0
- package/src/tests/rbac-e2e-helpers.test.ts +88 -1
- package/src/tests/rbac-e2e-helpers.ts +36 -11
- package/src/tests/runner-push-delivery.test.ts +25 -0
- package/src/tests/runtime-controller-liveness.test.ts +133 -0
- package/src/tests/runtime-providers-docker.test.ts +2 -0
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/script-run-config-scope.test.ts +91 -3
- package/src/tests/script-runs-retention.test.ts +212 -0
- package/src/tests/sdk-allowlist.test.ts +39 -0
- package/src/tests/session-logs.test.ts +70 -0
- package/src/tests/session-source-backfill.test.ts +429 -0
- package/src/tests/session-source-keys.test.ts +236 -0
- package/src/tests/session-source-labels.test.ts +419 -0
- package/src/tests/sessions-detail-batch.test.ts +2 -0
- package/src/tests/sessions-move.test.ts +131 -0
- package/src/tests/sessions-tree.test.ts +336 -2
- package/src/tests/slack-inbound-files.test.ts +103 -23
- package/src/tests/status.test.ts +101 -18
- package/src/tests/tasks-workflow-run-filter.test.ts +146 -0
- package/src/tests/test-net.ts +31 -0
- package/src/tests/transcription.test.ts +8 -0
- package/src/tests/used-by-route.test.ts +11 -0
- package/src/tests/workflow-cascade-cancel.test.ts +1341 -0
- package/src/tests/workflow-foreach-supersede-retry.test.ts +488 -0
- package/src/tests/workflow-http-v2.test.ts +131 -0
- package/src/tests/workflow-idempotency.test.ts +915 -0
- package/src/tests/workflow-step-order.test.ts +92 -0
- package/src/tests/workflow-sub-workflow.test.ts +30 -0
- package/src/tools/get-tasks.ts +8 -0
- package/src/tools/kv/kv-read-auth.ts +4 -2
- package/src/tools/task-action.ts +1 -1
- package/src/tools/workflows/cancel-workflow-run.ts +1 -1
- package/src/tools/workflows/get-workflow-run.ts +14 -4
- package/src/types.ts +24 -0
- package/src/utils/company-profile.ts +51 -1
- package/src/utils/context-window.ts +8 -6
- package/src/utils/credentials.ts +5 -2
- package/src/utils/internal-ai/complete-structured.ts +5 -0
- package/src/utils/internal-ai/credentials.ts +4 -3
- package/src/utils/provider-key-probes.ts +328 -0
- package/src/utils/transcription.ts +4 -1
- package/src/workflows/approval-cancel.ts +15 -13
- package/src/workflows/approval-notifications.ts +5 -1
- package/src/workflows/checkpoint.ts +6 -3
- package/src/workflows/engine.ts +30 -8
- package/src/workflows/executors/foreach.ts +2 -2
- package/src/workflows/executors/sub-workflow.ts +8 -1
- package/src/workflows/foreach-driver.ts +10 -3
- package/src/workflows/foreach-join.ts +29 -6
- package/src/workflows/recovery.ts +6 -1
- package/src/workflows/resume.ts +168 -56
- package/src/workflows/retry-poller.ts +49 -3
- package/src/workflows/task-step-routing.ts +29 -7
- package/templates/ai-toolbox.manifest.json +8 -8
- package/templates/community/open-prompt-showreel/PLAYBOOK.md +5 -6
- package/templates/community/open-prompt-showreel/lead-prompt.md +1 -1
- package/templates/community/open-prompt-showreel/skills/open-prompt-showreel/SKILL.md +4 -4
- package/templates/skills/agent-browser/SKILL.md +4 -4
- package/templates/skills/agent-browser/content.md +4 -4
- package/templates/skills/code-quality/config.json +1 -1
- package/templates/skills/code-quality/content.md +2 -2
- package/templates/skills/delegate-work/content.md +29 -25
- package/templates/skills/delegate-work/files/scripts/codex-exec.sh +5 -5
- package/templates/skills/qa/content.md +2 -2
- package/templates/skills/researching/content.md +4 -0
- package/templates/skills/swarm-scripts/SKILL.md +1 -0
- package/templates/skills/swarm-scripts/content.md +1 -0
- package/templates/skills/work-on-task/SKILL.md +1 -1
- package/templates/skills/work-on-task/content.md +1 -1
- package/dist/cli-7421jzsw.js +0 -84
- package/dist/cli-e45e4m6b.js +0 -413
- package/dist/cli-zw88zjba.js +0 -307
- package/dist/handlers-19xr6dnz.js +0 -41
- package/dist/index-kw2mmat7.js +0 -43
- package/dist/lead-zyerk1x2.js +0 -79
- package/dist/render-v2-hgytz8nn.js +0 -12
- package/dist/worker-42t8emjt.js +0 -79
package/src/be/db.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
2
|
import pkg from "../../package.json";
|
|
3
|
-
import { defaultAssetKey, normalizeAssetKey
|
|
3
|
+
import { defaultAssetKey, normalizeAssetKey } from "../assets/key";
|
|
4
|
+
import { sessionSourceKey, sessionThreadGroupKey } from "../assets/source-key";
|
|
4
5
|
import {
|
|
5
6
|
generateDefaultClaudeMd,
|
|
6
7
|
generateDefaultIdentityMd,
|
|
@@ -207,6 +208,7 @@ import {
|
|
|
207
208
|
sessionCountQuery,
|
|
208
209
|
sessionPageFields,
|
|
209
210
|
sessionSummaryQuery,
|
|
211
|
+
threadRootsSql,
|
|
210
212
|
} from "./db/session-tree";
|
|
211
213
|
import { searchSkillRowsRanked } from "./db/skill-search";
|
|
212
214
|
import { classifyTaskHumanFree, reclassifyTaskHumanFree } from "./db/tasks/human-free";
|
|
@@ -222,7 +224,19 @@ import {
|
|
|
222
224
|
rowToAgentTaskSummary,
|
|
223
225
|
} from "./db/tasks/read";
|
|
224
226
|
import { configureTaskWriteDependencies, failTask } from "./db/tasks/write";
|
|
225
|
-
import {
|
|
227
|
+
import { tombstoneWorkflowIdempotencyKeys } from "./db/workflow-idempotency";
|
|
228
|
+
import {
|
|
229
|
+
emitChildRunFinished,
|
|
230
|
+
getRunLineageBlock,
|
|
231
|
+
getStepExecutionBlock,
|
|
232
|
+
rowToWorkflowRun,
|
|
233
|
+
rowToWorkflowRunStep,
|
|
234
|
+
WORKFLOW_RUN_SUMMARY_COLUMNS,
|
|
235
|
+
type WorkflowRunRow,
|
|
236
|
+
type WorkflowRunStepRow,
|
|
237
|
+
WorkflowStepNotExecutableError,
|
|
238
|
+
wakeParentsOfDeletedRuns,
|
|
239
|
+
} from "./db/workflow-runs";
|
|
226
240
|
import { scrubJsonValue } from "./scrub-json";
|
|
227
241
|
import { openSealedJson, sealedJsonForDisplay, sealJson } from "./sealed-json";
|
|
228
242
|
import { configSecretName, registerStoredSecret } from "./secret-registry";
|
|
@@ -235,7 +249,7 @@ import {
|
|
|
235
249
|
} from "./swarm-config-guard";
|
|
236
250
|
import { emitTaskStarted } from "./task-lifecycle-events";
|
|
237
251
|
import { publishWorkerConfigNudge, publishWorkerNudge } from "./worker-nudges";
|
|
238
|
-
import {
|
|
252
|
+
import type { WorkflowPayloadView } from "./workflow-replay";
|
|
239
253
|
|
|
240
254
|
export {
|
|
241
255
|
refreshActiveSessionOnActivity,
|
|
@@ -278,7 +292,7 @@ export {
|
|
|
278
292
|
updateAgentStatus,
|
|
279
293
|
updateAgentStatusFromCapacity,
|
|
280
294
|
} from "./db/agents";
|
|
281
|
-
export { recordKeySeatMismatch } from "./db/api-keys";
|
|
295
|
+
export { recordKeySeatMismatch, recordKeyValidation } from "./db/api-keys";
|
|
282
296
|
export {
|
|
283
297
|
type ApprovalRequestSummary,
|
|
284
298
|
type ApprovalVote,
|
|
@@ -2490,6 +2504,8 @@ export async function createTaskExtended(
|
|
|
2490
2504
|
);
|
|
2491
2505
|
}
|
|
2492
2506
|
let requestedByUserIdInherited = false;
|
|
2507
|
+
// The parent key is read again inside the INSERT transaction (see below).
|
|
2508
|
+
let keyInherited = false;
|
|
2493
2509
|
// True only when `options.routingAffinity` ends up populated purely via
|
|
2494
2510
|
// the plain parent-fallback inherit below (child declared no affinity of
|
|
2495
2511
|
// its own, the parent wasn't lead-only, AND the parent's affinity actually
|
|
@@ -2654,6 +2670,7 @@ export async function createTaskExtended(
|
|
|
2654
2670
|
}
|
|
2655
2671
|
if (parent.key && !options.key) {
|
|
2656
2672
|
options.key = parent.key;
|
|
2673
|
+
keyInherited = true;
|
|
2657
2674
|
}
|
|
2658
2675
|
if (parent.contextKey && !options.contextKey) {
|
|
2659
2676
|
options.contextKey = parent.contextKey;
|
|
@@ -2843,7 +2860,18 @@ export async function createTaskExtended(
|
|
|
2843
2860
|
}
|
|
2844
2861
|
|
|
2845
2862
|
const auditUserId = getCurrentRequestUserId() ?? null;
|
|
2846
|
-
const assetKey = normalizeAssetKey(
|
|
2863
|
+
const assetKey = normalizeAssetKey(
|
|
2864
|
+
options?.key ??
|
|
2865
|
+
(options?.parentTaskId
|
|
2866
|
+
? null
|
|
2867
|
+
: sessionSourceKey({
|
|
2868
|
+
id,
|
|
2869
|
+
slackChannelId: options?.slackChannelId,
|
|
2870
|
+
slackThreadTs: options?.slackThreadTs,
|
|
2871
|
+
contextKey: options?.contextKey,
|
|
2872
|
+
})) ??
|
|
2873
|
+
defaultAssetKey("task", id),
|
|
2874
|
+
);
|
|
2847
2875
|
// The Linear tracker dedup guard and the INSERT commit as one unit. Two
|
|
2848
2876
|
// distinct webhook deliveries for the same issue are dispatched
|
|
2849
2877
|
// fire-and-forget (src/linear/webhook.ts), nothing serializes them, and
|
|
@@ -2855,11 +2883,32 @@ export async function createTaskExtended(
|
|
|
2855
2883
|
const claim = await getDbClient().transaction<
|
|
2856
2884
|
{ existing: ExistingTrackerContextWork } | { row: AgentTaskRow }
|
|
2857
2885
|
>(async () => {
|
|
2886
|
+
// A workflow step's task commits only while the step may still start
|
|
2887
|
+
// work. Checked in the INSERT's transaction: a cascade cancel of the
|
|
2888
|
+
// step's run tree either commits first and is seen here, or sees and
|
|
2889
|
+
// cancels this task.
|
|
2890
|
+
if (options?.workflowRunStepId) {
|
|
2891
|
+
const blocked = await getStepExecutionBlock(options.workflowRunStepId);
|
|
2892
|
+
if (blocked) throw new WorkflowStepNotExecutableError(options.workflowRunStepId, blocked);
|
|
2893
|
+
}
|
|
2858
2894
|
const existingTrackerWork = options?.bypassTrackerContextDedup
|
|
2859
2895
|
? null
|
|
2860
2896
|
: await findExistingLinearTrackerContextWork(options?.contextKey);
|
|
2861
2897
|
if (existingTrackerWork) return { existing: existingTrackerWork };
|
|
2862
2898
|
|
|
2899
|
+
// A chain move (a user move, the source key backfill) can commit between
|
|
2900
|
+
// the parent read above and this write lock. Its chain query did not see
|
|
2901
|
+
// this child, so take the parent's key as it is now.
|
|
2902
|
+
const parentKey =
|
|
2903
|
+
keyInherited && options?.parentTaskId
|
|
2904
|
+
? (
|
|
2905
|
+
await getDbClient().get<{ key: string }>('SELECT "key" FROM agent_tasks WHERE id = ?', [
|
|
2906
|
+
options.parentTaskId,
|
|
2907
|
+
])
|
|
2908
|
+
)?.key
|
|
2909
|
+
: undefined;
|
|
2910
|
+
const insertKey = parentKey ? normalizeAssetKey(parentKey) : assetKey;
|
|
2911
|
+
|
|
2863
2912
|
let routingDecisionSnapshot: RoutingDecisionSnapshot | null = null;
|
|
2864
2913
|
try {
|
|
2865
2914
|
routingDecisionSnapshot = await captureRoutingDecisionSnapshot(options);
|
|
@@ -2890,7 +2939,7 @@ export async function createTaskExtended(
|
|
|
2890
2939
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`,
|
|
2891
2940
|
[
|
|
2892
2941
|
id,
|
|
2893
|
-
|
|
2942
|
+
insertKey,
|
|
2894
2943
|
options?.agentId ?? null,
|
|
2895
2944
|
options?.creatorAgentId ?? null,
|
|
2896
2945
|
// Free text from every task source; scrub at the single INSERT.
|
|
@@ -4739,7 +4788,7 @@ export async function createSessionLogs(logs: {
|
|
|
4739
4788
|
for (let start = 0; start < logs.lines.length; start += BATCH_SIZE) {
|
|
4740
4789
|
// Yield to the event loop between batches.
|
|
4741
4790
|
if (start > 0) await new Promise<void>((r) => setTimeout(r, 5));
|
|
4742
|
-
const batch:
|
|
4791
|
+
const batch: string[] = [];
|
|
4743
4792
|
const end = Math.min(start + BATCH_SIZE, logs.lines.length);
|
|
4744
4793
|
for (let i = start; i < end; i++) {
|
|
4745
4794
|
const line = logs.lines[i];
|
|
@@ -4748,10 +4797,22 @@ export async function createSessionLogs(logs: {
|
|
|
4748
4797
|
// content that is already scrubbed at the adapter emit site. We scrub
|
|
4749
4798
|
// again here so any future write path that bypasses the adapter still
|
|
4750
4799
|
// lands clean text in the persistent session_logs table.
|
|
4751
|
-
batch.push(
|
|
4800
|
+
batch.push(scrubSecrets(line));
|
|
4752
4801
|
}
|
|
4753
4802
|
await getDbClient().transaction(async (tx) => {
|
|
4754
|
-
|
|
4803
|
+
// The worker flushes one (sessionId, iteration) in many POSTs, so the
|
|
4804
|
+
// lineNumber continues from the newest stored row instead of restarting
|
|
4805
|
+
// at the POST's index. Reading the newest row by rowid walks the
|
|
4806
|
+
// sessionId index backwards and stops at the first hit, where MAX()
|
|
4807
|
+
// would scan the whole session. Rows written here are monotonic in
|
|
4808
|
+
// rowid, so this equals MAX + 1 for them.
|
|
4809
|
+
const last = await tx.get<{ lineNumber: number }>(
|
|
4810
|
+
`SELECT lineNumber FROM session_logs WHERE sessionId = ? AND iteration = ?
|
|
4811
|
+
ORDER BY rowid DESC LIMIT 1`,
|
|
4812
|
+
[logs.sessionId, logs.iteration],
|
|
4813
|
+
);
|
|
4814
|
+
let lineNumber = last ? last.lineNumber + 1 : 0;
|
|
4815
|
+
for (const content of batch) {
|
|
4755
4816
|
await tx.run(
|
|
4756
4817
|
`INSERT INTO session_logs (id, taskId, sessionId, iteration, cli, content, lineNumber, createdAt)
|
|
4757
4818
|
VALUES (?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))`,
|
|
@@ -4762,7 +4823,7 @@ export async function createSessionLogs(logs: {
|
|
|
4762
4823
|
logs.iteration,
|
|
4763
4824
|
logs.cli,
|
|
4764
4825
|
content,
|
|
4765
|
-
lineNumber
|
|
4826
|
+
lineNumber++,
|
|
4766
4827
|
],
|
|
4767
4828
|
);
|
|
4768
4829
|
}
|
|
@@ -4770,6 +4831,10 @@ export async function createSessionLogs(logs: {
|
|
|
4770
4831
|
}
|
|
4771
4832
|
}
|
|
4772
4833
|
|
|
4834
|
+
// Session log reads order by rowid, which is insert order. Rows written before
|
|
4835
|
+
// lineNumber was assigned server-side restart at 0 on every worker flush, so
|
|
4836
|
+
// only rowid orders them. The API never runs VACUUM (runbooks/db-retention.md);
|
|
4837
|
+
// a manual VACUUM may renumber rowids but copies rows in rowid order.
|
|
4773
4838
|
export async function getSessionLogsByTaskId(
|
|
4774
4839
|
taskId: string,
|
|
4775
4840
|
limit?: number,
|
|
@@ -4777,16 +4842,16 @@ export async function getSessionLogsByTaskId(
|
|
|
4777
4842
|
if (typeof limit === "number" && limit > 0) {
|
|
4778
4843
|
const rows = await getDbClient().query<SessionLogRow>(
|
|
4779
4844
|
`SELECT * FROM (
|
|
4780
|
-
SELECT * FROM session_logs WHERE taskId = ?
|
|
4781
|
-
ORDER BY
|
|
4845
|
+
SELECT rowid AS seq, * FROM session_logs WHERE taskId = ?
|
|
4846
|
+
ORDER BY rowid DESC
|
|
4782
4847
|
LIMIT ?
|
|
4783
|
-
) ORDER BY
|
|
4848
|
+
) ORDER BY seq ASC`,
|
|
4784
4849
|
[taskId, limit],
|
|
4785
4850
|
);
|
|
4786
4851
|
return rows.map(rowToSessionLog);
|
|
4787
4852
|
}
|
|
4788
4853
|
const rows = await getDbClient().query<SessionLogRow>(
|
|
4789
|
-
"SELECT * FROM session_logs WHERE taskId = ? ORDER BY
|
|
4854
|
+
"SELECT * FROM session_logs WHERE taskId = ? ORDER BY rowid ASC",
|
|
4790
4855
|
[taskId],
|
|
4791
4856
|
);
|
|
4792
4857
|
return rows.map(rowToSessionLog);
|
|
@@ -4797,7 +4862,7 @@ export async function getSessionLogsBySession(
|
|
|
4797
4862
|
iteration: number,
|
|
4798
4863
|
): Promise<SessionLog[]> {
|
|
4799
4864
|
const rows = await getDbClient().query<SessionLogRow>(
|
|
4800
|
-
"SELECT * FROM session_logs WHERE sessionId = ? AND iteration = ? ORDER BY
|
|
4865
|
+
"SELECT * FROM session_logs WHERE sessionId = ? AND iteration = ? ORDER BY rowid ASC",
|
|
4801
4866
|
[sessionId, iteration],
|
|
4802
4867
|
);
|
|
4803
4868
|
return rows.map(rowToSessionLog);
|
|
@@ -7790,7 +7855,9 @@ async function deleteWorkflowRows(id: string, source?: "api" | "mcp"): Promise<b
|
|
|
7790
7855
|
await reclassifyTaskHumanFree(linkedTaskIds);
|
|
7791
7856
|
// 4. Delete every user's favorite of it (no FK to the workflow)
|
|
7792
7857
|
await client.run("DELETE FROM user_favorites WHERE itemType = 'workflow' AND itemId = ?", [id]);
|
|
7793
|
-
// 5.
|
|
7858
|
+
// 5. Keep Idempotency-Keys that created or triggered it taken, without the stored response
|
|
7859
|
+
await tombstoneWorkflowIdempotencyKeys(id);
|
|
7860
|
+
// 6. Delete workflow
|
|
7794
7861
|
const result = await client.run("DELETE FROM workflows WHERE id = ?", [id]);
|
|
7795
7862
|
const deleted = result.changes > 0;
|
|
7796
7863
|
if (deleted) {
|
|
@@ -7826,53 +7893,6 @@ export async function getWorkflowsByScheduleId(scheduleId: string): Promise<Work
|
|
|
7826
7893
|
// Workflow Run CRUD
|
|
7827
7894
|
// ============================================================================
|
|
7828
7895
|
|
|
7829
|
-
type WorkflowRunRow = {
|
|
7830
|
-
id: string;
|
|
7831
|
-
workflowId: string;
|
|
7832
|
-
status: string;
|
|
7833
|
-
triggerType: string;
|
|
7834
|
-
triggerData: string | null;
|
|
7835
|
-
/** Absent from list rows: see `WORKFLOW_RUN_SUMMARY_COLUMNS`. */
|
|
7836
|
-
context?: string | null;
|
|
7837
|
-
/** Sealed exact `context` (migration 201). Absent from list rows. */
|
|
7838
|
-
context_replay?: string | null;
|
|
7839
|
-
error: string | null;
|
|
7840
|
-
created_by: string | null;
|
|
7841
|
-
startedAt: string;
|
|
7842
|
-
lastUpdatedAt: string;
|
|
7843
|
-
finishedAt: string | null;
|
|
7844
|
-
/** The `sub-workflow` step that started this run (migration 203). */
|
|
7845
|
-
parentStepId?: string | null;
|
|
7846
|
-
/** That step's attempt (`retryCount`) when it started this run (migration 240). */
|
|
7847
|
-
parentStepAttempt?: number | null;
|
|
7848
|
-
};
|
|
7849
|
-
|
|
7850
|
-
/**
|
|
7851
|
-
* `view` picks the `context` copy: `replay` (default) is the exact sealed value
|
|
7852
|
-
* the engine resumes from; `display` is the scrubbed column for API, MCP and UI
|
|
7853
|
-
* responses. See `src/be/workflow-replay.ts`.
|
|
7854
|
-
*/
|
|
7855
|
-
function rowToWorkflowRun(row: WorkflowRunRow, view: WorkflowPayloadView = "replay"): WorkflowRun {
|
|
7856
|
-
const run: WorkflowRun = {
|
|
7857
|
-
id: row.id,
|
|
7858
|
-
workflowId: row.workflowId,
|
|
7859
|
-
status: row.status as WorkflowRunStatus,
|
|
7860
|
-
triggerData: row.triggerData ? JSON.parse(row.triggerData) : undefined,
|
|
7861
|
-
context: undefined,
|
|
7862
|
-
error: row.error ?? undefined,
|
|
7863
|
-
createdBy: row.created_by ?? undefined,
|
|
7864
|
-
startedAt: normalizeDateRequired(row.startedAt),
|
|
7865
|
-
lastUpdatedAt: normalizeDateRequired(row.lastUpdatedAt),
|
|
7866
|
-
finishedAt: normalizeDate(row.finishedAt) ?? undefined,
|
|
7867
|
-
parentStepId: row.parentStepId ?? undefined,
|
|
7868
|
-
parentStepAttempt: row.parentStepId ? (row.parentStepAttempt ?? 0) : undefined,
|
|
7869
|
-
};
|
|
7870
|
-
return defineWorkflowPayload(run, "context", row.context, row.context_replay, view, {
|
|
7871
|
-
runId: row.id,
|
|
7872
|
-
target: "its context",
|
|
7873
|
-
});
|
|
7874
|
-
}
|
|
7875
|
-
|
|
7876
7896
|
export async function createWorkflowRun(data: {
|
|
7877
7897
|
id: string;
|
|
7878
7898
|
workflowId: string;
|
|
@@ -7998,12 +8018,6 @@ export type WorkflowRunListOptions = {
|
|
|
7998
8018
|
includeContext?: boolean;
|
|
7999
8019
|
};
|
|
8000
8020
|
|
|
8001
|
-
// Everything but `context`. `triggerData` stays: it is small, and stored
|
|
8002
|
-
// scripts read it off list rows (dedupe by trigger, failure reports). The
|
|
8003
|
-
// parent link and attempt stay so a list row identifies a child's invocation.
|
|
8004
|
-
const WORKFLOW_RUN_SUMMARY_COLUMNS =
|
|
8005
|
-
"id, workflowId, status, triggerType, triggerData, error, created_by, startedAt, lastUpdatedAt, finishedAt, parentStepId, parentStepAttempt";
|
|
8006
|
-
|
|
8007
8021
|
export type WorkflowRunPage = {
|
|
8008
8022
|
runs: WorkflowRun[];
|
|
8009
8023
|
page: {
|
|
@@ -8088,56 +8102,6 @@ export async function listWorkflowRunsPage(
|
|
|
8088
8102
|
// Workflow Run Step CRUD
|
|
8089
8103
|
// ============================================================================
|
|
8090
8104
|
|
|
8091
|
-
type WorkflowRunStepRow = {
|
|
8092
|
-
id: string;
|
|
8093
|
-
runId: string;
|
|
8094
|
-
nodeId: string;
|
|
8095
|
-
nodeType: string;
|
|
8096
|
-
status: string;
|
|
8097
|
-
input: string | null;
|
|
8098
|
-
output: string | null;
|
|
8099
|
-
/** Sealed exact `output` (migration 201). */
|
|
8100
|
-
output_replay: string | null;
|
|
8101
|
-
error: string | null;
|
|
8102
|
-
startedAt: string;
|
|
8103
|
-
finishedAt: string | null;
|
|
8104
|
-
retryCount: number;
|
|
8105
|
-
maxRetries: number;
|
|
8106
|
-
nextRetryAt: string | null;
|
|
8107
|
-
idempotencyKey: string | null;
|
|
8108
|
-
diagnostics: string | null;
|
|
8109
|
-
nextPort: string | null;
|
|
8110
|
-
};
|
|
8111
|
-
|
|
8112
|
-
/** `view` picks the `output` copy, as in `rowToWorkflowRun`. */
|
|
8113
|
-
function rowToWorkflowRunStep(
|
|
8114
|
-
row: WorkflowRunStepRow,
|
|
8115
|
-
view: WorkflowPayloadView = "replay",
|
|
8116
|
-
): WorkflowRunStep {
|
|
8117
|
-
const step: WorkflowRunStep = {
|
|
8118
|
-
id: row.id,
|
|
8119
|
-
runId: row.runId,
|
|
8120
|
-
nodeId: row.nodeId,
|
|
8121
|
-
nodeType: row.nodeType,
|
|
8122
|
-
status: row.status as WorkflowRunStepStatus,
|
|
8123
|
-
input: row.input ? JSON.parse(row.input) : undefined,
|
|
8124
|
-
output: undefined,
|
|
8125
|
-
error: row.error ?? undefined,
|
|
8126
|
-
startedAt: normalizeDateRequired(row.startedAt),
|
|
8127
|
-
finishedAt: normalizeDate(row.finishedAt) ?? undefined,
|
|
8128
|
-
retryCount: row.retryCount,
|
|
8129
|
-
maxRetries: row.maxRetries,
|
|
8130
|
-
nextRetryAt: normalizeDate(row.nextRetryAt) ?? undefined,
|
|
8131
|
-
idempotencyKey: row.idempotencyKey ?? undefined,
|
|
8132
|
-
diagnostics: row.diagnostics ?? undefined,
|
|
8133
|
-
nextPort: row.nextPort ?? undefined,
|
|
8134
|
-
};
|
|
8135
|
-
return defineWorkflowPayload(step, "output", row.output, row.output_replay, view, {
|
|
8136
|
-
runId: row.runId,
|
|
8137
|
-
target: `the output of step ${row.id} (node ${row.nodeId})`,
|
|
8138
|
-
});
|
|
8139
|
-
}
|
|
8140
|
-
|
|
8141
8105
|
export async function createWorkflowRunStep(data: {
|
|
8142
8106
|
id: string;
|
|
8143
8107
|
runId: string;
|
|
@@ -8251,7 +8215,7 @@ export async function getWorkflowRunStepsByRunId(
|
|
|
8251
8215
|
view: WorkflowPayloadView = "replay",
|
|
8252
8216
|
): Promise<WorkflowRunStep[]> {
|
|
8253
8217
|
const rows = await getDbClient().query<WorkflowRunStepRow>(
|
|
8254
|
-
"SELECT * FROM workflow_run_steps WHERE runId = ? ORDER BY startedAt ASC",
|
|
8218
|
+
"SELECT * FROM workflow_run_steps WHERE runId = ? ORDER BY startedAt ASC, rowid ASC",
|
|
8255
8219
|
[runId],
|
|
8256
8220
|
);
|
|
8257
8221
|
return rows.map((row) => rowToWorkflowRunStep(row, view));
|
|
@@ -8367,7 +8331,7 @@ export async function getLatestStepForNode(
|
|
|
8367
8331
|
nodeId: string,
|
|
8368
8332
|
): Promise<WorkflowRunStep | null> {
|
|
8369
8333
|
const row = await getDbClient().get<WorkflowRunStepRow>(
|
|
8370
|
-
"SELECT * FROM workflow_run_steps WHERE runId = ? AND nodeId = ? ORDER BY startedAt DESC LIMIT 1",
|
|
8334
|
+
"SELECT * FROM workflow_run_steps WHERE runId = ? AND nodeId = ? ORDER BY startedAt DESC, rowid DESC LIMIT 1",
|
|
8371
8335
|
[runId, nodeId],
|
|
8372
8336
|
);
|
|
8373
8337
|
return row ? rowToWorkflowRunStep(row) : null;
|
|
@@ -9787,15 +9751,29 @@ export async function createApprovalRequest(data: {
|
|
|
9787
9751
|
const row = await getDbClient().transaction(async () => {
|
|
9788
9752
|
let status: ApprovalRequest["status"] = "pending";
|
|
9789
9753
|
let resolutionReason: string | null = null;
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9754
|
+
// A request linked to an existing run, with or without a step, is born
|
|
9755
|
+
// cancelled unless the run is live and its tree is not cancelled: a
|
|
9756
|
+
// pending request in a cancelled tree would be open work no cancel may
|
|
9757
|
+
// leave behind. A missing run is refused only on the workflow (HITL) path.
|
|
9758
|
+
const actionable = data.requireActionableWorkflow && data.workflowRunStepId;
|
|
9759
|
+
const run = data.workflowRunId ? await getWorkflowRun(data.workflowRunId, "display") : null;
|
|
9760
|
+
if (data.workflowRunId && (run || actionable)) {
|
|
9761
|
+
const step = actionable ? await getWorkflowRunStep(data.workflowRunStepId!) : undefined;
|
|
9793
9762
|
if (!run || (run.status !== "running" && run.status !== "waiting")) {
|
|
9794
9763
|
status = "cancelled";
|
|
9795
9764
|
resolutionReason = run?.error ?? `Workflow run is ${run?.status ?? "missing"}`;
|
|
9796
|
-
} else if (
|
|
9765
|
+
} else if (
|
|
9766
|
+
step !== undefined &&
|
|
9767
|
+
(!step || step.runId !== run.id || step.status !== "running")
|
|
9768
|
+
) {
|
|
9797
9769
|
status = "cancelled";
|
|
9798
9770
|
resolutionReason = `Human-in-the-loop step is ${step?.status ?? "missing"}`;
|
|
9771
|
+
} else {
|
|
9772
|
+
const blocked = await getRunLineageBlock(run.id);
|
|
9773
|
+
if (blocked) {
|
|
9774
|
+
status = "cancelled";
|
|
9775
|
+
resolutionReason = blocked;
|
|
9776
|
+
}
|
|
9799
9777
|
}
|
|
9800
9778
|
}
|
|
9801
9779
|
|
|
@@ -11695,6 +11673,8 @@ export interface ApiKeyStatus {
|
|
|
11695
11673
|
/** Auth failures in a row since the last success or clear. */
|
|
11696
11674
|
consecutiveAuthFailures: number;
|
|
11697
11675
|
lastAuthFailureAt: string | null;
|
|
11676
|
+
lastValidationError: string | null;
|
|
11677
|
+
lastValidationFailedAt: string | null;
|
|
11698
11678
|
createdAt: string;
|
|
11699
11679
|
updatedAt: string;
|
|
11700
11680
|
}
|
|
@@ -11720,6 +11700,7 @@ function rowToApiKeyStatus(row: ApiKeyStatusRow): ApiKeyStatus {
|
|
|
11720
11700
|
|
|
11721
11701
|
export interface AvailableKeyIndicesResult {
|
|
11722
11702
|
availableIndices: number[];
|
|
11703
|
+
rejectedIndices: number[];
|
|
11723
11704
|
/** Indices excluded only by an active model-scoped window block (not key-wide). */
|
|
11724
11705
|
modelBlockedIndices: number[];
|
|
11725
11706
|
/** ISO of the earliest resetsAt among modelBlockedIndices, or null when none. */
|
|
@@ -11768,8 +11749,9 @@ export async function getAvailableKeyIndices(
|
|
|
11768
11749
|
rateLimitWindows: string | null;
|
|
11769
11750
|
plan: string | null;
|
|
11770
11751
|
authFailureSeq: number;
|
|
11752
|
+
lastValidationFailedAt: string | null;
|
|
11771
11753
|
}>(
|
|
11772
|
-
`SELECT keyIndex, status, rateLimitWindows, plan, authFailureSeq FROM api_key_status
|
|
11754
|
+
`SELECT keyIndex, status, rateLimitWindows, plan, authFailureSeq, lastValidationFailedAt FROM api_key_status
|
|
11773
11755
|
WHERE keyType = ? AND scope = ? AND scopeId = ?`,
|
|
11774
11756
|
[keyType, scope, effectiveScopeId],
|
|
11775
11757
|
);
|
|
@@ -11777,6 +11759,12 @@ export async function getAvailableKeyIndices(
|
|
|
11777
11759
|
const blockedIndices = new Set(
|
|
11778
11760
|
rows.filter((r) => r.status === "rate_limited").map((r) => r.keyIndex),
|
|
11779
11761
|
);
|
|
11762
|
+
const rejectedIndices = [
|
|
11763
|
+
...new Set(
|
|
11764
|
+
rows.filter((row) => row.lastValidationFailedAt !== null).map((row) => row.keyIndex),
|
|
11765
|
+
),
|
|
11766
|
+
];
|
|
11767
|
+
for (const index of rejectedIndices) blockedIndices.add(index);
|
|
11780
11768
|
|
|
11781
11769
|
const modelBlockedIndices: number[] = [];
|
|
11782
11770
|
let earliestModelResetsAtSec: number | undefined;
|
|
@@ -11819,6 +11807,7 @@ export async function getAvailableKeyIndices(
|
|
|
11819
11807
|
|
|
11820
11808
|
return {
|
|
11821
11809
|
availableIndices,
|
|
11810
|
+
rejectedIndices,
|
|
11822
11811
|
modelBlockedIndices,
|
|
11823
11812
|
seatBlockedIndices,
|
|
11824
11813
|
earliestModelResetAt:
|
|
@@ -12892,7 +12881,8 @@ export async function listTaskTemplates(opts?: {
|
|
|
12892
12881
|
/**
|
|
12893
12882
|
* Walk the chain rooted at `rootTaskId`, ordered by `createdAt` (root first; `rowid` breaks
|
|
12894
12883
|
* ties as idx_agent_tasks_created did). `CROSS JOIN` keeps the chain as the outer loop: with
|
|
12895
|
-
* a plain JOIN, SQLite scanned all of agent_tasks to skip the sort.
|
|
12884
|
+
* a plain JOIN, SQLite scanned all of agent_tasks to skip the sort. Each task carries its
|
|
12885
|
+
* `totalCostUsd`, so the session header can total the whole chain, not only the root.
|
|
12896
12886
|
*/
|
|
12897
12887
|
export async function getRootTaskChain(rootTaskId: string): Promise<AgentTask[]> {
|
|
12898
12888
|
const rows = await getDbClient().query<AgentTaskRow>(
|
|
@@ -12902,7 +12892,9 @@ export async function getRootTaskChain(rootTaskId: string): Promise<AgentTask[]>
|
|
|
12902
12892
|
SELECT t.id FROM agent_tasks t
|
|
12903
12893
|
JOIN chain c ON t.parentTaskId = c.id
|
|
12904
12894
|
)
|
|
12905
|
-
SELECT t
|
|
12895
|
+
SELECT t.*,
|
|
12896
|
+
(SELECT SUM(totalCostUsd) FROM session_costs WHERE session_costs.taskId = t.id) AS totalCostUsd
|
|
12897
|
+
FROM chain
|
|
12906
12898
|
CROSS JOIN agent_tasks t ON t.id = chain.id
|
|
12907
12899
|
ORDER BY t.createdAt, t.rowid`,
|
|
12908
12900
|
[rootTaskId],
|
|
@@ -12947,6 +12939,7 @@ export async function listRecentSessions(
|
|
|
12947
12939
|
opts: ListRecentSessionsOpts = {},
|
|
12948
12940
|
): Promise<SessionListItem[] | SessionListItemSummary[]> {
|
|
12949
12941
|
const query = sessionSummaryQuery(opts);
|
|
12942
|
+
const threadRoots = threadRootsSql();
|
|
12950
12943
|
const rootRows = await getDbClient().query<
|
|
12951
12944
|
AgentTaskRow & {
|
|
12952
12945
|
__chainCount: number;
|
|
@@ -12955,15 +12948,17 @@ export async function listRecentSessions(
|
|
|
12955
12948
|
__readState: SessionReadState | null;
|
|
12956
12949
|
__snoozeUntil: string | null;
|
|
12957
12950
|
__needsYou: number;
|
|
12951
|
+
__threadRoots: number;
|
|
12958
12952
|
}
|
|
12959
12953
|
>(
|
|
12960
12954
|
`SELECT r.*, a.chainCount AS __chainCount, a.lastActivityAt AS __lastActivityAt,
|
|
12961
12955
|
a.latestStatus AS __latestStatus, a.readState AS __readState,
|
|
12962
|
-
a.snoozeUntil AS __snoozeUntil, a.needsYou AS __needsYou
|
|
12956
|
+
a.snoozeUntil AS __snoozeUntil, a.needsYou AS __needsYou,
|
|
12957
|
+
${threadRoots.sql} AS __threadRoots
|
|
12963
12958
|
FROM (${query.sql}) a CROSS JOIN agent_tasks r ON r.id = a.root_id
|
|
12964
12959
|
ORDER BY ${opts.triage === "later" ? "a.snoozeUntil ASC," : ""}
|
|
12965
12960
|
a.lastActivityAt DESC, r.createdAt DESC, r.id DESC LIMIT ? OFFSET ?`,
|
|
12966
|
-
[...query.params, opts.limit ?? 25, opts.offset ?? 0],
|
|
12961
|
+
[...threadRoots.params, ...query.params, opts.limit ?? 25, opts.offset ?? 0],
|
|
12967
12962
|
);
|
|
12968
12963
|
const fields = await sessionPageFields(
|
|
12969
12964
|
rootRows.map((row) => ({
|
|
@@ -12979,7 +12974,7 @@ export async function listRecentSessions(
|
|
|
12979
12974
|
...(row.__readState ? { readState: row.__readState } : {}),
|
|
12980
12975
|
snoozeUntil: row.__snoozeUntil,
|
|
12981
12976
|
needsYou: !!row.__needsYou,
|
|
12982
|
-
groupKey:
|
|
12977
|
+
groupKey: sessionThreadGroupKey(row.key, row.__threadRoots),
|
|
12983
12978
|
...fields.get(row.id),
|
|
12984
12979
|
}));
|
|
12985
12980
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
+
import { selectCredential } from "../../../utils/credentials";
|
|
2
3
|
import { getOpenRouterAttributionHeaders } from "../../../utils/openrouter-base-url";
|
|
3
4
|
import { DEFAULT_EMBEDDING_MODEL, EMBEDDING_DIMENSIONS } from "../constants";
|
|
4
5
|
import type { EmbeddingProvider } from "../types";
|
|
@@ -46,7 +47,10 @@ export class OpenAIEmbeddingProvider implements EmbeddingProvider {
|
|
|
46
47
|
private readonly apiKey: string | undefined;
|
|
47
48
|
|
|
48
49
|
constructor(config?: OpenAIEmbeddingConfig) {
|
|
49
|
-
|
|
50
|
+
const apiKey = config?.apiKey ?? process.env.EMBEDDING_API_KEY ?? process.env.OPENAI_API_KEY;
|
|
51
|
+
this.apiKey = apiKey
|
|
52
|
+
? selectCredential(apiKey, undefined, "EMBEDDING_API_KEY").selected
|
|
53
|
+
: undefined;
|
|
50
54
|
|
|
51
55
|
this.model = config?.model ?? process.env.EMBEDDING_MODEL ?? "text-embedding-3-small";
|
|
52
56
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- Idempotency-Key records for POST /api/workflows and POST /api/workflows/{id}/trigger.
|
|
2
|
+
--
|
|
3
|
+
-- One row is one operation the server accepted under a client key. It commits
|
|
4
|
+
-- in the same transaction as the workflow (create) or the run and its initial
|
|
5
|
+
-- state (trigger), so a retry after a lost response, a restart or a concurrent
|
|
6
|
+
-- duplicate finds it and gets the original result instead of a second
|
|
7
|
+
-- workflow or run.
|
|
8
|
+
--
|
|
9
|
+
-- The scope is (principal, operation, targetId, keyHash): the caller's stable
|
|
10
|
+
-- identity (never the bearer value), the operation, the triggered workflow id
|
|
11
|
+
-- ('' for create) and a SHA-256 of the client key. requestFingerprint is a
|
|
12
|
+
-- SHA-256 of the canonical request; a different request under the same key is
|
|
13
|
+
-- a conflict. responseBody is the original response, sealed (sealJson). When
|
|
14
|
+
-- the workflow is deleted, responseBody is cleared and resourceDeletedAt set:
|
|
15
|
+
-- the key stays taken and is never accepted again.
|
|
16
|
+
--
|
|
17
|
+
-- No FK to workflows: a row outlives the workflow as that tombstone.
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS workflow_idempotency_keys (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
principal TEXT NOT NULL,
|
|
22
|
+
operation TEXT NOT NULL CHECK (operation IN ('workflow.create', 'workflow.trigger')),
|
|
23
|
+
targetId TEXT NOT NULL DEFAULT '',
|
|
24
|
+
keyHash TEXT NOT NULL,
|
|
25
|
+
requestFingerprint TEXT NOT NULL,
|
|
26
|
+
workflowId TEXT NOT NULL,
|
|
27
|
+
runId TEXT,
|
|
28
|
+
responseStatus INTEGER NOT NULL,
|
|
29
|
+
responseBody TEXT,
|
|
30
|
+
resourceDeletedAt TEXT,
|
|
31
|
+
createdAt TEXT NOT NULL,
|
|
32
|
+
created_by TEXT,
|
|
33
|
+
updated_by TEXT
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_idempotency_keys_scope
|
|
37
|
+
ON workflow_idempotency_keys(principal, operation, targetId, keyHash);
|
|
38
|
+
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_idempotency_keys_workflowId
|
|
40
|
+
ON workflow_idempotency_keys(workflowId);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
-- Last provider rejection of a pooled key by a worker live test (HTTP 401).
|
|
2
|
+
-- A key with lastValidationFailedAt set is left out of /api/keys/available.
|
|
3
|
+
ALTER TABLE api_key_status ADD COLUMN lastValidationError TEXT;
|
|
4
|
+
ALTER TABLE api_key_status ADD COLUMN lastValidationFailedAt TEXT;
|
package/src/be/onboarding.ts
CHANGED
|
@@ -130,6 +130,10 @@ export const OnboardingSignalsSchema = z.object({
|
|
|
130
130
|
state: z.enum(["unverified", "configured", "verified"]),
|
|
131
131
|
workers: z.number().int().nonnegative(),
|
|
132
132
|
verifiedWorkers: z.number().int().nonnegative(),
|
|
133
|
+
/** The latest live test failed: its error. */
|
|
134
|
+
error: z.string().nullable(),
|
|
135
|
+
/** The latest live test passed, but some pool keys failed: names them. */
|
|
136
|
+
warning: z.string().nullable(),
|
|
133
137
|
}),
|
|
134
138
|
),
|
|
135
139
|
embeddings: z.object({
|
|
@@ -250,7 +250,7 @@ export interface SwarmSdk {
|
|
|
250
250
|
workflow_list(args?: { enabled?: boolean; includeFull?: boolean; consecutiveErrorsMin?: number; lastRunStatus?: "running" | "waiting" | "completed" | "failed" | "skipped" | "cancelled" }): Promise<unknown>;
|
|
251
251
|
workflow_get(args: { id: string }): Promise<unknown>;
|
|
252
252
|
workflow_listRuns(args: { workflowId: string; status?: "running" | "waiting" | "completed" | "failed" | "skipped" | "cancelled"; limit?: number; offset?: number }): Promise<unknown>;
|
|
253
|
-
workflow_getRun(args: { id: string }): Promise<unknown>;
|
|
253
|
+
workflow_getRun(args: { id: string; fields?: "full" | "slim" }): Promise<unknown>;
|
|
254
254
|
// --- prompt templates ---
|
|
255
255
|
prompt_list(args?: { eventType?: string; scope?: "global" | "agent" | "repo"; scopeId?: string; isDefault?: boolean }): Promise<unknown>;
|
|
256
256
|
prompt_get(args: { id: string }): Promise<unknown>;
|
package/src/be/sealed-json.ts
CHANGED
|
@@ -30,6 +30,7 @@ export const SEALED_REPLAY_COLUMNS: readonly { table: string; column: string }[]
|
|
|
30
30
|
{ table: "workflow_run_steps", column: "output_replay" },
|
|
31
31
|
{ table: "workflow_runs", column: "context_replay" },
|
|
32
32
|
{ table: "approval_requests", column: "responses" },
|
|
33
|
+
{ table: "workflow_idempotency_keys", column: "responseBody" },
|
|
33
34
|
];
|
|
34
35
|
|
|
35
36
|
/** SQL `EXISTS` arms matching a sealed value in each `SEALED_REPLAY_COLUMNS` entry. */
|
|
@@ -574,14 +574,14 @@ export default async function compoundInsights(args: any, ctx: any) {
|
|
|
574
574
|
const rows = rowsToObjects(
|
|
575
575
|
await ctx.swarm.db_query({
|
|
576
576
|
sql: `WITH raw AS (
|
|
577
|
-
SELECT sessionId, iteration, lineNumber, content,
|
|
577
|
+
SELECT rowid AS seq, sessionId, iteration, lineNumber, content,
|
|
578
578
|
json_extract(content, '$.tool_name') as jsonToolName
|
|
579
579
|
FROM session_logs
|
|
580
580
|
WHERE createdAt > ${w}
|
|
581
581
|
AND (content LIKE '%"type":"tool_use"%' OR json_extract(content, '$.tool_name') IS NOT NULL)
|
|
582
582
|
)
|
|
583
583
|
SELECT sessionId, iteration, lineNumber, jsonToolName, content
|
|
584
|
-
FROM raw ORDER BY sessionId, iteration,
|
|
584
|
+
FROM raw ORDER BY sessionId, iteration, seq LIMIT 100`,
|
|
585
585
|
}),
|
|
586
586
|
);
|
|
587
587
|
const bySession = new Map<string, string[]>();
|
|
@@ -574,14 +574,14 @@ export default async function compoundInsights(args: any, ctx: any) {
|
|
|
574
574
|
const rows = rowsToObjects(
|
|
575
575
|
await ctx.swarm.db_query({
|
|
576
576
|
sql: `WITH raw AS (
|
|
577
|
-
SELECT sessionId, iteration, lineNumber, content,
|
|
577
|
+
SELECT rowid AS seq, sessionId, iteration, lineNumber, content,
|
|
578
578
|
json_extract(content, '$.tool_name') as jsonToolName
|
|
579
579
|
FROM session_logs
|
|
580
580
|
WHERE createdAt > ${w}
|
|
581
581
|
AND (content LIKE '%"type":"tool_use"%' OR json_extract(content, '$.tool_name') IS NOT NULL)
|
|
582
582
|
)
|
|
583
583
|
SELECT sessionId, iteration, lineNumber, jsonToolName, content
|
|
584
|
-
FROM raw ORDER BY sessionId, iteration,
|
|
584
|
+
FROM raw ORDER BY sessionId, iteration, seq LIMIT 100`,
|
|
585
585
|
}),
|
|
586
586
|
);
|
|
587
587
|
const bySession = new Map<string, string[]>();
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"delegate-work": [
|
|
19
19
|
{
|
|
20
20
|
"path": "scripts/codex-exec.sh",
|
|
21
|
-
"content": "#!/usr/bin/env bash\n#\n# codex-exec.sh — invoke `codex exec` (non-interactive) for delegated\n# implementation work. This is the SINGLE SOURCE OF TRUTH for the invocation\n# flags. The delegate-work skill calls only this script; its routing matrix\n# decides WHICH gpt-
|
|
21
|
+
"content": "#!/usr/bin/env bash\n#\n# codex-exec.sh — invoke `codex exec` (non-interactive) for delegated\n# implementation work. This is the SINGLE SOURCE OF TRUTH for the invocation\n# flags. The delegate-work skill calls only this script; its routing matrix\n# decides WHICH gpt-6 variant (-m) and effort (-e) each task gets:\n# gpt-6-luna = trivial/mechanical gpt-6.1-sol = default (medium) to hard (high/xhigh)\n# gpt-6-astra = escalation only effort: medium|high|xhigh|max (never ultra)\n#\n# Usage:\n# codex-exec.sh [-m <model>] [-e <effort>] -C <workdir> -o <last-message-file> [-l <log-file>] \"PROMPT\"\n# printf '%s' \"$PROMPT\" | codex-exec.sh -C <workdir> -o <file> # prompt via stdin (preferred)\n#\n# Notes:\n# * -C sets codex's working root (the git worktree, for parallel isolation).\n# * -o writes codex's final message (its report) to a file you can read back.\n# * Reads the prompt from stdin when no positional PROMPT is given.\n# * In `exec` mode approvals are already \"never\", so nothing hangs waiting for\n# a human. The sandbox mode below bounds what codex may WRITE.\n#\n# Sandbox default: `workspace-write` — codex may freely edit files inside its\n# working root (the worktree) and read elsewhere on disk (so it can read the\n# plan by absolute path), but cannot write outside the workspace. This keeps\n# parallel worktree runs from clobbering each other or the main tree.\n#\n# Env overrides (flags -m/-e take precedence):\n# CODEX_MODEL default: gpt-6.1-sol gpt-6.1-sol | gpt-6-astra | gpt-6-luna\n# CODEX_EFFORT default: high reasoning effort (never \"fast\"/low)\n# CODEX_SANDBOX default: workspace-write (passed to codex's -s option)\n# CODEX_BYPASS set to 1 to use --dangerously-bypass-approvals-and-sandbox\n# (fully unsandboxed — opt in only when a phase must write\n# outside its worktree; overrides CODEX_SANDBOX)\nset -euo pipefail\n\nWORKDIR=\".\"\nOUTFILE=\"\"\nLOGFILE=\"\"\nPROMPT=\"\"\nMODEL_FLAG=\"\"\nEFFORT_FLAG=\"\"\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n -m|--model) MODEL_FLAG=\"$2\"; shift 2 ;;\n -e|--effort) EFFORT_FLAG=\"$2\"; shift 2 ;;\n -C|--cd) WORKDIR=\"$2\"; shift 2 ;;\n -o|--out) OUTFILE=\"$2\"; shift 2 ;;\n -l|--log) LOGFILE=\"$2\"; shift 2 ;;\n --) shift; PROMPT=\"${1:-}\"; break ;;\n -*) echo \"codex-exec.sh: unknown flag: $1\" >&2; exit 2 ;;\n *) PROMPT=\"$1\"; shift ;;\n esac\ndone\n\nMODEL=\"${MODEL_FLAG:-${CODEX_MODEL:-gpt-6.1-sol}}\"\nEFFORT=\"${EFFORT_FLAG:-${CODEX_EFFORT:-high}}\"\nSANDBOX=\"${CODEX_SANDBOX:-workspace-write}\"\n\nargs=( exec\n -m \"$MODEL\"\n -c \"model_reasoning_effort=\\\"$EFFORT\\\"\"\n -C \"$WORKDIR\"\n)\nif [[ \"${CODEX_BYPASS:-0}\" == \"1\" ]]; then\n args+=( --dangerously-bypass-approvals-and-sandbox )\nelse\n args+=( -s \"$SANDBOX\" )\nfi\n[[ -n \"$OUTFILE\" ]] && args+=( -o \"$OUTFILE\" )\n\n# Prompt source: positional arg if present, otherwise stdin (`-`).\nif [[ -n \"$PROMPT\" ]]; then\n set -- \"$PROMPT\"\nelse\n set -- \"-\"\nfi\n\nif [[ -n \"$LOGFILE\" ]]; then\n codex \"${args[@]}\" \"$@\" 2>&1 | tee \"$LOGFILE\"\nelse\n codex \"${args[@]}\" \"$@\"\nfi\n"
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"design-docs": [
|