@desplega.ai/agent-swarm 1.131.1 → 1.134.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 +3 -3
- package/dist/{actions-jgcy477k.js → actions-7kast243.js} +20 -18
- package/dist/{anthropic-messages-rjmd2e7n.js → anthropic-messages-706yad38.js} +33 -17
- package/dist/app-0g84t8wf.js +28 -0
- package/dist/{artifact-jysj3wrg.js → artifact-dje5ke4h.js} +37 -131
- package/dist/{assistant-f2vkk1hj.js → assistant-ac4htcky.js} +25 -22
- package/dist/{azure-openai-responses-c0yjmbfd.js → azure-openai-responses-be59fbsz.js} +13 -13
- package/dist/{boot-reembed-q7mp8hcr.js → boot-reembed-b1rcqn85.js} +13 -11
- package/dist/{boot-reembed-xmw8wcx6.js → boot-reembed-kw2541c4.js} +14 -12
- package/dist/{boot-scrub-logs-dsqrv79n.js → boot-scrub-logs-ja29t92g.js} +11 -9
- package/dist/{claude-adapter-q6x7yspx.js → claude-adapter-5cg1fv8s.js} +33 -29
- package/dist/{claude-managed-adapter-wsg37bt8.js → claude-managed-adapter-9z9sdytx.js} +9 -9
- package/dist/{claude-managed-setup-52z4mq9w.js → claude-managed-setup-3zqp51cr.js} +5 -5
- package/dist/{claude-1ex232fc.js → claude-wqn3dtca.js} +1 -1
- package/dist/{cli-4wgngmwv.js → cli-00w4hbam.js} +1 -1
- package/dist/{cli-er3a4bb0.js → cli-15429qdw.js} +6 -1
- package/dist/{cli-e5dabkx0.js → cli-1cwhyvta.js} +4 -4
- package/dist/{cli-zsspvvm2.js → cli-1ybr6vw2.js} +237 -237
- package/dist/{cli-xpxde7rm.js → cli-2wv4kj0e.js} +60 -31
- package/dist/cli-34w2584r.js +530 -0
- package/dist/{cli-se2p6rkb.js → cli-38taxznr.js} +6 -6
- package/dist/{cli-9sbhdpvb.js → cli-3cgfyfzm.js} +14 -14
- package/dist/{cli-5n6e5yfn.js → cli-3zmdzfjf.js} +79 -74
- package/dist/{cli-3ty0t082.js → cli-43x36mty.js} +197 -8
- package/dist/{cli-ycrnynpw.js → cli-480nehnh.js} +29 -22
- package/dist/{cli-0258203w.js → cli-492e7ap5.js} +140 -20
- package/dist/{cli-3fj60etf.js → cli-497b685t.js} +3 -3
- package/dist/{cli-pxfxkx5m.js → cli-4bap00k0.js} +1 -1
- package/dist/{cli-w2wxd56v.js → cli-4bc8vmhm.js} +848 -770
- package/dist/{cli-aca5pz9f.js → cli-589599p9.js} +1 -1
- package/dist/{cli-t930g0xh.js → cli-5tnr64pm.js} +1 -1
- package/dist/{cli-jxg3s9ey.js → cli-65d93ves.js} +7 -7
- package/dist/{cli-6dpytdr2.js → cli-6x363v1z.js} +2 -2
- package/dist/{cli-dxak0fqd.js → cli-787ph852.js} +11 -11
- package/dist/{cli-793jvbsh.js → cli-7bv8nckk.js} +16 -11
- package/dist/{cli-zyxs93y9.js → cli-7jcc9y1r.js} +3 -3
- package/dist/{cli-f1am9szv.js → cli-87t2gstf.js} +1 -1
- package/dist/{cli-9aryf9tv.js → cli-95m51ztz.js} +1 -1
- package/dist/{cli-4w4fmq9x.js → cli-9w49enmh.js} +2 -2
- package/dist/{cli-v69vk5h0.js → cli-9y5b02vr.js} +13 -13
- package/dist/{cli-x23me2mg.js → cli-a1rrkrb4.js} +1 -1
- package/dist/{cli-psrqtw2m.js → cli-a3pkfpqs.js} +2 -2
- package/dist/{cli-h0rgxd24.js → cli-a4ajmfvp.js} +6 -6
- package/dist/{cli-ygrbmjja.js → cli-aw8bb6sf.js} +6 -6
- package/dist/{cli-g74vpjp2.js → cli-brm3et47.js} +55 -22
- package/dist/{cli-czkae1fp.js → cli-c5ddbdfj.js} +9 -9
- package/dist/{cli-114fvtmj.js → cli-c79a9zrc.js} +1 -1
- package/dist/{cli-49n9f49x.js → cli-dx3dz0ms.js} +3 -3
- package/dist/{cli-6dp3ydxa.js → cli-e07exmsb.js} +18 -14
- package/dist/cli-et1bbwqf.js +13 -0
- package/dist/{cli-yazx6hap.js → cli-f3s9dry0.js} +14 -14
- package/dist/{cli-t8d349cy.js → cli-f4wj0s3m.js} +3 -3
- package/dist/{cli-d6n0thxw.js → cli-f64gdfxc.js} +1 -1
- package/dist/{cli-pwfsqc2x.js → cli-fyd58xgb.js} +55 -55
- package/dist/{cli-7dm2zqy2.js → cli-g0j14czv.js} +2 -2
- package/dist/{cli-b0p7rfnd.js → cli-g2p9bd1z.js} +14 -14
- package/dist/{cli-z905tvmm.js → cli-g814jbst.js} +2 -2
- package/dist/{cli-5dsbcjjw.js → cli-ghexzd2d.js} +970 -970
- package/dist/{cli-jvv0g8bh.js → cli-gpt9kf01.js} +15 -15
- package/dist/{cli-rgrfzg8z.js → cli-grt6qv91.js} +380 -380
- package/dist/{cli-wz9115x0.js → cli-gtafvdy0.js} +8 -8
- package/dist/{cli-q5dzzak0.js → cli-gy07xk4s.js} +2 -2
- package/dist/{cli-sy7jk3tx.js → cli-h0djenzm.js} +2 -2
- package/dist/{cli-nrkkknat.js → cli-h37gbjbf.js} +2 -281
- package/dist/{cli-jevgrb4w.js → cli-h39xxnq6.js} +1200 -491
- package/dist/{cli-gz9sbyk3.js → cli-jepmgn7r.js} +1 -1
- package/dist/{cli-ccf9vy7q.js → cli-jmvk6et8.js} +7 -7
- package/dist/{cli-2rk0cx7s.js → cli-jxj92gkt.js} +51 -41
- package/dist/{cli-bqw0mt1n.js → cli-k46t4664.js} +18 -3
- package/dist/{cli-50vbt00w.js → cli-m07313tr.js} +1153 -696
- package/dist/{cli-4j2mrzag.js → cli-mkq1rk7b.js} +1 -1
- package/dist/{cli-1z7048dy.js → cli-mnm7w46e.js} +1 -1
- package/dist/{cli-kd1ck4rx.js → cli-mp9sg4cg.js} +14 -8
- package/dist/{cli-jbcva0xj.js → cli-mrammd8c.js} +60 -35
- package/dist/cli-nanaxrz6.js +27 -0
- package/dist/{cli-p9swy5t3.js → cli-pq2ee5ja.js} +8 -6
- package/dist/{cli-2wadx7p2.js → cli-pt43pdp1.js} +2 -2
- package/dist/{cli-7sgrxg9a.js → cli-q6d0vvey.js} +4 -4
- package/dist/{cli-k9qkf1hw.js → cli-qf9kpsve.js} +9 -9
- package/dist/cli-qh4sqfws.js +15 -0
- package/dist/{cli-e15jhafb.js → cli-qntkxysp.js} +14 -14
- package/dist/{cli-sajgpkqg.js → cli-qs9hhsvb.js} +1723 -325
- package/dist/{cli-z2zcxes1.js → cli-qt5bt3vk.js} +1 -1
- package/dist/{cli-wx82tw1k.js → cli-qtekrty1.js} +3 -3
- package/dist/{cli-g1re8r05.js → cli-rh6f3s9n.js} +3 -3
- package/dist/{cli-n0krnc6d.js → cli-rzhcrw2p.js} +2 -2
- package/dist/{cli-gecy3z2s.js → cli-snw62ze5.js} +4 -4
- package/dist/{cli-n6h8qt8n.js → cli-snz3p4yf.js} +15 -10
- package/dist/{cli-r6kqqbj0.js → cli-tkf8n6cw.js} +11 -11
- package/dist/{cli-4rkfg1wx.js → cli-tkrr24mz.js} +14 -9
- package/dist/{cli-9dr5qzc0.js → cli-tv9f1kyb.js} +54 -43
- package/dist/{cli-gm9cbhbq.js → cli-vtz6yj3v.js} +28 -9
- package/dist/{cli-2f07m0xr.js → cli-wf86d5t7.js} +1 -1
- package/dist/{cli-7zd05xb4.js → cli-whrvct19.js} +45 -45
- package/dist/{cli-ap1czx8f.js → cli-wrrea8xm.js} +3 -3
- package/dist/{cli-57khth04.js → cli-xmyqv00z.js} +120 -4
- package/dist/{cli-cwy5hqbq.js → cli-yjmk7tzc.js} +1 -1
- package/dist/{cli-6pcz9h15.js → cli-zykjrwcx.js} +180 -394
- package/dist/cli.js +45 -45
- package/dist/{codex-adapter-htjkn22b.js → codex-adapter-hsq6mz3m.js} +21 -19
- package/dist/{codex-hook-hq54t9ft.js → codex-hook-8c500gq8.js} +8 -7
- package/dist/{codex-login-z6yhbkmk.js → codex-login-x7603481.js} +3 -3
- package/dist/{codex-session-runner-wjfc7smz.js → codex-session-runner-c1x3x143.js} +15 -13
- package/dist/{commands-xhrfwqsk.js → commands-rwtddtst.js} +11 -9
- package/dist/{db-anvwb22f.js → db-j2b355vz.js} +458 -444
- package/dist/{devin-adapter-v1sarqtw.js → devin-adapter-8qmhqpy3.js} +3 -3
- package/dist/{devtools-2y1r7yqk.js → devtools-j2rnj8w7.js} +4 -4
- package/dist/{e2b-jdkwemv2.js → e2b-znpx78eg.js} +16 -16
- package/dist/{es5-vjgtkgp6.js → es5-fmqrjzy3.js} +2 -2
- package/dist/{event-bus-axn823e9.js → event-bus-n8sb35pw.js} +4 -4
- package/dist/{getMachineId-bsd-6tc9wxdj.js → getMachineId-bsd-wpzbhkm6.js} +4 -4
- package/dist/{getMachineId-darwin-sjt9sgnc.js → getMachineId-darwin-45zabjy0.js} +4 -4
- package/dist/{getMachineId-linux-v5n18y9p.js → getMachineId-linux-warnp5pd.js} +3 -3
- package/dist/{getMachineId-unsupported-yrjyqw3d.js → getMachineId-unsupported-5spent2a.js} +3 -3
- package/dist/{getMachineId-win-w3r8063c.js → getMachineId-win-v4bvcw7a.js} +4 -4
- package/dist/{google-generative-ai-hysrd8qx.js → google-generative-ai-b0wzss55.js} +17 -14
- package/dist/{google-vertex-p5arrga0.js → google-vertex-e8q4dpya.js} +18 -15
- package/dist/{handlers-b9kbc621.js → handlers-hchgrxkh.js} +32 -29
- package/dist/{hook-xkvn6c5h.js → hook-p49egqc0.js} +66 -52
- package/dist/hook-spb00w76.js +34 -0
- package/dist/{http-9xh6ta4r.js → http-nh14kkms.js} +663 -181
- package/dist/index-1qthq7vc.js +6 -0
- package/dist/{index-0g68f0p6.js → index-20xqmn3v.js} +3 -3
- package/dist/{index-vdkr5z2w.js → index-3e03k6e4.js} +114 -114
- package/dist/{index-ywds4812.js → index-4cbyhq2g.js} +43 -41
- package/dist/index-67pzqfrb.js +36 -0
- package/dist/{index-bccrkdkn.js → index-7m8yxkw5.js} +16 -16
- package/dist/{index-eaxyqcmj.js → index-dvsk64sm.js} +163 -83
- package/dist/{index-dqkpnmqm.js → index-e19s2m8k.js} +18 -18
- package/dist/{index-j30k5zxn.js → index-emvxcy98.js} +16 -16
- package/dist/{index-7ndw6ecy.js → index-gqnmr60d.js} +9 -9
- package/dist/{index-9znhar3x.js → index-j02xvjtd.js} +184 -185
- package/dist/{index-1s2442yw.js → index-ns5kksc1.js} +7 -7
- package/dist/{index-dpy2hth8.js → index-pdxc8kfh.js} +71 -71
- package/dist/{index-z1m7pw0v.js → index-ptcqm8bc.js} +107 -107
- package/dist/{index-070v4eyb.js → index-pyp7rexm.js} +5 -6
- package/dist/{index-86znjz1p.js → index-shne41sd.js} +13 -13
- package/dist/{index-2qn2qndv.js → index-t36q2v4t.js} +183 -183
- package/dist/index-tcnvv8w6.js +7 -0
- package/dist/index-w91qbfv1.js +7 -0
- package/dist/{index-fzc0mwvj.js → index-yqweff5n.js} +32 -32
- package/dist/index-yrfphye1.js +39 -0
- package/dist/{keepalive-vc7s2aa6.js → keepalive-9k51nqhc.js} +21 -15
- package/dist/lead-2xq3dxbz.js +88 -0
- package/dist/maintenance-0c0g6nym.js +28 -0
- package/dist/mistral-conversations-2njwdwhj.js +717 -0
- package/dist/{multipart-parser-qaktc7p8.js → multipart-parser-6gftesw0.js} +2 -2
- package/dist/{oauth-refresh-sweep-yecgjpk4.js → oauth-refresh-sweep-273a64r2.js} +14 -12
- package/dist/{onboard-xj0f73f9.js → onboard-tsv9wwhz.js} +12 -12
- package/dist/{openai-codex-responses-5g27pd6f.js → openai-codex-responses-kt84eq86.js} +26 -26
- package/dist/{openai-completions-3vkmfz2a.js → openai-completions-mrypq7qp.js} +17 -16
- package/dist/{openai-responses-dg4t7j7a.js → openai-responses-qhrk21ez.js} +20 -17
- package/dist/{opencode-adapter-1gm38aba.js → opencode-adapter-rar9676j.js} +13 -11
- package/dist/{openrouter-images-g3gm8931.js → openrouter-images-684fysx9.js} +5 -5
- package/dist/{otel-impl-nxg0n0b3.js → otel-impl-wp1mfzd2.js} +752 -537
- package/dist/{photon_rs-ky7dj5qw.js → photon_rs-8dwt2pzy.js} +581 -581
- package/dist/{pi-messages-tqj8q6b9.js → pi-messages-txp9f97r.js} +7 -7
- package/dist/{pi-mono-adapter-4g5kby31.js → pi-mono-adapter-yz47kk8e.js} +1910 -1180
- package/dist/pricing-refresh-jw1yw2fn.js +22 -0
- package/dist/rbac-roles-dg964c8p.js +32 -0
- package/dist/{rbac-roles-1hcxdtg7.js → rbac-roles-p53cg5cv.js} +19 -17
- package/dist/{registry-02cy9z5z.js → registry-mh12y17v.js} +4 -4
- package/dist/render-v2-56vn2rk9.js +36 -0
- package/dist/seed-pricing-52xx6z63.js +19 -0
- package/dist/{setup-46xtgq3c.js → setup-e8gp79sy.js} +7 -7
- package/dist/token-util-zy908s1a.js +6 -0
- package/dist/{token-fxkn2zf2.js → token-xg5711x5.js} +4 -4
- package/dist/worker-s17f1g46.js +88 -0
- package/dist/{x-6mg4kfpe.js → x-xkfh0w0v.js} +5 -5
- package/openapi.json +566 -22
- package/package.json +6 -6
- package/src/be/budget-refusal-notify.ts +14 -7
- package/src/be/db-queries/task-artifacts.ts +182 -0
- package/src/be/db.ts +834 -171
- package/src/be/events.ts +5 -0
- package/src/be/migrations/131_session_logs_created_at_index.sql +2 -0
- package/src/be/migrations/132_multi_runtime_instances.sql +44 -0
- package/src/be/migrations/133_workflow_run_trigger_type.sql +12 -0
- package/src/be/migrations/135_backfill_task_pull_request_attachments.sql +228 -0
- package/src/be/migrations/136_task_requester_provenance.sql +37 -0
- package/src/be/migrations/137_memory_retrieval_composite_index.sql +1 -0
- package/src/be/migrations/runner.ts +17 -11
- package/src/be/multi-runtime.ts +430 -0
- package/src/be/scripts/extract-schema.ts +3 -1
- package/src/be/scripts/typecheck.ts +6 -2
- package/src/be/seed-prompt-templates.ts +25 -2
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/steering.ts +1 -1
- package/src/be/swarm-config-guard.ts +18 -0
- package/src/commands/credential-wait.ts +54 -0
- package/src/commands/onboard/steps/core-credentials.tsx +1 -1
- package/src/commands/onboard/steps/custom-templates.tsx +1 -1
- package/src/commands/onboard/steps/harness-credentials.tsx +1 -1
- package/src/commands/onboard/steps/health-check.tsx +1 -1
- package/src/commands/onboard/steps/start.tsx +1 -1
- package/src/commands/profile-sync-audit.ts +56 -0
- package/src/commands/profile-sync.ts +287 -15
- package/src/commands/provider-credentials.ts +46 -19
- package/src/commands/runner.ts +199 -33
- package/src/commands/templates.ts +22 -0
- package/src/github/handlers.ts +55 -9
- package/src/heartbeat/heartbeat.ts +109 -17
- package/src/hooks/hook.ts +49 -33
- package/src/http/active-sessions.ts +11 -1
- package/src/http/agents.ts +261 -30
- package/src/http/all-routes.ts +1 -0
- package/src/http/config.ts +13 -2
- package/src/http/core.ts +102 -4
- package/src/http/db-query-bounded.ts +313 -0
- package/src/http/db-query-shared.ts +249 -0
- package/src/http/db-query.ts +54 -42
- package/src/http/events.ts +2 -0
- package/src/http/index.ts +23 -2
- package/src/http/mcp-bridge.ts +37 -3
- package/src/http/mcp.ts +12 -0
- package/src/http/memory.ts +13 -2
- package/src/http/openapi.ts +1 -0
- package/src/http/poll.ts +70 -27
- package/src/http/prompt-templates.ts +36 -13
- package/src/http/route-def.ts +43 -9
- package/src/http/schedules.ts +2 -2
- package/src/http/scripts.ts +10 -1
- package/src/http/session-data.ts +44 -0
- package/src/http/tasks.ts +2 -2
- package/src/http/users.ts +74 -52
- package/src/http/webhooks.ts +5 -2
- package/src/http/workflows.ts +1 -4
- package/src/integrations/kapso/inbound.ts +1 -1
- package/src/jira/outbound.ts +39 -8
- package/src/jira/webhook-lifecycle.ts +13 -2
- package/src/linear/outbound.ts +43 -10
- package/src/oauth/keepalive.ts +13 -2
- package/src/prompts/base-prompt.ts +1 -1
- package/src/prompts/default-drift.ts +21 -0
- package/src/prompts/session-templates.ts +56 -7
- package/src/providers/claude-adapter.ts +6 -0
- package/src/providers/codex-adapter.ts +6 -0
- package/src/providers/opencode-adapter.ts +6 -0
- package/src/providers/pi-mono-adapter.ts +8 -0
- package/src/providers/pricing-sources.md +24 -0
- package/src/queue-stall-alarm.ts +216 -0
- package/src/rbac/legacy-policy.ts +3 -0
- package/src/rbac/permissions.ts +12 -0
- package/src/scheduler/scheduler.ts +7 -0
- package/src/script-workflows/executor.ts +2 -1
- package/src/scripts-runtime/executors/native.ts +2 -1
- package/src/scripts-runtime/executors/types.ts +5 -0
- package/src/scripts-runtime/loader.ts +5 -0
- package/src/scripts-runtime/sdk-allowlist.ts +3 -0
- package/src/scripts-runtime/swarm-config.ts +8 -0
- package/src/scripts-runtime/swarm-sdk.ts +7 -0
- package/src/scripts-runtime/types/stdlib.d.ts +4 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +4 -0
- package/src/server.ts +6 -0
- package/src/slack/channel-join.ts +22 -3
- package/src/slack/channel-lifecycle.ts +114 -0
- package/src/tests/budget-claim-gate.test.ts +20 -0
- package/src/tests/claude-adapter.test.ts +32 -0
- package/src/tests/codex-adapter.test.ts +30 -0
- package/src/tests/create-task-validation.test.ts +128 -0
- package/src/tests/credential-wait.test.ts +67 -1
- package/src/tests/db-query.test.ts +711 -2
- package/src/tests/heartbeat-checklist.test.ts +28 -0
- package/src/tests/http-api-integration.test.ts +81 -0
- package/src/tests/http-users.test.ts +166 -1
- package/src/tests/identity-field-budget.test.ts +176 -0
- package/src/tests/mcp-tools-user.test.ts +34 -0
- package/src/tests/mcp-user-route.test.ts +17 -0
- package/src/tests/metrics-http.test.ts +44 -0
- package/src/tests/migration-failure.test.ts +86 -0
- package/src/tests/multi-runtime-registration.test.ts +2810 -0
- package/src/tests/openapi-response-contract.test.ts +24 -0
- package/src/tests/openapi-route-headers.test.ts +83 -0
- package/src/tests/opencode-adapter.test.ts +40 -0
- package/src/tests/outbound-listener-rejection.test.ts +138 -0
- package/src/tests/pi-mono-adapter.test.ts +98 -0
- package/src/tests/preload.ts +2 -0
- package/src/tests/profile-sync-warning.test.ts +277 -0
- package/src/tests/profile-sync.test.ts +232 -6
- package/src/tests/prompt-template-resolver.test.ts +177 -6
- package/src/tests/prompt-template-session.test.ts +39 -3
- package/src/tests/queue-stall-alarm.test.ts +226 -0
- package/src/tests/rbac-charact-slack.test.ts +29 -0
- package/src/tests/rbac-engine.test.ts +3 -0
- package/src/tests/requester-comms.test.ts +32 -0
- package/src/tests/runner-requester-profile.test.ts +38 -0
- package/src/tests/schedule-target-type.test.ts +38 -0
- package/src/tests/script-connections.test.ts +13 -1
- package/src/tests/scripts-runtime-identity.test.ts +375 -0
- package/src/tests/scripts-runtime.test.ts +4 -3
- package/src/tests/sdk-allowlist.test.ts +47 -0
- package/src/tests/send-task-requested-by.test.ts +9 -0
- package/src/tests/session-costs.test.ts +506 -1
- package/src/tests/shutdown-error-scrubbing.test.ts +92 -0
- package/src/tests/slack-channel-lifecycle.test.ts +241 -0
- package/src/tests/slack-render-v2.test.ts +43 -0
- package/src/tests/steering-core.test.ts +28 -0
- package/src/tests/swarm-config-reserved-keys.test.ts +22 -0
- package/src/tests/task-artifacts.test.ts +386 -0
- package/src/tests/task-attachments-schema.test.ts +17 -1
- package/src/tests/task-completion-idempotency.test.ts +57 -0
- package/src/tests/task-pull-request-backfill-migration.test.ts +321 -0
- package/src/tests/tool-annotations.test.ts +4 -0
- package/src/tests/update-profile-api.test.ts +67 -39
- package/src/tests/update-profile-auth.test.ts +48 -4
- package/src/tests/user-attribution-migration.test.ts +54 -0
- package/src/tests/user-identity.test.ts +72 -0
- package/src/tests/workflow-async-v2.test.ts +39 -1
- package/src/tests/workflow-http-v2.test.ts +3 -2
- package/src/tests/workflow-mcp-trigger-schema.test.ts +52 -3
- package/src/tests/workflow-retry-v2.test.ts +45 -1
- package/src/tools/db-query.ts +18 -8
- package/src/tools/get-task-details.ts +24 -3
- package/src/tools/manage-user.ts +36 -3
- package/src/tools/poll-task.ts +93 -14
- package/src/tools/script-common.ts +5 -0
- package/src/tools/send-task.ts +1 -4
- package/src/tools/slack-archive-channel.ts +70 -0
- package/src/tools/slack-create-channel.ts +74 -0
- package/src/tools/slack-invite-to-channel.ts +78 -0
- package/src/tools/store-progress.ts +13 -2
- package/src/tools/swarm-config/delete-config.ts +9 -0
- package/src/tools/swarm-config/set-config.ts +3 -2
- package/src/tools/task-action.ts +30 -0
- package/src/tools/task-tool-ctx.ts +8 -1
- package/src/tools/tool-config.ts +4 -1
- package/src/tools/update-profile.ts +16 -21
- package/src/tools/utils.ts +5 -0
- package/src/tools/workflows/trigger-workflow.ts +7 -1
- package/src/types.ts +165 -1
- package/src/utils/github-pull-request.ts +76 -0
- package/src/utils/identity-field-budget.ts +73 -0
- package/src/utils/multi-runtime.ts +20 -0
- package/src/utils/requester-comms.ts +24 -0
- package/src/workflows/engine.ts +22 -2
- package/src/workflows/resume.ts +19 -11
- package/src/workflows/retry-poller.ts +1 -0
- package/src/workflows/triggers.ts +4 -0
- package/templates/skills/db-query-guidance/config.json +14 -0
- package/templates/skills/db-query-guidance/content.md +57 -0
- package/dist/app-5da78bd4.js +0 -26
- package/dist/cli-3te4jdkm.js +0 -225
- package/dist/cli-bmze986d.js +0 -7
- package/dist/cli-kh3ba2zf.js +0 -607
- package/dist/hook-cgk4wxmx.js +0 -31
- package/dist/index-25wjsdv2.js +0 -34
- package/dist/index-76at2ymp.js +0 -7
- package/dist/index-hase6zbe.js +0 -6
- package/dist/index-vg4snay4.js +0 -36
- package/dist/index-vy8edt27.js +0 -7
- package/dist/lead-r2yqfmx7.js +0 -85
- package/dist/maintenance-mw70k468.js +0 -26
- package/dist/mistral-conversations-81fwav0j.js +0 -30578
- package/dist/otel-nqa12wf3.js +0 -3149
- package/dist/pricing-refresh-2cn6effr.js +0 -20
- package/dist/rbac-roles-vynday5g.js +0 -30
- package/dist/render-v2-tc0bh8kk.js +0 -34
- package/dist/seed-pricing-8kceb43f.js +0 -17
- package/dist/token-util-pqyc8kng.js +0 -6
- package/dist/worker-qrbz6hmv.js +0 -85
|
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import * as z from "zod";
|
|
6
|
-
import { getAgentById,
|
|
6
|
+
import { getAgentById, updateAgentProfile } from "@/be/db";
|
|
7
7
|
import { can } from "@/rbac";
|
|
8
8
|
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
9
9
|
import { type Agent, AgentAvatarSchema, AgentStatusSchema, ProviderNameSchema } from "@/types";
|
|
@@ -110,7 +110,7 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
110
110
|
.max(MAX_PROFILE_FILE_LENGTH)
|
|
111
111
|
.optional()
|
|
112
112
|
.describe(
|
|
113
|
-
"Personal CLAUDE.md content. Loaded on session start and synced back on session end.
|
|
113
|
+
"Personal CLAUDE.md content. Loaded on session start and synced back on session end. Above 20,000 characters, updates may only keep or reduce the stored size; move durable overflow into memory.",
|
|
114
114
|
),
|
|
115
115
|
soulMd: z
|
|
116
116
|
.string()
|
|
@@ -118,7 +118,7 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
118
118
|
.max(MAX_PROFILE_FILE_LENGTH)
|
|
119
119
|
.optional()
|
|
120
120
|
.describe(
|
|
121
|
-
"Soul content: persona and behavioral directives. Updates both DB and /workspace/SOUL.md. Must be at least 200 characters
|
|
121
|
+
"Soul content: persona and behavioral directives. Updates both DB and /workspace/SOUL.md. Must be at least 200 characters; above 10,000 characters, updates may only keep or reduce the stored size.",
|
|
122
122
|
),
|
|
123
123
|
identityMd: z
|
|
124
124
|
.string()
|
|
@@ -126,7 +126,7 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
126
126
|
.max(MAX_PROFILE_FILE_LENGTH)
|
|
127
127
|
.optional()
|
|
128
128
|
.describe(
|
|
129
|
-
"Identity content: expertise and working style. Updates both DB and /workspace/IDENTITY.md. Must be at least 200 characters
|
|
129
|
+
"Identity content: expertise and working style. Updates both DB and /workspace/IDENTITY.md. Must be at least 200 characters; above 10,000 characters, updates may only keep or reduce the stored size.",
|
|
130
130
|
),
|
|
131
131
|
setupScript: z
|
|
132
132
|
.string()
|
|
@@ -140,7 +140,7 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
140
140
|
.max(MAX_PROFILE_FILE_LENGTH)
|
|
141
141
|
.optional()
|
|
142
142
|
.describe(
|
|
143
|
-
"Environment-specific operational knowledge.
|
|
143
|
+
"Environment-specific operational knowledge. Synced to /workspace/TOOLS.md. Above 20,000 characters, updates may only keep or reduce the stored size; move durable overflow into memory.",
|
|
144
144
|
),
|
|
145
145
|
heartbeatMd: z
|
|
146
146
|
.string()
|
|
@@ -250,21 +250,14 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return toolErr("Target agent not found.", {
|
|
258
|
-
data: { yourAgentId: requestInfo.agentId },
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Update profile fields if provided. `avatar` is spread in only when
|
|
264
|
-
// present so `null` (reset) stays distinguishable from "not provided".
|
|
253
|
+
// Apply name and profile fields in one DB transaction so validation or
|
|
254
|
+
// update failures cannot leave a partially-applied combined payload.
|
|
255
|
+
// `avatar` is spread in only when present so `null` (reset) stays
|
|
256
|
+
// distinguishable from "not provided".
|
|
265
257
|
agent = updateAgentProfile(
|
|
266
258
|
targetAgentId,
|
|
267
259
|
{
|
|
260
|
+
name,
|
|
268
261
|
description,
|
|
269
262
|
role,
|
|
270
263
|
capabilities,
|
|
@@ -282,6 +275,12 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
282
275
|
},
|
|
283
276
|
);
|
|
284
277
|
|
|
278
|
+
// Do not perform audit or workspace-file side effects when the target
|
|
279
|
+
// disappeared before the transactional update could find it.
|
|
280
|
+
if (!agent) {
|
|
281
|
+
return toolErr("Agent not found.", { data: { yourAgentId: requestInfo.agentId } });
|
|
282
|
+
}
|
|
283
|
+
|
|
285
284
|
if (setupScript !== undefined && previousSetupScript !== undefined) {
|
|
286
285
|
try {
|
|
287
286
|
const diff = await computeSetupScriptDiff(previousSetupScript, setupScript);
|
|
@@ -348,10 +347,6 @@ export const registerUpdateProfileTool = (server: McpServer) => {
|
|
|
348
347
|
}
|
|
349
348
|
}
|
|
350
349
|
|
|
351
|
-
if (!agent) {
|
|
352
|
-
return toolErr("Agent not found.", { data: { yourAgentId: requestInfo.agentId } });
|
|
353
|
-
}
|
|
354
|
-
|
|
355
350
|
const updatedFields: string[] = [];
|
|
356
351
|
if (name !== undefined) updatedFields.push("name");
|
|
357
352
|
if (description !== undefined) updatedFields.push("description");
|
package/src/tools/utils.ts
CHANGED
|
@@ -32,6 +32,8 @@ export function markScriptSdkRequestOrigin<T extends object>(meta: T): T {
|
|
|
32
32
|
export type RequestInfo = {
|
|
33
33
|
sessionId: string | undefined;
|
|
34
34
|
agentId: string | undefined;
|
|
35
|
+
/** Calling worker process, when multi-runtime mode is on. */
|
|
36
|
+
runtimeInstanceId: string | undefined;
|
|
35
37
|
sourceTaskId: string | undefined;
|
|
36
38
|
contextKey: string | undefined;
|
|
37
39
|
callOrigin: "mcp" | "script-sdk";
|
|
@@ -41,6 +43,8 @@ export const getRequestInfo = (req: Meta): RequestInfo => {
|
|
|
41
43
|
const agentIdHeader = req.requestInfo?.headers?.["x-agent-id"];
|
|
42
44
|
const sourceTaskIdHeader = req.requestInfo?.headers?.["x-source-task-id"];
|
|
43
45
|
const contextKeyHeader = req.requestInfo?.headers?.["x-context-key"];
|
|
46
|
+
const runtimeHeader = req.requestInfo?.headers?.["x-runtime-instance-id"];
|
|
47
|
+
const runtimeInstanceId = Array.isArray(runtimeHeader) ? runtimeHeader[0] : runtimeHeader;
|
|
44
48
|
|
|
45
49
|
let agentId: string | undefined;
|
|
46
50
|
if (Array.isArray(agentIdHeader)) {
|
|
@@ -66,6 +70,7 @@ export const getRequestInfo = (req: Meta): RequestInfo => {
|
|
|
66
70
|
return {
|
|
67
71
|
sessionId: req.sessionId || undefined,
|
|
68
72
|
agentId,
|
|
73
|
+
runtimeInstanceId: typeof runtimeInstanceId === "string" ? runtimeInstanceId : undefined,
|
|
69
74
|
sourceTaskId,
|
|
70
75
|
contextKey,
|
|
71
76
|
callOrigin: scriptSdkRequestOrigins.has(req) ? "script-sdk" : "mcp",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { resolveTaskAuditUserId } from "@/be/audit-user";
|
|
3
4
|
import { getWorkflow, getWorkflowRun } from "@/be/db";
|
|
4
5
|
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
5
6
|
import { getExecutorRegistry, startWorkflowExecution } from "@/workflows";
|
|
@@ -28,7 +29,7 @@ export const registerTriggerWorkflowTool = (server: McpServer) => {
|
|
|
28
29
|
triggerSchema: z.record(z.string(), z.unknown()).optional(),
|
|
29
30
|
}),
|
|
30
31
|
},
|
|
31
|
-
async ({ id, triggerData }) => {
|
|
32
|
+
async ({ id, triggerData }, requestInfo) => {
|
|
32
33
|
try {
|
|
33
34
|
const workflow = getWorkflow(id);
|
|
34
35
|
if (!workflow) {
|
|
@@ -41,6 +42,11 @@ export const registerTriggerWorkflowTool = (server: McpServer) => {
|
|
|
41
42
|
workflow,
|
|
42
43
|
triggerData ?? {},
|
|
43
44
|
getExecutorRegistry(),
|
|
45
|
+
{
|
|
46
|
+
triggerType: "manual",
|
|
47
|
+
requestedByUserId:
|
|
48
|
+
resolveTaskAuditUserId(requestInfo.sourceTaskId, requestInfo.agentId) ?? undefined,
|
|
49
|
+
},
|
|
44
50
|
);
|
|
45
51
|
|
|
46
52
|
// Check if the run was skipped due to cooldown
|
package/src/types.ts
CHANGED
|
@@ -633,6 +633,102 @@ export const AgentTaskSchema = z
|
|
|
633
633
|
})
|
|
634
634
|
.openapi("AgentTask");
|
|
635
635
|
|
|
636
|
+
// ─── Create-task input contract ──────────────────────────────────────────────
|
|
637
|
+
//
|
|
638
|
+
// Runtime schema for `createTaskExtended` options (src/be/db.ts). Every task
|
|
639
|
+
// write — REST POST /api/tasks, MCP send-task, the scripts bridge, webhooks,
|
|
640
|
+
// the scheduler, and internal callers — funnels through that function, so
|
|
641
|
+
// this schema is the single enforcement point for task-input shapes. It
|
|
642
|
+
// rejects, never coerces: a type mismatch or out-of-range value throws, and
|
|
643
|
+
// only an ABSENT field falls back to the `??` defaults at the INSERT bind
|
|
644
|
+
// site. Deliberately NOT an `.openapi()` component: it is an internal write
|
|
645
|
+
// contract, not a response shape.
|
|
646
|
+
export const CreateTaskOptionsSchema = z.object({
|
|
647
|
+
key: z.string().min(1).optional(),
|
|
648
|
+
agentId: z.string().nullable().optional(),
|
|
649
|
+
creatorAgentId: z.string().optional(),
|
|
650
|
+
source: AgentTaskSourceSchema.optional(),
|
|
651
|
+
taskType: z.string().max(50).optional(),
|
|
652
|
+
tags: z.array(z.string()).optional(),
|
|
653
|
+
priority: z.number().int().min(0).max(100).optional(),
|
|
654
|
+
dependsOn: z.array(z.string()).optional(),
|
|
655
|
+
offeredTo: z.string().optional(),
|
|
656
|
+
/** Explicitly set initial status. */
|
|
657
|
+
status: z.enum(["backlog", "unassigned"]).optional(),
|
|
658
|
+
slackChannelId: z.string().optional(),
|
|
659
|
+
slackThreadTs: z.string().optional(),
|
|
660
|
+
/** Exact Slack message that directly triggered this task; never inherited. */
|
|
661
|
+
slackTriggerMessageTs: z.string().optional(),
|
|
662
|
+
slackUserId: z.string().optional(),
|
|
663
|
+
/**
|
|
664
|
+
* Opt out of the residual Slack/contextKey normalization (see the
|
|
665
|
+
* "Residual-mismatch guard" comment near the INSERT in src/be/db.ts): a
|
|
666
|
+
* deliberate cross-channel/thread dispatch (e.g. `send-task`'s
|
|
667
|
+
* `overrideSlackContext: true`) sets this so its explicit slackChannelId/
|
|
668
|
+
* slackThreadTs survive even when they disagree with a slack-family
|
|
669
|
+
* `contextKey`/parent. Trusted callers that don't set this get normalized —
|
|
670
|
+
* this boundary must not let a caller silently persist a mismatch.
|
|
671
|
+
*/
|
|
672
|
+
overrideSlackContext: z.boolean().optional(),
|
|
673
|
+
vcsProvider: z.enum(["github", "gitlab"]).optional(),
|
|
674
|
+
vcsRepo: z.string().optional(),
|
|
675
|
+
vcsEventType: z.string().optional(),
|
|
676
|
+
vcsNumber: z.number().int().optional(),
|
|
677
|
+
vcsCommentId: z.number().int().optional(),
|
|
678
|
+
vcsAuthor: z.string().optional(),
|
|
679
|
+
vcsUrl: z.string().optional(),
|
|
680
|
+
vcsInstallationId: z.number().int().optional(),
|
|
681
|
+
vcsNodeId: z.string().optional(),
|
|
682
|
+
agentmailInboxId: z.string().optional(),
|
|
683
|
+
agentmailMessageId: z.string().optional(),
|
|
684
|
+
agentmailThreadId: z.string().optional(),
|
|
685
|
+
mentionMessageId: z.string().optional(),
|
|
686
|
+
mentionChannelId: z.string().optional(),
|
|
687
|
+
dir: z.string().optional(),
|
|
688
|
+
parentTaskId: z.string().optional(),
|
|
689
|
+
model: z.string().optional(),
|
|
690
|
+
modelTier: ModelTierSchema.optional(),
|
|
691
|
+
effort: ReasoningEffortSchema.optional(),
|
|
692
|
+
scheduleId: z.string().optional(),
|
|
693
|
+
workflowRunId: z.string().optional(),
|
|
694
|
+
workflowRunStepId: z.string().optional(),
|
|
695
|
+
sourceTaskId: z.string().optional(),
|
|
696
|
+
/**
|
|
697
|
+
* Optional JSON Schema the agent's final output must conform to.
|
|
698
|
+
*
|
|
699
|
+
* Enforced via the MCP `store-progress` tool (validated in
|
|
700
|
+
* `src/tools/store-progress.ts`). NOT enforced when the task runs on
|
|
701
|
+
* default-mode Devin (no MCP) — see runbooks/harness-providers.md
|
|
702
|
+
* ("Per-task outputSchema support"). Callers reading `task.output` for
|
|
703
|
+
* a schema'd task should be defensive about JSON parsing.
|
|
704
|
+
*/
|
|
705
|
+
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
706
|
+
/**
|
|
707
|
+
* When a `parentTaskId` is set, the child inherits the parent's `outputSchema`
|
|
708
|
+
* by default. Set this to `false` to opt out — used by control-plane children
|
|
709
|
+
* (e.g. the Lead `reroute-decision` task) that must inherit Slack/VCS context
|
|
710
|
+
* from the parent but must NOT be forced to satisfy the original work's output
|
|
711
|
+
* contract on completion (which would block the control task — DES-523).
|
|
712
|
+
*/
|
|
713
|
+
inheritParentOutputSchema: z.boolean().optional(),
|
|
714
|
+
followUpConfig: FollowUpConfigSchema.optional(),
|
|
715
|
+
requestedByUserId: z.string().optional(),
|
|
716
|
+
contextKey: z.string().optional(),
|
|
717
|
+
/**
|
|
718
|
+
* Internal control-plane escape hatch for continuations that MUST coexist
|
|
719
|
+
* with their active Linear parent (for example promoted steering). General
|
|
720
|
+
* task creation keeps tracker-context dedup enabled.
|
|
721
|
+
*/
|
|
722
|
+
bypassTrackerContextDedup: z.boolean().optional(),
|
|
723
|
+
/**
|
|
724
|
+
* Routing-affinity snapshot gating pool eligibility (see
|
|
725
|
+
* `isAgentEligibleForTask`). Inherited from the parent (via `parentTaskId`)
|
|
726
|
+
* when not explicitly set — same treatment as `vcsRepo`/`contextKey`.
|
|
727
|
+
*/
|
|
728
|
+
routingAffinity: RoutingAffinitySchema.optional(),
|
|
729
|
+
});
|
|
730
|
+
export type CreateTaskOptions = z.infer<typeof CreateTaskOptionsSchema>;
|
|
731
|
+
|
|
636
732
|
// ============================================================================
|
|
637
733
|
// Task Attachments (Phase 1 — pointer-based artifacts)
|
|
638
734
|
// ============================================================================
|
|
@@ -645,11 +741,19 @@ export const AgentTaskSchema = z
|
|
|
645
741
|
export const TaskAttachmentKindSchema = z.enum(["agent-fs", "url", "shared-fs", "page"]);
|
|
646
742
|
export type TaskAttachmentKind = z.infer<typeof TaskAttachmentKindSchema>;
|
|
647
743
|
|
|
744
|
+
export const SERVER_GENERATED_ATTACHMENT_CAPABILITY = "_agentSwarmGeneratedBy";
|
|
745
|
+
|
|
746
|
+
const attachmentCapabilitiesSchema = z
|
|
747
|
+
.record(z.string(), z.unknown())
|
|
748
|
+
.refine((capabilities) => !(SERVER_GENERATED_ATTACHMENT_CAPABILITY in capabilities), {
|
|
749
|
+
message: `${SERVER_GENERATED_ATTACHMENT_CAPABILITY} is reserved for server-generated attachments`,
|
|
750
|
+
});
|
|
751
|
+
|
|
648
752
|
const attachmentCommonFields = {
|
|
649
753
|
name: z.string().min(1).describe("Display name for the attachment."),
|
|
650
754
|
providerId: z.string().min(1).optional(),
|
|
651
755
|
providerKey: z.string().min(1).optional(),
|
|
652
|
-
capabilities:
|
|
756
|
+
capabilities: attachmentCapabilitiesSchema.optional(),
|
|
653
757
|
mimeType: z.string().optional(),
|
|
654
758
|
sizeBytes: z.number().int().min(0).optional(),
|
|
655
759
|
sha256: z.string().optional(),
|
|
@@ -755,6 +859,22 @@ export const UserSchema = z
|
|
|
755
859
|
|
|
756
860
|
export type User = z.infer<typeof UserSchema>;
|
|
757
861
|
|
|
862
|
+
/**
|
|
863
|
+
* Structured communication preferences read from `users.metadata.comms`.
|
|
864
|
+
* All fields are free-form strings; values render verbatim into the requester
|
|
865
|
+
* profile prompt. Written merge-safely via the `comms` field on
|
|
866
|
+
* PATCH /api/users/{id} and the manage-user tool.
|
|
867
|
+
*/
|
|
868
|
+
export const UserCommsPrefsSchema = z
|
|
869
|
+
.object({
|
|
870
|
+
tone: z.string().optional(),
|
|
871
|
+
language: z.string().optional(),
|
|
872
|
+
verbosity: z.string().optional(),
|
|
873
|
+
})
|
|
874
|
+
.openapi("UserCommsPrefs");
|
|
875
|
+
|
|
876
|
+
export type UserCommsPrefs = z.infer<typeof UserCommsPrefsSchema>;
|
|
877
|
+
|
|
758
878
|
/**
|
|
759
879
|
* Identity event types — mirrored in lockstep with the CHECK constraint on
|
|
760
880
|
* `user_identity_events.eventType` in migration 064. Drift breaks helper
|
|
@@ -1338,6 +1458,8 @@ export const EventNameSchema = z.enum([
|
|
|
1338
1458
|
"system.boot",
|
|
1339
1459
|
"system.migration",
|
|
1340
1460
|
"system.error",
|
|
1461
|
+
"system.profile_sync_rejected",
|
|
1462
|
+
"system.profile_sync_reconciled",
|
|
1341
1463
|
// Script catalog events
|
|
1342
1464
|
"script.global_upsert",
|
|
1343
1465
|
// Schedule events
|
|
@@ -1563,6 +1685,8 @@ export const ActiveSessionSchema = z
|
|
|
1563
1685
|
taskDescription: z.string().nullable(),
|
|
1564
1686
|
runnerSessionId: z.string().nullable(),
|
|
1565
1687
|
providerSessionId: z.string().nullable(),
|
|
1688
|
+
/** Runtime process that owns this session; null for single-runtime rows. */
|
|
1689
|
+
runtimeInstanceId: z.string().nullable().optional(),
|
|
1566
1690
|
startedAt: z.iso.datetime(),
|
|
1567
1691
|
lastHeartbeatAt: z.iso.datetime(),
|
|
1568
1692
|
})
|
|
@@ -1570,6 +1694,45 @@ export const ActiveSessionSchema = z
|
|
|
1570
1694
|
|
|
1571
1695
|
export type ActiveSession = z.infer<typeof ActiveSessionSchema>;
|
|
1572
1696
|
|
|
1697
|
+
// ============================================================================
|
|
1698
|
+
// Runtime Instance Types (multi-runtime worker tracking)
|
|
1699
|
+
// ============================================================================
|
|
1700
|
+
|
|
1701
|
+
/**
|
|
1702
|
+
* Lifecycle of a runtime instance. Zod is the source of truth for the allowed
|
|
1703
|
+
* values — the SQL column has no CHECK constraint (migration 132) so adding a
|
|
1704
|
+
* state doesn't require a table rebuild.
|
|
1705
|
+
*/
|
|
1706
|
+
export const RuntimeInstanceStatusSchema = z.enum(["active", "offline"]);
|
|
1707
|
+
|
|
1708
|
+
/**
|
|
1709
|
+
* One worker process serving a logical agent. The `agents` row (AGENT_ID /
|
|
1710
|
+
* X-Agent-ID) keeps durable identity and the logical maxTasks policy; a
|
|
1711
|
+
* runtime instance carries only process-scoped state: liveness and its own
|
|
1712
|
+
* reported execution capacity. A logical agent may be served by 0..N runtime
|
|
1713
|
+
* instances; rows exist only for multi-runtime registrations
|
|
1714
|
+
* (MULTI_RUNTIME_ENABLED).
|
|
1715
|
+
*/
|
|
1716
|
+
export const RuntimeInstanceSchema = z
|
|
1717
|
+
.object({
|
|
1718
|
+
id: z.string(),
|
|
1719
|
+
agentId: z.string(),
|
|
1720
|
+
status: RuntimeInstanceStatusSchema,
|
|
1721
|
+
/** Runtime-local concurrent task capacity, self-reported at registration. */
|
|
1722
|
+
reportedSlots: z.number().int(),
|
|
1723
|
+
/** Process-local credential readiness; null when never reported. */
|
|
1724
|
+
credentialReady: z.boolean().nullable().optional(),
|
|
1725
|
+
/** Provider-neutral metadata; unused in the initial slice. */
|
|
1726
|
+
metadata: z.record(z.string(), z.unknown()).nullable(),
|
|
1727
|
+
lastSeenAt: z.iso.datetime(),
|
|
1728
|
+
createdAt: z.iso.datetime(),
|
|
1729
|
+
updatedAt: z.iso.datetime(),
|
|
1730
|
+
})
|
|
1731
|
+
.openapi("RuntimeInstance");
|
|
1732
|
+
|
|
1733
|
+
export type RuntimeInstanceStatus = z.infer<typeof RuntimeInstanceStatusSchema>;
|
|
1734
|
+
export type RuntimeInstance = z.infer<typeof RuntimeInstanceSchema>;
|
|
1735
|
+
|
|
1573
1736
|
// ============================================================================
|
|
1574
1737
|
// Workflow Engine Types
|
|
1575
1738
|
// ============================================================================
|
|
@@ -2238,6 +2401,7 @@ export const WorkflowRunSchema = z
|
|
|
2238
2401
|
triggerData: z.unknown().optional(),
|
|
2239
2402
|
context: z.record(z.string(), z.unknown()).optional(),
|
|
2240
2403
|
error: z.string().optional(),
|
|
2404
|
+
createdBy: z.string().optional(),
|
|
2241
2405
|
startedAt: z.string(),
|
|
2242
2406
|
lastUpdatedAt: z.string(),
|
|
2243
2407
|
finishedAt: z.string().optional(),
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface GitHubPullRequestUrl {
|
|
2
|
+
url: string;
|
|
3
|
+
owner: string;
|
|
4
|
+
repo: string;
|
|
5
|
+
number: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const CANDIDATE_TOKEN_RE = /[^\s()[\]{}<>"'`]+/g;
|
|
9
|
+
const TRAILING_PROSE_PUNCTUATION_RE = /[)\]},.;:!]+$/;
|
|
10
|
+
const GITHUB_PATH_SEGMENT_RE = /^[\w.-]+$/;
|
|
11
|
+
|
|
12
|
+
function parseGitHubPullRequestToken(token: string): GitHubPullRequestUrl | null {
|
|
13
|
+
const candidate = token.replace(TRAILING_PROSE_PUNCTUATION_RE, "");
|
|
14
|
+
const lowerCandidate = candidate.toLowerCase();
|
|
15
|
+
if (
|
|
16
|
+
!lowerCandidate.startsWith("https://github.com/") &&
|
|
17
|
+
!lowerCandidate.startsWith("http://github.com/") &&
|
|
18
|
+
!lowerCandidate.startsWith("github.com/")
|
|
19
|
+
) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const withScheme = /^https?:\/\//i.test(candidate) ? candidate : `https://${candidate}`;
|
|
23
|
+
|
|
24
|
+
let parsed: URL;
|
|
25
|
+
try {
|
|
26
|
+
parsed = new URL(withScheme);
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
if (
|
|
31
|
+
parsed.host.toLowerCase() !== "github.com" ||
|
|
32
|
+
parsed.username.length > 0 ||
|
|
33
|
+
parsed.password.length > 0
|
|
34
|
+
) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const [owner, repo, pull, numberText] = parsed.pathname.split("/").filter(Boolean);
|
|
39
|
+
if (
|
|
40
|
+
!owner ||
|
|
41
|
+
!repo ||
|
|
42
|
+
pull?.toLowerCase() !== "pull" ||
|
|
43
|
+
!numberText ||
|
|
44
|
+
!GITHUB_PATH_SEGMENT_RE.test(owner) ||
|
|
45
|
+
!GITHUB_PATH_SEGMENT_RE.test(repo) ||
|
|
46
|
+
!/^\d+$/.test(numberText)
|
|
47
|
+
) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
url: `https://github.com/${owner}/${repo}/pull/${numberText}`,
|
|
53
|
+
owner,
|
|
54
|
+
repo,
|
|
55
|
+
number: Number(numberText),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Extract distinct canonical GitHub pull-request URLs from free text. */
|
|
60
|
+
export function extractGitHubPullRequestUrls(
|
|
61
|
+
text: string | null | undefined,
|
|
62
|
+
): GitHubPullRequestUrl[] {
|
|
63
|
+
if (!text) return [];
|
|
64
|
+
|
|
65
|
+
const results: GitHubPullRequestUrl[] = [];
|
|
66
|
+
const seen = new Set<string>();
|
|
67
|
+
for (const match of text.matchAll(CANDIDATE_TOKEN_RE)) {
|
|
68
|
+
const pullRequest = parseGitHubPullRequestToken(match[0]);
|
|
69
|
+
if (!pullRequest) continue;
|
|
70
|
+
const dedupeKey = pullRequest.url.toLowerCase();
|
|
71
|
+
if (seen.has(dedupeKey)) continue;
|
|
72
|
+
seen.add(dedupeKey);
|
|
73
|
+
results.push(pullRequest);
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BOOTSTRAP_MAX_CHARS } from "../prompts/base-prompt";
|
|
2
|
+
|
|
3
|
+
export const SOUL_MD_MAX_CHARS = 10_000;
|
|
4
|
+
export const IDENTITY_MD_MAX_CHARS = 10_000;
|
|
5
|
+
|
|
6
|
+
export const IDENTITY_FIELD_BUDGETS = {
|
|
7
|
+
soulMd: SOUL_MD_MAX_CHARS,
|
|
8
|
+
identityMd: IDENTITY_MD_MAX_CHARS,
|
|
9
|
+
claudeMd: BOOTSTRAP_MAX_CHARS,
|
|
10
|
+
toolsMd: BOOTSTRAP_MAX_CHARS,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export type BudgetedIdentityField = keyof typeof IDENTITY_FIELD_BUDGETS;
|
|
14
|
+
|
|
15
|
+
export interface IdentityFieldBudgetRejection {
|
|
16
|
+
field: BudgetedIdentityField;
|
|
17
|
+
dbSize: number;
|
|
18
|
+
diskSize: number;
|
|
19
|
+
budget: number;
|
|
20
|
+
delta: number;
|
|
21
|
+
reason: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type IdentityFieldBudgetResult =
|
|
25
|
+
| { ok: true }
|
|
26
|
+
| ({ ok: false } & IdentityFieldBudgetRejection);
|
|
27
|
+
|
|
28
|
+
export function checkIdentityFieldBudget({
|
|
29
|
+
field,
|
|
30
|
+
currentValue,
|
|
31
|
+
nextValue,
|
|
32
|
+
}: {
|
|
33
|
+
field: BudgetedIdentityField;
|
|
34
|
+
currentValue: string;
|
|
35
|
+
nextValue: string;
|
|
36
|
+
}): IdentityFieldBudgetResult {
|
|
37
|
+
const budget = IDENTITY_FIELD_BUDGETS[field];
|
|
38
|
+
if (nextValue.length <= budget || nextValue.length <= currentValue.length) {
|
|
39
|
+
return { ok: true };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const delta = nextValue.length - currentValue.length;
|
|
43
|
+
const remediation =
|
|
44
|
+
field === "toolsMd"
|
|
45
|
+
? ` Content past the ${budget}-character cap is already silently dropped at read time, so shrinking that tail loses nothing sessions currently receive. Move durable content into memories and keep pointers to it in this field.`
|
|
46
|
+
: field === "claudeMd"
|
|
47
|
+
? ` The tail past the ${budget}-character cap is dropped from the base prompt and only reaches harnesses with a native CLAUDE.md loader. Move durable content into memories and keep pointers to it in this field.`
|
|
48
|
+
: " Move durable content into memories and keep pointers to it in this field.";
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
ok: false,
|
|
52
|
+
field,
|
|
53
|
+
dbSize: currentValue.length,
|
|
54
|
+
diskSize: nextValue.length,
|
|
55
|
+
budget,
|
|
56
|
+
delta,
|
|
57
|
+
reason:
|
|
58
|
+
`Update rejected for ${field}: current size ${currentValue.length} characters, ` +
|
|
59
|
+
`budget ${budget} characters, delta ${delta >= 0 ? "+" : ""}${delta} characters.` +
|
|
60
|
+
remediation,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class IdentityFieldBudgetError extends Error {
|
|
65
|
+
constructor(
|
|
66
|
+
readonly rejection: IdentityFieldBudgetRejection,
|
|
67
|
+
readonly dbHash: string,
|
|
68
|
+
readonly diskHash: string,
|
|
69
|
+
) {
|
|
70
|
+
super(rejection.reason);
|
|
71
|
+
this.name = "IdentityFieldBudgetError";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { parseEnvFlag } from "./env-flag";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Opt-in, default off: allows one logical agent to be served by several
|
|
5
|
+
* worker processes. Lives outside `src/be` so worker-side code can import it
|
|
6
|
+
* without crossing the DB boundary.
|
|
7
|
+
*/
|
|
8
|
+
export function isMultiRuntimeEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
9
|
+
return parseEnvFlag(env.MULTI_RUNTIME_ENABLED, false);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Per-boot runtime identity the runner stamps into the process environment
|
|
14
|
+
* before any provider session exists. Adapters read it here to send the
|
|
15
|
+
* X-Runtime-Instance-ID header on the swarm MCP session — runtime identity is
|
|
16
|
+
* process/auth context, never a tool argument.
|
|
17
|
+
*/
|
|
18
|
+
export function swarmRuntimeInstanceId(env: NodeJS.ProcessEnv = process.env): string | undefined {
|
|
19
|
+
return env.SWARM_RUNTIME_INSTANCE_ID || undefined;
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { User, UserCommsPrefs } from "../types";
|
|
2
|
+
|
|
3
|
+
function pickString(value: unknown): string | undefined {
|
|
4
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extract structured communication preferences from `users.metadata.comms`.
|
|
9
|
+
* `metadata` is a free-form JSON blob with no write-side validation, so only
|
|
10
|
+
* non-empty string fields survive; returns undefined when nothing usable is set.
|
|
11
|
+
*/
|
|
12
|
+
export function getUserCommsPrefs(
|
|
13
|
+
user: Pick<User, "metadata"> | null | undefined,
|
|
14
|
+
): UserCommsPrefs | undefined {
|
|
15
|
+
const comms = user?.metadata?.comms;
|
|
16
|
+
if (!comms || typeof comms !== "object" || Array.isArray(comms)) return undefined;
|
|
17
|
+
const record = comms as Record<string, unknown>;
|
|
18
|
+
const prefs: UserCommsPrefs = {
|
|
19
|
+
tone: pickString(record.tone),
|
|
20
|
+
language: pickString(record.language),
|
|
21
|
+
verbosity: pickString(record.verbosity),
|
|
22
|
+
};
|
|
23
|
+
return prefs.tone || prefs.language || prefs.verbosity ? prefs : undefined;
|
|
24
|
+
}
|
package/src/workflows/engine.ts
CHANGED
|
@@ -76,7 +76,13 @@ export async function startWorkflowExecution(
|
|
|
76
76
|
// Cooldown check
|
|
77
77
|
if (workflow.cooldown && shouldSkipCooldown(workflow.id, workflow.cooldown)) {
|
|
78
78
|
const runId = crypto.randomUUID();
|
|
79
|
-
createWorkflowRun({
|
|
79
|
+
createWorkflowRun({
|
|
80
|
+
id: runId,
|
|
81
|
+
workflowId: workflow.id,
|
|
82
|
+
triggerType: options.triggerType ?? "manual",
|
|
83
|
+
triggerData,
|
|
84
|
+
createdBy: options.requestedByUserId,
|
|
85
|
+
});
|
|
80
86
|
updateWorkflowRun(runId, {
|
|
81
87
|
status: "skipped",
|
|
82
88
|
error: "cooldown",
|
|
@@ -86,7 +92,13 @@ export async function startWorkflowExecution(
|
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
const runId = crypto.randomUUID();
|
|
89
|
-
createWorkflowRun({
|
|
95
|
+
createWorkflowRun({
|
|
96
|
+
id: runId,
|
|
97
|
+
workflowId: workflow.id,
|
|
98
|
+
triggerType: options.triggerType ?? "manual",
|
|
99
|
+
triggerData,
|
|
100
|
+
createdBy: options.requestedByUserId,
|
|
101
|
+
});
|
|
90
102
|
telemetry.workflow("started", {
|
|
91
103
|
workflowId: workflow.id,
|
|
92
104
|
nodeCount: workflow.definition.nodes.length,
|
|
@@ -160,6 +172,14 @@ export async function walkGraph(
|
|
|
160
172
|
secretKeys: Set<string> = new Set(),
|
|
161
173
|
options: WorkflowExecutionOptions = {},
|
|
162
174
|
): Promise<void> {
|
|
175
|
+
// Initial triggers carry the requester in options. Resumes, retries, and
|
|
176
|
+
// recovery start from persisted state, so rehydrate it from the run.
|
|
177
|
+
if (!options.requestedByUserId) {
|
|
178
|
+
options = {
|
|
179
|
+
...options,
|
|
180
|
+
requestedByUserId: getWorkflowRun(runId)?.createdBy,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
163
183
|
let nodeExecutionCount = 0;
|
|
164
184
|
// `run.id` is a context builtin (like `trigger` / `input`) so nodes can reference
|
|
165
185
|
// their own run — e.g. an audit/receipt node correlating its output with the run
|