@desplega.ai/agent-swarm 1.165.0 → 1.167.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/dist/acp-adapter-zpvy6321.js +34 -0
- package/dist/{actions-jna0b3wm.js → actions-fq2zrwtf.js} +30 -34
- package/dist/{amp-adapter-0eve81pz.js → amp-adapter-5gbk7501.js} +7 -7
- package/dist/{anthropic-messages-hst62ws9.js → anthropic-messages-13yn502s.js} +4 -4
- package/dist/{app-75hm5cfa.js → app-nctetn1e.js} +11 -11
- package/dist/{assistant-yzd51j33.js → assistant-0aq8gjvj.js} +31 -35
- package/dist/{azure-openai-responses-mh8tvf78.js → azure-openai-responses-9st34pfz.js} +5 -5
- package/dist/{boot-reembed-z158xq32.js → boot-reembed-1ze5853n.js} +14 -16
- package/dist/{boot-reembed-2ex2mcsh.js → boot-reembed-fmp5ww69.js} +15 -16
- package/dist/boot-scrub-sweep-cbp8xd4e.js +212 -0
- package/dist/{boot-seeds-2bmnh18p.js → boot-seeds-22tx8a53.js} +13 -12
- package/dist/{claude-adapter-jbj1mycz.js → claude-adapter-0jhgeh1d.js} +25 -25
- package/dist/{claude-managed-adapter-17ggz09t.js → claude-managed-adapter-tzwxy803.js} +5 -5
- package/dist/{claude-managed-setup-ptm1nzm2.js → claude-managed-setup-nrhfx5b0.js} +5 -5
- package/dist/{claude-sdk-session-9re1g7r2.js → claude-sdk-session-wh77rh83.js} +2632 -2614
- package/dist/{cli-zsh093hk.js → cli-014vns2y.js} +63 -1
- package/dist/{cli-qvfk83fy.js → cli-13xwcqvj.js} +2 -2
- package/dist/{cli-8gpbwy09.js → cli-1yrcfa5s.js} +5 -5
- package/dist/{cli-xtgtyafv.js → cli-577bxkf6.js} +212 -451
- package/dist/{cli-ma3zvh39.js → cli-5qkcdv8c.js} +6118 -5874
- package/dist/{cli-cwxhbf43.js → cli-5t5my0h8.js} +85 -2
- package/dist/{cli-zvckv750.js → cli-69egj654.js} +2 -2
- package/dist/{cli-9xb89xca.js → cli-6bpvv8h4.js} +9 -9
- package/dist/{cli-90v942q1.js → cli-6qxmjpem.js} +8 -8
- package/dist/{cli-9866bd07.js → cli-6vfz44sr.js} +1 -1
- package/dist/{cli-32bca7nr.js → cli-7avy4v8w.js} +1 -1
- package/dist/{cli-xb3c6aat.js → cli-7mhy3ths.js} +21 -18
- package/dist/{cli-q38n4bq0.js → cli-95zs84qw.js} +3 -3
- package/dist/cli-a35hzdve.js +33 -0
- package/dist/{cli-x3x0qwky.js → cli-bxqez1p0.js} +51 -23
- package/dist/{cli-prt9emct.js → cli-c2tpw9ck.js} +3 -3
- package/dist/{cli-0n4fasz0.js → cli-c8r99akr.js} +16 -16
- package/dist/{cli-5anb0ev3.js → cli-cexctgn5.js} +89 -26
- package/dist/{cli-bns5c8k9.js → cli-cf2vgn9d.js} +105 -91
- package/dist/{cli-ng97fjq7.js → cli-cmxkbzzs.js} +33 -7
- package/dist/{cli-nexwh8zg.js → cli-g7k7zbcz.js} +12 -5
- package/dist/{cli-mmzwwptd.js → cli-hf5s9pgf.js} +1 -1
- package/dist/{cli-nvvfd8bq.js → cli-jbzbr36n.js} +4091 -3793
- package/dist/{cli-zn2v3t8v.js → cli-jvmtxqtc.js} +27 -15
- package/dist/{cli-pkke6geq.js → cli-km4x66j0.js} +83 -65
- package/dist/cli-kw0jcfje.js +516 -0
- package/dist/{cli-28smfvbn.js → cli-m7vmeepg.js} +32 -19
- package/dist/{cli-hpryr6em.js → cli-mb75wpxf.js} +1 -1
- package/dist/{cli-qdv8kgz7.js → cli-mkdsy1nq.js} +14018 -3333
- package/dist/{cli-b0f70z24.js → cli-mn8qkd8v.js} +1 -1
- package/dist/{cli-420bdgw0.js → cli-mv2520nm.js} +1 -1
- package/dist/{cli-n9ehc28t.js → cli-mxry91sa.js} +31 -10
- package/dist/{cli-wfajtmf7.js → cli-mxvnnv5q.js} +596 -13
- package/dist/cli-nkqjj42q.js +104 -0
- package/dist/{cli-e7t4snpa.js → cli-p8rt8spp.js} +5 -5
- package/dist/{cli-gh5yqzpe.js → cli-pkj1w46r.js} +12 -7
- package/dist/cli-q1vnz8wv.js +96 -0
- package/dist/{cli-fj86xr3c.js → cli-qd97v6z2.js} +2 -2
- package/dist/{cli-ba66wyhy.js → cli-qzmzwegq.js} +60 -20
- package/dist/{cli-5b2fjjzh.js → cli-r7eeddkq.js} +14 -9
- package/dist/{cli-8ssjez7e.js → cli-rhy7z1rp.js} +22 -11
- package/dist/{cli-4mevd1hf.js → cli-s9y81s7j.js} +5 -5
- package/dist/{cli-59jn5twa.js → cli-tc5zec7v.js} +7 -7
- package/dist/{cli-ttbsse3f.js → cli-tmhsxhb8.js} +1 -1
- package/dist/{cli-k6xx3pve.js → cli-tx2zvn23.js} +4 -4
- package/dist/{cli-pjxnr1jn.js → cli-ty4bzkqr.js} +5 -5
- package/dist/{cli-nfygw434.js → cli-v1pwxreq.js} +55 -52
- package/dist/{cli-ftry7975.js → cli-v1w7pbd8.js} +3 -2
- package/dist/{cli-10zmp1p7.js → cli-vr5avem2.js} +27 -32
- package/dist/{cli-bzr0ftht.js → cli-wnb9b2g3.js} +19 -0
- package/dist/cli-wt7ccy4r.js +2654 -0
- package/dist/{cli-50eg13rj.js → cli-wydz3feg.js} +549 -321
- package/dist/{cli-krqm5f11.js → cli-xezn9nkh.js} +16 -13
- package/dist/{cli-8kt0bmgx.js → cli-xf713zz0.js} +2 -2
- package/dist/{cli-x7afk5wm.js → cli-xvc3q9br.js} +1 -1
- package/dist/{cli-9s3h836g.js → cli-xvdgasgy.js} +1 -1
- package/dist/{cli-j0pdrmwg.js → cli-y0kjpfm9.js} +3 -3
- package/dist/{cli-6zcfw0x7.js → cli-y195hv1a.js} +1 -1
- package/dist/{cli-amwhs8h2.js → cli-ykt8f7va.js} +22 -9
- package/dist/{cli-1kzfvd1z.js → cli-ymmc1zxg.js} +15 -11
- package/dist/{cli-xnzrzets.js → cli-ypgba1a8.js} +2 -2
- package/dist/{cli-bdv39kgj.js → cli-z1dqhc9y.js} +31 -20
- package/dist/{cli-fw6vdcq5.js → cli-zp67qg5x.js} +34 -1
- package/dist/{cli-qbksc292.js → cli-zy39d433.js} +2 -0
- package/dist/cli.js +36 -32
- package/dist/{cloudflare-workers-ai-system-one-tt484t61.js → cloudflare-workers-ai-system-one-sta45jf9.js} +7 -5
- package/dist/{codex-adapter-3qnxshje.js → codex-adapter-cgesnjkr.js} +20 -20
- package/dist/{codex-login-brkxhhdg.js → codex-login-g1cyt5zm.js} +2 -2
- package/dist/{codex-session-runner-612wnapp.js → codex-session-runner-8kd7ddhr.js} +20 -20
- package/dist/{commands-2ybfcxkj.js → commands-h6zaaxym.js} +11 -10
- package/dist/{cursor-adapter-p3jgdehv.js → cursor-adapter-v8mm6bp5.js} +7 -7
- package/dist/{db-f4ans0jj.js → db-qg3myn53.js} +13 -10
- package/dist/{devin-adapter-dhzt01ff.js → devin-adapter-bffjj5n4.js} +2 -2
- package/dist/{dispatcher-pk182apd.js → dispatcher-7vnwj9qw.js} +28 -32
- package/dist/{dsh-adapter-7twaeps1.js → dsh-adapter-tz6hfp5r.js} +7 -7
- package/dist/{e2b-y8t3jzyz.js → e2b-nd50eccg.js} +1 -1
- package/dist/{easter-egg-3d-mtpnw06s.js → easter-egg-3d-66zxervv.js} +2 -2
- package/dist/{event-bus-w7ac4n3c.js → event-bus-vnfthafg.js} +2 -2
- package/dist/{execute-s4ccjq3n.js → execute-h4jgevyw.js} +61 -11
- package/dist/{google-generative-ai-d6nphg3q.js → google-generative-ai-b8zxrpax.js} +5 -5
- package/dist/{google-vertex-cpshkref.js → google-vertex-nrdd697t.js} +5 -5
- package/dist/grok-adapter-jdt2dz2s.js +39 -0
- package/dist/{handlers-g2wnr4t9.js → handlers-2qtkpncr.js} +31 -35
- package/dist/{hook-f7jt9vnm.js → hook-51yfcgsv.js} +48 -39
- package/dist/{hook-bbdpnkb4.js → hook-qnbdgwvd.js} +15 -17
- package/dist/{http-w40q4w94.js → http-jsmtag08.js} +536 -231
- package/dist/{index-056j5kzn.js → index-2t9kesn1.js} +13 -12
- package/dist/{index-cj1r9q83.js → index-bt8wkv1w.js} +29 -33
- package/dist/{index-7n70jwbb.js → index-cx1sb9bq.js} +42 -35
- package/dist/{index-9bfssf54.js → index-ekywyv2v.js} +28 -32
- package/dist/{index-fdk1t4d6.js → index-n0rxa4ca.js} +11962 -9900
- package/dist/{index-k8xc083e.js → index-t4g06w93.js} +28 -32
- package/dist/{keepalive-1tj10tf4.js → keepalive-4aezx4bj.js} +16 -12
- package/dist/{lead-st0bg7v4.js → lead-r44bkpm5.js} +52 -56
- package/dist/{llama-cpp-classify-tgj35k8d.js → llama-cpp-classify-6erb7wwv.js} +3 -1
- package/dist/{maintenance-nz71zats.js → maintenance-grz5jrzh.js} +12 -13
- package/dist/{mistral-conversations-8445ddjn.js → mistral-conversations-059y51zt.js} +4 -4
- package/dist/{node-f0ykebbv.js → node-qm9eb6z0.js} +25 -7
- package/dist/{oauth-refresh-sweep-aefzwvvq.js → oauth-refresh-sweep-wm4ctjfj.js} +15 -11
- package/dist/{onboard-kgpr9mbn.js → onboard-v60zgqf0.js} +2 -2
- package/dist/{openai-codex-responses-9ynm88zy.js → openai-codex-responses-jzxkta9b.js} +8 -7
- package/dist/{openai-completions-nhqwjmaw.js → openai-completions-663yncfq.js} +4 -4
- package/dist/openai-decisions-vj9nkpf8.js +162 -0
- package/dist/{openai-responses-xx1c4kgm.js → openai-responses-m3g43rrt.js} +5 -5
- package/dist/{opencode-adapter-0c8e70dk.js → opencode-adapter-yjyqynzf.js} +8 -8
- package/dist/{openrouter-images-8yx3487g.js → openrouter-images-kr60n6b9.js} +1 -1
- package/dist/{otel-impl-x8zp4y5a.js → otel-impl-ghh4dyf8.js} +2 -2
- package/dist/{pi-messages-vxdt8v7j.js → pi-messages-xszk613n.js} +1 -1
- package/dist/{pi-mono-adapter-t280ah5c.js → pi-mono-adapter-0eg8kw2c.js} +69 -52
- package/dist/{pricing-refresh-9e0q7cwk.js → pricing-refresh-mjrqvnvw.js} +12 -11
- package/dist/{rbac-roles-790j3ga8.js → rbac-roles-axv4d74x.js} +11 -10
- package/dist/{rbac-roles-kcp6zge2.js → rbac-roles-fd5tskj9.js} +11 -10
- package/dist/{render-v2-tch4nefj.js → render-v2-k50j33qd.js} +11 -11
- package/dist/{runtime-v2t1r79e.js → runtime-h9ha1mq6.js} +4 -4
- package/dist/{setup-rcm303ns.js → setup-4syh0pd2.js} +2 -2
- package/dist/{typesafe-system-one-datfr82p.js → typesafe-system-one-e988vty7.js} +7 -5
- package/dist/{virtual-modules-wm8mxdxx.js → virtual-modules-ftr9kwe8.js} +11 -11
- package/dist/{work-objects-ctg7t70w.js → work-objects-jcdbg8rr.js} +32 -36
- package/dist/{worker-5dp0xm55.js → worker-x8j8c9sx.js} +52 -56
- package/dist/{x-v3yw66zs.js → x-ma4gnfgy.js} +2 -2
- package/openapi.json +5 -2
- package/package.json +15 -11
- package/src/be/automation-preflight.ts +9 -4
- package/src/be/boot-scrub-sweep.ts +302 -0
- package/src/be/crypto/key-bootstrap.ts +1 -1
- package/src/be/db/approvals.ts +15 -1
- package/src/be/db/codex-oauth-device-flows.ts +40 -0
- package/src/be/db/config-secrets.ts +31 -0
- package/src/be/db/runtime.ts +4 -0
- package/src/be/db/script-runs.ts +15 -0
- package/src/be/db/tasks/write.ts +1 -1
- package/src/be/db-queries/mcp-oauth.ts +5 -0
- package/src/be/db-queries/oauth.ts +77 -0
- package/src/be/db.ts +162 -59
- package/src/be/events.ts +17 -1
- package/src/be/memory/index-content.ts +2 -2
- package/src/be/memory/providers/openai-embedding.ts +7 -2
- package/src/be/memory/providers/sqlite-store.ts +63 -11
- package/src/be/memory/raters/llm-summarizer.ts +7 -2
- package/src/be/memory/types.ts +14 -0
- package/src/be/migrations/201_workflow_replay_columns.sql +10 -0
- package/src/be/migrations/202_codex_oauth_device_flows.sql +24 -0
- package/src/be/modelsdev-cache.json +61 -0
- package/src/be/scripts/db.ts +28 -4
- package/src/be/scripts/source-secrets.ts +37 -0
- package/src/be/scrub-json.ts +32 -0
- package/src/be/sealed-json.ts +59 -0
- package/src/be/secret-registry.ts +131 -0
- package/src/be/seed-pricing.ts +84 -53
- package/src/be/swarm-config-guard.ts +13 -0
- package/src/be/workflow-replay.ts +77 -0
- package/src/commands/provider-credentials.ts +28 -5
- package/src/commands/runner.ts +7 -12
- package/src/heartbeat/heartbeat.ts +91 -19
- package/src/hooks/hook.ts +72 -27
- package/src/http/codex-oauth-device.ts +8 -10
- package/src/http/db-query-bounded.ts +3 -0
- package/src/http/db-query-shared.ts +107 -15
- package/src/http/db-query.ts +10 -2
- package/src/http/index.ts +23 -6
- package/src/http/mcp.ts +5 -0
- package/src/http/onboarding.ts +2 -0
- package/src/http/script-runs.ts +9 -1
- package/src/http/scripts.ts +15 -0
- package/src/http/workflows.ts +3 -2
- package/src/oauth/mcp-wrapper.ts +1 -1
- package/src/providers/acp-adapter.ts +25 -11
- package/src/providers/acp-target-catalog.ts +35 -1
- package/src/providers/acp-targets.ts +78 -7
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/claude-adapter.ts +26 -0
- package/src/providers/codex-adapter.ts +30 -3
- package/src/providers/codex-oauth/auth-json.ts +21 -4
- package/src/providers/codex-oauth/types.ts +2 -0
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/providers/dsh-adapter.ts +10 -1
- package/src/providers/grok-adapter.ts +18 -2
- package/src/providers/opencode-adapter.ts +21 -5
- package/src/providers/pi-mono-extension.ts +56 -25
- package/src/providers/pricing-sources.md +2 -0
- package/src/script-workflows/supervisor.ts +11 -2
- package/src/scripts-runtime/eval-harness.ts +2 -12
- package/src/scripts-runtime/executors/quickjs-bundle.ts +152 -0
- package/src/scripts-runtime/executors/quickjs-prelude.ts +285 -0
- package/src/scripts-runtime/executors/quickjs-runner.ts +580 -0
- package/src/scripts-runtime/executors/quickjs-worker.ts +81 -0
- package/src/scripts-runtime/executors/quickjs.ts +196 -0
- package/src/scripts-runtime/executors/registry.ts +2 -0
- package/src/scripts-runtime/executors/sourcemap.ts +79 -0
- package/src/scripts-runtime/script-error-hints.ts +14 -0
- package/src/server.ts +66 -4
- package/src/tests/acp-adapter.test.ts +277 -12
- package/src/tests/boot-scrub-sweep.test.ts +390 -0
- package/src/tests/check-text-columns.test.ts +145 -0
- package/src/tests/ci-unit-test-report.test.ts +73 -0
- package/src/tests/claude-default-route.test.ts +75 -0
- package/src/tests/claude-hook-output.test.ts +233 -0
- package/src/tests/claude-sdk-process.fixture.ts +13 -2
- package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +4 -2
- package/src/tests/codex-adapter.test.ts +166 -26
- package/src/tests/codex-oauth-auth-timestamps.test.ts +76 -0
- package/src/tests/codex-oauth-device.test.ts +23 -37
- package/src/tests/codex-oauth.test.ts +4 -1
- package/src/tests/context-window.test.ts +2 -2
- package/src/tests/credential-check.test.ts +51 -1
- package/src/tests/db-query-denylist.test.ts +202 -0
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +1 -0
- package/src/tests/dsh-adapter.test.ts +23 -1
- package/src/tests/enabled-tools.test.ts +269 -0
- package/src/tests/entrypoint-acp-target-binary.test.ts +31 -1
- package/src/tests/entrypoint-codex-oauth-seed.test.ts +12 -0
- package/src/tests/events-scrub.test.ts +88 -0
- package/src/tests/fixtures/secret-corpus.ts +320 -0
- package/src/tests/grok-adapter.test.ts +13 -0
- package/src/tests/haiku-5-5-pricing.test.ts +38 -0
- package/src/tests/heartbeat-checklist.test.ts +158 -1
- package/src/tests/onboarding.test.ts +44 -0
- package/src/tests/opencode-adapter.test.ts +66 -3
- package/src/tests/opencode-plugin.test.ts +37 -0
- package/src/tests/openrouter-attribution-call-sites.test.ts +204 -0
- package/src/tests/openrouter-base-url.test.ts +30 -39
- package/src/tests/pi-mono-extension.test.ts +161 -2
- package/src/tests/pricing-refresh.test.ts +70 -1
- package/src/tests/reasoning-effort.test.ts +3 -1
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/script-executor-conformance.test.ts +3 -0
- package/src/tests/script-executor-quickjs.test.ts +442 -0
- package/src/tests/script-executor-registry.test.ts +6 -1
- package/src/tests/script-runs-http.test.ts +88 -1
- package/src/tests/script-runs-scrub.test.ts +275 -0
- package/src/tests/scripts-http.test.ts +82 -1
- package/src/tests/scrubbed-text-12e.test.ts +289 -0
- package/src/tests/sealed-key-guard.test.ts +166 -0
- package/src/tests/secret-canary-sweep.test.ts +958 -0
- package/src/tests/secret-registry.test.ts +355 -0
- package/src/tests/secret-rules.test.ts +230 -0
- package/src/tests/secret-scrubber.test.ts +3 -2
- package/src/tests/telemetry-trigger.test.ts +12 -1
- package/src/tests/workflow-llm.test.ts +14 -0
- package/src/tests/workflow-replay.test.ts +518 -0
- package/src/tests/workflow-scrub.test.ts +242 -0
- package/src/tests/workflow-system-one-decision-providers.test.ts +33 -0
- package/src/tools/db-query.ts +1 -1
- package/src/tools/inject-learning.ts +1 -1
- package/src/tools/request-human-input.ts +7 -2
- package/src/tools/workflows/get-workflow-run.ts +3 -2
- package/src/types.ts +1 -1
- package/src/utils/enabled-tools.ts +27 -0
- package/src/utils/internal-ai/complete-structured.ts +11 -3
- package/src/utils/openrouter-base-url.ts +23 -0
- package/src/utils/secret-rules.generated.ts +2055 -0
- package/src/utils/secret-scrubber.ts +363 -29
- package/src/workflows/engine.ts +39 -4
- package/src/workflows/executors/raw-llm.ts +1 -0
- package/src/workflows/executors/system-one-decision.ts +2 -0
- package/src/workflows/executors/validate.ts +1 -0
- package/src/workflows/executors/workflow-llm.ts +9 -2
- package/src/workflows/recovery.ts +10 -1
- package/src/workflows/resume.ts +62 -3
- package/src/workflows/retry-poller.ts +3 -0
- package/templates/skills/agent-browser/SKILL.md +2 -0
- package/templates/skills/agent-browser/content.md +2 -0
- package/templates/skills/code-quality/content.md +1 -0
- package/templates/skills/heartbeat-runbook/content.md +1 -1
- package/templates/skills/work-on-task/SKILL.md +4 -0
- package/templates/skills/work-on-task/content.md +4 -0
- package/templates/skills/workflow-iterate/content.md +9 -0
- package/dist/acp-adapter-w6zws6me.js +0 -23
- package/dist/boot-scrub-logs-246yn076.js +0 -99
- package/dist/cli-3a4m1aws.js +0 -572
- package/dist/cli-3dpj7atn.js +0 -11
- package/dist/cli-a87b04k8.js +0 -951
- package/dist/cli-cvk6yzw5.js +0 -40
- package/dist/cli-gvcgmx69.js +0 -183
- package/dist/cli-h1spv8v4.js +0 -427
- package/dist/cli-jqt9hrnz.js +0 -168
- package/dist/cli-yhmwmv0g.js +0 -9281
- package/dist/grok-adapter-yt9pab3k.js +0 -29
- package/src/be/boot-scrub-logs.ts +0 -132
- package/dist/{codex-hook-d2rkvf39.js → codex-hook-15dgc4cb.js} +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterEach, describe, expect, spyOn, test } from "bun:test";
|
|
2
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
-
import { createServer, type IncomingMessage, type
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import type { Usage } from "@agentclientprotocol/sdk";
|
|
@@ -22,7 +22,12 @@ import {
|
|
|
22
22
|
sanitizeAcpConfigOptions,
|
|
23
23
|
toAcpMcpServers,
|
|
24
24
|
} from "../providers/acp-adapter";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
AcpTargetResolutionError,
|
|
27
|
+
COPILOT_INSTRUCTIONS_FILE,
|
|
28
|
+
copilotInstructionsDir,
|
|
29
|
+
resolveAcpTarget,
|
|
30
|
+
} from "../providers/acp-targets";
|
|
26
31
|
import type { ProviderEvent, ProviderSessionConfig } from "../providers/types";
|
|
27
32
|
import { listenOnFreePort } from "./test-net";
|
|
28
33
|
|
|
@@ -59,20 +64,29 @@ function baseConfig(overrides: Partial<ProviderSessionConfig> = {}): ProviderSes
|
|
|
59
64
|
|
|
60
65
|
/**
|
|
61
66
|
* Start a minimal swarm API stub that handles POST /api/sessions/tokens and
|
|
62
|
-
* DELETE /api/sessions/tokens/:id. Returns
|
|
63
|
-
*
|
|
67
|
+
* DELETE /api/sessions/tokens/:id. Returns its base URL and `close()`, which
|
|
68
|
+
* the caller must await. The adapter revokes a minted token fire-and-forget,
|
|
69
|
+
* so closing before that DELETE lands fails it and leaks a revoke warning
|
|
70
|
+
* into a later test.
|
|
64
71
|
*/
|
|
65
72
|
async function startTokenStubServer(
|
|
66
73
|
tokenId: string,
|
|
67
74
|
plaintext: string,
|
|
68
|
-
): Promise<{
|
|
75
|
+
): Promise<{ apiUrl: string; close: () => Promise<void> }> {
|
|
76
|
+
let minted = false;
|
|
77
|
+
let resolveRevoked!: () => void;
|
|
78
|
+
const revoked = new Promise<void>((resolve) => {
|
|
79
|
+
resolveRevoked = resolve;
|
|
80
|
+
});
|
|
69
81
|
const stub = createServer(async (req: IncomingMessage, res: ServerResponse) => {
|
|
70
82
|
if (req.method === "POST" && req.url === "/api/sessions/tokens") {
|
|
83
|
+
minted = true;
|
|
71
84
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
72
85
|
res.end(JSON.stringify({ tokenId, plaintext }));
|
|
73
86
|
} else if (req.method === "DELETE" && req.url?.startsWith("/api/sessions/tokens/")) {
|
|
74
87
|
res.writeHead(204);
|
|
75
88
|
res.end();
|
|
89
|
+
resolveRevoked();
|
|
76
90
|
} else {
|
|
77
91
|
res.writeHead(404);
|
|
78
92
|
res.end();
|
|
@@ -80,7 +94,13 @@ async function startTokenStubServer(
|
|
|
80
94
|
});
|
|
81
95
|
await new Promise<void>((resolve) => stub.listen(0, "127.0.0.1", resolve));
|
|
82
96
|
const addr = stub.address() as import("net").AddressInfo;
|
|
83
|
-
|
|
97
|
+
const close = async () => {
|
|
98
|
+
// A minted token is always revoked; wait for it, bounded so a failed test
|
|
99
|
+
// still tears down.
|
|
100
|
+
if (minted) await Promise.race([revoked, Bun.sleep(5_000)]);
|
|
101
|
+
await new Promise<void>((resolve) => stub.close(() => resolve()));
|
|
102
|
+
};
|
|
103
|
+
return { apiUrl: `http://127.0.0.1:${addr.port}`, close };
|
|
84
104
|
}
|
|
85
105
|
|
|
86
106
|
describe("ACPAdapter", () => {
|
|
@@ -300,7 +320,7 @@ new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
|
300
320
|
`,
|
|
301
321
|
);
|
|
302
322
|
|
|
303
|
-
const {
|
|
323
|
+
const { close: closeTokenStub, apiUrl } = await startTokenStubServer(
|
|
304
324
|
"stub-token-id",
|
|
305
325
|
"aseph_stubtokenfortest1234567890",
|
|
306
326
|
);
|
|
@@ -498,7 +518,7 @@ new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
|
498
518
|
closeDb();
|
|
499
519
|
}
|
|
500
520
|
} finally {
|
|
501
|
-
await
|
|
521
|
+
await closeTokenStub();
|
|
502
522
|
}
|
|
503
523
|
});
|
|
504
524
|
|
|
@@ -532,8 +552,130 @@ new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
|
532
552
|
),
|
|
533
553
|
).toMatchObject({
|
|
534
554
|
OPENAI_API_KEY: "example-test-key",
|
|
535
|
-
OPENCODE_CONFIG_CONTENT: JSON.stringify({
|
|
555
|
+
OPENCODE_CONFIG_CONTENT: JSON.stringify({
|
|
556
|
+
theme: "dark",
|
|
557
|
+
model: "opencode/model",
|
|
558
|
+
provider: {
|
|
559
|
+
openrouter: {
|
|
560
|
+
options: {
|
|
561
|
+
headers: {
|
|
562
|
+
"HTTP-Referer": "https://agent-swarm.dev",
|
|
563
|
+
"X-OpenRouter-Title": "Agent Swarm",
|
|
564
|
+
"X-OpenRouter-Categories": "personal-agent,cloud-agent",
|
|
565
|
+
"X-Title": "Agent Swarm",
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
}),
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
test("OpenCode preset merges the OpenRouter gateway with model and provider config", () => {
|
|
575
|
+
const config = baseConfig({
|
|
576
|
+
model: " openrouter/openai/gpt-4o-mini ",
|
|
577
|
+
env: {
|
|
578
|
+
ACP_TARGET: "opencode",
|
|
579
|
+
OPENROUTER_BASE_URL: " http://127.0.0.1:8080/api/v1/ ",
|
|
580
|
+
OPENCODE_CONFIG_CONTENT: JSON.stringify({
|
|
581
|
+
theme: "dark",
|
|
582
|
+
provider: { openrouter: { options: { apiKey: "dummy" } } },
|
|
583
|
+
}),
|
|
584
|
+
},
|
|
585
|
+
});
|
|
586
|
+
const env = resolveAcpTarget(config).env(config);
|
|
587
|
+
expect(JSON.parse(env.OPENCODE_CONFIG_CONTENT!)).toEqual({
|
|
588
|
+
theme: "dark",
|
|
589
|
+
model: "openrouter/openai/gpt-4o-mini",
|
|
590
|
+
provider: {
|
|
591
|
+
openrouter: { options: { apiKey: "dummy", baseURL: "http://127.0.0.1:8080/api/v1" } },
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
test("OpenCode preset omits gateway override for unset, blank, or default URL", () => {
|
|
597
|
+
for (const url of [undefined, "", "https://openrouter.ai/api/v1/"]) {
|
|
598
|
+
const config = baseConfig({
|
|
599
|
+
env: { ACP_TARGET: "opencode", OPENROUTER_BASE_URL: url },
|
|
600
|
+
});
|
|
601
|
+
const env = resolveAcpTarget(config).env(config);
|
|
602
|
+
const content = JSON.parse(env.OPENCODE_CONFIG_CONTENT!);
|
|
603
|
+
expect(content).toEqual({
|
|
604
|
+
model: config.model,
|
|
605
|
+
provider: {
|
|
606
|
+
openrouter: {
|
|
607
|
+
options: {
|
|
608
|
+
headers: {
|
|
609
|
+
"HTTP-Referer": "https://agent-swarm.dev",
|
|
610
|
+
"X-OpenRouter-Title": "Agent Swarm",
|
|
611
|
+
"X-OpenRouter-Categories": "personal-agent,cloud-agent",
|
|
612
|
+
"X-Title": "Agent Swarm",
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
expect(content.provider.openrouter.options.baseURL).toBeUndefined();
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
test("OpenCode preset adds attribution headers to OPENCODE_CONFIG_CONTENT for an OpenRouter host", () => {
|
|
623
|
+
const config = baseConfig({
|
|
624
|
+
model: "",
|
|
625
|
+
env: {
|
|
626
|
+
ACP_TARGET: "opencode",
|
|
627
|
+
OPENROUTER_BASE_URL: "https://openrouter.ai/api/v1",
|
|
628
|
+
OPENCODE_CONFIG_CONTENT: JSON.stringify({
|
|
629
|
+
theme: "dark",
|
|
630
|
+
provider: { openrouter: { options: { headers: { "X-Custom": "preserved" } } } },
|
|
631
|
+
}),
|
|
632
|
+
},
|
|
633
|
+
});
|
|
634
|
+
const env = resolveAcpTarget(config).env(config);
|
|
635
|
+
expect(JSON.parse(env.OPENCODE_CONFIG_CONTENT!)).toEqual({
|
|
636
|
+
theme: "dark",
|
|
637
|
+
provider: {
|
|
638
|
+
openrouter: {
|
|
639
|
+
options: {
|
|
640
|
+
headers: {
|
|
641
|
+
"X-Custom": "preserved",
|
|
642
|
+
"HTTP-Referer": "https://agent-swarm.dev",
|
|
643
|
+
"X-OpenRouter-Title": "Agent Swarm",
|
|
644
|
+
"X-OpenRouter-Categories": "personal-agent,cloud-agent",
|
|
645
|
+
"X-Title": "Agent Swarm",
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
},
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
test("OpenCode preset leaves OPENCODE_CONFIG_CONTENT unchanged when attribution is disabled", () => {
|
|
654
|
+
const content = JSON.stringify({
|
|
655
|
+
theme: "dark",
|
|
656
|
+
provider: { openrouter: { options: { headers: { "X-Custom": "preserved" } } } },
|
|
657
|
+
});
|
|
658
|
+
const config = baseConfig({
|
|
659
|
+
model: "",
|
|
660
|
+
env: {
|
|
661
|
+
ACP_TARGET: "opencode",
|
|
662
|
+
OPENROUTER_BASE_URL: "https://openrouter.ai/api/v1",
|
|
663
|
+
OPENROUTER_APP_ATTRIBUTION: "false",
|
|
664
|
+
OPENCODE_CONFIG_CONTENT: content,
|
|
665
|
+
},
|
|
536
666
|
});
|
|
667
|
+
expect(resolveAcpTarget(config).env(config).OPENCODE_CONFIG_CONTENT).toBe(content);
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test("OpenCode preset injects gateway even without a model fallback", () => {
|
|
671
|
+
const config = baseConfig({
|
|
672
|
+
model: "",
|
|
673
|
+
env: { ACP_TARGET: "opencode", OPENROUTER_BASE_URL: "http://127.0.0.1:8080/api/v1" },
|
|
674
|
+
});
|
|
675
|
+
const env = resolveAcpTarget(config).env(config);
|
|
676
|
+
expect(JSON.parse(env.OPENCODE_CONFIG_CONTENT!).provider.openrouter.options.baseURL).toBe(
|
|
677
|
+
"http://127.0.0.1:8080/api/v1",
|
|
678
|
+
);
|
|
537
679
|
});
|
|
538
680
|
|
|
539
681
|
test("Gemini preset supplies command, credentials, trust, and a model environment fallback", () => {
|
|
@@ -600,6 +742,129 @@ new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
|
600
742
|
expect(target.env(config).GEMINI_SYSTEM_MD).toBeUndefined();
|
|
601
743
|
});
|
|
602
744
|
|
|
745
|
+
test("Copilot preset forwards its own credentials, pins the model, and never forwards GITHUB_TOKEN", () => {
|
|
746
|
+
const config = baseConfig({
|
|
747
|
+
model: "openai/gpt-5.2",
|
|
748
|
+
env: {
|
|
749
|
+
PATH: "/bin",
|
|
750
|
+
HOME: "/home/test",
|
|
751
|
+
ACP_TARGET: "copilot",
|
|
752
|
+
COPILOT_GITHUB_TOKEN: "example-copilot-token",
|
|
753
|
+
COPILOT_PROVIDER_BASE_URL: "https://llm.example/v1",
|
|
754
|
+
COPILOT_PROVIDER_API_KEY: "example-provider-key",
|
|
755
|
+
COPILOT_CUSTOM_INSTRUCTIONS_DIRS: "/opt/team-instructions",
|
|
756
|
+
GITHUB_TOKEN: "example-git-token",
|
|
757
|
+
GH_TOKEN: "example-gh-token",
|
|
758
|
+
},
|
|
759
|
+
});
|
|
760
|
+
const target = resolveAcpTarget(config);
|
|
761
|
+
|
|
762
|
+
expect(target.target).toBe("copilot");
|
|
763
|
+
expect(target.command(config)).toEqual(["copilot", "--acp"]);
|
|
764
|
+
const env = target.env(config);
|
|
765
|
+
expect(env).toMatchObject({
|
|
766
|
+
COPILOT_GITHUB_TOKEN: "example-copilot-token",
|
|
767
|
+
COPILOT_PROVIDER_BASE_URL: "https://llm.example/v1",
|
|
768
|
+
COPILOT_PROVIDER_API_KEY: "example-provider-key",
|
|
769
|
+
COPILOT_MODEL: "openai/gpt-5.2",
|
|
770
|
+
COPILOT_AUTO_UPDATE: "false",
|
|
771
|
+
COPILOT_CUSTOM_INSTRUCTIONS_DIRS: `${copilotInstructionsDir(config)},/opt/team-instructions`,
|
|
772
|
+
});
|
|
773
|
+
// The worker's git token lacks the Copilot Requests permission and would
|
|
774
|
+
// shadow a BYOK or COPILOT_GITHUB_TOKEN setup.
|
|
775
|
+
expect(env.GITHUB_TOKEN).toBeUndefined();
|
|
776
|
+
expect(env.GH_TOKEN).toBeUndefined();
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
test("Copilot preset delivers the system prompt outside the repo and removes it after the session", async () => {
|
|
780
|
+
const cwd = makeTempDir();
|
|
781
|
+
const binDir = makeTempDir();
|
|
782
|
+
const captureFile = join(binDir, "capture.json");
|
|
783
|
+
const agentPath = join(binDir, "fake-copilot-acp.ts");
|
|
784
|
+
const sdkPath = join(process.cwd(), "node_modules/@agentclientprotocol/sdk/dist/acp.js");
|
|
785
|
+
const repoAgentsMd = "# Repo rules\nKeep this file as is.\n";
|
|
786
|
+
await Bun.write(join(cwd, "AGENTS.md"), repoAgentsMd);
|
|
787
|
+
await Bun.write(
|
|
788
|
+
agentPath,
|
|
789
|
+
`
|
|
790
|
+
import { readFileSync } from "node:fs";
|
|
791
|
+
import { join } from "node:path";
|
|
792
|
+
import { Readable, Writable } from "node:stream";
|
|
793
|
+
import { AgentSideConnection, PROTOCOL_VERSION, ndJsonStream } from "${sdkPath}";
|
|
794
|
+
class FakeCopilot {
|
|
795
|
+
constructor(connection) { this.connection = connection; }
|
|
796
|
+
async initialize() {
|
|
797
|
+
return { protocolVersion: PROTOCOL_VERSION, agentCapabilities: { loadSession: false } };
|
|
798
|
+
}
|
|
799
|
+
async newSession() {
|
|
800
|
+
const dir = process.env.COPILOT_CUSTOM_INSTRUCTIONS_DIRS.split(",")[0];
|
|
801
|
+
await Bun.write(${JSON.stringify(captureFile)}, JSON.stringify({
|
|
802
|
+
argv: process.argv.slice(2),
|
|
803
|
+
dir,
|
|
804
|
+
instructions: readFileSync(join(dir, ${JSON.stringify(COPILOT_INSTRUCTIONS_FILE)}), "utf8"),
|
|
805
|
+
model: process.env.COPILOT_MODEL,
|
|
806
|
+
}));
|
|
807
|
+
return { sessionId: "copilot-session-1" };
|
|
808
|
+
}
|
|
809
|
+
async prompt(params) {
|
|
810
|
+
await this.connection.sessionUpdate({
|
|
811
|
+
sessionId: params.sessionId,
|
|
812
|
+
update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text: "done" }, messageId: "m1" },
|
|
813
|
+
});
|
|
814
|
+
return { stopReason: "end_turn" };
|
|
815
|
+
}
|
|
816
|
+
async cancel() {}
|
|
817
|
+
}
|
|
818
|
+
const stream = ndJsonStream(Writable.toWeb(process.stdout), Readable.toWeb(process.stdin));
|
|
819
|
+
new AgentSideConnection((connection) => new FakeCopilot(connection), stream);
|
|
820
|
+
`,
|
|
821
|
+
);
|
|
822
|
+
const copilotStub = join(binDir, "copilot");
|
|
823
|
+
await Bun.write(copilotStub, `#!/bin/sh\nexec "${process.execPath}" "${agentPath}" "$@"\n`);
|
|
824
|
+
chmodSync(copilotStub, 0o755);
|
|
825
|
+
mkdirSync(join(binDir, "home"));
|
|
826
|
+
|
|
827
|
+
const { close: closeTokenStub, apiUrl } = await startTokenStubServer(
|
|
828
|
+
"copilot-token-id",
|
|
829
|
+
"example-aseph_x",
|
|
830
|
+
);
|
|
831
|
+
try {
|
|
832
|
+
const config = baseConfig({
|
|
833
|
+
cwd,
|
|
834
|
+
apiUrl,
|
|
835
|
+
model: "openai/gpt-5.2",
|
|
836
|
+
systemPrompt: "You are a swarm worker.",
|
|
837
|
+
env: {
|
|
838
|
+
PATH: `${binDir}:${process.env.PATH ?? ""}`,
|
|
839
|
+
HOME: join(binDir, "home"),
|
|
840
|
+
ACP_TARGET: "copilot",
|
|
841
|
+
},
|
|
842
|
+
});
|
|
843
|
+
const session = await new ACPAdapter().createSession(config);
|
|
844
|
+
const result = await session.waitForCompletion();
|
|
845
|
+
expect(result.isError).toBe(false);
|
|
846
|
+
|
|
847
|
+
const captured = JSON.parse(await Bun.file(captureFile).text()) as {
|
|
848
|
+
argv: string[];
|
|
849
|
+
dir: string;
|
|
850
|
+
instructions: string;
|
|
851
|
+
model: string;
|
|
852
|
+
};
|
|
853
|
+
expect(captured.argv).toEqual(["--acp"]);
|
|
854
|
+
expect(captured.dir).toBe(copilotInstructionsDir(config));
|
|
855
|
+
expect(captured.dir.startsWith(cwd)).toBe(false);
|
|
856
|
+
expect(captured.instructions).toBe('---\napplyTo: "**"\n---\n\nYou are a swarm worker.\n');
|
|
857
|
+
expect(captured.model).toBe("openai/gpt-5.2");
|
|
858
|
+
expect(await Bun.file(join(cwd, "AGENTS.md")).text()).toBe(repoAgentsMd);
|
|
859
|
+
|
|
860
|
+
const deadline = Date.now() + 2_000;
|
|
861
|
+
while (existsSync(captured.dir) && Date.now() < deadline) await Bun.sleep(10);
|
|
862
|
+
expect(existsSync(captured.dir)).toBe(false);
|
|
863
|
+
} finally {
|
|
864
|
+
await closeTokenStub();
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
|
|
603
868
|
test("custom target passes through only explicitly named env and supports a model env fallback", () => {
|
|
604
869
|
const config = baseConfig({
|
|
605
870
|
model: "custom-model",
|
|
@@ -952,7 +1217,7 @@ const stream = ndJsonStream(Writable.toWeb(process.stdout), Readable.toWeb(proce
|
|
|
952
1217
|
new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
953
1218
|
`,
|
|
954
1219
|
);
|
|
955
|
-
const {
|
|
1220
|
+
const { close: closeTokenStub, apiUrl } = await startTokenStubServer(
|
|
956
1221
|
"stub-token-id",
|
|
957
1222
|
"aseph_stubtokenfortest1234567890",
|
|
958
1223
|
);
|
|
@@ -1015,7 +1280,7 @@ new AgentSideConnection((connection) => new FakeAgent(connection), stream);
|
|
|
1015
1280
|
closeDb();
|
|
1016
1281
|
}
|
|
1017
1282
|
} finally {
|
|
1018
|
-
await
|
|
1283
|
+
await closeTokenStub();
|
|
1019
1284
|
}
|
|
1020
1285
|
});
|
|
1021
1286
|
});
|