@desplega.ai/agent-swarm 2.4.5 → 2.5.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 +4 -2
- package/dist/{acp-adapter-2wdkktv6.js → acp-adapter-11gp67nr.js} +8 -6
- package/dist/{actions-c40ebcm4.js → actions-8p2kze8j.js} +23 -21
- package/dist/{amp-adapter-wb67m95z.js → amp-adapter-z4qvhacj.js} +2 -2
- package/dist/{anthropic-messages-g6pqmqk4.js → anthropic-messages-txs190dd.js} +17 -20
- package/dist/{app-353vre8g.js → app-0qp0a2gk.js} +3 -3
- package/dist/{assistant-sj1njh23.js → assistant-jedd3ktm.js} +24 -22
- package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
- package/dist/{boot-reembed-qdkvxeem.js → boot-reembed-4xwq5tg0.js} +1 -1
- package/dist/{boot-reembed-b9c3az3c.js → boot-reembed-n4wq5dd2.js} +1 -1
- package/dist/{boot-scrub-sweep-m3wh8eks.js → boot-scrub-sweep-69h90xcq.js} +4 -4
- package/dist/{boot-seeds-j2273s54.js → boot-seeds-3vn0m9sg.js} +4 -4
- package/dist/{claude-adapter-m7q0a085.js → claude-adapter-221mvad5.js} +8 -6
- package/dist/{claude-managed-adapter-5ptb6tzs.js → claude-managed-adapter-gt6pa35d.js} +2 -2
- package/dist/{claude-managed-setup-smrqk5j5.js → claude-managed-setup-c3hp36ph.js} +4 -4
- package/dist/{claude-sdk-session-38xnz21e.js → claude-sdk-session-8thjsk5e.js} +9012 -8928
- package/dist/{cli-b9fcxxev.js → cli-007cnhm1.js} +50 -4
- package/dist/{cli-j4rqdf2n.js → cli-03vpq45j.js} +2 -2
- package/dist/{cli-dk44dxec.js → cli-0y6f0ckq.js} +1 -1
- package/dist/{cli-kpw04va0.js → cli-0z3vjrpm.js} +1 -1
- package/dist/{cli-94gwyg7m.js → cli-179xcyky.js} +9 -9
- package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
- package/dist/{cli-4zfqgjc5.js → cli-1pr672hz.js} +2 -2
- package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
- package/dist/{cli-43x64hv3.js → cli-36j4jnk3.js} +4 -4
- package/dist/{cli-k8g16gz3.js → cli-3qv8naq8.js} +115 -119
- package/dist/cli-3zwye9sn.js +1193 -0
- package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
- package/dist/{cli-v8fjakwf.js → cli-4w24f7z3.js} +1 -1
- package/dist/{cli-n72rg53p.js → cli-5kzk3472.js} +812 -418
- package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
- package/dist/{cli-j99azg3g.js → cli-5rvg1ddk.js} +5 -5
- package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
- package/dist/{cli-848hxdwj.js → cli-6rg2jn2y.js} +2 -1
- package/dist/{cli-fv5hepyy.js → cli-7bwtc6yx.js} +3 -3
- package/dist/{cli-ms85309d.js → cli-7g40g8hq.js} +11 -11
- package/dist/{cli-xpa64rek.js → cli-92mqenkc.js} +2362 -159
- package/dist/{cli-018r4jq6.js → cli-9ce2xw98.js} +8 -8
- package/dist/{cli-1syn2xy1.js → cli-bgdtv62r.js} +32 -18
- package/dist/{cli-wxbn3yfx.js → cli-cz5nmdxt.js} +2 -2
- package/dist/{cli-wt645v7q.js → cli-dabehxhp.js} +1 -1
- package/dist/{cli-vfha21c9.js → cli-e5bxnjps.js} +2 -2
- package/dist/{cli-wt0jf9hm.js → cli-fcc5qe3f.js} +553 -193
- package/dist/{cli-ftc1g5tj.js → cli-fes51ya2.js} +3 -3
- package/dist/{cli-3a45zcgm.js → cli-ftmq4nvk.js} +2 -2
- package/dist/{cli-37j04k05.js → cli-fy1jyyym.js} +13 -13
- package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
- package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
- package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
- package/dist/{cli-g35m2xwm.js → cli-j1eghqfm.js} +2 -2
- package/dist/{cli-qfxc84gh.js → cli-jpxsrxcb.js} +1 -1
- package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
- package/dist/{cli-p14m2cnp.js → cli-mbfj11fq.js} +1 -1
- package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
- package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
- package/dist/{cli-f01h25yt.js → cli-n6kmqngw.js} +2 -2
- package/dist/{cli-v0yrfmdh.js → cli-nnvjb17s.js} +3 -3
- package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
- package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
- package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
- package/dist/cli-pkaqk57w.js +128 -0
- package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
- package/dist/{cli-9yqgm9nd.js → cli-r25qpaxt.js} +161 -63
- package/dist/{cli-eww120g8.js → cli-rh5smt8t.js} +18 -4
- package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
- package/dist/{cli-a92r1127.js → cli-s4sntwt4.js} +2 -2
- package/dist/{cli-be2161h1.js → cli-segs7hx9.js} +6 -6
- package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
- package/dist/{cli-z7d29rw9.js → cli-sy8f9705.js} +4 -4
- package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
- package/dist/{cli-st8aw1m6.js → cli-we0ra057.js} +4 -4
- package/dist/{cli-7c9qs530.js → cli-x21dqn18.js} +5 -5
- package/dist/{cli-1sp861s4.js → cli-x6vf4sad.js} +11 -11
- package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
- package/dist/{cli-tw4p90jb.js → cli-xawhpgc9.js} +5 -5
- package/dist/{cli-f0g3pgvf.js → cli-xd4eqtr2.js} +2 -2
- package/dist/{cli-1f3qzw6y.js → cli-xt768r5m.js} +2 -2
- package/dist/{cli-cxxe61f6.js → cli-y4x8ww6s.js} +2 -2
- package/dist/{cli-bnes4z6b.js → cli-y9jvxfhk.js} +3 -3
- package/dist/{cli-qwhy2qma.js → cli-z63a269p.js} +2 -2
- package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -5
- package/dist/cli.js +29 -27
- package/dist/{cloudflare-workers-ai-system-one-ch2wxfcp.js → cloudflare-workers-ai-system-one-43v9qkjk.js} +7 -2
- package/dist/{codex-adapter-tn6k5mkg.js → codex-adapter-tcg1q3jk.js} +6 -4
- package/dist/{codex-login-m819c41r.js → codex-login-rn7c5gxt.js} +1 -1
- package/dist/{codex-session-runner-7vjt7jbw.js → codex-session-runner-xfx4wd9x.js} +7 -5
- package/dist/{commands-t7rz9146.js → commands-ew83nj70.js} +2 -2
- package/dist/{controller-m2jasma5.js → controller-gnq1k1mf.js} +4 -4
- package/dist/{controllers-connect-9ftpex99.js → controllers-connect-tw1dan9r.js} +25 -23
- package/dist/{cursor-adapter-mjv79e4z.js → cursor-adapter-yq5xgfcg.js} +1 -1
- package/dist/{db-6sfrn9g3.js → db-7gbc53fd.js} +14 -2
- package/dist/{db-rn673r06.js → db-t86xrnes.js} +3 -3
- package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
- package/dist/{dispatcher-c155xz0p.js → dispatcher-64bdyhps.js} +22 -20
- package/dist/{docker-fkgtr75t.js → docker-nfy2gc8t.js} +2 -2
- package/dist/{dsh-adapter-3mmszc1x.js → dsh-adapter-tvhc4k2d.js} +1 -1
- package/dist/{e2b-16d6ch39.js → e2b-9gkdhm3c.js} +2 -2
- package/dist/{e2b-zn0b4w5w.js → e2b-cjtf8k1z.js} +2 -2
- package/dist/{easter-egg-3d-5cgynaja.js → easter-egg-3d-e4qv8dxj.js} +1 -1
- package/dist/{event-bus-9vpk8gmq.js → event-bus-3z78ep5n.js} +1 -1
- package/dist/{execute-t4e6m3rw.js → execute-0xpz8950.js} +85 -23
- package/dist/{external-channel-35k6tkv8.js → external-channel-e9nw24zv.js} +2 -2
- package/dist/{google-generative-ai-bmq8gkf3.js → google-generative-ai-mk9vcpe1.js} +15 -15
- package/dist/{google-vertex-b1rvp52s.js → google-vertex-q580kz8k.js} +20 -20
- package/dist/{grok-adapter-tfrq7tg1.js → grok-adapter-v82srhrx.js} +9 -7
- package/dist/handlers-c9ajzhbn.js +41 -0
- package/dist/{heartbeat-dyg4npkp.js → heartbeat-2vqs1319.js} +25 -23
- package/dist/{hook-x26b31bg.js → hook-01nk13wx.js} +7 -5
- package/dist/{hook-drspbwpe.js → hook-jzpheegg.js} +9 -7
- package/dist/{http-pk972xyw.js → http-fc1k6ec8.js} +544 -76
- package/dist/index-07ef7nkm.js +42 -0
- package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
- package/dist/index-7yts8n9s.js +43 -0
- package/dist/index-q3t40ryv.js +46 -0
- package/dist/{index-arytgj5q.js → index-sepja052.js} +1 -1
- package/dist/{index-jwxkkex2.js → index-zdycv3ja.js} +13 -11
- package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
- package/dist/{keepalive-7yrng7px.js → keepalive-5nh2rhmr.js} +4 -4
- package/dist/lead-aayq64jn.js +79 -0
- package/dist/{llama-cpp-classify-vv43gswy.js → llama-cpp-classify-ee7vmd7q.js} +4 -1
- package/dist/{maintenance-e6cemdqt.js → maintenance-hjhzdt3k.js} +1 -1
- package/dist/{mistral-conversations-1medfwv7.js → mistral-conversations-sd0xf1tn.js} +13 -13
- package/dist/{node-de6akczr.js → node-jzjj7r9x.js} +1 -1
- package/dist/{oauth-refresh-sweep-yw3xdbcj.js → oauth-refresh-sweep-y3n1knmd.js} +3 -3
- package/dist/{onboard-0a9y5yrc.js → onboard-1zq3m7db.js} +2 -2
- package/dist/{openai-codex-responses-de9pvs4d.js → openai-codex-responses-79s8xnbh.js} +29 -23
- package/dist/{openai-completions-mtqge3nf.js → openai-completions-tdbyts0x.js} +21 -20
- package/dist/{openai-decisions-ygk4kkxd.js → openai-decisions-bqhnjyfz.js} +2 -1
- package/dist/{openai-responses-dkyng71g.js → openai-responses-dm3t5vqp.js} +26 -17
- package/dist/{opencode-adapter-x4tqzhkh.js → opencode-adapter-e56086m1.js} +7 -5
- package/dist/{openrouter-images-wvv7camj.js → openrouter-images-ssttr1y4.js} +6 -3
- package/dist/{otel-impl-trjpkfb7.js → otel-impl-h9yyza47.js} +2 -2
- package/dist/{pi-messages-nhh1pkz2.js → pi-messages-3nf8bq1a.js} +6 -4
- package/dist/{pi-mono-adapter-mcfkn9vf.js → pi-mono-adapter-tzps8f38.js} +9 -37
- package/dist/{pricing-refresh-d2b5my0y.js → pricing-refresh-nevhat8h.js} +3 -3
- package/dist/{rbac-roles-nxh5ahwk.js → rbac-roles-4y6ngvzq.js} +1 -1
- package/dist/{rbac-roles-hey3yv9d.js → rbac-roles-exbg8xb6.js} +2 -2
- package/dist/{render-v2-rr3p2atg.js → render-v2-cfsh13z3.js} +3 -3
- package/dist/{resume-2efkf1s1.js → resume-5s2t0dbs.js} +10 -8
- package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
- package/dist/{session-access-s2mttxpw.js → session-access-dnbyp3cn.js} +6 -4
- package/dist/{setup-vypma5yt.js → setup-1wj1y77j.js} +1 -1
- package/dist/{typesafe-system-one-2hgpayzy.js → typesafe-system-one-bre38hvs.js} +4 -2
- package/dist/{virtual-modules-4r3zkc20.js → virtual-modules-mnfbh5mr.js} +8 -2
- package/dist/{work-objects-rvhckdkp.js → work-objects-7mg6216g.js} +25 -23
- package/dist/worker-nwb789mg.js +79 -0
- package/dist/{x-y45mthwn.js → x-pbpezr0s.js} +2 -2
- package/openapi.json +785 -5
- package/package.json +9 -9
- package/src/assets/key.ts +17 -0
- package/src/azure-devops/handlers.ts +1 -1
- package/src/be/db/approvals.ts +18 -0
- package/src/be/db/session-moves.ts +164 -0
- package/src/be/db/session-tree.ts +384 -0
- package/src/be/db/tasks/read.ts +40 -4
- package/src/be/db/workflow-runs.ts +96 -0
- package/src/be/db.ts +80 -236
- package/src/be/onboarding.ts +3 -0
- package/src/be/skill-sync.ts +43 -2
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/bitbucket/api.ts +81 -0
- package/src/bitbucket/auth.ts +64 -0
- package/src/bitbucket/handlers.ts +434 -0
- package/src/bitbucket/index.ts +28 -0
- package/src/bitbucket/templates.ts +134 -0
- package/src/bitbucket/types.ts +65 -0
- package/src/commands/runner.ts +55 -3
- package/src/e2b/env.ts +1 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +2 -2
- package/src/extensions/post-bridge.ts +1 -0
- package/src/github/handlers.ts +6 -6
- package/src/gitlab/handlers.ts +5 -5
- package/src/http/assets.ts +14 -2
- package/src/http/core.ts +12 -0
- package/src/http/index.ts +4 -0
- package/src/http/onboarding.ts +1 -0
- package/src/http/sessions.ts +366 -12
- package/src/http/skills.ts +48 -1
- package/src/http/tasks.ts +1 -1
- package/src/http/users.ts +1 -0
- package/src/http/webhooks.ts +141 -0
- package/src/integrations/chat-sdk/adapters.ts +19 -3
- package/src/integrations/chat-sdk/facts.ts +30 -12
- package/src/integrations/chat-sdk/outbound.ts +38 -1
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +5 -53
- package/src/scripts-runtime/types/swarm-extension.d.ts +6 -4
- package/src/slack/handlers.test.ts +158 -0
- package/src/slack/handlers.ts +19 -28
- package/src/tasks/context-key.ts +61 -1
- package/src/tests/bitbucket-auth.test.ts +156 -0
- package/src/tests/bitbucket-handlers.test.ts +425 -0
- package/src/tests/bitbucket-webhook.test.ts +220 -0
- package/src/tests/chat-sdk-inbound.test.ts +39 -0
- package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
- package/src/tests/context-key.test.ts +50 -0
- package/src/tests/core-auth.test.ts +5 -0
- package/src/tests/db-task-read-contract.test.ts +7 -0
- package/src/tests/db-task-write-contract.test.ts +6 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
- package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
- package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
- package/src/tests/generate-mcp-docs.test.ts +101 -0
- package/src/tests/gitlab-handlers.test.ts +3 -3
- package/src/tests/gitlab-vcs-db.test.ts +4 -4
- package/src/tests/integration-disable-flags.test.ts +36 -0
- package/src/tests/mcp-tools.test.ts +1 -1
- package/src/tests/onboarding.test.ts +12 -0
- package/src/tests/pi-codemode.test.ts +8 -2
- package/src/tests/preload-env.test.ts +57 -0
- package/src/tests/preload.ts +21 -0
- package/src/tests/prompt-template-remaining.test.ts +38 -0
- package/src/tests/run-root-coverage.test.ts +39 -0
- package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
- package/src/tests/runner-skills-refresh.test.ts +58 -0
- package/src/tests/secret-scrubber.test.ts +15 -0
- package/src/tests/sessions-move.test.ts +576 -0
- package/src/tests/sessions-tree.test.ts +493 -0
- package/src/tests/skill-files-http.test.ts +50 -0
- package/src/tests/skills-bundle.test.ts +99 -0
- package/src/tests/swarm-config-export-to-env.test.ts +2 -1
- package/src/tests/vcs-bitbucket.test.ts +91 -0
- package/src/tests/vcs-provider-isolation.test.ts +123 -0
- package/src/tests/vcs-provider.test.ts +16 -1
- package/src/tests/vcs-tracking.test.ts +3 -3
- package/src/tests/workflow-foreach-bodies.test.ts +637 -0
- package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
- package/src/tests/workflow-foreach-retry.test.ts +537 -0
- package/src/tests/workflow-foreach.test.ts +44 -23
- package/src/tests/workflow-step-claims.test.ts +6 -6
- package/src/tests/workflow-tla-races.test.ts +2 -2
- package/src/tools/script-delete.ts +1 -1
- package/src/tools/workflows/create-workflow.ts +5 -3
- package/src/types.ts +3 -2
- package/src/utils/config-env-export.ts +1 -0
- package/src/utils/secret-scrubber.ts +4 -0
- package/src/utils/skills-refresh.ts +83 -43
- package/src/vcs/bitbucket.ts +58 -0
- package/src/vcs/index.ts +2 -0
- package/src/vcs/types.ts +2 -2
- package/src/workflows/approval-resolution.ts +4 -1
- package/src/workflows/checkpoint.ts +9 -1
- package/src/workflows/constants.ts +3 -0
- package/src/workflows/definition.ts +48 -17
- package/src/workflows/engine.ts +25 -15
- package/src/workflows/executors/foreach.ts +45 -99
- package/src/workflows/foreach-body.ts +146 -0
- package/src/workflows/foreach-driver.ts +552 -0
- package/src/workflows/foreach-join.ts +206 -7
- package/src/workflows/node-timeout.ts +21 -0
- package/src/workflows/recovery.ts +68 -3
- package/src/workflows/resume.ts +221 -43
- package/src/workflows/retry-poller.ts +39 -24
- package/src/workflows/step-input.ts +59 -0
- package/src/workflows/task-step-routing.ts +114 -56
- package/templates/skills/slack-interaction/content.md +5 -0
- package/templates/skills/work-on-task/SKILL.md +1 -1
- package/templates/skills/work-on-task/content.md +1 -1
- package/dist/cli-9hstj09h.js +0 -2657
- package/dist/cli-yw91rnmw.js +0 -13
- package/dist/handlers-7gw64dxw.js +0 -39
- package/dist/index-bgdyvcnv.js +0 -40
- package/dist/index-gabbcdn2.js +0 -43
- package/dist/index-tfb26zhy.js +0 -41
- package/dist/lead-7e02z839.js +0 -77
- package/dist/worker-5snytpbd.js +0 -77
|
@@ -17,14 +17,40 @@ import {
|
|
|
17
17
|
} from "../types";
|
|
18
18
|
import { checkpointStep, checkpointStepFailure } from "./checkpoint";
|
|
19
19
|
import { getSuccessors } from "./definition";
|
|
20
|
-
import {
|
|
20
|
+
import type { ExecutorRegistry } from "./executors/registry";
|
|
21
|
+
import { type ForeachSettleResult, resolveForeachParent, settleForeachChild } from "./foreach-join";
|
|
21
22
|
|
|
22
|
-
export interface
|
|
23
|
-
/**
|
|
23
|
+
export interface TaskStepRoutingResult {
|
|
24
|
+
/**
|
|
25
|
+
* False when another handler already moved the step out of `waiting` — the
|
|
26
|
+
* caller must not route successors again. The same task terminal event can
|
|
27
|
+
* reach two resume paths (the DB-emitted bus event and a direct emit, or a
|
|
28
|
+
* recovery sweep racing a live event); only the first one may route.
|
|
29
|
+
*/
|
|
24
30
|
claimed: boolean;
|
|
31
|
+
foreachChild: boolean;
|
|
32
|
+
joined: boolean;
|
|
25
33
|
successors: WorkflowNode[];
|
|
34
|
+
/** True when this call failed the run: nothing may route or re-park it. */
|
|
35
|
+
runFailed: boolean;
|
|
26
36
|
}
|
|
27
37
|
|
|
38
|
+
const UNCLAIMED: TaskStepRoutingResult = {
|
|
39
|
+
claimed: false,
|
|
40
|
+
foreachChild: false,
|
|
41
|
+
joined: false,
|
|
42
|
+
successors: [],
|
|
43
|
+
runFailed: false,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Port-routed resume result. `claimed` is false when the step was already
|
|
48
|
+
* claimed or its run is terminal. A foreach child (`foreachChild`) routes
|
|
49
|
+
* nothing unless its settlement closed the join (`joined`), in which case
|
|
50
|
+
* `successors` are the parent's.
|
|
51
|
+
*/
|
|
52
|
+
export type PortStepRoutingResult = TaskStepRoutingResult;
|
|
53
|
+
|
|
28
54
|
/**
|
|
29
55
|
* True while `taskId` is still the task bound to `stepId`. A retry detaches
|
|
30
56
|
* the failed task and the poller binds a fresh one to the same step, so a
|
|
@@ -37,24 +63,41 @@ async function isTaskBoundToStep(taskId: string, stepId: string): Promise<boolea
|
|
|
37
63
|
}
|
|
38
64
|
|
|
39
65
|
/**
|
|
40
|
-
* Atomically fail a waiting step and its run. Returns false when
|
|
41
|
-
* handler already moved the step out of `waiting` — the same task
|
|
42
|
-
* event can reach both the live bus listener and a recovery sweep,
|
|
43
|
-
* blind write here would stomp a run another handler is already
|
|
44
|
-
* With `ownerTaskId`, also
|
|
45
|
-
* bound to the step (a stale snapshot of a step that was since
|
|
66
|
+
* Atomically fail a waiting step and its run. Returns `claimed: false` when
|
|
67
|
+
* another handler already moved the step out of `waiting` — the same task
|
|
68
|
+
* terminal event can reach both the live bus listener and a recovery sweep,
|
|
69
|
+
* and a blind write here would stomp a run another handler is already
|
|
70
|
+
* advancing. With `ownerTaskId`, also unclaimed when that task is no longer
|
|
71
|
+
* the one bound to the step (a stale snapshot of a step that was since
|
|
72
|
+
* redriven).
|
|
73
|
+
*
|
|
74
|
+
* A synthetic foreach child settles `failed` through `settleForeachChild`
|
|
75
|
+
* instead: under `onNodeFailure: "fail"` that fails the run as before; under
|
|
76
|
+
* `"continue"` the item counts as failed and the join may close, so the
|
|
77
|
+
* caller walks `successors` when `joined`.
|
|
46
78
|
*/
|
|
47
79
|
export async function failStepAndRunIfWaiting(
|
|
80
|
+
def: WorkflowDefinition,
|
|
48
81
|
stepId: string,
|
|
49
82
|
runId: string,
|
|
50
83
|
reason: string,
|
|
51
84
|
ownerTaskId?: string,
|
|
52
|
-
|
|
85
|
+
options: { ctx?: Record<string, unknown>; registry?: ExecutorRegistry } = {},
|
|
86
|
+
): Promise<TaskStepRoutingResult> {
|
|
53
87
|
const now = new Date().toISOString();
|
|
54
|
-
return await getDbClient().transaction(async () => {
|
|
88
|
+
return await getDbClient().transaction(async (): Promise<TaskStepRoutingResult> => {
|
|
55
89
|
const current = await getWorkflowRunStep(stepId);
|
|
56
|
-
if (!current || current.status !== "waiting") return
|
|
57
|
-
if (ownerTaskId && !(await isTaskBoundToStep(ownerTaskId, stepId))) return
|
|
90
|
+
if (!current || current.status !== "waiting") return UNCLAIMED;
|
|
91
|
+
if (ownerTaskId && !(await isTaskBoundToStep(ownerTaskId, stepId))) return UNCLAIMED;
|
|
92
|
+
if (resolveForeachParent(def, current.nodeId)) {
|
|
93
|
+
const ctx =
|
|
94
|
+
options.ctx ?? (((await getWorkflowRun(runId))?.context ?? {}) as Record<string, unknown>);
|
|
95
|
+
return toRoutingResult(
|
|
96
|
+
await settleForeachChild(def, runId, stepId, { status: "failed", error: reason }, ctx, {
|
|
97
|
+
registry: options.registry,
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
58
101
|
await updateWorkflowRunStep(stepId, {
|
|
59
102
|
status: "failed",
|
|
60
103
|
error: reason,
|
|
@@ -65,10 +108,20 @@ export async function failStepAndRunIfWaiting(
|
|
|
65
108
|
error: reason,
|
|
66
109
|
finishedAt: now,
|
|
67
110
|
});
|
|
68
|
-
return true;
|
|
111
|
+
return { claimed: true, foreachChild: false, joined: false, successors: [], runFailed: true };
|
|
69
112
|
});
|
|
70
113
|
}
|
|
71
114
|
|
|
115
|
+
function toRoutingResult(settle: ForeachSettleResult): TaskStepRoutingResult {
|
|
116
|
+
return {
|
|
117
|
+
claimed: settle.claimed,
|
|
118
|
+
foreachChild: true,
|
|
119
|
+
joined: settle.joined,
|
|
120
|
+
successors: settle.successors,
|
|
121
|
+
runFailed: settle.runFailed,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
72
125
|
/**
|
|
73
126
|
* Checkpoint a waiting step with a port-based result and resolve its
|
|
74
127
|
* successors. Mirrors `completeTaskStepAndResolveSuccessors`: callers check
|
|
@@ -84,17 +137,41 @@ export async function checkpointPortStepAndResolveSuccessors(
|
|
|
84
137
|
output: unknown,
|
|
85
138
|
nextPort: string,
|
|
86
139
|
ctx: Record<string, unknown>,
|
|
140
|
+
registry?: ExecutorRegistry,
|
|
87
141
|
): Promise<PortStepRoutingResult> {
|
|
88
142
|
return await getDbClient().transaction(async (): Promise<PortStepRoutingResult> => {
|
|
89
143
|
const current = await getWorkflowRunStep(stepId);
|
|
90
|
-
if (!current || current.status !== "waiting") return
|
|
144
|
+
if (!current || current.status !== "waiting") return UNCLAIMED;
|
|
91
145
|
const run = await getWorkflowRun(runId);
|
|
92
146
|
if (!run || (run.status !== "waiting" && run.status !== "running")) {
|
|
93
|
-
return
|
|
147
|
+
return UNCLAIMED;
|
|
148
|
+
}
|
|
149
|
+
// A foreach child's port (approval rejected/timeout, wait event/timeout)
|
|
150
|
+
// is stored for display and still counts as a completed item: the body's
|
|
151
|
+
// ports do not route, the item's consumer reads the output.
|
|
152
|
+
if (resolveForeachParent(def, nodeId)) {
|
|
153
|
+
return toRoutingResult(
|
|
154
|
+
await settleForeachChild(
|
|
155
|
+
def,
|
|
156
|
+
runId,
|
|
157
|
+
stepId,
|
|
158
|
+
{ status: "completed", output, nextPort },
|
|
159
|
+
ctx,
|
|
160
|
+
{
|
|
161
|
+
registry,
|
|
162
|
+
},
|
|
163
|
+
),
|
|
164
|
+
);
|
|
94
165
|
}
|
|
95
166
|
await checkpointStep(runId, stepId, nodeId, { output, nextPort }, ctx);
|
|
96
167
|
await updateWorkflowRun(runId, { status: "running" });
|
|
97
|
-
return {
|
|
168
|
+
return {
|
|
169
|
+
claimed: true,
|
|
170
|
+
foreachChild: false,
|
|
171
|
+
joined: true,
|
|
172
|
+
successors: getSuccessors(def, nodeId, nextPort),
|
|
173
|
+
runFailed: false,
|
|
174
|
+
};
|
|
98
175
|
});
|
|
99
176
|
}
|
|
100
177
|
|
|
@@ -179,26 +256,6 @@ async function isSupersedeCut(taskId: string, reason: string): Promise<boolean>
|
|
|
179
256
|
return task?.failureReason === SUPERSEDED_WORKFLOW_TASK_REASON;
|
|
180
257
|
}
|
|
181
258
|
|
|
182
|
-
export interface TaskStepRoutingResult {
|
|
183
|
-
/**
|
|
184
|
-
* False when another handler already moved the step out of `waiting` — the
|
|
185
|
-
* caller must not route successors again. The same task terminal event can
|
|
186
|
-
* reach two resume paths (the DB-emitted bus event and a direct emit, or a
|
|
187
|
-
* recovery sweep racing a live event); only the first one may route.
|
|
188
|
-
*/
|
|
189
|
-
claimed: boolean;
|
|
190
|
-
foreachChild: boolean;
|
|
191
|
-
joined: boolean;
|
|
192
|
-
successors: WorkflowNode[];
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const UNCLAIMED: TaskStepRoutingResult = {
|
|
196
|
-
claimed: false,
|
|
197
|
-
foreachChild: false,
|
|
198
|
-
joined: false,
|
|
199
|
-
successors: [],
|
|
200
|
-
};
|
|
201
|
-
|
|
202
259
|
/**
|
|
203
260
|
* Persist an agent-task result and resolve its next nodes. Synthetic foreach
|
|
204
261
|
* children never checkpoint into workflow context; only their parent join does.
|
|
@@ -211,6 +268,7 @@ export async function completeTaskStepAndResolveSuccessors(
|
|
|
211
268
|
ctx: Record<string, unknown>,
|
|
212
269
|
failureReason?: string,
|
|
213
270
|
ownerTaskId?: string,
|
|
271
|
+
registry?: ExecutorRegistry,
|
|
214
272
|
): Promise<TaskStepRoutingResult> {
|
|
215
273
|
// The task step, optional foreach join checkpoint, workflow context, and
|
|
216
274
|
// running status must commit together. A crash after this transaction is
|
|
@@ -223,25 +281,24 @@ export async function completeTaskStepAndResolveSuccessors(
|
|
|
223
281
|
// A stale snapshot of a step since redriven to a fresh task must not route it.
|
|
224
282
|
if (ownerTaskId && !(await isTaskBoundToStep(ownerTaskId, step.id))) return UNCLAIMED;
|
|
225
283
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
};
|
|
284
|
+
if (resolveForeachParent(def, step.nodeId)) {
|
|
285
|
+
// onNodeFailure:"continue" completions persist the failure reason as
|
|
286
|
+
// explicit metadata — the join classifies children on THIS, not on
|
|
287
|
+
// whether user-controlled output text happens to start with "[FAILED:".
|
|
288
|
+
return toRoutingResult(
|
|
289
|
+
await settleForeachChild(
|
|
290
|
+
def,
|
|
291
|
+
runId,
|
|
292
|
+
step.id,
|
|
293
|
+
{
|
|
294
|
+
status: "completed",
|
|
295
|
+
output,
|
|
296
|
+
...(failureReason !== undefined ? { error: failureReason } : {}),
|
|
297
|
+
},
|
|
298
|
+
ctx,
|
|
299
|
+
{ registry },
|
|
300
|
+
),
|
|
301
|
+
);
|
|
245
302
|
}
|
|
246
303
|
|
|
247
304
|
await checkpointStep(runId, step.id, step.nodeId, { output }, ctx);
|
|
@@ -251,6 +308,7 @@ export async function completeTaskStepAndResolveSuccessors(
|
|
|
251
308
|
foreachChild: false,
|
|
252
309
|
joined: true,
|
|
253
310
|
successors: getSuccessors(def, step.nodeId),
|
|
311
|
+
runFailed: false,
|
|
254
312
|
};
|
|
255
313
|
});
|
|
256
314
|
}
|
|
@@ -37,6 +37,11 @@ The task carries `slackChannelId` and `slackThreadTs` in its metadata. A follow-
|
|
|
37
37
|
|
|
38
38
|
Files attached to your task already come with download commands in the task message. Use those before `slack-download-file`. `slack-read` on your task also attaches the files in the thread and gives each one a `fetchCommand`. Don't look for Slack files under `/app/shared` or `/workspace/shared/downloads`: those paths are the API server's disk.
|
|
39
39
|
|
|
40
|
+
## Message limits
|
|
41
|
+
|
|
42
|
+
- Text sent without `blocks` is split into sections under Slack's 3,000-character section limit for you. With explicit `blocks`, keep each section's text at or under 3,000 characters yourself.
|
|
43
|
+
- Truncate user text by code point (`Array.from(s).slice(0, n).join("")`), never with `s.slice(0, n)`: cutting an emoji in half leaves a lone UTF-16 surrogate, and Slack rejects the blocks with `invalid_blocks_format`.
|
|
44
|
+
|
|
40
45
|
## Unknown user
|
|
41
46
|
|
|
42
47
|
A task without `requestedByUserId` came from a Slack user the swarm does not know. Register them with `manage-user`, using the Slack user ID and display name from the task metadata, then continue. When you learn a requester's stable preferences (language, tone, verbosity), the lead stores them in the user's `comms` field with `manage-user`.
|
|
@@ -13,7 +13,7 @@ When the task names a skill (`researching`, `planning`, `implementing`), use it.
|
|
|
13
13
|
|
|
14
14
|
Finish the task with one of the four endings in your operating contract: `completed`, `defer-task`, `request-human-input`, or `failed`. Then stop.
|
|
15
15
|
|
|
16
|
-
Resuming (a resume task, or work cut by a graceful shutdown): read the parent's last progress line, then re-read live state once (PR state and head SHA, branch, `git status`) before new work. Re-run controls only if the head moved. Never redo a pushed commit or open a second PR for the same branch. Store a progress line with branch, PR number and head SHA each time you push. A document task has no branch: its live state is the brief's agent-fs output path and the task attachments. Run `agent-fs ls` on that path, download any partial and extend it
|
|
16
|
+
Resuming (a resume task, or work cut by a graceful shutdown): read the parent's last progress line, then re-read live state once (PR state and head SHA, branch, `git status`) before new work. Re-run controls only if the head moved. Never redo a pushed commit or open a second PR for the same branch. Store a progress line with branch, PR number and head SHA each time you push. A document task has no branch: its live state is the brief's agent-fs output path and the task attachments. Run `agent-fs ls` on that path, download any partial and extend it. Then list the task's local work directory: a shutdown can leave the newest draft only there, or leave cache files half-written. Parse every cache file, delete the ones that fail, and re-run only the stages whose output is missing. Never re-run collection steps that already produced artifacts. If your task's `model` differs from the parent's, say so in the output, because the result's provenance changed.
|
|
17
17
|
|
|
18
18
|
Write times in replies, outputs and defer notes in the requester's timezone when the Requester Profile names one, never raw UTC.
|
|
19
19
|
|
|
@@ -8,7 +8,7 @@ When the task names a skill (`researching`, `planning`, `implementing`), use it.
|
|
|
8
8
|
|
|
9
9
|
Finish the task with one of the four endings in your operating contract: `completed`, `defer-task`, `request-human-input`, or `failed`. Then stop.
|
|
10
10
|
|
|
11
|
-
Resuming (a resume task, or work cut by a graceful shutdown): read the parent's last progress line, then re-read live state once (PR state and head SHA, branch, `git status`) before new work. Re-run controls only if the head moved. Never redo a pushed commit or open a second PR for the same branch. Store a progress line with branch, PR number and head SHA each time you push. A document task has no branch: its live state is the brief's agent-fs output path and the task attachments. Run `agent-fs ls` on that path, download any partial and extend it
|
|
11
|
+
Resuming (a resume task, or work cut by a graceful shutdown): read the parent's last progress line, then re-read live state once (PR state and head SHA, branch, `git status`) before new work. Re-run controls only if the head moved. Never redo a pushed commit or open a second PR for the same branch. Store a progress line with branch, PR number and head SHA each time you push. A document task has no branch: its live state is the brief's agent-fs output path and the task attachments. Run `agent-fs ls` on that path, download any partial and extend it. Then list the task's local work directory: a shutdown can leave the newest draft only there, or leave cache files half-written. Parse every cache file, delete the ones that fail, and re-run only the stages whose output is missing. Never re-run collection steps that already produced artifacts. If your task's `model` differs from the parent's, say so in the output, because the result's provenance changed.
|
|
12
12
|
|
|
13
13
|
Write times in replies, outputs and defer notes in the requester's timezone when the Requester Profile names one, never raw UTC.
|
|
14
14
|
|