@desplega.ai/agent-swarm 2.3.0 → 2.4.1
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 -0
- package/dist/{acp-adapter-v85a2bqy.js → acp-adapter-zvzr538d.js} +9 -9
- package/dist/{actions-zgcxfspj.js → actions-jhtqdw69.js} +21 -19
- package/dist/{amp-adapter-jw9xfz42.js → amp-adapter-bd84rhs2.js} +4 -4
- package/dist/{app-4e1s4675.js → app-kreq1gwg.js} +3 -3
- package/dist/{assistant-v238n9dk.js → assistant-3k22sbsq.js} +23 -21
- package/dist/{boot-reembed-p666cw5n.js → boot-reembed-e53x6b9v.js} +1 -1
- package/dist/{boot-reembed-w6pm64j4.js → boot-reembed-f6z923ny.js} +1 -1
- package/dist/{boot-scrub-sweep-jcyjagn3.js → boot-scrub-sweep-0538vsb7.js} +4 -4
- package/dist/{boot-seeds-gbedmamp.js → boot-seeds-6wxqkfk2.js} +4 -4
- package/dist/{claude-adapter-q7wspzt8.js → claude-adapter-gfts5044.js} +9 -9
- package/dist/{claude-managed-adapter-n7ahjyx6.js → claude-managed-adapter-h2y889ge.js} +3 -3
- package/dist/{claude-managed-setup-wza784fb.js → claude-managed-setup-h00hsgtz.js} +2 -2
- package/dist/{claude-sdk-session-yf400ptr.js → claude-sdk-session-56besmfz.js} +13 -13
- package/dist/{cli-65q70v2v.js → cli-0bh477zn.js} +33 -6
- package/dist/{cli-4ync7m60.js → cli-0ebey9hg.js} +1 -1
- package/dist/{cli-665j3feb.js → cli-0xk505e8.js} +1 -1
- package/dist/{cli-7gh7020n.js → cli-1dmcq2eh.js} +1 -1
- package/dist/{cli-gzvb3d4a.js → cli-1jx0srjt.js} +3 -3
- package/dist/{cli-zj4d6afs.js → cli-1pa3rz69.js} +21 -6
- package/dist/{cli-7ayprxp7.js → cli-2dfbv8qr.js} +8 -0
- package/dist/{cli-30m5q8mc.js → cli-3kh4kpqy.js} +6 -6
- package/dist/{cli-qrwp40st.js → cli-3p8fqcnh.js} +2 -2
- package/dist/{cli-y3dvz6ge.js → cli-3r448dqn.js} +3 -3
- package/dist/{cli-a17tzmn0.js → cli-3tnpj2bh.js} +7 -7
- package/dist/{cli-ea7chd26.js → cli-471qk6s2.js} +93 -46
- package/dist/{cli-a49vpbf3.js → cli-5kqnemen.js} +1 -1
- package/dist/{cli-0rh20bp3.js → cli-6ncjvx55.js} +3 -3
- package/dist/{cli-fb6t92v8.js → cli-6x9ma5w5.js} +1 -1
- package/dist/{cli-k28p6xh7.js → cli-7225gwj7.js} +2 -2
- package/dist/{cli-8cvvytad.js → cli-8nyhf7za.js} +3 -3
- package/dist/{cli-e09hj50q.js → cli-8wkb09q5.js} +11 -11
- package/dist/{cli-j0v75y13.js → cli-a0kcty51.js} +4 -4
- package/dist/{cli-zes4tsbb.js → cli-a4gvwttf.js} +4 -4
- package/dist/{cli-jhp7w1fy.js → cli-a5ebc95n.js} +2 -2
- package/dist/{cli-5d1m1qca.js → cli-ash6xxk7.js} +2 -2
- package/dist/{cli-fp4xbw07.js → cli-axh29tyr.js} +14 -12
- package/dist/{cli-p22zdvnt.js → cli-bn0rewsy.js} +3 -3
- package/dist/{cli-hz64bcnj.js → cli-bn5kevnf.js} +11 -373
- package/dist/{cli-8jtrekpy.js → cli-d2mb5s8a.js} +7 -7
- package/dist/{cli-c5sbmw1v.js → cli-d82btycs.js} +94 -15
- package/dist/{cli-vjfpshn3.js → cli-ejs3m1sx.js} +1 -1
- package/dist/{cli-yv0vgscc.js → cli-fpmsqq59.js} +18 -2
- package/dist/cli-fz9kewbh.js +382 -0
- package/dist/{cli-4s1kqrqg.js → cli-g0hgtz4p.js} +6 -6
- package/dist/{cli-hn3pftj2.js → cli-gf0kfg81.js} +7 -7
- package/dist/{cli-d43xqzbe.js → cli-hqhzg1qq.js} +2 -2
- package/dist/{cli-azs9bhc5.js → cli-j4rqdf2n.js} +2 -2
- package/dist/{cli-wtg6edvd.js → cli-jh0qcrga.js} +1 -1
- package/dist/{cli-kqypty34.js → cli-k9z4zd4p.js} +6 -5
- package/dist/{cli-jhmjwqcg.js → cli-kmqgmcnb.js} +47 -14
- package/dist/{cli-8qsx817b.js → cli-kr2pmfqx.js} +583 -769
- package/dist/{cli-4g629sgr.js → cli-m2qgh5sv.js} +20 -1
- package/dist/{cli-9e9kjqsj.js → cli-mfe7f7b5.js} +2 -2
- package/dist/{cli-x3en6ct3.js → cli-nwyw3zhg.js} +1 -1
- package/dist/{cli-6vcyw6v7.js → cli-nx462e4v.js} +5 -3
- package/dist/{cli-tr24eeny.js → cli-p0rakbrk.js} +9 -9
- package/dist/{cli-4hmaheb6.js → cli-p6argxh9.js} +9 -9
- package/dist/{cli-3avfh5az.js → cli-pemywhfq.js} +2 -2
- package/dist/{cli-etvn5ej2.js → cli-pnp2j5zg.js} +2 -2
- package/dist/{cli-wk8ccrz6.js → cli-pw7v69vp.js} +2 -2
- package/dist/{cli-ka01m5rb.js → cli-rdq7tzwm.js} +17 -14
- package/dist/{cli-re4wkbzx.js → cli-rqqsfz30.js} +677 -104
- package/dist/{cli-xgn4rwyv.js → cli-s48yvzb8.js} +4 -4
- package/dist/{cli-zv4vy2b0.js → cli-s95dknxh.js} +1 -1
- package/dist/{cli-g6p7c2my.js → cli-sjyetj21.js} +2 -2
- package/dist/{cli-rdr166ht.js → cli-smvcw9z5.js} +1 -1
- package/dist/{cli-fhvqt2fp.js → cli-sv5gb0yb.js} +1 -1
- package/dist/{cli-yv3n83x8.js → cli-syhq378v.js} +2 -2
- package/dist/{cli-q1812jbw.js → cli-tbhwrxpt.js} +9 -9
- package/dist/{cli-w7z94e6c.js → cli-tx00c0h6.js} +4 -2
- package/dist/{cli-dxwh4j32.js → cli-vy0fay6k.js} +46 -37
- package/dist/{cli-ptkpaqfy.js → cli-wt645v7q.js} +1 -1
- package/dist/{cli-ppapy34w.js → cli-wxbn3yfx.js} +2 -2
- package/dist/{cli-cby329ny.js → cli-x5mq1fyq.js} +3 -3
- package/dist/{cli-rc3r0bnh.js → cli-xbzvet96.js} +6 -6
- package/dist/{cli-4mkvwgzr.js → cli-xf234ws8.js} +1 -1
- package/dist/{cli-6p7ddg72.js → cli-xftrvxag.js} +5 -5
- package/dist/cli-z071fb95.js +848 -0
- package/dist/{cli-1v8w782f.js → cli-z1ew8vbq.js} +14 -7
- package/dist/{cli-9td5ss65.js → cli-zfg9enh9.js} +3 -3
- package/dist/{cli-yxqag76b.js → cli-zw88zjba.js} +1 -1
- package/dist/cli.js +19 -19
- package/dist/{codex-adapter-nhjj2veb.js → codex-adapter-p6rmm7vv.js} +6 -6
- package/dist/{codex-hook-x6tm6y5m.js → codex-hook-x7nejyrr.js} +8 -5
- package/dist/{codex-login-35p4sk85.js → codex-login-m819c41r.js} +1 -1
- package/dist/{codex-session-runner-6hggrjbx.js → codex-session-runner-8vd5t9t0.js} +7 -7
- package/dist/{commands-mrw1ph2w.js → commands-7ems2p13.js} +2 -2
- package/dist/{controller-pt1zam5w.js → controller-m263fg43.js} +4 -4
- package/dist/{controllers-connect-ymw5541d.js → controllers-connect-bg33ae53.js} +28 -24
- package/dist/{cursor-adapter-cf4zh5x0.js → cursor-adapter-cz6nm6mj.js} +3 -3
- package/dist/{db-hy80219q.js → db-w505dwa8.js} +2 -2
- package/dist/{db-hhpy6m4x.js → db-ys2rbdft.js} +3 -2
- package/dist/{devin-adapter-7egzmt0k.js → devin-adapter-zgqadvnm.js} +1 -1
- package/dist/{dispatcher-6pdjtkr1.js → dispatcher-0s0mckqr.js} +20 -18
- package/dist/{docker-njavd3fb.js → docker-fkgtr75t.js} +2 -2
- package/dist/{dsh-adapter-fbx06re2.js → dsh-adapter-3n3net33.js} +3 -3
- package/dist/{e2b-5r6a5jeb.js → e2b-7am6tmq6.js} +2 -2
- package/dist/{e2b-pw1nvtmh.js → e2b-thdcxtjd.js} +2 -2
- package/dist/{easter-egg-3d-6hg2r942.js → easter-egg-3d-5cgynaja.js} +1 -1
- package/dist/{event-bus-101fenkh.js → event-bus-9vpk8gmq.js} +1 -1
- package/dist/{execute-bcqc69a5.js → execute-t4e6m3rw.js} +1 -1
- package/dist/{external-channel-j6vb6ya1.js → external-channel-5b23fv8z.js} +2 -2
- package/dist/{google-generative-ai-phpmwxvg.js → google-generative-ai-bmq8gkf3.js} +1 -1
- package/dist/{google-vertex-es9ybgdy.js → google-vertex-b1rvp52s.js} +1 -1
- package/dist/{grok-adapter-1193sprp.js → grok-adapter-q9fghe5q.js} +10 -10
- package/dist/handlers-mqrym347.js +39 -0
- package/dist/{heartbeat-h1w1ktce.js → heartbeat-tww6yx1w.js} +23 -21
- package/dist/{hook-ejja4bpe.js → hook-dx0pkvar.js} +16 -9
- package/dist/{hook-skrbja18.js → hook-pvmh9b6m.js} +6 -6
- package/dist/{http-mzh41mfj.js → http-k2ejbt05.js} +975 -292
- package/dist/{index-6rmnn89d.js → index-2z710v4x.js} +10 -10
- package/dist/{index-xmmkyx82.js → index-dgz61nff.js} +20 -18
- package/dist/{index-wgsw9xcz.js → index-g6tbb6ve.js} +1 -1
- package/dist/index-h2ek08d6.js +40 -0
- package/dist/index-pqfwh9nn.js +41 -0
- package/dist/{index-epr2gnbw.js → index-x5aktmp8.js} +1 -1
- package/dist/{index-x0q2a4f9.js → index-ysd45kgc.js} +1 -1
- package/dist/{index-g909y089.js → index-zgvqzjsw.js} +8 -8
- package/dist/{keepalive-4djvbm2j.js → keepalive-nhvpw10z.js} +4 -4
- package/dist/lead-jb6sf69z.js +78 -0
- package/dist/{maintenance-f3xhnjsm.js → maintenance-agakc519.js} +1 -1
- package/dist/{oauth-refresh-sweep-fpd6x6rw.js → oauth-refresh-sweep-4dcbhtn0.js} +3 -3
- package/dist/{onboard-196tjgyn.js → onboard-4n2kwa4v.js} +3 -3
- package/dist/{opencode-adapter-eeesgfqk.js → opencode-adapter-3s7ax02e.js} +7 -7
- package/dist/{otel-impl-g8fh4c21.js → otel-impl-tfa12080.js} +2 -2
- package/dist/{pi-mono-adapter-zasp3ze3.js → pi-mono-adapter-ytp7gz8b.js} +24 -13
- package/dist/{pricing-refresh-sdcf5yaz.js → pricing-refresh-3cqx3f3x.js} +3 -3
- package/dist/{rbac-roles-bsp5657v.js → rbac-roles-9fae5rnv.js} +5 -3
- package/dist/{rbac-roles-2x4g1wb5.js → rbac-roles-y6zbfzve.js} +2 -2
- package/dist/{render-v2-0pyb39bb.js → render-v2-emawjvc4.js} +3 -3
- package/dist/{resume-a86tkj6r.js → resume-zhgts7h7.js} +10 -8
- package/dist/{runtime-ar8310ba.js → runtime-xe3aqy4x.js} +1 -1
- package/dist/session-access-cm823e06.js +25 -0
- package/dist/{setup-ypbzcapd.js → setup-tkp99w1e.js} +1 -1
- package/dist/{virtual-modules-wzk6jf3a.js → virtual-modules-4r3zkc20.js} +2 -2
- package/dist/{work-objects-yjp8de12.js → work-objects-f722h263.js} +23 -21
- package/dist/worker-p7f336rq.js +78 -0
- package/dist/{x-8ewt8gxn.js → x-y45mthwn.js} +2 -2
- package/openapi.json +1086 -305
- package/package.json +2 -2
- package/src/apps/action-caller.ts +6 -0
- package/src/apps/action-runner.ts +146 -0
- package/src/apps/row-store.ts +4 -2
- package/src/apps/script-types.ts +17 -4
- package/src/be/db/active-sessions.ts +5 -0
- package/src/be/db/session-visibility.ts +29 -0
- package/src/be/db/tasks/read.ts +61 -3
- package/src/be/db/tasks/write.ts +15 -6
- package/src/be/db.ts +106 -37
- package/src/be/events.ts +11 -0
- package/src/be/fleet-benchmark-stats.ts +10 -5
- package/src/be/migrations/230_session_shares.sql +23 -0
- package/src/be/models-catalog.ts +4 -0
- package/src/be/onboarding.ts +6 -0
- package/src/be/rbac-roles.ts +2 -0
- package/src/be/scripts/typecheck.ts +13 -0
- package/src/be/session-shares.ts +244 -0
- package/src/be/swarm-config-guard.ts +33 -3
- package/src/be/telemetry-enable.ts +1 -1
- package/src/commands/provider-credentials.ts +12 -2
- package/src/commands/runner.ts +14 -0
- package/src/heartbeat/heartbeat.ts +2 -2
- package/src/hooks/codex-hook.ts +6 -2
- package/src/hooks/hook.ts +7 -0
- package/src/hooks/pr-body-guard.ts +38 -11
- package/src/hooks/pr-room-guard.ts +88 -0
- package/src/http/active-sessions.ts +13 -2
- package/src/http/agents.ts +11 -3
- package/src/http/all-routes.ts +1 -0
- package/src/http/api-keys.ts +3 -1
- package/src/http/approval-requests.ts +2 -1
- package/src/http/apps.ts +118 -190
- package/src/http/config.ts +3 -0
- package/src/http/context.ts +2 -0
- package/src/http/core.ts +39 -2
- package/src/http/events.ts +6 -2
- package/src/http/favorite-owner.ts +1 -1
- package/src/http/fleet-benchmark.ts +79 -30
- package/src/http/fs.ts +38 -3
- package/src/http/global-config.ts +7 -0
- package/src/http/index.ts +3 -1
- package/src/http/memory.ts +3 -1
- package/src/http/ranking.ts +351 -0
- package/src/http/realtime.ts +26 -21
- package/src/http/route-def.ts +77 -11
- package/src/http/script-runs.ts +2 -1
- package/src/http/scripts.ts +8 -0
- package/src/http/session-access.ts +179 -0
- package/src/http/session-data.ts +10 -2
- package/src/http/sessions.ts +212 -12
- package/src/http/stats.ts +7 -3
- package/src/http/tasks.ts +85 -8
- package/src/http/telemetry-ui.ts +1 -1
- package/src/http/used-by.ts +64 -20
- package/src/http/users.ts +2 -2
- package/src/prompts/session-templates.ts +3 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +15 -0
- package/src/providers/reasoning-effort.ts +2 -1
- package/src/providers/types.ts +2 -0
- package/src/ranking/telemetry-ranking.ts +119 -0
- package/src/ranking/usage.ts +57 -0
- package/src/rbac/admission.ts +22 -7
- package/src/rbac/legacy-policy.ts +2 -0
- package/src/rbac/permissions.ts +9 -0
- package/src/realtime/auth.ts +69 -0
- package/src/realtime/tickets.ts +4 -1
- package/src/realtime/transport.ts +77 -9
- package/src/scripts-runtime/sdk-allowlist.ts +7 -0
- package/src/scripts-runtime/types/stdlib.d.ts +31 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +31 -0
- package/src/server.ts +4 -0
- package/src/slack/blocks.ts +18 -0
- package/src/slack/dm.ts +29 -0
- package/src/telemetry-context.ts +19 -1
- package/src/telemetry-contract/EVENTS.md +45 -8
- package/src/telemetry-contract/SOURCE.json +38 -4
- package/src/telemetry-contract/catalog.json +294 -5
- package/src/telemetry-contract/ranking/fixtures/expected.json +30 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/bad-category.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/bad-claim.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/blank-description.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/blank-name.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/description-too-long.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/domain-uppercase.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/domain-with-scheme.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/domain-with-www.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/http-source-url.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/missing-description.json +10 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/missing-version.json +10 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/name-not-string.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/name-too-long.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/not-object.json +1 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/null.json +1 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/other-with-subcategory.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/oversize.json +1 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/short-claim.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/subcategory-other-category.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/trailing-data.json +1 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/unknown-field.json +12 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/unsupported-version.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/updated-at-not-date.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/updated-at-offset.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/invalid/wrong-case-field.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/valid/category-without-subcategory.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/valid/full.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/valid/minimal.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/valid/no-claim.json +10 -0
- package/src/telemetry-contract/ranking/fixtures/valid/padded-text.json +11 -0
- package/src/telemetry-contract/ranking/fixtures/valid/unicode-name.json +11 -0
- package/src/telemetry-contract/ranking/listing.v1.schema.json +61 -0
- package/src/telemetry-contract/ranking/taxonomy.json +8 -0
- package/src/telemetry-contract/ranking-taxonomy.gen.ts +11 -0
- package/src/telemetry-contract/types.gen.ts +963 -58
- package/src/telemetry-identity.ts +47 -9
- package/src/telemetry-snapshot.ts +9 -1
- package/src/telemetry-ui-events.ts +9 -2
- package/src/telemetry.ts +40 -5
- package/src/tests/app-action-run-tool.test.ts +178 -0
- package/src/tests/app-row-tools.test.ts +360 -0
- package/src/tests/apps-rbac.test.ts +189 -2
- package/src/tests/apps-script-types.test.ts +16 -3
- package/src/tests/credential-check.test.ts +38 -0
- package/src/tests/db-extraction-contract.test.ts +1 -0
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/docs-index-footprint.test.js +2 -2
- package/src/tests/fleet-benchmark.test.ts +122 -2
- package/src/tests/http-users.test.ts +62 -1
- package/src/tests/model-catalog-table.test.ts +63 -0
- package/src/tests/model-profiles-api.test.ts +19 -7
- package/src/tests/models-catalog.test.ts +50 -0
- package/src/tests/onboarding.test.ts +21 -0
- package/src/tests/org-identity.test.ts +44 -0
- package/src/tests/org-website.test.ts +62 -0
- package/src/tests/pi-mono-adapter.test.ts +23 -0
- package/src/tests/pr-body-leaks.test.ts +4 -0
- package/src/tests/pr-room-guard.test.ts +242 -0
- package/src/tests/ranking-listing.test.ts +97 -0
- package/src/tests/ranking-route.test.ts +321 -0
- package/src/tests/ranking-usage.test.ts +50 -0
- package/src/tests/rbac-admission-e2e.test.ts +8 -0
- package/src/tests/rbac-admission.test.ts +38 -0
- package/src/tests/rbac-charact-http.test.ts +4 -3
- package/src/tests/rbac-engine.test.ts +2 -0
- package/src/tests/rbac-roles.test.ts +2 -0
- package/src/tests/realtime-room-surfaces.test.ts +3 -1
- package/src/tests/realtime-session-join-race.test.ts +142 -0
- package/src/tests/realtime-tickets.test.ts +24 -17
- package/src/tests/realtime-transport.test.ts +91 -0
- package/src/tests/reasoning-effort.test.ts +39 -3
- package/src/tests/runner-harness-telemetry-env.test.ts +56 -1
- package/src/tests/session-route-posture.test.ts +639 -0
- package/src/tests/session-sharing-routes.test.ts +282 -0
- package/src/tests/session-sharing.test.ts +526 -0
- package/src/tests/sessions-detail-batch.test.ts +7 -1
- package/src/tests/slack-tool-blocks.test.ts +101 -0
- package/src/tests/slack-update.test.ts +55 -0
- package/src/tests/slack-user-dm.test.ts +177 -0
- package/src/tests/swarm-tool-result-gate.test.ts +2 -4
- package/src/tests/telemetry-context.test.ts +128 -2
- package/src/tests/telemetry-ui-route.test.ts +123 -0
- package/src/tests/tool-annotations.test.ts +3 -2
- package/src/tests/used-by-route.test.ts +153 -9
- package/src/tests/workflow-agent-task-retry.test.ts +130 -4
- package/src/tests/workflow-wait-recovery.test.ts +116 -4
- package/src/tools/app-action-run.ts +63 -0
- package/src/tools/app-rows.ts +234 -0
- package/src/tools/model-catalog/index.ts +1 -1
- package/src/tools/slack-post.ts +18 -12
- package/src/tools/slack-read.ts +13 -1
- package/src/tools/slack-reply.ts +7 -10
- package/src/tools/slack-start-thread.ts +18 -11
- package/src/tools/slack-update.ts +2 -9
- package/src/tools/tool-config.ts +8 -0
- package/src/tools/utils.ts +1 -1
- package/src/tools/workflows/retry-workflow-run.ts +1 -1
- package/src/types.ts +52 -0
- package/src/utils/company-profile.ts +24 -0
- package/src/utils/org-identity.ts +33 -0
- package/src/utils/org-website.ts +58 -21
- package/src/workflows/recovery.ts +10 -22
- package/src/workflows/resume.ts +16 -0
- package/src/workflows/task-step-routing.ts +47 -7
- package/templates/skills/apps/SKILL.md +58 -2
- package/templates/skills/apps/content.md +58 -2
- package/dist/handlers-tb3xgjnm.js +0 -37
- package/dist/index-nyfcdpky.js +0 -39
- package/dist/index-vjn3wbzf.js +0 -38
- package/dist/lead-61kqp604.js +0 -76
- package/dist/worker-4ptnn1ge.js +0 -76
- package/dist/{cli-n5mrsg0f.js → cli-60cgh1rv.js} +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-swarm.dev",
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"dependencies": {
|
|
201
201
|
"@agentclientprotocol/sdk": "1.9.0",
|
|
202
202
|
"@ai-sdk/openai": "^3.0.41",
|
|
203
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
203
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.303",
|
|
204
204
|
"@anthropic-ai/sdk": "^0.135.0",
|
|
205
205
|
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
206
206
|
"@aws-sdk/client-bedrock": "3.1048.0",
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { normalizeAssetKey } from "../assets/key";
|
|
2
|
+
import { getLeadAgent } from "../be/db";
|
|
3
|
+
import { getScriptById } from "../be/scripts/db";
|
|
4
|
+
import { getSavedScriptOwnerAgentId, runSavedScriptAsAgent } from "../be/scripts/run-saved";
|
|
5
|
+
import { resolveTemplate } from "../prompts/resolver";
|
|
6
|
+
import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
|
|
7
|
+
import { scrubObject } from "../utils/secret-scrubber";
|
|
8
|
+
import type { AppActionCaller } from "./action-caller";
|
|
9
|
+
import type { AppRecord } from "./store";
|
|
10
|
+
import { runAppSync } from "./sync";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* One `error` string for a sync result, or undefined when every pass succeeded.
|
|
14
|
+
* Each failed pair is named so a multi-pair sync says which one broke; the pass
|
|
15
|
+
* list in `result.passes` carries the rest.
|
|
16
|
+
*/
|
|
17
|
+
function syncPassError(sync: Awaited<ReturnType<typeof runAppSync>>): string | undefined {
|
|
18
|
+
const failed = sync.passes.filter((pass) => pass.error !== undefined);
|
|
19
|
+
if (failed.length === 0) return undefined;
|
|
20
|
+
return failed.map((pass) => `${pass.model}.${pass.source}: ${pass.error}`).join("; ");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function runAppAction({
|
|
24
|
+
app,
|
|
25
|
+
name,
|
|
26
|
+
input = {},
|
|
27
|
+
caller,
|
|
28
|
+
actor,
|
|
29
|
+
}: {
|
|
30
|
+
app: AppRecord;
|
|
31
|
+
name: string;
|
|
32
|
+
input?: Record<string, unknown>;
|
|
33
|
+
caller: AppActionCaller;
|
|
34
|
+
actor: string;
|
|
35
|
+
}) {
|
|
36
|
+
const actions = app.definition.actions;
|
|
37
|
+
if (!actions || !Object.hasOwn(actions, name)) {
|
|
38
|
+
return { status: 404 as const, body: { error: "app action not found" } };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const action = actions[name]!;
|
|
42
|
+
|
|
43
|
+
if (action.kind === "script") {
|
|
44
|
+
const script = await getScriptById(action.scriptId);
|
|
45
|
+
if (!script) {
|
|
46
|
+
return {
|
|
47
|
+
status: 400 as const,
|
|
48
|
+
body: {
|
|
49
|
+
error: "invalid app action",
|
|
50
|
+
issues: [
|
|
51
|
+
{
|
|
52
|
+
path: `actions.${name}.scriptId`,
|
|
53
|
+
message: `script "${action.scriptId}" no longer exists`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Script actions use the owner's bindings. Definition validation checks
|
|
61
|
+
// which scripts an agent can wire into an app.
|
|
62
|
+
const runAsAgentId = getSavedScriptOwnerAgentId(script);
|
|
63
|
+
if (!runAsAgentId) {
|
|
64
|
+
return {
|
|
65
|
+
status: 400 as const,
|
|
66
|
+
body: { error: "agentId is required: this script has no owning agent to run as" },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const output = await runSavedScriptAsAgent({
|
|
71
|
+
script,
|
|
72
|
+
input: { ...action.args, ...input, app: { id: app.id }, caller },
|
|
73
|
+
agentId: runAsAgentId,
|
|
74
|
+
});
|
|
75
|
+
const ok = output.exitCode === 0 && !output.error && !output.runtimeError;
|
|
76
|
+
const error = ok
|
|
77
|
+
? undefined
|
|
78
|
+
: output.runtimeError
|
|
79
|
+
? `${output.runtimeError.name}: ${output.runtimeError.message}`
|
|
80
|
+
: (output.error ?? `Script exited with code ${output.exitCode}`);
|
|
81
|
+
return {
|
|
82
|
+
status: 200 as const,
|
|
83
|
+
body: scrubObject({
|
|
84
|
+
ok,
|
|
85
|
+
result: output.result,
|
|
86
|
+
stdout: output.stdout,
|
|
87
|
+
...(error === undefined ? {} : { error }),
|
|
88
|
+
durationMs: output.durationMs,
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (action.kind === "sync") {
|
|
94
|
+
const startedAt = Date.now();
|
|
95
|
+
const sync = await runAppSync({
|
|
96
|
+
appId: app.id,
|
|
97
|
+
...(action.model === undefined ? {} : { model: action.model }),
|
|
98
|
+
...(action.source === undefined ? {} : { source: action.source }),
|
|
99
|
+
invokedBy: actor,
|
|
100
|
+
});
|
|
101
|
+
const durationMs = Date.now() - startedAt;
|
|
102
|
+
if (sync.issues && sync.issues.length > 0) {
|
|
103
|
+
return { status: 400 as const, body: { error: "invalid sync action", issues: sync.issues } };
|
|
104
|
+
}
|
|
105
|
+
// Deliberately the SCRIPT-action response shape, minus `taskId`:
|
|
106
|
+
// app-surface.tsx branches on `taskId` first, so omitting it gives the
|
|
107
|
+
// dashboard running -> ok/error + refetchAll() with zero UI changes.
|
|
108
|
+
const error = syncPassError(sync);
|
|
109
|
+
return {
|
|
110
|
+
status: 200 as const,
|
|
111
|
+
body: scrubObject({
|
|
112
|
+
ok: sync.ok,
|
|
113
|
+
result: { passes: sync.passes },
|
|
114
|
+
...(error === undefined ? {} : { error }),
|
|
115
|
+
durationMs,
|
|
116
|
+
}),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const lead = action.agentId ? null : await getLeadAgent();
|
|
121
|
+
const taskPrompt = resolveTemplate("task.app.action", {
|
|
122
|
+
prompt: action.prompt,
|
|
123
|
+
app_id: app.id,
|
|
124
|
+
action_name: name,
|
|
125
|
+
input_json: JSON.stringify(input),
|
|
126
|
+
caller_json: JSON.stringify(caller),
|
|
127
|
+
});
|
|
128
|
+
const task = await createTaskWithSiblingAwareness(
|
|
129
|
+
taskPrompt.text,
|
|
130
|
+
{
|
|
131
|
+
source: "api",
|
|
132
|
+
agentId: action.agentId ?? lead?.id,
|
|
133
|
+
routingReason: action.agentId ? "human_pinned" : lead ? "skill" : undefined,
|
|
134
|
+
routingSource: action.agentId || lead ? "engine_default" : undefined,
|
|
135
|
+
// App-spawned tasks group under the app's asset namespace so a
|
|
136
|
+
// swarm-tasks source can pull them back via config.assetKey.
|
|
137
|
+
key: normalizeAssetKey(`shared/app:${app.id}/action:${name}/`),
|
|
138
|
+
...(actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}),
|
|
139
|
+
},
|
|
140
|
+
{ origin: "app" },
|
|
141
|
+
);
|
|
142
|
+
return {
|
|
143
|
+
status: 200 as const,
|
|
144
|
+
body: { ok: true as const, taskId: task.id, status: task.status },
|
|
145
|
+
};
|
|
146
|
+
}
|
package/src/apps/row-store.ts
CHANGED
|
@@ -109,7 +109,7 @@ function indexKeys(model: string, definition: ModelDef, row: AppRow): string[] {
|
|
|
109
109
|
return keys;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function validValue(column: ColumnDef, value: unknown): boolean {
|
|
112
|
+
export function validValue(column: ColumnDef, value: unknown): boolean {
|
|
113
113
|
if (value === null) return column.required !== true;
|
|
114
114
|
if (column.kind === "string") return typeof value === "string";
|
|
115
115
|
if (column.kind === "number") return typeof value === "number" && Number.isFinite(value);
|
|
@@ -526,18 +526,20 @@ export async function rebuildAppColumnIndexUnlocked(
|
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
+
/** `matches` re-checks the row under the lock; a row that no longer matches is kept. */
|
|
529
530
|
export function deleteAppRow(
|
|
530
531
|
appId: string,
|
|
531
532
|
model: string,
|
|
532
533
|
_definition: ModelDef,
|
|
533
534
|
rowId: string,
|
|
535
|
+
matches?: (row: AppRow) => boolean,
|
|
534
536
|
): Promise<boolean> {
|
|
535
537
|
return withMutationLock(appId, model, async () => {
|
|
536
538
|
const currentDefinition = await currentModelDefinition(appId, model);
|
|
537
539
|
if (!currentDefinition) return false;
|
|
538
540
|
const namespace = appsNamespace(appId);
|
|
539
541
|
const row = await getAppRow(appId, model, rowId);
|
|
540
|
-
if (!row) return false;
|
|
542
|
+
if (!row || (matches && !matches(row))) return false;
|
|
541
543
|
for (const key of indexKeys(model, currentDefinition, row)) await deleteKv(namespace, key);
|
|
542
544
|
await deleteKv(namespace, rowKey(model, rowId));
|
|
543
545
|
return true;
|
package/src/apps/script-types.ts
CHANGED
|
@@ -8,6 +8,13 @@ const APP_TYPES_PREAMBLE = `// ── Swarm Apps: generated per-app types (sourc
|
|
|
8
8
|
// Rows are the app's declared columns plus the 5 system columns. Query
|
|
9
9
|
// overloads narrow only when appId AND query are string literals.
|
|
10
10
|
|
|
11
|
+
export type AppActionCaller = {
|
|
12
|
+
kind: "user" | "agent" | "operator" | "guest";
|
|
13
|
+
id: string | null;
|
|
14
|
+
name?: string;
|
|
15
|
+
pageId?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
11
18
|
export interface SwarmAppQueryResult<Row> {
|
|
12
19
|
success: boolean;
|
|
13
20
|
status: number;
|
|
@@ -175,9 +182,8 @@ function renderQuery(
|
|
|
175
182
|
}
|
|
176
183
|
|
|
177
184
|
function renderApp(app: AppRecord, namespace: string): string {
|
|
178
|
-
// Reserve
|
|
179
|
-
|
|
180
|
-
const modelNames = new Set<string>(["ActionName"]);
|
|
185
|
+
// Reserve action types so model names cannot collide with them.
|
|
186
|
+
const modelNames = new Set<string>(["ActionName", "ActionArgs", "AppActionCaller"]);
|
|
181
187
|
const renderedModels = Object.entries(app.definition.models).map(([modelName, model]) =>
|
|
182
188
|
renderModel(modelName, model, modelNames),
|
|
183
189
|
);
|
|
@@ -200,8 +206,15 @@ function renderApp(app: AppRecord, namespace: string): string {
|
|
|
200
206
|
export namespace ${namespace} {
|
|
201
207
|
${renderedModels.map((model) => model.source).join("\n\n")}
|
|
202
208
|
|
|
203
|
-
/** Declared actions
|
|
209
|
+
/** Scripts can write rows. Declared actions are callable through REST or MCP only. */
|
|
204
210
|
export type ActionName = ${actionType};
|
|
211
|
+
|
|
212
|
+
/** Script action arguments include server-stamped app and caller context. */
|
|
213
|
+
export interface ActionArgs {
|
|
214
|
+
app: { id: ${JSON.stringify(app.id)} };
|
|
215
|
+
caller: AppActionCaller;
|
|
216
|
+
[key: string]: unknown;
|
|
217
|
+
}
|
|
205
218
|
}
|
|
206
219
|
|
|
207
220
|
export interface SwarmSdk {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ActiveSession } from "../../types";
|
|
1
2
|
import { getDbClient } from "./runtime";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -28,3 +29,7 @@ export async function refreshActiveSessionOnActivity(
|
|
|
28
29
|
);
|
|
29
30
|
return result.changes > 0;
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
export async function getActiveSessionById(id: string): Promise<ActiveSession | null> {
|
|
34
|
+
return getDbClient().get<ActiveSession>("SELECT * FROM active_sessions WHERE id = ?", [id]);
|
|
35
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-list visibility for session sharing. `all`: sessions the viewer
|
|
3
|
+
* owns, ownerless sessions, and sessions shared with the viewer or everyone.
|
|
4
|
+
* `mine`: owned by the viewer. `shared`: owned by someone else and shared with
|
|
5
|
+
* the viewer or everyone. A null `userId` (a guest page session) owns nothing.
|
|
6
|
+
*/
|
|
7
|
+
export type SessionViewer = { userId: string | null; scope: "all" | "mine" | "shared" };
|
|
8
|
+
|
|
9
|
+
/** SQL condition + params restricting root tasks (alias `r`) to what `viewer` may open. */
|
|
10
|
+
export function sessionViewerCondition(viewer: SessionViewer): {
|
|
11
|
+
sql: string;
|
|
12
|
+
params: (string | null)[];
|
|
13
|
+
} {
|
|
14
|
+
const shared = `EXISTS (SELECT 1 FROM session_shares s
|
|
15
|
+
WHERE s.rootTaskId = r.id AND s.revokedAt IS NULL AND (s.userId IS NULL OR s.userId = ?))`;
|
|
16
|
+
if (viewer.scope === "mine") {
|
|
17
|
+
return { sql: "r.requestedByUserId = ?", params: [viewer.userId] };
|
|
18
|
+
}
|
|
19
|
+
if (viewer.scope === "shared") {
|
|
20
|
+
return {
|
|
21
|
+
sql: `(r.requestedByUserId IS NOT NULL AND r.requestedByUserId IS NOT ? AND ${shared})`,
|
|
22
|
+
params: [viewer.userId, viewer.userId],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
sql: `(r.requestedByUserId IS NULL OR r.requestedByUserId = ? OR ${shared})`,
|
|
27
|
+
params: [viewer.userId, viewer.userId],
|
|
28
|
+
};
|
|
29
|
+
}
|
package/src/be/db/tasks/read.ts
CHANGED
|
@@ -556,10 +556,14 @@ export async function hasNonTerminalRerouteDecisionChild(parentId: string): Prom
|
|
|
556
556
|
return row !== undefined && row !== null;
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
-
export async function getTasksByAgentId(
|
|
559
|
+
export async function getTasksByAgentId(
|
|
560
|
+
agentId: string,
|
|
561
|
+
readableBy?: { userId: string | null },
|
|
562
|
+
): Promise<AgentTask[]> {
|
|
563
|
+
const readable = readableBy ? readableSessionCondition(readableBy.userId) : undefined;
|
|
560
564
|
const rows = await getDbClient().query<AgentTaskRow>(
|
|
561
|
-
|
|
562
|
-
[agentId],
|
|
565
|
+
`SELECT * FROM agent_tasks WHERE agentId = ?${readable ? ` AND ${readable.sql}` : ""} ORDER BY createdAt DESC`,
|
|
566
|
+
[agentId, ...(readable?.params ?? [])],
|
|
563
567
|
);
|
|
564
568
|
return rows.map(rowToAgentTask);
|
|
565
569
|
}
|
|
@@ -642,6 +646,48 @@ export interface TaskFilters {
|
|
|
642
646
|
limit?: number;
|
|
643
647
|
offset?: number;
|
|
644
648
|
includeHeartbeat?: boolean;
|
|
649
|
+
/** Only tasks of sessions this user may read; `userId: null` is a guest. */
|
|
650
|
+
readableBy?: { userId: string | null };
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* The SQL twin of `sessionAccessForRoot` (../../session-shares). A session's
|
|
655
|
+
* root is its topmost existing task; the session is hidden when the root has
|
|
656
|
+
* an owner other than the user and no active share names the user or
|
|
657
|
+
* everyone. Descending from hidden roots is linear in their tasks at any chain
|
|
658
|
+
* depth, and as a WHERE term it keeps paging and `COUNT(*)` on the same rows.
|
|
659
|
+
* `parentTaskId` is fixed at insert to an existing task, so no parent cycle
|
|
660
|
+
* (which would have no root) can form.
|
|
661
|
+
*
|
|
662
|
+
* `taskIdColumn` applies the same filter to any table keyed by task id. A
|
|
663
|
+
* nullable column keeps its task-less rows: they belong to no session.
|
|
664
|
+
*/
|
|
665
|
+
export function readableSessionCondition(
|
|
666
|
+
userId: string | null,
|
|
667
|
+
taskIdColumn = "agent_tasks.id",
|
|
668
|
+
opts: { nullable?: boolean } = {},
|
|
669
|
+
): { sql: string; params: string[] } {
|
|
670
|
+
const otherOwner = userId
|
|
671
|
+
? "r.requestedByUserId IS NOT NULL AND r.requestedByUserId != ?"
|
|
672
|
+
: "r.requestedByUserId IS NOT NULL";
|
|
673
|
+
const shareMatch = userId ? "(s.userId IS NULL OR s.userId = ?)" : "s.userId IS NULL";
|
|
674
|
+
const notHidden = `${taskIdColumn} NOT IN (
|
|
675
|
+
WITH RECURSIVE hidden(id) AS (
|
|
676
|
+
SELECT r.id FROM agent_tasks r
|
|
677
|
+
WHERE (r.parentTaskId IS NULL
|
|
678
|
+
OR NOT EXISTS (SELECT 1 FROM agent_tasks p WHERE p.id = r.parentTaskId))
|
|
679
|
+
AND ${otherOwner}
|
|
680
|
+
AND NOT EXISTS (SELECT 1 FROM session_shares s
|
|
681
|
+
WHERE s.rootTaskId = r.id AND s.revokedAt IS NULL AND ${shareMatch})
|
|
682
|
+
UNION ALL
|
|
683
|
+
SELECT c.id FROM agent_tasks c JOIN hidden ON c.parentTaskId = hidden.id
|
|
684
|
+
)
|
|
685
|
+
SELECT id FROM hidden
|
|
686
|
+
)`;
|
|
687
|
+
return {
|
|
688
|
+
sql: opts.nullable ? `(${taskIdColumn} IS NULL OR ${notHidden})` : notHidden,
|
|
689
|
+
params: userId ? [userId, userId] : [],
|
|
690
|
+
};
|
|
645
691
|
}
|
|
646
692
|
|
|
647
693
|
export function getAllTasks(filters?: TaskFilters): Promise<AgentTask[]>;
|
|
@@ -756,6 +802,12 @@ export async function getAllTasks(
|
|
|
756
802
|
);
|
|
757
803
|
}
|
|
758
804
|
|
|
805
|
+
if (filters?.readableBy) {
|
|
806
|
+
const readable = readableSessionCondition(filters.readableBy.userId);
|
|
807
|
+
conditions.push(readable.sql);
|
|
808
|
+
params.push(...readable.params);
|
|
809
|
+
}
|
|
810
|
+
|
|
759
811
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
760
812
|
const limit = filters?.limit ?? 25;
|
|
761
813
|
const offset = filters?.offset ?? 0;
|
|
@@ -916,6 +968,12 @@ export async function getTasksCount(
|
|
|
916
968
|
);
|
|
917
969
|
}
|
|
918
970
|
|
|
971
|
+
if (filters?.readableBy) {
|
|
972
|
+
const readable = readableSessionCondition(filters.readableBy.userId);
|
|
973
|
+
conditions.push(readable.sql);
|
|
974
|
+
params.push(...readable.params);
|
|
975
|
+
}
|
|
976
|
+
|
|
919
977
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
920
978
|
const query = `SELECT COUNT(*) as count FROM agent_tasks ${whereClause}`;
|
|
921
979
|
|
package/src/be/db/tasks/write.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
type AgentTaskRow,
|
|
28
28
|
getTaskById,
|
|
29
29
|
NEVER_STARTED_TASK_STATUSES,
|
|
30
|
+
readableSessionCondition,
|
|
30
31
|
rowToAgentTask,
|
|
31
32
|
} from "./read";
|
|
32
33
|
|
|
@@ -1019,12 +1020,16 @@ export async function resumeTask(taskId: string): Promise<AgentTask | null> {
|
|
|
1019
1020
|
* Used on startup to resume tasks that were interrupted by deployment.
|
|
1020
1021
|
* Returns tasks ordered by creation time (oldest first for FIFO).
|
|
1021
1022
|
*/
|
|
1022
|
-
export async function getPausedTasksForAgent(
|
|
1023
|
+
export async function getPausedTasksForAgent(
|
|
1024
|
+
agentId: string,
|
|
1025
|
+
readableBy?: { userId: string | null },
|
|
1026
|
+
): Promise<AgentTask[]> {
|
|
1027
|
+
const readable = readableBy ? readableSessionCondition(readableBy.userId) : undefined;
|
|
1023
1028
|
const rows = await getDbClient().query<AgentTaskRow>(
|
|
1024
1029
|
`SELECT * FROM agent_tasks
|
|
1025
|
-
WHERE agentId = ? AND status = 'paused'
|
|
1030
|
+
WHERE agentId = ? AND status = 'paused'${readable ? ` AND ${readable.sql}` : ""}
|
|
1026
1031
|
ORDER BY createdAt ASC, rowid ASC`,
|
|
1027
|
-
[agentId],
|
|
1032
|
+
[agentId, ...(readable?.params ?? [])],
|
|
1028
1033
|
);
|
|
1029
1034
|
return rows.map(rowToAgentTask);
|
|
1030
1035
|
}
|
|
@@ -1093,15 +1098,19 @@ export async function resetOrphanedInProgressTasksForAgent(
|
|
|
1093
1098
|
* Used by hooks to detect task cancellation and stop the worker loop.
|
|
1094
1099
|
* Returns tasks cancelled within the last 5 minutes.
|
|
1095
1100
|
*/
|
|
1096
|
-
export async function getRecentlyCancelledTasksForAgent(
|
|
1101
|
+
export async function getRecentlyCancelledTasksForAgent(
|
|
1102
|
+
agentId: string,
|
|
1103
|
+
readableBy?: { userId: string | null },
|
|
1104
|
+
): Promise<AgentTask[]> {
|
|
1097
1105
|
const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString();
|
|
1106
|
+
const readable = readableBy ? readableSessionCondition(readableBy.userId) : undefined;
|
|
1098
1107
|
const rows = await getDbClient().query<AgentTaskRow>(
|
|
1099
1108
|
`SELECT * FROM agent_tasks
|
|
1100
1109
|
WHERE agentId = ?
|
|
1101
1110
|
AND status = 'cancelled'
|
|
1102
|
-
AND finishedAt > ?
|
|
1111
|
+
AND finishedAt > ?${readable ? ` AND ${readable.sql}` : ""}
|
|
1103
1112
|
ORDER BY finishedAt DESC`,
|
|
1104
|
-
[agentId, fiveMinutesAgo],
|
|
1113
|
+
[agentId, fiveMinutesAgo, ...(readable?.params ?? [])],
|
|
1105
1114
|
);
|
|
1106
1115
|
return rows.map(rowToAgentTask);
|
|
1107
1116
|
}
|