@desplega.ai/agent-swarm 1.149.1 → 1.151.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 +18 -3
- package/dist/{acp-adapter-vhkzfpjg.js → acp-adapter-ex8hzjfc.js} +5 -5
- package/dist/{actions-9d2694yk.js → actions-2bgpyhww.js} +39 -11
- package/dist/{app-fq2ggynt.js → app-1706zhr1.js} +7 -7
- package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
- package/dist/{assistant-edb6n9nn.js → assistant-bavke5p7.js} +44 -20
- package/dist/{azure-openai-responses-cqar64rc.js → azure-openai-responses-f38x2avq.js} +13 -13
- package/dist/{boot-reembed-msweabbp.js → boot-reembed-3cmrrmpa.js} +9 -9
- package/dist/{boot-reembed-q5wd3tha.js → boot-reembed-nafcmmmc.js} +14 -16
- package/dist/{boot-scrub-logs-3g1az933.js → boot-scrub-logs-cd6a2sq0.js} +5 -5
- package/dist/{claude-adapter-v3rnzsdc.js → claude-adapter-wfp2gzvz.js} +15 -16
- package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-dsmkcrjy.js} +3 -3
- package/dist/{claude-sdk-session-qxrpsna1.js → claude-sdk-session-bht9jjak.js} +15 -16
- package/dist/{cli-5m0qmvdp.js → cli-0qb1z6s2.js} +1 -1
- package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
- package/dist/{cli-7evafqvy.js → cli-2tbvf1z1.js} +85 -69
- package/dist/{cli-k351hv5k.js → cli-3v9xhjcn.js} +24 -12
- package/dist/{cli-1ebpar1q.js → cli-4wppfkcm.js} +350 -20
- package/dist/{cli-4260r1tg.js → cli-5jd2z7av.js} +97 -84
- package/dist/{cli-cv7s5zdq.js → cli-5tpgq60f.js} +9865 -715
- package/dist/{cli-6skz3rk8.js → cli-7tgcstn2.js} +9 -4
- package/dist/{cli-01g3x1ca.js → cli-9004vfdf.js} +108 -56
- package/dist/{cli-1c94wvcw.js → cli-a1z3h107.js} +124 -99
- package/dist/{cli-9br8ypfv.js → cli-czjtgfys.js} +2 -2
- package/dist/{cli-5my3bjsd.js → cli-d3p82erb.js} +7 -7
- package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
- package/dist/{cli-wby1xnnb.js → cli-f1wky6zp.js} +1 -1
- package/dist/{cli-zvz62chv.js → cli-fm4ytsdk.js} +4 -4
- package/dist/{cli-tg8qj8ee.js → cli-frcta2w4.js} +6 -6
- package/dist/{cli-7xx10h0a.js → cli-g69fdc9g.js} +2 -2
- package/dist/{cli-cmp8g3sw.js → cli-gbfwcd3k.js} +44 -9
- package/dist/{handlers-nsg0bcye.js → cli-gjyvhmmh.js} +97 -45
- package/dist/{cli-08b07b4r.js → cli-ht5rs63n.js} +1 -1
- package/dist/{cli-jecc01cb.js → cli-j4nv2wqy.js} +2 -4
- package/dist/{cli-cd60fv6j.js → cli-j9xczhaq.js} +1 -1
- package/dist/cli-pf9q3696.js +172 -0
- package/dist/{cli-xm87hzbw.js → cli-pgj4a5fb.js} +1 -1
- package/dist/{cli-jezx9b9c.js → cli-ppm4975n.js} +9 -3
- package/dist/{cli-3z634pqe.js → cli-q88st9aj.js} +2 -2
- package/dist/{cli-3sysyjve.js → cli-r2q6pevn.js} +142 -49
- package/dist/{cli-07jd68a1.js → cli-re8z5p8p.js} +1 -1
- package/dist/{cli-qgd4sqz5.js → cli-s14agm5s.js} +121 -14
- package/dist/{cli-svbrpf5q.js → cli-sjaae6ff.js} +9872 -424
- package/dist/{cli-73gq0zxn.js → cli-vwm416m6.js} +13 -13
- package/dist/{cli-4wtq5jjv.js → cli-wbyk465z.js} +1 -1
- package/dist/{cli-3apbzgyk.js → cli-z61ykvam.js} +19 -14
- package/dist/{cli-e06a8a7y.js → cli-zkxymas5.js} +4 -3
- package/dist/cli.js +26 -25
- package/dist/{codex-adapter-jyw7a91z.js → codex-adapter-jjjk8w4m.js} +8 -9
- package/dist/{codex-hook-hfrt9shr.js → codex-hook-8jexc34x.js} +3 -3
- package/dist/{codex-session-runner-bmngj0s5.js → codex-session-runner-nd6ayxkx.js} +8 -9
- package/dist/{commands-n755g391.js → commands-9v4psyq1.js} +5 -5
- package/dist/{db-s1cgh5gv.js → db-wnt58tpe.js} +5 -5
- package/dist/dispatcher-05jh1aqk.js +74 -0
- package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
- package/dist/{google-generative-ai-tsskx7te.js → google-generative-ai-ndjmj5fa.js} +7 -7
- package/dist/{google-vertex-ppw8ydpa.js → google-vertex-fr665tqs.js} +10 -10
- package/dist/handlers-tw90pkh5.js +65 -0
- package/dist/{hook-jf0xe8zh.js → hook-123e2scb.js} +11 -12
- package/dist/{hook-h9cqrm8q.js → hook-sxe3r349.js} +11 -12
- package/dist/{http-nc6pydw5.js → http-ecsar8ez.js} +1442 -581
- package/dist/{index-ezxkds2n.js → index-16js521z.js} +335 -107
- package/dist/{index-769nc012.js → index-hw26vj40.js} +25 -19
- package/dist/{index-0wdy6gwc.js → index-nnrbpcjp.js} +25 -17
- package/dist/index-ymn7em0p.js +25 -0
- package/dist/{index-x1zcj09z.js → index-zj518gf9.js} +26 -20
- package/dist/{keepalive-nesm3xb6.js → keepalive-asqtcm4y.js} +7 -7
- package/dist/{lead-bwy6t2za.js → lead-xbfr7fvt.js} +40 -48
- package/dist/{maintenance-8w393zf0.js → maintenance-qma55qvw.js} +9 -9
- package/dist/{oauth-refresh-sweep-sh8xjy08.js → oauth-refresh-sweep-3s04c6qw.js} +6 -6
- package/dist/{onboard-25ps29h1.js → onboard-drskd386.js} +13 -4
- package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-wy6a43wd.js} +13 -13
- package/dist/{openai-responses-nmeyptke.js → openai-responses-6xwf7bzg.js} +19 -19
- package/dist/{opencode-adapter-dce4wskd.js → opencode-adapter-28axqa09.js} +4 -4
- package/dist/{otel-impl-b93gxnz5.js → otel-impl-943c96er.js} +1 -1
- package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-jcqt71cg.js} +17 -19
- package/dist/{pricing-refresh-5v56x7gb.js → pricing-refresh-mx51az05.js} +7 -7
- package/dist/{rbac-roles-x55cnezn.js → rbac-roles-78baecqd.js} +13 -9
- package/dist/{rbac-roles-0p0s6pbj.js → rbac-roles-wcmrg6sv.js} +7 -7
- package/dist/{render-v2-hyd45w8b.js → render-v2-8zjntgf5.js} +7 -7
- package/dist/{seed-pricing-49gbgn96.js → seed-pricing-jqjs6cws.js} +6 -6
- package/dist/{setup-qvq64vzq.js → setup-4pks0vfk.js} +2 -2
- package/dist/work-objects-wangt792.js +165 -0
- package/dist/{worker-scj60cxg.js → worker-p2mr422x.js} +40 -48
- package/openapi.json +1365 -268
- package/package.json +4 -3
- package/src/agentmail/handlers.ts +95 -66
- package/src/be/budget-refusal-notify.ts +1 -0
- package/src/be/db/tasks/read.ts +3 -0
- package/src/be/db/tasks/write.ts +13 -1
- package/src/be/db-client.ts +5 -0
- package/src/be/db.ts +15 -5
- package/src/be/extensions/db.ts +461 -0
- package/src/be/extensions/validate.ts +107 -0
- package/src/be/memory/boot-reembed.ts +17 -12
- package/src/be/memory/index.ts +12 -0
- package/src/be/memory/providers/openai-embedding.ts +4 -0
- package/src/be/memory/types.ts +2 -0
- package/src/be/migrations/153_deferred_task_wait_members.sql +25 -0
- package/src/be/migrations/154_routing_source.sql +3 -0
- package/src/be/migrations/155_extensions.sql +66 -0
- package/src/be/migrations/156_inbox_item_state_read_at.sql +7 -0
- package/src/be/rbac-roles.ts +3 -2
- package/src/be/scripts/typecheck.ts +59 -41
- package/src/be/seed/schedules-seeder.ts +25 -2
- package/src/be/seed/workflows-seeder.ts +17 -0
- package/src/be/seed-scripts/catalog/delegate.ts +3 -1
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/steering.ts +1 -0
- package/src/be/swarm-config-guard.ts +3 -1
- package/src/commands/credential-refresh.ts +70 -0
- package/src/commands/onboard/compose-generator.ts +14 -2
- package/src/commands/onboard/env-generator.ts +7 -0
- package/src/commands/provider-credentials.ts +2 -25
- package/src/commands/runner.ts +24 -57
- package/src/extensions/apply-task-create.ts +135 -0
- package/src/extensions/bundle-path.ts +10 -0
- package/src/extensions/contract-runtime.ts +7 -0
- package/src/extensions/contract-types.generated.ts +4 -0
- package/src/extensions/contract.ts +270 -0
- package/src/extensions/ctx.ts +186 -0
- package/src/extensions/dispatcher.ts +479 -0
- package/src/extensions/identity.ts +44 -0
- package/src/extensions/lifecycle.ts +281 -0
- package/src/extensions/loader.ts +207 -0
- package/src/extensions/post-bridge.ts +161 -0
- package/src/github/handlers.ts +185 -140
- package/src/gitlab/handlers.ts +97 -77
- package/src/heartbeat/heartbeat.ts +155 -83
- package/src/http/agents.ts +1 -1
- package/src/http/all-routes.ts +1 -0
- package/src/http/approval-requests.ts +1 -0
- package/src/http/apps.ts +14 -9
- package/src/http/config.ts +4 -1
- package/src/http/core.ts +38 -2
- package/src/http/extensions.ts +547 -0
- package/src/http/inbox-state.ts +2 -0
- package/src/http/index.ts +41 -3
- package/src/http/mcp-bridge.ts +96 -62
- package/src/http/mcp.ts +1 -1
- package/src/http/script-runs.ts +5 -0
- package/src/http/status.ts +6 -4
- package/src/http/tasks.ts +51 -30
- package/src/integrations/kapso/inbound.ts +15 -10
- package/src/jira/sync.ts +26 -16
- package/src/linear/sync.ts +26 -16
- package/src/prompts/session-templates.ts +18 -13
- package/src/providers/claude-adapter.ts +21 -8
- package/src/rbac/admission.ts +1 -1
- package/src/rbac/elevated-agents.ts +24 -0
- package/src/rbac/legacy-policy.ts +35 -6
- package/src/rbac/permissions.ts +8 -0
- package/src/scheduler/deferred-task-waits.ts +138 -27
- package/src/scheduler/schedule-task.ts +54 -24
- package/src/scheduler/scheduler.ts +108 -125
- package/src/scripts-runtime/executors/native.ts +5 -1
- package/src/scripts-runtime/executors/types.ts +5 -0
- package/src/scripts-runtime/import-allowlist.ts +79 -19
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/swarm-config.ts +8 -0
- package/src/scripts-runtime/swarm-sdk.ts +3 -0
- package/src/scripts-runtime/types/stdlib.d.ts +16 -3
- package/src/scripts-runtime/types/swarm-extension.d.ts +562 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +16 -3
- package/src/server.ts +6 -0
- package/src/slack/HEURISTICS.md +3 -1
- package/src/slack/actions.ts +21 -16
- package/src/slack/app.ts +2 -0
- package/src/slack/assistant.ts +4 -12
- package/src/slack/blocks.ts +1 -1
- package/src/slack/handlers.ts +107 -19
- package/src/slack/inbound-files.ts +9 -5
- package/src/slack/render-v2.ts +188 -38
- package/src/slack/router.ts +13 -3
- package/src/slack/steering.ts +3 -3
- package/src/slack/thread-buffer.ts +66 -23
- package/src/slack/work-objects.test.ts +252 -0
- package/src/slack/work-objects.ts +118 -0
- package/src/tasks/errors.ts +9 -0
- package/src/tasks/sibling-awareness.ts +35 -1
- package/src/tasks/worker-follow-up.ts +67 -11
- package/src/tests/acp-adapter.test.ts +10 -10
- package/src/tests/agent-fs-live-url.test.ts +40 -0
- package/src/tests/agent-fs-provision-seeder.test.ts +12 -12
- package/src/tests/api-key-tracking.test.ts +18 -18
- package/src/tests/api-key.test.ts +4 -2
- package/src/tests/apps-rbac.test.ts +1 -1
- package/src/tests/apps-spike5.test.ts +1 -1
- package/src/tests/apps-sync-engine.test.ts +8 -8
- package/src/tests/apps-user-config.test.ts +1 -1
- package/src/tests/artifact-sdk.test.ts +8 -8
- package/src/tests/asset-key-mcp.test.ts +2 -0
- package/src/tests/automation-preflight-alert.test.ts +1 -1
- package/src/tests/base-prompt.test.ts +7 -6
- package/src/tests/budget-user-scope.test.ts +1 -1
- package/src/tests/budgets-routes.test.ts +1 -1
- package/src/tests/claude-adapter-binary.test.ts +22 -40
- package/src/tests/claude-adapter-otel.test.ts +13 -7
- package/src/tests/claude-adapter.test.ts +8 -6
- package/src/tests/claude-hook-credentials.test.ts +3 -3
- package/src/tests/claude-managed-adapter.test.ts +4 -4
- package/src/tests/claude-managed-setup.test.ts +3 -3
- package/src/tests/claude-sdk-lifecycle.test.ts +1 -1
- package/src/tests/claude-sdk-transport.test.ts +6 -6
- package/src/tests/claude-stop-hook.test.ts +8 -8
- package/src/tests/claude-worker-parity.test.ts +3 -3
- package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +5 -5
- package/src/tests/codex-adapter.test.ts +7 -5
- package/src/tests/codex-app-server.test.ts +2 -2
- package/src/tests/codex-login.test.ts +15 -15
- package/src/tests/codex-oauth-credential-info.test.ts +4 -4
- package/src/tests/codex-oauth-keep-warm.test.ts +4 -4
- package/src/tests/codex-oauth-refresh-lock.test.ts +1 -1
- package/src/tests/codex-oauth-storage.test.ts +7 -7
- package/src/tests/codex-pool.test.ts +1 -1
- package/src/tests/codex-steering-hook.test.ts +1 -1
- package/src/tests/codex-swarm-events.test.ts +1 -1
- package/src/tests/config-api-only-keys.test.ts +1 -1
- package/src/tests/config-session-auth.test.ts +2 -2
- package/src/tests/connection-embedded-auth.test.ts +20 -18
- package/src/tests/core-auth.test.ts +1 -1
- package/src/tests/create-page-tool.test.ts +3 -3
- package/src/tests/credential-refresh.test.ts +115 -0
- package/src/tests/credential-wait.test.ts +2 -2
- package/src/tests/credentials.test.ts +6 -4
- package/src/tests/db-queries-oauth.test.ts +40 -40
- package/src/tests/defer-task.test.ts +73 -8
- package/src/tests/deferred-task-wait-migration.test.ts +64 -0
- package/src/tests/deferred-task-wake.test.ts +349 -8
- package/src/tests/devin-adapter.test.ts +1 -1
- package/src/tests/devin-api.test.ts +1 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/e2b-dispatch.test.ts +21 -19
- package/src/tests/e2e-claude-transport.test.ts +3 -3
- package/src/tests/e2e-redact.test.ts +6 -6
- package/src/tests/ensure-token.test.ts +68 -68
- package/src/tests/entrypoint-api-readiness.test.ts +1 -1
- package/src/tests/entrypoint-codex-oauth-seed.test.ts +13 -13
- package/src/tests/env-flag.test.ts +1 -0
- package/src/tests/events-http.test.ts +1 -1
- package/src/tests/extensions-db.test.ts +216 -0
- package/src/tests/extensions-dispatcher.test.ts +275 -0
- package/src/tests/extensions-example-heartbeat-remediate.test.ts +69 -0
- package/src/tests/extensions-example-mcp-install.test.ts +63 -0
- package/src/tests/extensions-example-no-exclamation-marks.test.ts +72 -0
- package/src/tests/extensions-example-rewrite-and-suppress.test.ts +70 -0
- package/src/tests/extensions-example-route-slack-channel.test.ts +217 -0
- package/src/tests/extensions-heartbeat.test.ts +291 -0
- package/src/tests/extensions-http.test.ts +431 -0
- package/src/tests/extensions-lead-equivalence.test.ts +49 -0
- package/src/tests/extensions-lifecycle.test.ts +209 -0
- package/src/tests/extensions-loader.test.ts +95 -0
- package/src/tests/extensions-mcp-tools.test.ts +245 -0
- package/src/tests/extensions-pre-task.test.ts +487 -0
- package/src/tests/extensions-run-context.test.ts +41 -0
- package/src/tests/extensions-tool-call.test.ts +288 -0
- package/src/tests/extensions-validate.test.ts +196 -0
- package/src/tests/fixtures/extensions/bad-import/hooks.ts +8 -0
- package/src/tests/fixtures/extensions/bad-import/manifest.json +9 -0
- package/src/tests/fixtures/extensions/bad-return-shape/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/bad-return-shape/manifest.json +9 -0
- package/src/tests/fixtures/extensions/block-tasks-from-source/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/block-tasks-from-source/manifest.json +9 -0
- package/src/tests/fixtures/extensions/ignore-channel/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/ignore-channel/manifest.json +9 -0
- package/src/tests/fixtures/extensions/load.ts +10 -0
- package/src/tests/fixtures/extensions/minimal/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/minimal/manifest.json +9 -0
- package/src/tests/fixtures/extensions/never-fail-long-tasks/hooks.ts +11 -0
- package/src/tests/fixtures/extensions/never-fail-long-tasks/manifest.json +9 -0
- package/src/tests/fixtures/extensions/no-exclamation-marks/hooks.ts +23 -0
- package/src/tests/fixtures/extensions/no-exclamation-marks/manifest.json +9 -0
- package/src/tests/fixtures/extensions/post-logger/hooks.ts +9 -0
- package/src/tests/fixtures/extensions/post-logger/manifest.json +9 -0
- package/src/tests/fixtures/extensions/priority-a/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/priority-a/manifest.json +9 -0
- package/src/tests/fixtures/extensions/priority-b/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/priority-b/manifest.json +9 -0
- package/src/tests/fixtures/extensions/record-only-on-tag/hooks.ts +16 -0
- package/src/tests/fixtures/extensions/record-only-on-tag/manifest.json +9 -0
- package/src/tests/fixtures/extensions/reserved-assets/hooks.ts +5 -0
- package/src/tests/fixtures/extensions/reserved-assets/manifest.json +10 -0
- package/src/tests/fixtures/extensions/rewrite-progress-prefix/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/rewrite-progress-prefix/manifest.json +9 -0
- package/src/tests/fixtures/extensions/rewrite-task-priority/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/rewrite-task-priority/manifest.json +9 -0
- package/src/tests/fixtures/extensions/route-channel-to-agent/hooks.ts +26 -0
- package/src/tests/fixtures/extensions/route-channel-to-agent/manifest.json +9 -0
- package/src/tests/fixtures/extensions/slow/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/slow/manifest.json +9 -0
- package/src/tests/fixtures/extensions/suppress-lead-follow-up/hooks.ts +12 -0
- package/src/tests/fixtures/extensions/suppress-lead-follow-up/manifest.json +9 -0
- package/src/tests/fixtures/extensions/throws/hooks.ts +12 -0
- package/src/tests/fixtures/extensions/throws/manifest.json +9 -0
- package/src/tests/fixtures/extensions/worker-runtime/hooks.ts +5 -0
- package/src/tests/fixtures/extensions/worker-runtime/manifest.json +9 -0
- package/src/tests/fs-routes.test.ts +1 -1
- package/src/tests/gitlab-auth.test.ts +10 -10
- package/src/tests/harness-provider-resolution.test.ts +8 -5
- package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
- package/src/tests/helper-credentials.test.ts +137 -0
- package/src/tests/http/context-routes.test.ts +2 -2
- package/src/tests/http-api-integration.test.ts +5 -2
- package/src/tests/http-users.test.ts +1 -1
- package/src/tests/identity-refresh.test.ts +2 -2
- package/src/tests/internal-ai/complete-structured.test.ts +2 -2
- package/src/tests/internal-ai/credentials.test.ts +19 -17
- package/src/tests/jira-metadata.test.ts +1 -1
- package/src/tests/jira-oauth.test.ts +5 -5
- package/src/tests/jira-sync.test.ts +1 -1
- package/src/tests/jira-webhook-lifecycle.test.ts +3 -3
- package/src/tests/jira-webhook.test.ts +2 -2
- package/src/tests/kapso-inbound.test.ts +2 -2
- package/src/tests/kv-http.test.ts +1 -1
- package/src/tests/kv-namespace-resolution.test.ts +1 -1
- package/src/tests/kv-page-proxy.test.ts +2 -2
- package/src/tests/launch-password-rejection.test.ts +2 -2
- package/src/tests/linear-webhook.test.ts +1 -1
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +6 -6
- package/src/tests/mcp-oauth-ensure-token.test.ts +28 -22
- package/src/tests/mcp-oauth-manual-client.test.ts +16 -12
- package/src/tests/mcp-oauth-queries.test.ts +35 -32
- package/src/tests/mcp-oauth-resolve-secrets.test.ts +8 -8
- package/src/tests/mcp-oauth-wrapper.test.ts +20 -20
- package/src/tests/mcp-user-route.test.ts +1 -1
- package/src/tests/memory-edges.test.ts +1 -1
- package/src/tests/memory-edit-authorization.test.ts +32 -0
- package/src/tests/memory-rate-endpoint.test.ts +1 -1
- package/src/tests/memory-rate-tool.test.ts +2 -2
- package/src/tests/memory-rater-e2e.test.ts +1 -1
- package/src/tests/memory-rater-llm-summarizer.test.ts +3 -3
- package/src/tests/memory-rater-llm.test.ts +1 -1
- package/src/tests/model-control.test.ts +3 -0
- package/src/tests/multi-runtime-enabled-stats.test.ts +2 -2
- package/src/tests/multi-runtime-registration.test.ts +111 -17
- package/src/tests/oauth-access-token-tool.test.ts +18 -18
- package/src/tests/oauth-callback-flow.test.ts +8 -8
- package/src/tests/oauth-credential-bindings.test.ts +29 -27
- package/src/tests/oauth-keepalive.test.ts +10 -10
- package/src/tests/oauth-presets.test.ts +13 -5
- package/src/tests/oauth-refresh-failure.test.ts +9 -9
- package/src/tests/oauth-refresh-sweep.test.ts +20 -13
- package/src/tests/oauth-wrapper.test.ts +1 -1
- package/src/tests/onboard-compose.test.ts +47 -3
- package/src/tests/onboard-env.test.ts +26 -26
- package/src/tests/onboard-non-interactive.test.ts +4 -4
- package/src/tests/opencode-adapter.test.ts +1 -1
- package/src/tests/opencode-plugin.test.ts +2 -2
- package/src/tests/otel-session-cost-metrics.test.ts +1 -1
- package/src/tests/page-proxy-authed.test.ts +2 -2
- package/src/tests/page-proxy.test.ts +2 -2
- package/src/tests/page-session.test.ts +7 -7
- package/src/tests/page-viewer-auth.test.ts +2 -2
- package/src/tests/pages-authed-mode.test.ts +1 -1
- package/src/tests/pages-http.test.ts +1 -1
- package/src/tests/pages-password-mode.test.ts +1 -1
- package/src/tests/pages-public-authed-401.test.ts +1 -1
- package/src/tests/pages-public-html.test.ts +2 -2
- package/src/tests/pages-view-count.test.ts +1 -1
- package/src/tests/pi-mono-adapter.test.ts +10 -10
- package/src/tests/pi-mono-extension.test.ts +2 -2
- package/src/tests/preload.ts +5 -0
- package/src/tests/pricing-routes.test.ts +1 -1
- package/src/tests/profile-sync-warning.test.ts +8 -8
- package/src/tests/profile-sync.test.ts +8 -8
- package/src/tests/prompt-template-session.test.ts +36 -5
- package/src/tests/provider-process-group.test.ts +95 -4
- package/src/tests/providers/pi-cost.test.ts +1 -1
- package/src/tests/queue-stall-alarm.test.ts +1 -1
- package/src/tests/rbac-admission.test.ts +19 -4
- package/src/tests/rbac-charact-http.test.ts +1 -1
- package/src/tests/rbac-e2e-helpers.ts +1 -1
- package/src/tests/rbac-engine.test.ts +39 -0
- package/src/tests/realtime-room-auth.test.ts +1 -1
- package/src/tests/realtime-room-surfaces.test.ts +1 -1
- package/src/tests/reload-config.test.ts +45 -1
- package/src/tests/routing-affinity-inventory.test.ts +1 -1
- package/src/tests/routing-reason-contract.test.ts +76 -3
- package/src/tests/routing-reason-inventory.test.ts +11 -6
- package/src/tests/routing-source.test.ts +53 -0
- package/src/tests/runner-agent-fs-provision-retry.test.ts +1 -1
- package/src/tests/runner-context-preamble.test.ts +1 -1
- package/src/tests/runner-deployment-resume.test.ts +1 -1
- package/src/tests/runner-fallback-output.test.ts +1 -1
- package/src/tests/runner-identity-refresh.test.ts +1 -1
- package/src/tests/runner-skills-refresh.test.ts +1 -1
- package/src/tests/schedule-target-type.test.ts +3 -3
- package/src/tests/scheduled-tasks.test.ts +14 -5
- package/src/tests/scheduler-occurrence.test.ts +347 -0
- package/src/tests/script-apis-mcp.test.ts +1 -1
- package/src/tests/script-connections-http.test.ts +61 -58
- package/src/tests/script-connections-mcp.test.ts +1 -1
- package/src/tests/script-connections.test.ts +3 -1
- package/src/tests/script-runs-http.test.ts +15 -7
- package/src/tests/script-workflows-runtime-e2e.test.ts +1 -1
- package/src/tests/scripts-boot-reembed.test.ts +4 -0
- package/src/tests/scripts-embeddings.test.ts +4 -0
- package/src/tests/scripts-external-api.test.ts +1 -1
- package/src/tests/scripts-http.test.ts +1 -1
- package/src/tests/scripts-import-allowlist.test.ts +44 -1
- package/src/tests/scripts-mcp-e2e.test.ts +81 -1
- package/src/tests/scripts-only-gating.test.ts +4 -2
- package/src/tests/scripts-retention.test.ts +1 -1
- package/src/tests/scripts-runtime-identity.test.ts +2 -2
- package/src/tests/scripts-runtime-secret-egress.test.ts +1 -1
- package/src/tests/scripts-runtime.test.ts +6 -4
- package/src/tests/scripts-typecheck.test.ts +21 -0
- package/src/tests/sdk-allowlist.test.ts +1 -1
- package/src/tests/secret-scrubber.test.ts +38 -31
- package/src/tests/seed-registry.test.ts +46 -8
- package/src/tests/seed-schedules.test.ts +44 -9
- package/src/tests/seed-workflows.test.ts +21 -9
- package/src/tests/send-task-output-schema.test.ts +9 -1
- package/src/tests/send-task-requested-by.test.ts +1 -0
- package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
- package/src/tests/session-costs-codex-recompute.test.ts +1 -1
- package/src/tests/session-costs-golden.test.ts +2 -2
- package/src/tests/session-costs-model-key-normalize.test.ts +2 -2
- package/src/tests/session-costs-recompute-all-providers.test.ts +1 -1
- package/src/tests/session-tokens.test.ts +1 -1
- package/src/tests/shutdown-error-scrubbing.test.ts +1 -1
- package/src/tests/slack-blocks.test.ts +12 -1
- package/src/tests/slack-file-tools-attachments.test.ts +1 -1
- package/src/tests/slack-inbound-files.test.ts +222 -86
- package/src/tests/slack-reaction-config.test.ts +5 -4
- package/src/tests/slack-read-boundaries.test.ts +1 -1
- package/src/tests/slack-render-v2.test.ts +196 -4
- package/src/tests/slack-router.test.ts +17 -2
- package/src/tests/slack-steering.test.ts +19 -0
- package/src/tests/status.test.ts +19 -7
- package/src/tests/steering-core.test.ts +1 -1
- package/src/tests/steering-enabled.test.ts +6 -8
- package/src/tests/steering-transport.test.ts +4 -4
- package/src/tests/store-progress-output-guidance.test.ts +34 -0
- package/src/tests/swarm-tool-result-gate.test.ts +11 -11
- package/src/tests/swarm-x-tool.test.ts +7 -5
- package/src/tests/sync-ai-toolbox-skills.test.ts +19 -0
- package/src/tests/task-supersede-resume.test.ts +1 -1
- package/src/tests/task-tool-preload-mcp.test.ts +4 -1
- package/src/tests/task-tools-ctx.test.ts +2 -0
- package/src/tests/tasks-requested-by-filter.test.ts +2 -2
- package/src/tests/telemetry-init.test.ts +11 -3
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/tool-output-agent-id.test.ts +1 -0
- package/src/tests/tool-registrar-no-input.test.ts +42 -1
- package/src/tests/tracker-fold.test.ts +7 -7
- package/src/tests/tracker-tools.test.ts +3 -3
- package/src/tests/ui-followup-lead-delegation.test.ts +1 -0
- package/src/tests/unified-oauth-migration.test.ts +5 -5
- package/src/tests/user-token-rest-auth.test.ts +1 -1
- package/src/tests/user-token-routes.test.ts +1 -1
- package/src/tests/whoami-route.test.ts +1 -1
- package/src/tests/workflow-agent-task.test.ts +15 -13
- package/src/tests/workflow-ctx.test.ts +1 -1
- package/src/tests/workflow-e2e.test.ts +1 -1
- package/src/tests/workflow-engine-v2.test.ts +3 -1
- package/src/tests/workflow-executors.test.ts +2 -2
- package/src/tests/workflow-http-v2.test.ts +8 -6
- package/src/tests/workflow-input-redaction.test.ts +7 -5
- package/src/tests/workflow-integration-io.test.ts +2 -2
- package/src/tests/workflow-llm.test.ts +5 -5
- package/src/tests/workflow-registry.test.ts +1 -1
- package/src/tests/workflow-swarm-script.test.ts +1 -1
- package/src/tests/workflow-triggers-v2.test.ts +23 -21
- package/src/tests/x-composio.test.ts +9 -7
- package/src/tests/x402-client.test.ts +1 -1
- package/src/tests/x402-config.test.ts +28 -41
- package/src/tools/defer-task.ts +156 -24
- package/src/tools/extension-common.ts +84 -0
- package/src/tools/extension-install.ts +65 -0
- package/src/tools/extension-list.ts +66 -0
- package/src/tools/script-common.ts +43 -18
- package/src/tools/send-task.ts +87 -105
- package/src/tools/skills/skill-publish.ts +1 -0
- package/src/tools/store-progress.ts +1 -1
- package/src/tools/task-action.ts +43 -22
- package/src/tools/task-tool-ctx.ts +2 -0
- package/src/tools/templates.ts +2 -1
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/utils.ts +140 -16
- package/src/types.ts +144 -0
- package/src/utils/constants.ts +7 -1
- package/src/utils/credentials.test.ts +16 -16
- package/src/utils/multi-runtime.ts +2 -2
- package/src/utils/steering-enabled.ts +4 -4
- package/src/workflows/executors/agent-task.ts +18 -3
- package/templates/ai-toolbox.manifest.json +7 -1
- package/templates/extensions/README.md +17 -0
- package/templates/extensions/notify-on-complete/README.md +11 -0
- package/templates/extensions/notify-on-complete/hooks.ts +61 -0
- package/templates/extensions/notify-on-complete/manifest.json +7 -0
- package/templates/extensions/require-ticket-ref/README.md +11 -0
- package/templates/extensions/require-ticket-ref/hooks.ts +30 -0
- package/templates/extensions/require-ticket-ref/manifest.json +7 -0
- package/templates/extensions/require-verification-note/README.md +11 -0
- package/templates/extensions/require-verification-note/hooks.ts +32 -0
- package/templates/extensions/require-verification-note/manifest.json +7 -0
- package/templates/schedules/daily-hn-briefing/config.json +1 -1
- package/templates/schedules/gtm-weekly-review/config.json +1 -1
- package/templates/schedules/weekly-code-health-reports/config.json +1 -1
- package/templates/schedules/weekly-dependabot-triage/config.json +1 -1
- package/templates/schedules/weekly-dora-metrics/config.json +1 -1
- package/templates/schedules/weekly-harness-upgrade-check/config.json +1 -1
- package/templates/skills/delegate-work/files/scripts/codex-exec.sh +1 -1
- package/templates/skills/scheduling/content.md +2 -0
- package/templates/skills/serply-search/SKILL.md +95 -0
- package/templates/skills/serply-search/config.json +13 -0
- package/templates/skills/serply-search/content.md +90 -0
- package/templates/skills/swarm-extensions/config.json +14 -0
- package/templates/skills/swarm-extensions/content.md +120 -0
- package/templates/skills/swarm-scripts/SKILL.md +2 -2
- package/templates/skills/swarm-scripts/content.md +2 -2
- package/templates/workflows/claude-code-changelog-watch/config.json +1 -1
- package/templates/workflows/gsc-topic-miner/config.json +1 -1
- package/templates/workflows/linear-drain-loop/config.json +1 -1
- package/templates/workflows/llm-safe-release-context/config.json +1 -1
- package/templates/workflows/ralph-loop/config.json +1 -1
- package/dist/cli-7fehefdf.js +0 -562
- package/dist/cli-ayvy5kde.js +0 -164
- package/dist/cli-ddfw1mc4.js +0 -4322
- package/dist/cli-hzqmgcm2.js +0 -3066
- package/dist/cli-j4d4f6hv.js +0 -338
- package/dist/cli-qgm2pfpq.js +0 -6377
- package/dist/cli-sdzq01t9.js +0 -823
- package/dist/cli-xvkmedgn.js +0 -332
- package/dist/cli-y3pq4v9g.js +0 -664
- package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-2y8nktar.js} +19 -19
- package/dist/{claude-managed-setup-f5pmsyrp.js → claude-managed-setup-48dwg9bv.js} +3 -3
- package/dist/{cli-81r683bv.js → cli-ch38q5z4.js} +0 -0
- package/dist/{cli-6664w7y4.js → cli-kj76p1ez.js} +8 -8
- package/dist/{cli-c71mg51n.js → cli-r2fpe7cx.js} +5 -5
- package/dist/{cli-4xz3pmrq.js → cli-y6x0gqtg.js} +16 -16
- package/dist/{index-aa3sa6s8.js → index-2wsdsnmm.js} +1 -1
- package/dist/{mistral-conversations-4ryk7h83.js → mistral-conversations-qhr84ph3.js} +9 -9
- package/dist/{openai-completions-0bqmsajw.js → openai-completions-32rdwmze.js} +19 -19
- package/dist/{openrouter-images-qx18fyp8.js → openrouter-images-9f9ek4rw.js} +3 -3
- package/dist/{pi-messages-79jvzz1d.js → pi-messages-b1mbr6gp.js} +4 -4
package/src/commands/runner.ts
CHANGED
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
buildResumeContextPreamble,
|
|
72
72
|
prependContextPreamble,
|
|
73
73
|
} from "./context-preamble.ts";
|
|
74
|
+
import { type CredentialRefreshState, refreshCredentialStatus } from "./credential-refresh.ts";
|
|
74
75
|
import {
|
|
75
76
|
awaitCredentials,
|
|
76
77
|
BootMaxWaitExceededError,
|
|
@@ -91,10 +92,8 @@ import {
|
|
|
91
92
|
buildLatestModelReport,
|
|
92
93
|
isCredCheckDisabled,
|
|
93
94
|
reportAcpStatus,
|
|
94
|
-
reportCredStatus,
|
|
95
95
|
reportLatestModel,
|
|
96
96
|
sendCredStatusReport,
|
|
97
|
-
shouldRefreshBedrockStatus,
|
|
98
97
|
} from "./provider-credentials.ts";
|
|
99
98
|
import {
|
|
100
99
|
type ResumeSessionCandidate,
|
|
@@ -4972,13 +4971,13 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
4972
4971
|
const cancelledSignaled = new Set<string>();
|
|
4973
4972
|
const steeringDispatchState = isSteeringEnabled() ? createSteeringDispatchState() : null;
|
|
4974
4973
|
|
|
4975
|
-
//
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4974
|
+
// Readiness acknowledged by the API, shared by boot and steady-state checks.
|
|
4975
|
+
const credentialRefreshState: CredentialRefreshState = {
|
|
4976
|
+
harnessProvider: null,
|
|
4977
|
+
ready: null,
|
|
4978
|
+
lastRefreshAt: 0,
|
|
4979
|
+
inFlight: false,
|
|
4980
|
+
};
|
|
4982
4981
|
|
|
4983
4982
|
// Throttle for live HARNESS_PROVIDER reconciliation. Each reconciliation
|
|
4984
4983
|
// calls `fetchResolvedEnv` which also re-resolves credential pools — we
|
|
@@ -4994,16 +4993,6 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
4994
4993
|
let lastServerCapsRefreshAt = 0;
|
|
4995
4994
|
const SERVER_CAPS_REFRESH_INTERVAL_MS = 300_000;
|
|
4996
4995
|
|
|
4997
|
-
// Throttle for the periodic Bedrock model-enumeration refresh. The credential
|
|
4998
|
-
// report below only re-runs on a harness_provider change (boot + provider
|
|
4999
|
-
// swap), so enabling Bedrock access after boot would otherwise never reach the
|
|
5000
|
-
// picker. This timer re-runs the enumeration on a fixed interval, decoupled
|
|
5001
|
-
// from the harness-change gate, so the UI stays accurate. 5 minutes keeps it
|
|
5002
|
-
// cheap (one bounded AWS enumeration per tick) while still surfacing newly
|
|
5003
|
-
// granted access within a few minutes.
|
|
5004
|
-
let lastBedrockRefreshAt = 0;
|
|
5005
|
-
const BEDROCK_REFRESH_INTERVAL_MS = 5 * 60 * 1000;
|
|
5006
|
-
|
|
5007
4996
|
// Fresh per boot and shared by registration, ping, and close: a restarted
|
|
5008
4997
|
// process is a new runtime, but one process presents one identity.
|
|
5009
4998
|
const runtimeInstanceId = crypto.randomUUID();
|
|
@@ -5055,7 +5044,7 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
5055
5044
|
? `${basePrompt}\n\n${additionalSystemPrompt}`
|
|
5056
5045
|
: basePrompt;
|
|
5057
5046
|
promptRebuiltForProvider = true;
|
|
5058
|
-
|
|
5047
|
+
credentialRefreshState.harnessProvider = null;
|
|
5059
5048
|
agentVisibleChanged = true;
|
|
5060
5049
|
console.log(
|
|
5061
5050
|
`[${role}] [harness] Swapped to ${resolvedProvider} (basePrompt rebuilt: ${basePrompt.length} chars)`,
|
|
@@ -5206,7 +5195,6 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
5206
5195
|
// CRED_CHECK_DISABLE=1 opts out entirely: the worker trusts the operator
|
|
5207
5196
|
// and starts polling immediately, with a NULL `cred_status` row that the
|
|
5208
5197
|
// dashboard surfaces as "unreported."
|
|
5209
|
-
cachedCredHarnessProvider = state.harnessProvider;
|
|
5210
5198
|
if (isCredCheckDisabled(process.env)) {
|
|
5211
5199
|
console.log(`[${role}] CRED_CHECK_DISABLE=1, skipping credential checks`);
|
|
5212
5200
|
} else {
|
|
@@ -5331,6 +5319,9 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
5331
5319
|
log: (line) => console.warn(`[${role}] ${line}`),
|
|
5332
5320
|
},
|
|
5333
5321
|
);
|
|
5322
|
+
credentialRefreshState.harnessProvider = state.harnessProvider;
|
|
5323
|
+
credentialRefreshState.ready = bootCredSnapshot?.ready ?? true;
|
|
5324
|
+
credentialRefreshState.lastRefreshAt = Date.now();
|
|
5334
5325
|
} catch (error) {
|
|
5335
5326
|
console.error(`[${role}] Failed to report credential readiness after recovery: ${error}`);
|
|
5336
5327
|
process.exit(1);
|
|
@@ -5915,41 +5906,17 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
5915
5906
|
}
|
|
5916
5907
|
}
|
|
5917
5908
|
|
|
5918
|
-
//
|
|
5919
|
-
//
|
|
5920
|
-
//
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
console.warn(`[${role}] cred_status post_task report failed (non-fatal): ${err}`),
|
|
5930
|
-
);
|
|
5931
|
-
} else if (
|
|
5932
|
-
shouldRefreshBedrockStatus({
|
|
5933
|
-
harnessProvider: currentHarness,
|
|
5934
|
-
env: process.env,
|
|
5935
|
-
lastRefreshAt: lastBedrockRefreshAt,
|
|
5936
|
-
now: Date.now(),
|
|
5937
|
-
intervalMs: BEDROCK_REFRESH_INTERVAL_MS,
|
|
5938
|
-
})
|
|
5939
|
-
) {
|
|
5940
|
-
// Bedrock enumeration drifts independently of the harness_provider:
|
|
5941
|
-
// access granted (or revoked) in the AWS console after boot won't flip
|
|
5942
|
-
// the provider, so the harness-change gate above never fires. Re-run the
|
|
5943
|
-
// enumeration on the throttled interval so the picker reflects the live
|
|
5944
|
-
// account state. One bounded AWS round-trip per tick.
|
|
5945
|
-
lastBedrockRefreshAt = Date.now();
|
|
5946
|
-
buildCredStatusReport(currentHarness, process.env, {}, "post_task")
|
|
5947
|
-
.then((snap) => reportCredStatus(apiUrl, apiKey, agentId, runtimeInstanceId, snap))
|
|
5948
|
-
.catch((err) =>
|
|
5949
|
-
console.warn(`[${role}] bedrock enumeration refresh failed (non-fatal): ${err}`),
|
|
5950
|
-
);
|
|
5951
|
-
}
|
|
5952
|
-
}
|
|
5909
|
+
// Recheck provider changes, blocked credentials, and Bedrock enumeration.
|
|
5910
|
+
// The helper honors CRED_CHECK_DISABLE, throttles retries, and prevents
|
|
5911
|
+
// overlapping reports while keeping polling responsive.
|
|
5912
|
+
refreshCredentialStatus(
|
|
5913
|
+
apiConfig,
|
|
5914
|
+
credentialRefreshState,
|
|
5915
|
+
state.harnessProvider,
|
|
5916
|
+
process.env,
|
|
5917
|
+
).catch((err) =>
|
|
5918
|
+
console.warn(`[${role}] cred_status post_task refresh failed (non-fatal): ${err}`),
|
|
5919
|
+
);
|
|
5953
5920
|
|
|
5954
5921
|
// Periodic VCS detection for running tasks (fire-and-forget, throttled per task)
|
|
5955
5922
|
const now = Date.now();
|
|
@@ -5970,7 +5937,7 @@ export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
|
5970
5937
|
|
|
5971
5938
|
// Check for cancelled tasks and signal their subprocesses. Deliberately
|
|
5972
5939
|
// NOT gated on steeringDispatchState — cancellation abort must keep
|
|
5973
|
-
// working when steering dispatch is off (STEERING_ENABLED
|
|
5940
|
+
// working when steering dispatch is off (STEERING_ENABLED=false).
|
|
5974
5941
|
if (state.activeTasks.size > 0) {
|
|
5975
5942
|
for (const [taskId, task] of state.activeTasks) {
|
|
5976
5943
|
if (cancelledSignaled.has(taskId)) continue; // Already sent SIGTERM
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { RequestInfo } from "../tools/utils";
|
|
2
|
+
import { type CreateTaskOptions, CreateTaskOptionsSchema } from "../types";
|
|
3
|
+
import { scrubSecrets } from "../utils/secret-scrubber";
|
|
4
|
+
import type { TaskCreateModify, TaskCreateOrigin } from "./contract";
|
|
5
|
+
import { dispatchPre, extensionIdForAgent, listRegistered } from "./dispatcher";
|
|
6
|
+
|
|
7
|
+
const MODIFIABLE_OPTION_KEYS = [
|
|
8
|
+
"agentId",
|
|
9
|
+
"creatorAgentId",
|
|
10
|
+
"source",
|
|
11
|
+
"taskType",
|
|
12
|
+
"tags",
|
|
13
|
+
"priority",
|
|
14
|
+
"dependsOn",
|
|
15
|
+
"offeredTo",
|
|
16
|
+
"vcsProvider",
|
|
17
|
+
"vcsRepo",
|
|
18
|
+
"vcsEventType",
|
|
19
|
+
"vcsNumber",
|
|
20
|
+
"vcsCommentId",
|
|
21
|
+
"vcsAuthor",
|
|
22
|
+
"vcsUrl",
|
|
23
|
+
"vcsInstallationId",
|
|
24
|
+
"vcsNodeId",
|
|
25
|
+
"agentmailInboxId",
|
|
26
|
+
"agentmailMessageId",
|
|
27
|
+
"agentmailThreadId",
|
|
28
|
+
"mentionMessageId",
|
|
29
|
+
"mentionChannelId",
|
|
30
|
+
"dir",
|
|
31
|
+
"model",
|
|
32
|
+
"modelTier",
|
|
33
|
+
"effort",
|
|
34
|
+
"outputSchema",
|
|
35
|
+
"followUpConfig",
|
|
36
|
+
"bypassTrackerContextDedup",
|
|
37
|
+
] as const satisfies readonly Exclude<keyof TaskCreateModify, "description">[];
|
|
38
|
+
|
|
39
|
+
type AssertNever<T extends never> = T;
|
|
40
|
+
type _AllModifiableOptionKeysCovered = AssertNever<
|
|
41
|
+
Exclude<keyof TaskCreateModify, "description" | (typeof MODIFIABLE_OPTION_KEYS)[number]>
|
|
42
|
+
>;
|
|
43
|
+
|
|
44
|
+
const MODIFIABLE_OPTION_KEY_SET = new Set<string>(MODIFIABLE_OPTION_KEYS);
|
|
45
|
+
|
|
46
|
+
type ApplyPreTaskCreateArgs = {
|
|
47
|
+
description: string;
|
|
48
|
+
options: CreateTaskOptions;
|
|
49
|
+
origin: TaskCreateOrigin;
|
|
50
|
+
requestInfo?: RequestInfo;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type ApplyPreTaskCreateResult =
|
|
54
|
+
| {
|
|
55
|
+
kind: "blocked";
|
|
56
|
+
reason: string;
|
|
57
|
+
extension: { id: string; name: string };
|
|
58
|
+
}
|
|
59
|
+
| { kind: "proceed"; description: string; options: CreateTaskOptions };
|
|
60
|
+
|
|
61
|
+
function warnDroppedKey(extensionName: string, key: string): void {
|
|
62
|
+
console.warn(
|
|
63
|
+
scrubSecrets(
|
|
64
|
+
`[extensions] pre.task.create ignored disallowed key "${key}" from extension "${extensionName}"`,
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function applyPreTaskCreate(
|
|
70
|
+
args: ApplyPreTaskCreateArgs,
|
|
71
|
+
): Promise<ApplyPreTaskCreateResult> {
|
|
72
|
+
const creatingExtensionId = extensionIdForAgent(args.requestInfo?.agentId);
|
|
73
|
+
const creatingExtension = creatingExtensionId
|
|
74
|
+
? listRegistered().find((loaded) => loaded.record.id === creatingExtensionId)
|
|
75
|
+
: undefined;
|
|
76
|
+
const origin = creatingExtension
|
|
77
|
+
? (`extension:${creatingExtension.record.name}` as const)
|
|
78
|
+
: args.origin;
|
|
79
|
+
|
|
80
|
+
const result = await dispatchPre(
|
|
81
|
+
"pre.task.create",
|
|
82
|
+
{
|
|
83
|
+
description: args.description,
|
|
84
|
+
options: args.options,
|
|
85
|
+
origin,
|
|
86
|
+
requestInfo: args.requestInfo,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
skipExtensionId: creatingExtensionId,
|
|
90
|
+
transformModify: ({ data, currentPayload, extension }) => {
|
|
91
|
+
const currentOptions = (currentPayload.options ?? {}) as CreateTaskOptions;
|
|
92
|
+
const filtered: Record<string, unknown> = {};
|
|
93
|
+
for (const [key, value] of Object.entries(data)) {
|
|
94
|
+
if (key === "description") {
|
|
95
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
96
|
+
throw new Error("Extension task description must be a non-empty string");
|
|
97
|
+
}
|
|
98
|
+
filtered.description = value;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (
|
|
102
|
+
!MODIFIABLE_OPTION_KEY_SET.has(key) ||
|
|
103
|
+
(key === "dir" && currentOptions.parentTaskId)
|
|
104
|
+
) {
|
|
105
|
+
warnDroppedKey(extension.name, key);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
filtered[key] = value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { description: _description, ...optionChanges } = filtered;
|
|
112
|
+
CreateTaskOptionsSchema.parse({ ...currentOptions, ...optionChanges });
|
|
113
|
+
return filtered;
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (result.action === "block") {
|
|
119
|
+
return {
|
|
120
|
+
kind: "blocked",
|
|
121
|
+
reason: result.reason,
|
|
122
|
+
extension: result.extension,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (result.action === "continue") {
|
|
126
|
+
return { kind: "proceed", description: args.description, options: args.options };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const { description, ...optionChanges } = result.data;
|
|
130
|
+
return {
|
|
131
|
+
kind: "proceed",
|
|
132
|
+
description: description ?? args.description,
|
|
133
|
+
options: CreateTaskOptionsSchema.parse({ ...args.options, ...optionChanges }),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function isSafeBundlePath(path: string): boolean {
|
|
2
|
+
return (
|
|
3
|
+
path.length > 0 &&
|
|
4
|
+
path.length <= 256 &&
|
|
5
|
+
!path.startsWith("/") &&
|
|
6
|
+
!path.includes("\\") &&
|
|
7
|
+
!path.includes("\0") &&
|
|
8
|
+
path.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..")
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Generated by scripts/bundle-extension-types.ts. Do not edit.
|
|
2
|
+
// biome-ignore-all lint/suspicious/noTemplateCurlyInString: Type declarations contain literal template placeholders.
|
|
3
|
+
export const EXTENSION_TYPE_DEFINITIONS =
|
|
4
|
+
'// biome-ignore-all lint/suspicious/noConfusingVoidType: Extension handlers may explicitly return no result.\ndeclare module "swarm-extension" {\n export type CreateTaskOptions = {\n key?: string | undefined;\n agentId?: string | null | undefined;\n creatorAgentId?: string | undefined;\n source?:\n | "workflow"\n | "schedule"\n | "slack"\n | "agentmail"\n | "mcp"\n | "api"\n | "ui"\n | "github"\n | "gitlab"\n | "system"\n | "linear"\n | "jira"\n | undefined;\n routingReason?:\n | "skill"\n | "continuity"\n | "overflow"\n | "human_pinned"\n | "reroute_fault"\n | undefined;\n routingSource?: "declared" | "engine_default" | undefined;\n routingNote?: string | undefined;\n taskType?: string | undefined;\n tags?: string[] | undefined;\n priority?: number | undefined;\n dependsOn?: string[] | undefined;\n offeredTo?: string | undefined;\n status?: "draft" | "backlog" | "unassigned" | undefined;\n slackChannelId?: string | undefined;\n slackThreadTs?: string | undefined;\n slackTriggerMessageTs?: string | undefined;\n slackUserId?: string | undefined;\n overrideSlackContext?: boolean | undefined;\n vcsProvider?: "github" | "gitlab" | undefined;\n vcsRepo?: string | undefined;\n vcsEventType?: string | undefined;\n vcsNumber?: number | undefined;\n vcsCommentId?: number | undefined;\n vcsAuthor?: string | undefined;\n vcsUrl?: string | undefined;\n vcsInstallationId?: number | undefined;\n vcsNodeId?: string | undefined;\n agentmailInboxId?: string | undefined;\n agentmailMessageId?: string | undefined;\n agentmailThreadId?: string | undefined;\n mentionMessageId?: string | undefined;\n mentionChannelId?: string | undefined;\n dir?: string | undefined;\n parentTaskId?: string | undefined;\n model?: string | undefined;\n modelTier?: "smol" | "regular" | "smart" | "ultra" | undefined;\n effort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;\n scheduleId?: string | undefined;\n workflowRunId?: string | undefined;\n workflowRunStepId?: string | undefined;\n sourceTaskId?: string | undefined;\n outputSchema?: Record<string, unknown> | undefined;\n inheritParentOutputSchema?: boolean | undefined;\n inheritParentRoutingAffinity?: boolean | undefined;\n followUpConfig?:\n | {\n disabled?: boolean | undefined;\n onCompleted?: string | undefined;\n onFailed?: string | undefined;\n }\n | undefined;\n requestedByUserId?: string | undefined;\n contextKey?: string | undefined;\n bypassTrackerContextDedup?: boolean | undefined;\n routingAffinity?:\n | {\n capabilities: string[];\n sourceAgentId?: string | undefined;\n role?: string | undefined;\n harnessProvider?:\n | "claude"\n | "codex"\n | "pi"\n | "devin"\n | "claude-managed"\n | "opencode"\n | "acp"\n | undefined;\n leadOnly?: boolean | undefined;\n }\n | undefined;\n };\n\n export type AgentTask = {\n id: string;\n key: string;\n agentId: string | null;\n task: string;\n status:\n | "draft"\n | "backlog"\n | "unassigned"\n | "offered"\n | "reviewing"\n | "pending"\n | "in_progress"\n | "paused"\n | "completed"\n | "failed"\n | "cancelled"\n | "superseded";\n source:\n | "workflow"\n | "schedule"\n | "slack"\n | "agentmail"\n | "mcp"\n | "api"\n | "ui"\n | "github"\n | "gitlab"\n | "system"\n | "linear"\n | "jira";\n tags: string[];\n priority: number;\n dependsOn: string[];\n createdAt: string;\n lastUpdatedAt: string;\n slackReplySent: boolean;\n wasPaused: boolean;\n creatorAgentId?: string | undefined;\n title?: string | undefined;\n routingReason?:\n | "skill"\n | "continuity"\n | "overflow"\n | "human_pinned"\n | "reroute_fault"\n | undefined;\n routingSource?: "declared" | "engine_default" | undefined;\n routingNote?: string | undefined;\n taskType?: string | undefined;\n offeredTo?: string | undefined;\n offeredAt?: string | undefined;\n acceptedAt?: string | undefined;\n rejectionReason?: string | undefined;\n finishedAt?: string | undefined;\n notifiedAt?: string | undefined;\n failureReason?: string | undefined;\n output?: string | undefined;\n progress?: string | undefined;\n slackChannelId?: string | undefined;\n slackThreadTs?: string | undefined;\n slackTriggerMessageTs?: string | undefined;\n slackUserId?: string | undefined;\n slackProgressMessageTs?: string | undefined;\n slackTreeRootMessageTs?: string | undefined;\n vcsProvider?: "github" | "gitlab" | undefined;\n vcsRepo?: string | undefined;\n vcsEventType?: string | undefined;\n vcsNumber?: number | undefined;\n vcsCommentId?: number | undefined;\n vcsAuthor?: string | undefined;\n vcsUrl?: string | undefined;\n vcsInstallationId?: number | undefined;\n vcsNodeId?: string | undefined;\n agentmailInboxId?: string | undefined;\n agentmailMessageId?: string | undefined;\n agentmailThreadId?: string | undefined;\n mentionMessageId?: string | undefined;\n mentionChannelId?: string | undefined;\n dir?: string | undefined;\n parentTaskId?: string | undefined;\n claudeSessionId?: string | undefined;\n model?: string | undefined;\n modelTier?: "smol" | "regular" | "smart" | "ultra" | undefined;\n effort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;\n scheduleId?: string | undefined;\n workflowRunId?: string | null | undefined;\n workflowRunStepId?: string | null | undefined;\n contextKey?: string | undefined;\n outputSchema?: Record<string, unknown> | undefined;\n followUpConfig?:\n | {\n disabled?: boolean | undefined;\n onCompleted?: string | undefined;\n onFailed?: string | undefined;\n }\n | undefined;\n compactionCount?: number | undefined;\n peakContextPercent?: number | undefined;\n peakContextTokens?: number | undefined;\n contextWindowSize?: number | undefined;\n credentialKeySuffix?: string | undefined;\n credentialKeyType?: string | undefined;\n requestedByUserId?: string | undefined;\n swarmVersion?: string | undefined;\n provider?:\n | "claude"\n | "codex"\n | "pi"\n | "devin"\n | "claude-managed"\n | "opencode"\n | "acp"\n | undefined;\n providerMeta?: Record<string, unknown> | undefined;\n harnessVariant?: string | undefined;\n harnessVariantMeta?: Record<string, unknown> | undefined;\n totalCostUsd?: number | undefined;\n routingAffinity?:\n | {\n capabilities: string[];\n sourceAgentId?: string | undefined;\n role?: string | undefined;\n harnessProvider?:\n | "claude"\n | "codex"\n | "pi"\n | "devin"\n | "claude-managed"\n | "opencode"\n | "acp"\n | undefined;\n leadOnly?: boolean | undefined;\n }\n | undefined;\n routingAffinityInvalid?: boolean | undefined;\n };\n\n export type ActiveSession = {\n id: string;\n agentId: string;\n taskId: string | null;\n triggerType: string;\n inboxMessageId: string | null;\n taskDescription: string | null;\n runnerSessionId: string | null;\n providerSessionId: string | null;\n startedAt: string;\n lastHeartbeatAt: string;\n runtimeInstanceId?: string | null | undefined;\n };\n\n export type RequestInfo = {\n sessionId: string | undefined;\n agentId: string | undefined;\n runtimeInstanceId: string | undefined;\n sourceTaskId: string | undefined;\n contextKey: string | undefined;\n callOrigin: "mcp" | "extension" | "script-sdk";\n };\n\n import type { SwarmSdk } from "swarm-sdk";\n import type { z } from "zod";\n export type Runtime = "api" | "worker";\n export interface ExtensionManifest {\n name: string;\n description: string;\n version: string;\n runtime: Runtime;\n assets: {\n hooks: string;\n skills?: string[];\n workflows?: string[];\n schedules?: string[];\n };\n homepage?: string;\n author?: string;\n }\n export interface HooksModule {\n default: SwarmExtension;\n config?: z.ZodTypeAny;\n }\n export interface ExtensionState {\n get<T = unknown>(key: string): Promise<T | null>;\n set<T>(key: string, value: T): Promise<void>;\n incr(key: string, by?: number): Promise<number>;\n del(key: string): Promise<void>;\n }\n export interface ExtensionLogger {\n debug(message: string, data?: unknown): void;\n info(message: string, data?: unknown): void;\n warn(message: string, data?: unknown): void;\n error(message: string, data?: unknown): void;\n }\n type ConfigFor<M extends ExtensionManifest> = M extends {\n config: infer C extends z.ZodTypeAny;\n }\n ? z.infer<C>\n : Record<string, unknown>;\n export interface ApiCtx<Config = Record<string, unknown>> {\n swarm: SwarmSdk;\n state: ExtensionState;\n config: Config;\n log: ExtensionLogger;\n signal: AbortSignal;\n event: {\n name: keyof SwarmEventMap;\n at: string;\n extension: {\n id: string;\n version: number;\n };\n };\n }\n export interface WorkerCtx<Config = Record<string, unknown>>\n extends Omit<ApiCtx<Config>, "swarm"> {\n swarm: SwarmSdk;\n worker: {\n agentId: string;\n taskId: string;\n harness: string;\n };\n }\n export type CtxFor<M extends ExtensionManifest> = M["runtime"] extends "api"\n ? ApiCtx<ConfigFor<M>>\n : WorkerCtx<ConfigFor<M>>;\n export type PreResult<Modify> =\n | void\n | {\n action: "continue";\n }\n | {\n action: "modify";\n data: Modify;\n }\n | {\n action: "block";\n reason: string;\n };\n export type TaskCreateOrigin =\n | "rest"\n | "app"\n | "mcp"\n | "slack"\n | "schedule"\n | "workflow"\n | "webhook"\n | "followUp"\n | `extension:${string}`;\n export interface TaskCreateEvent {\n options: CreateTaskOptions;\n description: string;\n origin: TaskCreateOrigin;\n requestInfo?: RequestInfo;\n }\n export type TaskCreateModify = Partial<\n Pick<\n CreateTaskOptions,\n | "agentId"\n | "creatorAgentId"\n | "source"\n | "taskType"\n | "tags"\n | "priority"\n | "dependsOn"\n | "offeredTo"\n | "vcsProvider"\n | "vcsRepo"\n | "vcsEventType"\n | "vcsNumber"\n | "vcsCommentId"\n | "vcsAuthor"\n | "vcsUrl"\n | "vcsInstallationId"\n | "vcsNodeId"\n | "agentmailInboxId"\n | "agentmailMessageId"\n | "agentmailThreadId"\n | "mentionMessageId"\n | "mentionChannelId"\n | "dir"\n | "model"\n | "modelTier"\n | "effort"\n | "outputSchema"\n | "followUpConfig"\n | "bypassTrackerContextDedup"\n >\n > & {\n description?: string;\n };\n export interface TaskFollowUpEvent {\n completedTask: AgentTask;\n status: "completed" | "failed";\n output?: string;\n failureReason?: string;\n workerAgentId: string;\n leadAgentId: string;\n summary: string;\n }\n export type TaskFollowUpModify = Partial<\n Pick<CreateTaskOptions, "agentId" | "priority" | "followUpConfig">\n > & {\n description?: string;\n };\n export interface SlackRouteEvent {\n channelId: string;\n userId: string;\n text: string;\n threadTs?: string;\n botMentioned: boolean;\n threadContext?: {\n channelId: string;\n threadTs: string;\n };\n }\n export interface SlackRouteModify {\n target:\n | {\n kind: "agent";\n agentId: string;\n }\n | {\n kind: "lead";\n }\n | {\n kind: "broadcast";\n };\n }\n export type HeartbeatClassification = "no-session" | "stale-session" | "fresh-stalled";\n export type HeartbeatAction = "supersede-resume" | "fail" | "record";\n export interface HeartbeatRemediateEvent {\n task: AgentTask;\n session?: ActiveSession;\n classification: HeartbeatClassification;\n proposedAction: HeartbeatAction;\n reason: string;\n taskAgeMs: number;\n sessionHeartbeatAgeMs?: number;\n }\n export interface HeartbeatRemediateModify {\n proposedAction: HeartbeatAction;\n }\n export interface ToolCallEvent {\n tool: string;\n args: unknown;\n requestInfo: RequestInfo;\n }\n export interface ToolCallModify {\n args: unknown;\n }\n export interface TaskEvent {\n task: AgentTask;\n }\n export interface TaskCompletedEvent extends TaskEvent {\n output: string;\n }\n export interface TaskFailedEvent extends TaskEvent {\n failureReason: string;\n }\n export interface TaskSupersededEvent extends TaskEvent {\n supersededBy: string;\n }\n export interface TaskProgressEvent extends TaskEvent {\n progress: string;\n }\n export interface SlackMessageEvent {\n channelId: string;\n userId: string;\n text: string;\n threadTs?: string;\n taskId?: string;\n }\n export interface ToolCallCompletedEvent extends ToolCallEvent {\n result: unknown;\n durationMs: number;\n }\n export interface SwarmEventMap {\n "pre.task.create": {\n event: TaskCreateEvent;\n modify: TaskCreateModify;\n result: PreResult<TaskCreateModify>;\n };\n "pre.task.followUp": {\n event: TaskFollowUpEvent;\n modify: TaskFollowUpModify;\n result: PreResult<TaskFollowUpModify>;\n };\n "pre.slack.route": {\n event: SlackRouteEvent;\n modify: SlackRouteModify;\n result: PreResult<SlackRouteModify>;\n };\n "pre.heartbeat.remediate": {\n event: HeartbeatRemediateEvent;\n modify: HeartbeatRemediateModify;\n result: PreResult<HeartbeatRemediateModify>;\n };\n "pre.tool.call": {\n event: ToolCallEvent;\n modify: ToolCallModify;\n result: PreResult<ToolCallModify>;\n };\n "post.task.created": {\n event: TaskEvent;\n modify: never;\n result: void;\n };\n "post.task.completed": {\n event: TaskCompletedEvent;\n modify: never;\n result: void;\n };\n "post.task.failed": {\n event: TaskFailedEvent;\n modify: never;\n result: void;\n };\n "post.task.cancelled": {\n event: TaskEvent;\n modify: never;\n result: void;\n };\n "post.task.superseded": {\n event: TaskSupersededEvent;\n modify: never;\n result: void;\n };\n "post.task.progress": {\n event: TaskProgressEvent;\n modify: never;\n result: void;\n };\n "post.slack.message": {\n event: SlackMessageEvent;\n modify: never;\n result: void;\n };\n "post.tool.call": {\n event: ToolCallCompletedEvent;\n modify: never;\n result: void;\n };\n }\n export interface ExtensionApi<\n M extends ExtensionManifest = ExtensionManifest & {\n runtime: "api";\n },\n > {\n on<E extends keyof SwarmEventMap>(\n event: E,\n handler: (\n event: SwarmEventMap[E]["event"],\n ctx: CtxFor<M>,\n ) => Promise<SwarmEventMap[E]["result"]> | SwarmEventMap[E]["result"],\n opts?: {\n priority?: number;\n },\n ): void;\n }\n export type SwarmExtension<\n M extends ExtensionManifest = ExtensionManifest & {\n runtime: "api";\n },\n > = (api: ExtensionApi<M>) => void;\n export { block, modify } from "./contract-runtime";\n}\n';
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// biome-ignore-all lint/suspicious/noConfusingVoidType: Extension handlers may explicitly return no result.
|
|
2
|
+
import type { SwarmSdk } from "swarm-sdk";
|
|
3
|
+
import type { z } from "zod";
|
|
4
|
+
import type { RequestInfo } from "../tools/utils";
|
|
5
|
+
import type { ActiveSession, AgentTask, CreateTaskOptions } from "../types";
|
|
6
|
+
|
|
7
|
+
export type Runtime = "api" | "worker";
|
|
8
|
+
|
|
9
|
+
export interface ExtensionManifest {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
version: string;
|
|
13
|
+
runtime: Runtime;
|
|
14
|
+
assets: {
|
|
15
|
+
hooks: string;
|
|
16
|
+
skills?: string[];
|
|
17
|
+
workflows?: string[];
|
|
18
|
+
schedules?: string[];
|
|
19
|
+
};
|
|
20
|
+
homepage?: string;
|
|
21
|
+
author?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HooksModule {
|
|
25
|
+
default: SwarmExtension;
|
|
26
|
+
config?: z.ZodTypeAny;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ExtensionState {
|
|
30
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
31
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
32
|
+
incr(key: string, by?: number): Promise<number>;
|
|
33
|
+
del(key: string): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ExtensionLogger {
|
|
37
|
+
debug(message: string, data?: unknown): void;
|
|
38
|
+
info(message: string, data?: unknown): void;
|
|
39
|
+
warn(message: string, data?: unknown): void;
|
|
40
|
+
error(message: string, data?: unknown): void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type ConfigFor<M extends ExtensionManifest> = M extends {
|
|
44
|
+
config: infer C extends z.ZodTypeAny;
|
|
45
|
+
}
|
|
46
|
+
? z.infer<C>
|
|
47
|
+
: Record<string, unknown>;
|
|
48
|
+
|
|
49
|
+
export interface ApiCtx<Config = Record<string, unknown>> {
|
|
50
|
+
swarm: SwarmSdk;
|
|
51
|
+
state: ExtensionState;
|
|
52
|
+
config: Config;
|
|
53
|
+
log: ExtensionLogger;
|
|
54
|
+
signal: AbortSignal;
|
|
55
|
+
event: {
|
|
56
|
+
name: keyof SwarmEventMap;
|
|
57
|
+
at: string;
|
|
58
|
+
extension: { id: string; version: number };
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface WorkerCtx<Config = Record<string, unknown>> extends Omit<ApiCtx<Config>, "swarm"> {
|
|
63
|
+
swarm: SwarmSdk;
|
|
64
|
+
worker: { agentId: string; taskId: string; harness: string };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type CtxFor<M extends ExtensionManifest> = M["runtime"] extends "api"
|
|
68
|
+
? ApiCtx<ConfigFor<M>>
|
|
69
|
+
: WorkerCtx<ConfigFor<M>>;
|
|
70
|
+
|
|
71
|
+
export type PreResult<Modify> =
|
|
72
|
+
| void
|
|
73
|
+
| { action: "continue" }
|
|
74
|
+
| { action: "modify"; data: Modify }
|
|
75
|
+
| { action: "block"; reason: string };
|
|
76
|
+
|
|
77
|
+
export type TaskCreateOrigin =
|
|
78
|
+
| "rest"
|
|
79
|
+
| "app"
|
|
80
|
+
| "mcp"
|
|
81
|
+
| "slack"
|
|
82
|
+
| "schedule"
|
|
83
|
+
| "workflow"
|
|
84
|
+
| "webhook"
|
|
85
|
+
| "followUp"
|
|
86
|
+
| `extension:${string}`;
|
|
87
|
+
|
|
88
|
+
export interface TaskCreateEvent {
|
|
89
|
+
options: CreateTaskOptions;
|
|
90
|
+
description: string;
|
|
91
|
+
origin: TaskCreateOrigin;
|
|
92
|
+
requestInfo?: RequestInfo;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type TaskCreateModify = Partial<
|
|
96
|
+
Pick<
|
|
97
|
+
CreateTaskOptions,
|
|
98
|
+
| "agentId"
|
|
99
|
+
| "creatorAgentId"
|
|
100
|
+
| "source"
|
|
101
|
+
| "taskType"
|
|
102
|
+
| "tags"
|
|
103
|
+
| "priority"
|
|
104
|
+
| "dependsOn"
|
|
105
|
+
| "offeredTo"
|
|
106
|
+
| "vcsProvider"
|
|
107
|
+
| "vcsRepo"
|
|
108
|
+
| "vcsEventType"
|
|
109
|
+
| "vcsNumber"
|
|
110
|
+
| "vcsCommentId"
|
|
111
|
+
| "vcsAuthor"
|
|
112
|
+
| "vcsUrl"
|
|
113
|
+
| "vcsInstallationId"
|
|
114
|
+
| "vcsNodeId"
|
|
115
|
+
| "agentmailInboxId"
|
|
116
|
+
| "agentmailMessageId"
|
|
117
|
+
| "agentmailThreadId"
|
|
118
|
+
| "mentionMessageId"
|
|
119
|
+
| "mentionChannelId"
|
|
120
|
+
| "dir"
|
|
121
|
+
| "model"
|
|
122
|
+
| "modelTier"
|
|
123
|
+
| "effort"
|
|
124
|
+
| "outputSchema"
|
|
125
|
+
| "followUpConfig"
|
|
126
|
+
| "bypassTrackerContextDedup"
|
|
127
|
+
>
|
|
128
|
+
> & { description?: string };
|
|
129
|
+
|
|
130
|
+
export interface TaskFollowUpEvent {
|
|
131
|
+
completedTask: AgentTask;
|
|
132
|
+
status: "completed" | "failed";
|
|
133
|
+
output?: string;
|
|
134
|
+
failureReason?: string;
|
|
135
|
+
workerAgentId: string;
|
|
136
|
+
leadAgentId: string;
|
|
137
|
+
summary: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export type TaskFollowUpModify = Partial<
|
|
141
|
+
Pick<CreateTaskOptions, "agentId" | "priority" | "followUpConfig">
|
|
142
|
+
> & { description?: string };
|
|
143
|
+
|
|
144
|
+
export interface SlackRouteEvent {
|
|
145
|
+
channelId: string;
|
|
146
|
+
userId: string;
|
|
147
|
+
text: string;
|
|
148
|
+
threadTs?: string;
|
|
149
|
+
botMentioned: boolean;
|
|
150
|
+
threadContext?: { channelId: string; threadTs: string };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface SlackRouteModify {
|
|
154
|
+
target: { kind: "agent"; agentId: string } | { kind: "lead" } | { kind: "broadcast" };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export type HeartbeatClassification = "no-session" | "stale-session" | "fresh-stalled";
|
|
158
|
+
export type HeartbeatAction = "supersede-resume" | "fail" | "record";
|
|
159
|
+
|
|
160
|
+
export interface HeartbeatRemediateEvent {
|
|
161
|
+
task: AgentTask;
|
|
162
|
+
session?: ActiveSession;
|
|
163
|
+
classification: HeartbeatClassification;
|
|
164
|
+
proposedAction: HeartbeatAction;
|
|
165
|
+
reason: string;
|
|
166
|
+
taskAgeMs: number;
|
|
167
|
+
sessionHeartbeatAgeMs?: number;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface HeartbeatRemediateModify {
|
|
171
|
+
proposedAction: HeartbeatAction;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface ToolCallEvent {
|
|
175
|
+
tool: string;
|
|
176
|
+
args: unknown;
|
|
177
|
+
requestInfo: RequestInfo;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface ToolCallModify {
|
|
181
|
+
args: unknown;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface TaskEvent {
|
|
185
|
+
task: AgentTask;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface TaskCompletedEvent extends TaskEvent {
|
|
189
|
+
output: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface TaskFailedEvent extends TaskEvent {
|
|
193
|
+
failureReason: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface TaskSupersededEvent extends TaskEvent {
|
|
197
|
+
supersededBy: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface TaskProgressEvent extends TaskEvent {
|
|
201
|
+
progress: string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface SlackMessageEvent {
|
|
205
|
+
channelId: string;
|
|
206
|
+
userId: string;
|
|
207
|
+
text: string;
|
|
208
|
+
threadTs?: string;
|
|
209
|
+
taskId?: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface ToolCallCompletedEvent extends ToolCallEvent {
|
|
213
|
+
result: unknown;
|
|
214
|
+
durationMs: number;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface SwarmEventMap {
|
|
218
|
+
"pre.task.create": {
|
|
219
|
+
event: TaskCreateEvent;
|
|
220
|
+
modify: TaskCreateModify;
|
|
221
|
+
result: PreResult<TaskCreateModify>;
|
|
222
|
+
};
|
|
223
|
+
"pre.task.followUp": {
|
|
224
|
+
event: TaskFollowUpEvent;
|
|
225
|
+
modify: TaskFollowUpModify;
|
|
226
|
+
result: PreResult<TaskFollowUpModify>;
|
|
227
|
+
};
|
|
228
|
+
"pre.slack.route": {
|
|
229
|
+
event: SlackRouteEvent;
|
|
230
|
+
modify: SlackRouteModify;
|
|
231
|
+
result: PreResult<SlackRouteModify>;
|
|
232
|
+
};
|
|
233
|
+
"pre.heartbeat.remediate": {
|
|
234
|
+
event: HeartbeatRemediateEvent;
|
|
235
|
+
modify: HeartbeatRemediateModify;
|
|
236
|
+
result: PreResult<HeartbeatRemediateModify>;
|
|
237
|
+
};
|
|
238
|
+
"pre.tool.call": {
|
|
239
|
+
event: ToolCallEvent;
|
|
240
|
+
modify: ToolCallModify;
|
|
241
|
+
result: PreResult<ToolCallModify>;
|
|
242
|
+
};
|
|
243
|
+
"post.task.created": { event: TaskEvent; modify: never; result: void };
|
|
244
|
+
"post.task.completed": { event: TaskCompletedEvent; modify: never; result: void };
|
|
245
|
+
"post.task.failed": { event: TaskFailedEvent; modify: never; result: void };
|
|
246
|
+
"post.task.cancelled": { event: TaskEvent; modify: never; result: void };
|
|
247
|
+
"post.task.superseded": { event: TaskSupersededEvent; modify: never; result: void };
|
|
248
|
+
"post.task.progress": { event: TaskProgressEvent; modify: never; result: void };
|
|
249
|
+
"post.slack.message": { event: SlackMessageEvent; modify: never; result: void };
|
|
250
|
+
"post.tool.call": { event: ToolCallCompletedEvent; modify: never; result: void };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export interface ExtensionApi<
|
|
254
|
+
M extends ExtensionManifest = ExtensionManifest & { runtime: "api" },
|
|
255
|
+
> {
|
|
256
|
+
on<E extends keyof SwarmEventMap>(
|
|
257
|
+
event: E,
|
|
258
|
+
handler: (
|
|
259
|
+
event: SwarmEventMap[E]["event"],
|
|
260
|
+
ctx: CtxFor<M>,
|
|
261
|
+
) => Promise<SwarmEventMap[E]["result"]> | SwarmEventMap[E]["result"],
|
|
262
|
+
opts?: { priority?: number },
|
|
263
|
+
): void;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export type SwarmExtension<M extends ExtensionManifest = ExtensionManifest & { runtime: "api" }> = (
|
|
267
|
+
api: ExtensionApi<M>,
|
|
268
|
+
) => void;
|
|
269
|
+
|
|
270
|
+
export { block, modify } from "./contract-runtime";
|