@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/tools/send-task.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
hasCapacity,
|
|
16
16
|
} from "@/be/db";
|
|
17
17
|
import { repointTrackerSyncBySwarmId } from "@/be/db-queries/tracker";
|
|
18
|
+
import { applyPreTaskCreate } from "@/extensions/apply-task-create";
|
|
18
19
|
import { checkSlackRoutingCoherence } from "@/tasks/slack-routing";
|
|
19
20
|
import { findDuplicateTask } from "@/tools/task-dedup";
|
|
20
21
|
import { ownerCtx, type ToolCtx } from "@/tools/task-tool-ctx";
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
import {
|
|
29
30
|
type AgentTask,
|
|
30
31
|
AssetKeySchema,
|
|
32
|
+
type CreateTaskOptions,
|
|
31
33
|
FollowUpConfigSchema,
|
|
32
34
|
ModelTierSchema,
|
|
33
35
|
ReasoningEffortSchema,
|
|
@@ -69,7 +71,9 @@ export const sendTaskInputSchema = z
|
|
|
69
71
|
.string()
|
|
70
72
|
.max(200)
|
|
71
73
|
.optional()
|
|
72
|
-
.describe(
|
|
74
|
+
.describe(
|
|
75
|
+
"Why this worker fits the task. Required when agentId is supplied: at least 10 characters after trimming whitespace, maximum 200 characters. Optional for implicit parent or pool routing.",
|
|
76
|
+
),
|
|
73
77
|
task: z.string().min(1).describe("The task description to send."),
|
|
74
78
|
key: AssetKeySchema.optional().describe(
|
|
75
79
|
"Logical namespace key. Child tasks inherit their parent namespace when provided.",
|
|
@@ -190,6 +194,14 @@ export const sendTaskInputSchema = z
|
|
|
190
194
|
path: ["routingReason"],
|
|
191
195
|
});
|
|
192
196
|
}
|
|
197
|
+
if (data.agentId !== undefined && (data.routingNote?.trim().length ?? 0) < 10) {
|
|
198
|
+
ctx.addIssue({
|
|
199
|
+
code: z.ZodIssueCode.custom,
|
|
200
|
+
message:
|
|
201
|
+
"routingNote is required when agentId is supplied (at least 10 characters after trim).",
|
|
202
|
+
path: ["routingNote"],
|
|
203
|
+
});
|
|
204
|
+
}
|
|
193
205
|
checkOutputSchemaShape(data.outputSchema, ctx);
|
|
194
206
|
});
|
|
195
207
|
|
|
@@ -269,6 +281,11 @@ export async function sendTaskHandler(
|
|
|
269
281
|
if (agentId !== undefined && routingReason === undefined) {
|
|
270
282
|
return toolErr("routingReason is required when agentId is supplied.");
|
|
271
283
|
}
|
|
284
|
+
if (agentId !== undefined && (routingNote?.trim().length ?? 0) < 10) {
|
|
285
|
+
return toolErr(
|
|
286
|
+
"routingNote is required when agentId is supplied (at least 10 characters after trim).",
|
|
287
|
+
);
|
|
288
|
+
}
|
|
272
289
|
if (ctx.kind === "owner" && !ctx.agentId) {
|
|
273
290
|
return toolErr('Agent ID not found. The MCP client should define the "X-Agent-ID" header.', {
|
|
274
291
|
data: { yourAgentId: ctx.agentId },
|
|
@@ -364,6 +381,55 @@ export async function sendTaskHandler(
|
|
|
364
381
|
const effectiveRoutingReason =
|
|
365
382
|
agentId !== undefined ? routingReason : effectiveAgentId ? "continuity" : undefined;
|
|
366
383
|
const effectiveRoutingNote = effectiveRoutingReason ? routingNote : undefined;
|
|
384
|
+
const effectiveRoutingSource =
|
|
385
|
+
agentId !== undefined ? "declared" : effectiveAgentId ? "engine_default" : undefined;
|
|
386
|
+
|
|
387
|
+
const requestedTaskOptions: CreateTaskOptions = {
|
|
388
|
+
key: assetKey,
|
|
389
|
+
agentId: offerMode ? undefined : effectiveAgentId,
|
|
390
|
+
offeredTo: offerMode ? effectiveAgentId : undefined,
|
|
391
|
+
creatorAgentId,
|
|
392
|
+
requestedByUserId,
|
|
393
|
+
source: "mcp",
|
|
394
|
+
sourceTaskId,
|
|
395
|
+
taskType,
|
|
396
|
+
tags,
|
|
397
|
+
priority,
|
|
398
|
+
dependsOn,
|
|
399
|
+
dir,
|
|
400
|
+
parentTaskId: effectiveParentTaskId,
|
|
401
|
+
vcsRepo: effectiveVcsRepo,
|
|
402
|
+
model: normalizedModel.model,
|
|
403
|
+
modelTier: normalizedModel.modelTier,
|
|
404
|
+
effort,
|
|
405
|
+
slackChannelId,
|
|
406
|
+
slackThreadTs,
|
|
407
|
+
slackUserId,
|
|
408
|
+
overrideSlackContext,
|
|
409
|
+
followUpConfig,
|
|
410
|
+
outputSchema,
|
|
411
|
+
routingReason: effectiveRoutingReason,
|
|
412
|
+
routingSource: effectiveRoutingSource,
|
|
413
|
+
routingNote: effectiveRoutingNote,
|
|
414
|
+
routingAffinity:
|
|
415
|
+
effectiveLeadOnly || requiredCapabilities?.length
|
|
416
|
+
? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] }
|
|
417
|
+
: undefined,
|
|
418
|
+
};
|
|
419
|
+
const preCreate = await applyPreTaskCreate({
|
|
420
|
+
description: task,
|
|
421
|
+
options: requestedTaskOptions,
|
|
422
|
+
origin: "mcp",
|
|
423
|
+
requestInfo: ctx.kind === "owner" ? ctx.requestInfo : undefined,
|
|
424
|
+
});
|
|
425
|
+
if (preCreate.kind === "blocked") {
|
|
426
|
+
return toolErr(preCreate.reason, {
|
|
427
|
+
data: { yourAgentId: creatorAgentId },
|
|
428
|
+
details: JSON.stringify({ extension: preCreate.extension }),
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
const taskDescription = preCreate.description;
|
|
432
|
+
const taskOptions = preCreate.options;
|
|
367
433
|
|
|
368
434
|
// The three dedup guards are pure reads, so they run twice: once here as a
|
|
369
435
|
// fast path (keeping this tool's existing early-exit responses), and once
|
|
@@ -388,9 +454,9 @@ export async function sendTaskHandler(
|
|
|
388
454
|
// Dedup guard: check for similar recent tasks
|
|
389
455
|
if (!allowDuplicate && creatorAgentId) {
|
|
390
456
|
const duplicate = await findDuplicateTask({
|
|
391
|
-
taskDescription
|
|
392
|
-
creatorAgentId,
|
|
393
|
-
targetAgentId:
|
|
457
|
+
taskDescription,
|
|
458
|
+
creatorAgentId: taskOptions.creatorAgentId ?? creatorAgentId,
|
|
459
|
+
targetAgentId: taskOptions.agentId ?? taskOptions.offeredTo,
|
|
394
460
|
});
|
|
395
461
|
if (duplicate) {
|
|
396
462
|
return {
|
|
@@ -470,41 +536,13 @@ export async function sendTaskHandler(
|
|
|
470
536
|
const raced = await evaluateDedupGuards();
|
|
471
537
|
if (raced) return { success: raced.ok, message: raced.message, task: raced.task };
|
|
472
538
|
|
|
473
|
-
const finalTags = tags;
|
|
474
|
-
|
|
475
539
|
// If no agentId (and no auto-routed agentId), create an unassigned task for the pool
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
creatorAgentId,
|
|
480
|
-
requestedByUserId,
|
|
481
|
-
sourceTaskId,
|
|
482
|
-
taskType,
|
|
483
|
-
tags: finalTags,
|
|
484
|
-
priority,
|
|
485
|
-
dependsOn,
|
|
486
|
-
dir,
|
|
487
|
-
parentTaskId: effectiveParentTaskId,
|
|
488
|
-
vcsRepo: effectiveVcsRepo,
|
|
489
|
-
model: normalizedModel.model,
|
|
490
|
-
modelTier: normalizedModel.modelTier,
|
|
491
|
-
effort,
|
|
492
|
-
slackChannelId,
|
|
493
|
-
slackThreadTs,
|
|
494
|
-
slackUserId,
|
|
495
|
-
overrideSlackContext,
|
|
496
|
-
followUpConfig,
|
|
497
|
-
outputSchema,
|
|
498
|
-
routingReason: effectiveRoutingReason,
|
|
499
|
-
routingNote: effectiveRoutingNote,
|
|
500
|
-
routingAffinity:
|
|
501
|
-
effectiveLeadOnly || requiredCapabilities?.length
|
|
502
|
-
? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] }
|
|
503
|
-
: undefined,
|
|
504
|
-
});
|
|
540
|
+
const targetAgentId = taskOptions.offeredTo ?? taskOptions.agentId ?? undefined;
|
|
541
|
+
if (!targetAgentId) {
|
|
542
|
+
const newTask = await createTaskExtended(taskDescription, taskOptions);
|
|
505
543
|
await transferTrackerSyncToResumeChild({
|
|
506
|
-
parentTaskId:
|
|
507
|
-
taskType,
|
|
544
|
+
parentTaskId: taskOptions.parentTaskId,
|
|
545
|
+
taskType: taskOptions.taskType,
|
|
508
546
|
child: newTask,
|
|
509
547
|
});
|
|
510
548
|
|
|
@@ -515,16 +553,16 @@ export async function sendTaskHandler(
|
|
|
515
553
|
};
|
|
516
554
|
}
|
|
517
555
|
|
|
518
|
-
const agent = await getAgentById(
|
|
556
|
+
const agent = await getAgentById(targetAgentId);
|
|
519
557
|
|
|
520
558
|
if (!agent) {
|
|
521
559
|
return {
|
|
522
560
|
success: false,
|
|
523
|
-
message: `Agent with ID "${
|
|
561
|
+
message: `Agent with ID "${targetAgentId}" not found.`,
|
|
524
562
|
};
|
|
525
563
|
}
|
|
526
564
|
|
|
527
|
-
if (
|
|
565
|
+
if (taskOptions.routingAffinity?.leadOnly && !agent.isLead) {
|
|
528
566
|
return {
|
|
529
567
|
success: false,
|
|
530
568
|
message: `Lead-only task requires a Lead agent; "${agent.name}" is not a Lead.`,
|
|
@@ -532,48 +570,20 @@ export async function sendTaskHandler(
|
|
|
532
570
|
}
|
|
533
571
|
|
|
534
572
|
// For direct assignment (not offer), check if agent has capacity
|
|
535
|
-
if (!
|
|
536
|
-
const activeCount = await getActiveTaskCount(
|
|
573
|
+
if (!taskOptions.offeredTo && !(await hasCapacity(targetAgentId))) {
|
|
574
|
+
const activeCount = await getActiveTaskCount(targetAgentId);
|
|
537
575
|
return {
|
|
538
576
|
success: false,
|
|
539
577
|
message: `Agent "${agent.name}" is at capacity (${activeCount}/${agent.maxTasks ?? 1} tasks). Use offerMode: true to offer the task instead, or wait for a task to complete.`,
|
|
540
578
|
};
|
|
541
579
|
}
|
|
542
580
|
|
|
543
|
-
if (
|
|
581
|
+
if (taskOptions.offeredTo) {
|
|
544
582
|
// Offer the task to the agent (they must accept/reject)
|
|
545
|
-
const newTask = await createTaskExtended(
|
|
546
|
-
key: assetKey,
|
|
547
|
-
offeredTo: effectiveAgentId,
|
|
548
|
-
creatorAgentId,
|
|
549
|
-
requestedByUserId,
|
|
550
|
-
sourceTaskId,
|
|
551
|
-
taskType,
|
|
552
|
-
tags: finalTags,
|
|
553
|
-
priority,
|
|
554
|
-
dependsOn,
|
|
555
|
-
dir,
|
|
556
|
-
parentTaskId: effectiveParentTaskId,
|
|
557
|
-
vcsRepo: effectiveVcsRepo,
|
|
558
|
-
model: normalizedModel.model,
|
|
559
|
-
modelTier: normalizedModel.modelTier,
|
|
560
|
-
effort,
|
|
561
|
-
slackChannelId,
|
|
562
|
-
slackThreadTs,
|
|
563
|
-
slackUserId,
|
|
564
|
-
overrideSlackContext,
|
|
565
|
-
followUpConfig,
|
|
566
|
-
outputSchema,
|
|
567
|
-
routingReason: effectiveRoutingReason,
|
|
568
|
-
routingNote: effectiveRoutingNote,
|
|
569
|
-
routingAffinity:
|
|
570
|
-
effectiveLeadOnly || requiredCapabilities?.length
|
|
571
|
-
? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] }
|
|
572
|
-
: undefined,
|
|
573
|
-
});
|
|
583
|
+
const newTask = await createTaskExtended(taskDescription, taskOptions);
|
|
574
584
|
await transferTrackerSyncToResumeChild({
|
|
575
|
-
parentTaskId:
|
|
576
|
-
taskType,
|
|
585
|
+
parentTaskId: taskOptions.parentTaskId,
|
|
586
|
+
taskType: taskOptions.taskType,
|
|
577
587
|
child: newTask,
|
|
578
588
|
});
|
|
579
589
|
|
|
@@ -585,38 +595,10 @@ export async function sendTaskHandler(
|
|
|
585
595
|
}
|
|
586
596
|
|
|
587
597
|
// Direct assignment
|
|
588
|
-
const newTask = await createTaskExtended(
|
|
589
|
-
key: assetKey,
|
|
590
|
-
agentId: effectiveAgentId,
|
|
591
|
-
creatorAgentId,
|
|
592
|
-
requestedByUserId,
|
|
593
|
-
sourceTaskId,
|
|
594
|
-
taskType,
|
|
595
|
-
tags: finalTags,
|
|
596
|
-
priority,
|
|
597
|
-
dependsOn,
|
|
598
|
-
dir,
|
|
599
|
-
parentTaskId: effectiveParentTaskId,
|
|
600
|
-
vcsRepo: effectiveVcsRepo,
|
|
601
|
-
model: normalizedModel.model,
|
|
602
|
-
modelTier: normalizedModel.modelTier,
|
|
603
|
-
effort,
|
|
604
|
-
slackChannelId,
|
|
605
|
-
slackThreadTs,
|
|
606
|
-
slackUserId,
|
|
607
|
-
overrideSlackContext,
|
|
608
|
-
followUpConfig,
|
|
609
|
-
outputSchema,
|
|
610
|
-
routingReason: effectiveRoutingReason,
|
|
611
|
-
routingNote: effectiveRoutingNote,
|
|
612
|
-
routingAffinity:
|
|
613
|
-
effectiveLeadOnly || requiredCapabilities?.length
|
|
614
|
-
? { leadOnly: effectiveLeadOnly, capabilities: requiredCapabilities ?? [] }
|
|
615
|
-
: undefined,
|
|
616
|
-
});
|
|
598
|
+
const newTask = await createTaskExtended(taskDescription, taskOptions);
|
|
617
599
|
await transferTrackerSyncToResumeChild({
|
|
618
|
-
parentTaskId:
|
|
619
|
-
taskType,
|
|
600
|
+
parentTaskId: taskOptions.parentTaskId,
|
|
601
|
+
taskType: taskOptions.taskType,
|
|
620
602
|
child: newTask,
|
|
621
603
|
});
|
|
622
604
|
|
|
@@ -72,6 +72,7 @@ To reject: close this task with a rejection reason.`;
|
|
|
72
72
|
const task = await createTaskExtended(taskDescription, {
|
|
73
73
|
agentId: leadAgent.id,
|
|
74
74
|
routingReason: "skill",
|
|
75
|
+
routingSource: "engine_default",
|
|
75
76
|
creatorAgentId: requestInfo.agentId,
|
|
76
77
|
source: "mcp",
|
|
77
78
|
taskType: "skill-approval",
|
|
@@ -102,7 +102,7 @@ export const registerStoreProgressTool = (server: McpServer) => {
|
|
|
102
102
|
.string()
|
|
103
103
|
.optional()
|
|
104
104
|
.describe(
|
|
105
|
-
"The task result (used when completing). For Slack-originated tasks, this is published verbatim in the thread's outcome card
|
|
105
|
+
"The task result (used when completing). For Slack-originated tasks, this is published verbatim in the thread's outcome card. Keep free-text output under 120 words by default. Name the result and every artifact link, plus any IDs the human needs. Link documents instead of inlining them; omit process narration, transcripts, and restatements of the brief. Exceed the target only when requested depth, enumerated results, essential evidence, caveats, or instructions require it, or when the task's outputSchema requires longer output. When the task carries an outputSchema, output must be JSON matching it.",
|
|
106
106
|
),
|
|
107
107
|
failureReason: z
|
|
108
108
|
.string()
|
package/src/tools/task-action.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
updateTaskClaudeSessionId,
|
|
29
29
|
} from "@/be/db";
|
|
30
30
|
import { touchRuntimeInstance } from "@/be/multi-runtime";
|
|
31
|
+
import { applyPreTaskCreate } from "@/extensions/apply-task-create";
|
|
31
32
|
import { assertOwnsTask, ownerCtx, type ToolCtx } from "@/tools/task-tool-ctx";
|
|
32
33
|
import {
|
|
33
34
|
createToolRegistrar,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
import {
|
|
40
41
|
AssetKeySchema,
|
|
41
42
|
BudgetRefusalCauseSchema,
|
|
43
|
+
type CreateTaskOptions,
|
|
42
44
|
ModelTierSchema,
|
|
43
45
|
ReasoningEffortSchema,
|
|
44
46
|
splitLegacyModelAlias,
|
|
@@ -265,7 +267,14 @@ export async function taskActionHandler(
|
|
|
265
267
|
|
|
266
268
|
const agentId = ctx.agentId;
|
|
267
269
|
let assetKey: string | undefined;
|
|
270
|
+
let preparedCreate: { description: string; options: CreateTaskOptions } | undefined;
|
|
268
271
|
if (action === "create") {
|
|
272
|
+
if (!task) {
|
|
273
|
+
return taskActionResult(
|
|
274
|
+
{ success: false, message: "Task description is required for 'create' action." },
|
|
275
|
+
agentId,
|
|
276
|
+
);
|
|
277
|
+
}
|
|
269
278
|
try {
|
|
270
279
|
assetKey = key
|
|
271
280
|
? await authorizeAssetKeyWrite(key, await resolveTaskAuditUserId(ctx.sourceTaskId, agentId))
|
|
@@ -279,33 +288,45 @@ export async function taskActionHandler(
|
|
|
279
288
|
: String(error);
|
|
280
289
|
return taskActionResult({ success: false, message }, agentId);
|
|
281
290
|
}
|
|
291
|
+
|
|
292
|
+
const preCreate = await applyPreTaskCreate({
|
|
293
|
+
description: task,
|
|
294
|
+
options: {
|
|
295
|
+
key: assetKey,
|
|
296
|
+
creatorAgentId: agentId,
|
|
297
|
+
source: "mcp",
|
|
298
|
+
taskType,
|
|
299
|
+
tags,
|
|
300
|
+
priority,
|
|
301
|
+
dependsOn,
|
|
302
|
+
dir,
|
|
303
|
+
model: normalizedModel.model,
|
|
304
|
+
modelTier: normalizedModel.modelTier,
|
|
305
|
+
effort: input.effort,
|
|
306
|
+
routingAffinity:
|
|
307
|
+
leadOnly || requiredCapabilities?.length
|
|
308
|
+
? { leadOnly, capabilities: requiredCapabilities ?? [] }
|
|
309
|
+
: undefined,
|
|
310
|
+
},
|
|
311
|
+
origin: "mcp",
|
|
312
|
+
requestInfo: ctx.requestInfo,
|
|
313
|
+
});
|
|
314
|
+
if (preCreate.kind === "blocked") {
|
|
315
|
+
return taskActionResult({ success: false, message: preCreate.reason }, agentId);
|
|
316
|
+
}
|
|
317
|
+
preparedCreate = {
|
|
318
|
+
description: preCreate.description,
|
|
319
|
+
options: preCreate.options,
|
|
320
|
+
};
|
|
282
321
|
}
|
|
283
322
|
|
|
284
323
|
const result = await getDbClient().transaction(async (): Promise<TaskActionResult> => {
|
|
285
324
|
switch (action) {
|
|
286
325
|
case "create": {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
const newTask = await createTaskExtended(task, {
|
|
294
|
-
key: assetKey,
|
|
295
|
-
creatorAgentId: agentId,
|
|
296
|
-
taskType,
|
|
297
|
-
tags,
|
|
298
|
-
priority,
|
|
299
|
-
dependsOn,
|
|
300
|
-
dir,
|
|
301
|
-
model: normalizedModel.model,
|
|
302
|
-
modelTier: normalizedModel.modelTier,
|
|
303
|
-
effort: input.effort,
|
|
304
|
-
routingAffinity:
|
|
305
|
-
leadOnly || requiredCapabilities?.length
|
|
306
|
-
? { leadOnly, capabilities: requiredCapabilities ?? [] }
|
|
307
|
-
: undefined,
|
|
308
|
-
});
|
|
326
|
+
const newTask = await createTaskExtended(
|
|
327
|
+
preparedCreate!.description,
|
|
328
|
+
preparedCreate!.options,
|
|
329
|
+
);
|
|
309
330
|
return {
|
|
310
331
|
success: true,
|
|
311
332
|
message: `Created unassigned task "${newTask.id}".`,
|
|
@@ -9,6 +9,7 @@ export type ToolCtx =
|
|
|
9
9
|
runtimeInstanceId?: string;
|
|
10
10
|
sourceTaskId?: string;
|
|
11
11
|
sessionId?: string;
|
|
12
|
+
requestInfo?: RequestInfo;
|
|
12
13
|
}
|
|
13
14
|
| { kind: "user"; userId: string; user: User; sessionId?: string };
|
|
14
15
|
|
|
@@ -19,6 +20,7 @@ export function ownerCtx(info: RequestInfo): ToolCtx {
|
|
|
19
20
|
runtimeInstanceId: info.runtimeInstanceId,
|
|
20
21
|
sourceTaskId: info.sourceTaskId,
|
|
21
22
|
sessionId: info.sessionId,
|
|
23
|
+
requestInfo: info,
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
|
package/src/tools/templates.ts
CHANGED
|
@@ -198,6 +198,7 @@ Use the crashed agent's identity above as context for who was on it and what kin
|
|
|
198
198
|
Dispatch via \`send-task\` with ALL of:
|
|
199
199
|
- an explicit \`agentId\` (the chosen worker) — REQUIRED. If you omit it, \`send-task\` auto-routes to the original task's agent, which is the dead worker, and the work re-strands.
|
|
200
200
|
- \`routingReason: "reroute_fault"\`
|
|
201
|
+
- \`routingNote\`: explain why this worker is the right recovery target (at least 10 characters after trim, maximum 200)
|
|
201
202
|
- \`taskType: "resume"\`
|
|
202
203
|
- the tag \`resume-generation:{{generation_next}}\`
|
|
203
204
|
- \`parentTaskId: {{original_task_id}}\`
|
|
@@ -252,7 +253,7 @@ Required capabilities: {{required_capabilities}}{{artifacts_block}}
|
|
|
252
253
|
|
|
253
254
|
This task has been sitting unassigned because no currently-registered agent matches its required role/capabilities. Pick an agent to take this work over and RE-DELEGATE it — do NOT execute it yourself.
|
|
254
255
|
|
|
255
|
-
Dispatch via \`send-task\` with an explicit \`agentId\` (REQUIRED — omitting it re-pools the work under the same affinity tag and it will starve again), \`routingReason: "overflow"\`, and \`parentTaskId: {{original_task_id}}\`.
|
|
256
|
+
Dispatch via \`send-task\` with an explicit \`agentId\` (REQUIRED — omitting it re-pools the work under the same affinity tag and it will starve again), \`routingReason: "overflow"\`, a \`routingNote\` explaining the worker choice (at least 10 characters after trim, maximum 200), and \`parentTaskId: {{original_task_id}}\`.
|
|
256
257
|
|
|
257
258
|
This work will NOT fall back to the unassigned pool — you are the only re-delegation path.`,
|
|
258
259
|
variables: [
|
package/src/tools/tool-config.ts
CHANGED
|
@@ -197,13 +197,15 @@ export const DEFERRED_TOOLS = new Set([
|
|
|
197
197
|
"room-reset",
|
|
198
198
|
"room-decode",
|
|
199
199
|
|
|
200
|
-
// Reusable scripts (
|
|
200
|
+
// Reusable scripts and extensions (8)
|
|
201
201
|
"script-upsert",
|
|
202
202
|
"script-delete",
|
|
203
203
|
"script-apis",
|
|
204
204
|
"launch-script-run",
|
|
205
205
|
"get-script-run",
|
|
206
206
|
"list-script-runs",
|
|
207
|
+
"extension-install",
|
|
208
|
+
"extension-list",
|
|
207
209
|
|
|
208
210
|
// External command routes (1)
|
|
209
211
|
"swarm_x",
|
package/src/tools/utils.ts
CHANGED
|
@@ -5,6 +5,11 @@ import type {
|
|
|
5
5
|
ShapeOutput,
|
|
6
6
|
ZodRawShapeCompat,
|
|
7
7
|
} from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
8
|
+
import {
|
|
9
|
+
getParseErrorMessage,
|
|
10
|
+
normalizeObjectSchema,
|
|
11
|
+
safeParseAsync,
|
|
12
|
+
} from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
8
13
|
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
9
14
|
import type {
|
|
10
15
|
CallToolResult,
|
|
@@ -23,12 +28,18 @@ import { scrubObject, scrubSecrets } from "../utils/secret-scrubber";
|
|
|
23
28
|
type Meta = RequestHandlerExtra<ServerRequest, ServerNotification>;
|
|
24
29
|
|
|
25
30
|
const scriptSdkRequestOrigins = new WeakSet<object>();
|
|
31
|
+
const extensionRequestOrigins = new WeakSet<object>();
|
|
26
32
|
|
|
27
33
|
export function markScriptSdkRequestOrigin<T extends object>(meta: T): T {
|
|
28
34
|
scriptSdkRequestOrigins.add(meta);
|
|
29
35
|
return meta;
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
export function markExtensionRequestOrigin<T extends object>(meta: T): T {
|
|
39
|
+
extensionRequestOrigins.add(meta);
|
|
40
|
+
return meta;
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
export type RequestInfo = {
|
|
33
44
|
sessionId: string | undefined;
|
|
34
45
|
agentId: string | undefined;
|
|
@@ -36,7 +47,7 @@ export type RequestInfo = {
|
|
|
36
47
|
runtimeInstanceId: string | undefined;
|
|
37
48
|
sourceTaskId: string | undefined;
|
|
38
49
|
contextKey: string | undefined;
|
|
39
|
-
callOrigin: "mcp" | "script-sdk";
|
|
50
|
+
callOrigin: "mcp" | "script-sdk" | "extension";
|
|
40
51
|
};
|
|
41
52
|
|
|
42
53
|
export const getRequestInfo = (req: Meta): RequestInfo => {
|
|
@@ -73,7 +84,11 @@ export const getRequestInfo = (req: Meta): RequestInfo => {
|
|
|
73
84
|
runtimeInstanceId: typeof runtimeInstanceId === "string" ? runtimeInstanceId : undefined,
|
|
74
85
|
sourceTaskId,
|
|
75
86
|
contextKey,
|
|
76
|
-
callOrigin:
|
|
87
|
+
callOrigin: extensionRequestOrigins.has(req)
|
|
88
|
+
? "extension"
|
|
89
|
+
: scriptSdkRequestOrigins.has(req)
|
|
90
|
+
? "script-sdk"
|
|
91
|
+
: "mcp",
|
|
77
92
|
};
|
|
78
93
|
};
|
|
79
94
|
|
|
@@ -622,7 +637,7 @@ const ctxControlMiddleware: FinalizeMiddleware = async (result, ctx) => {
|
|
|
622
637
|
// Calls made through ctx.swarm.* execute inside a script sandbox, so their
|
|
623
638
|
// response never enters the model's context. The script SDK has a separate,
|
|
624
639
|
// much higher hard response limit to protect the sandbox heap.
|
|
625
|
-
if (ctx.callOrigin === "script-sdk") return result;
|
|
640
|
+
if (ctx.callOrigin === "script-sdk" || ctx.callOrigin === "extension") return result;
|
|
626
641
|
if (CTX_CONTROL_EXEMPT_TOOLS.has(ctx.toolName)) return result;
|
|
627
642
|
|
|
628
643
|
const fullWire = composeWireResult(result);
|
|
@@ -770,6 +785,85 @@ export function setPreloadedTools(server: McpServer, names: readonly string[]):
|
|
|
770
785
|
preloadedToolsByServer.set(server, new Set(names));
|
|
771
786
|
}
|
|
772
787
|
|
|
788
|
+
type ExtensionDispatcher = typeof import("../extensions/dispatcher");
|
|
789
|
+
|
|
790
|
+
async function applyPreToolCall(
|
|
791
|
+
name: string,
|
|
792
|
+
args: unknown,
|
|
793
|
+
requestInfo: RequestInfo,
|
|
794
|
+
inputSchema?: AnySchema | ZodRawShapeCompat,
|
|
795
|
+
): Promise<{
|
|
796
|
+
args: unknown;
|
|
797
|
+
blocked?: SwarmToolResult;
|
|
798
|
+
dispatcher?: ExtensionDispatcher;
|
|
799
|
+
}> {
|
|
800
|
+
if (requestInfo.callOrigin !== "mcp") return { args };
|
|
801
|
+
|
|
802
|
+
const dispatcher = await import("../extensions/dispatcher");
|
|
803
|
+
const result = await dispatcher.dispatchPre(
|
|
804
|
+
"pre.tool.call",
|
|
805
|
+
{ tool: name, args, requestInfo },
|
|
806
|
+
inputSchema
|
|
807
|
+
? {
|
|
808
|
+
validateModify: async (data) => {
|
|
809
|
+
const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
|
|
810
|
+
const parsed = await safeParseAsync(schema as AnySchema, data.args);
|
|
811
|
+
if (parsed.success) return { success: true, data: { args: parsed.data } };
|
|
812
|
+
|
|
813
|
+
const message = scrubSecrets(getParseErrorMessage(parsed.error));
|
|
814
|
+
console.warn(
|
|
815
|
+
`[extensions] Ignored invalid arguments from pre.tool.call for ${name}: ${message}`,
|
|
816
|
+
);
|
|
817
|
+
return {
|
|
818
|
+
success: false,
|
|
819
|
+
error: new Error(`Modified arguments for tool "${name}" are invalid: ${message}`),
|
|
820
|
+
};
|
|
821
|
+
},
|
|
822
|
+
}
|
|
823
|
+
: {
|
|
824
|
+
transformModify: ({ extension }) => {
|
|
825
|
+
const message = scrubSecrets(
|
|
826
|
+
`[extensions] Ignored pre.tool.call argument rewrite for tool "${name}" from extension "${extension.name}" because the tool has no input schema`,
|
|
827
|
+
);
|
|
828
|
+
console.warn(message);
|
|
829
|
+
throw new Error(message);
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
if (result.action === "block") {
|
|
835
|
+
return {
|
|
836
|
+
args,
|
|
837
|
+
blocked: toolErr(result.reason, {
|
|
838
|
+
details: `Extension "${result.extension.name}" rejected this tool call.`,
|
|
839
|
+
}),
|
|
840
|
+
dispatcher,
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
args: inputSchema && result.action === "modify" ? result.data.args : args,
|
|
845
|
+
dispatcher,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function dispatchPostToolCall(
|
|
850
|
+
dispatcher: ExtensionDispatcher | undefined,
|
|
851
|
+
name: string,
|
|
852
|
+
args: unknown,
|
|
853
|
+
outcome: SwarmToolResult,
|
|
854
|
+
requestInfo: RequestInfo,
|
|
855
|
+
durationMs: number,
|
|
856
|
+
): void {
|
|
857
|
+
if (!dispatcher) return;
|
|
858
|
+
void dispatcher.dispatchPost("post.tool.call", {
|
|
859
|
+
tool: name,
|
|
860
|
+
args,
|
|
861
|
+
result: outcome,
|
|
862
|
+
requestInfo,
|
|
863
|
+
durationMs,
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
|
|
773
867
|
/**
|
|
774
868
|
* Creates a tool registration helper that automatically extracts request info
|
|
775
869
|
* and passes it as the second parameter to the callback.
|
|
@@ -806,13 +900,24 @@ export const createToolRegistrar = (server: McpServer) => {
|
|
|
806
900
|
return withSpan(
|
|
807
901
|
"mcp.tool",
|
|
808
902
|
async (span) => {
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
903
|
+
const pre = await applyPreToolCall(name, {}, requestInfo);
|
|
904
|
+
let durationMs = 0;
|
|
905
|
+
let outcome = pre.blocked;
|
|
906
|
+
if (!outcome) {
|
|
907
|
+
const startedAt = Date.now();
|
|
908
|
+
try {
|
|
909
|
+
outcome = await (
|
|
910
|
+
cb as (
|
|
911
|
+
requestInfo: RequestInfo,
|
|
912
|
+
meta: Meta,
|
|
913
|
+
) => SwarmToolResult | Promise<SwarmToolResult>
|
|
914
|
+
)(requestInfo, meta);
|
|
915
|
+
} finally {
|
|
916
|
+
durationMs = Date.now() - startedAt;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
815
919
|
const result = await finalizeSwarmToolResult(name, outcome, requestInfo);
|
|
920
|
+
dispatchPostToolCall(pre.dispatcher, name, {}, outcome, requestInfo, durationMs);
|
|
816
921
|
span.setAttributes(toolResultAttributes(result));
|
|
817
922
|
return result;
|
|
818
923
|
},
|
|
@@ -831,14 +936,33 @@ export const createToolRegistrar = (server: McpServer) => {
|
|
|
831
936
|
// trace tree. Cardinality is bounded — tool names are a fixed enum.
|
|
832
937
|
`mcp.tool ${name}`,
|
|
833
938
|
async (span) => {
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
939
|
+
const pre = await applyPreToolCall(name, args, requestInfo, config.inputSchema);
|
|
940
|
+
const effectiveArgs = pre.args as InferInput<InputArgs>;
|
|
941
|
+
let durationMs = 0;
|
|
942
|
+
let outcome = pre.blocked;
|
|
943
|
+
if (!outcome) {
|
|
944
|
+
const startedAt = Date.now();
|
|
945
|
+
try {
|
|
946
|
+
outcome = await (
|
|
947
|
+
cb as (
|
|
948
|
+
args: InferInput<InputArgs>,
|
|
949
|
+
requestInfo: RequestInfo,
|
|
950
|
+
meta: Meta,
|
|
951
|
+
) => SwarmToolResult | Promise<SwarmToolResult>
|
|
952
|
+
)(effectiveArgs, requestInfo, meta);
|
|
953
|
+
} finally {
|
|
954
|
+
durationMs = Date.now() - startedAt;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
841
957
|
const result = await finalizeSwarmToolResult(name, outcome, requestInfo);
|
|
958
|
+
dispatchPostToolCall(
|
|
959
|
+
pre.dispatcher,
|
|
960
|
+
name,
|
|
961
|
+
effectiveArgs,
|
|
962
|
+
outcome,
|
|
963
|
+
requestInfo,
|
|
964
|
+
durationMs,
|
|
965
|
+
);
|
|
842
966
|
span.setAttributes(toolResultAttributes(result));
|
|
843
967
|
return result;
|
|
844
968
|
},
|