@desplega.ai/agent-swarm 2.4.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{acp-adapter-kedstxx6.js → acp-adapter-zvzr538d.js} +9 -9
- package/dist/{actions-vget6r1k.js → actions-jhtqdw69.js} +21 -21
- package/dist/{amp-adapter-xeb5mktv.js → amp-adapter-bd84rhs2.js} +4 -4
- package/dist/{app-mqap8t8m.js → app-kreq1gwg.js} +3 -3
- package/dist/{assistant-h0gv97mv.js → assistant-3k22sbsq.js} +22 -22
- package/dist/{boot-reembed-qr8a894z.js → boot-reembed-e53x6b9v.js} +1 -1
- package/dist/{boot-reembed-rj85jjhw.js → boot-reembed-f6z923ny.js} +1 -1
- package/dist/{boot-scrub-sweep-eyfvn6v9.js → boot-scrub-sweep-0538vsb7.js} +4 -4
- package/dist/{boot-seeds-xs9a8dx1.js → boot-seeds-6wxqkfk2.js} +4 -4
- package/dist/{claude-adapter-bm23cye7.js → claude-adapter-gfts5044.js} +9 -9
- package/dist/{claude-managed-adapter-1mwrsm9d.js → claude-managed-adapter-h2y889ge.js} +2 -2
- package/dist/{claude-managed-setup-gkfgks4j.js → claude-managed-setup-h00hsgtz.js} +2 -2
- package/dist/{claude-sdk-session-apb4ypz3.js → claude-sdk-session-56besmfz.js} +13 -13
- package/dist/{cli-nrrg0fvy.js → cli-0bh477zn.js} +18 -5
- package/dist/{cli-7gh7020n.js → cli-1dmcq2eh.js} +1 -1
- package/dist/{cli-7ayprxp7.js → cli-2dfbv8qr.js} +8 -0
- package/dist/{cli-1cevz46c.js → cli-3kh4kpqy.js} +6 -6
- package/dist/{cli-tg9ksbn8.js → cli-3p8fqcnh.js} +2 -2
- package/dist/{cli-x1p5dhq2.js → cli-3r448dqn.js} +3 -3
- package/dist/{cli-ecshf504.js → cli-3tnpj2bh.js} +7 -7
- package/dist/{cli-ffbrkh1r.js → cli-471qk6s2.js} +46 -38
- package/dist/{cli-a49vpbf3.js → cli-5kqnemen.js} +1 -1
- package/dist/{cli-zvze9rbm.js → cli-6ncjvx55.js} +3 -3
- package/dist/{cli-fb6t92v8.js → cli-6x9ma5w5.js} +1 -1
- package/dist/{cli-c8fwpgqb.js → cli-7225gwj7.js} +2 -2
- package/dist/{cli-bn26xbcs.js → cli-8nyhf7za.js} +1 -1
- package/dist/{cli-y83zk5sb.js → cli-a0kcty51.js} +4 -4
- package/dist/{cli-8b9wvjps.js → cli-a4gvwttf.js} +4 -4
- package/dist/{cli-jhp7w1fy.js → cli-a5ebc95n.js} +2 -2
- package/dist/{cli-mz1ezzzh.js → cli-ash6xxk7.js} +2 -2
- package/dist/{cli-rsd7ga7v.js → cli-axh29tyr.js} +11 -11
- package/dist/{cli-p22zdvnt.js → cli-bn0rewsy.js} +3 -3
- package/dist/{cli-6ftrrwm1.js → cli-bn5kevnf.js} +5 -5
- package/dist/{cli-p1m2b6gc.js → cli-d2mb5s8a.js} +7 -7
- package/dist/{cli-c5sbmw1v.js → cli-d82btycs.js} +94 -15
- package/dist/{cli-vjfpshn3.js → cli-ejs3m1sx.js} +1 -1
- package/dist/{cli-a1esmmee.js → cli-fpmsqq59.js} +7 -2
- package/dist/{cli-8cxkw1f5.js → cli-fz9kewbh.js} +2 -2
- package/dist/{cli-8rwvksbc.js → cli-g0hgtz4p.js} +5 -5
- package/dist/{cli-kz116kvw.js → cli-gf0kfg81.js} +7 -7
- package/dist/{cli-eqgfs202.js → cli-hqhzg1qq.js} +2 -2
- package/dist/{cli-3wjs22x3.js → cli-j4rqdf2n.js} +2 -2
- package/dist/{cli-ywyrffff.js → cli-jh0qcrga.js} +1 -1
- package/dist/{cli-ttaz6c7m.js → cli-k9z4zd4p.js} +6 -5
- package/dist/{cli-nme7wery.js → cli-kmqgmcnb.js} +46 -13
- package/dist/{cli-x719j3vs.js → cli-kr2pmfqx.js} +392 -168
- package/dist/{cli-wrv09v7q.js → cli-m2qgh5sv.js} +1 -1
- package/dist/{cli-xfe63zx3.js → cli-mfe7f7b5.js} +2 -2
- package/dist/{cli-x3en6ct3.js → cli-nwyw3zhg.js} +1 -1
- package/dist/{cli-5s5hx57y.js → cli-nx462e4v.js} +1 -1
- package/dist/{cli-bfc3k1x5.js → cli-p0rakbrk.js} +9 -9
- package/dist/{cli-avmqhatn.js → cli-p6argxh9.js} +8 -8
- package/dist/{cli-3avfh5az.js → cli-pemywhfq.js} +2 -2
- package/dist/{cli-sppc0cmw.js → cli-pnp2j5zg.js} +2 -2
- package/dist/{cli-wk8ccrz6.js → cli-pw7v69vp.js} +2 -2
- package/dist/{cli-bhwa8rzc.js → cli-rdq7tzwm.js} +13 -12
- package/dist/{cli-rg7ntypm.js → cli-rqqsfz30.js} +379 -87
- package/dist/{cli-kk2r80n5.js → cli-s48yvzb8.js} +4 -4
- package/dist/{cli-zv4vy2b0.js → cli-s95dknxh.js} +1 -1
- package/dist/{cli-b80a1100.js → cli-sjyetj21.js} +2 -2
- package/dist/{cli-rdr166ht.js → cli-smvcw9z5.js} +1 -1
- package/dist/{cli-2rwet3r7.js → cli-sv5gb0yb.js} +1 -1
- package/dist/{cli-5ff2sjyt.js → cli-syhq378v.js} +2 -2
- package/dist/{cli-tj4j2ts4.js → cli-tbhwrxpt.js} +8 -8
- package/dist/{cli-4fhyq711.js → cli-vy0fay6k.js} +13 -13
- package/dist/{cli-ptkpaqfy.js → cli-wt645v7q.js} +1 -1
- package/dist/{cli-f3nx1h8z.js → cli-wxbn3yfx.js} +2 -2
- package/dist/{cli-wyrr38xm.js → cli-x5mq1fyq.js} +1 -1
- package/dist/{cli-ccn0eybf.js → cli-xbzvet96.js} +6 -6
- package/dist/{cli-4mkvwgzr.js → cli-xf234ws8.js} +1 -1
- package/dist/{cli-tgvpmnwz.js → cli-xftrvxag.js} +5 -5
- package/dist/{cli-02vhhssk.js → cli-z071fb95.js} +5 -5
- package/dist/{cli-mvg2hf8p.js → cli-z1ew8vbq.js} +14 -7
- package/dist/{cli-dsgj3e7a.js → cli-zfg9enh9.js} +2 -2
- package/dist/{cli-yxqag76b.js → cli-zw88zjba.js} +1 -1
- package/dist/cli.js +19 -19
- package/dist/{codex-adapter-pp2gq8gr.js → codex-adapter-p6rmm7vv.js} +6 -6
- package/dist/{codex-hook-qwzccd64.js → codex-hook-x7nejyrr.js} +7 -4
- package/dist/{codex-login-35p4sk85.js → codex-login-m819c41r.js} +1 -1
- package/dist/{codex-session-runner-0vzn09t8.js → codex-session-runner-8vd5t9t0.js} +7 -7
- package/dist/{commands-psqhkttb.js → commands-7ems2p13.js} +2 -2
- package/dist/{controller-t20vz2k8.js → controller-m263fg43.js} +4 -4
- package/dist/{controllers-connect-gkxmqw9d.js → controllers-connect-bg33ae53.js} +23 -23
- package/dist/{cursor-adapter-3v542qe5.js → cursor-adapter-cz6nm6mj.js} +3 -3
- package/dist/{db-2xbyenjr.js → db-w505dwa8.js} +2 -2
- package/dist/{db-nc1rd869.js → db-ys2rbdft.js} +3 -3
- package/dist/{devin-adapter-7egzmt0k.js → devin-adapter-zgqadvnm.js} +1 -1
- package/dist/{dispatcher-ewceb8ts.js → dispatcher-0s0mckqr.js} +20 -20
- package/dist/{docker-njavd3fb.js → docker-fkgtr75t.js} +2 -2
- package/dist/{dsh-adapter-75xwh78t.js → dsh-adapter-3n3net33.js} +3 -3
- package/dist/{e2b-5r6a5jeb.js → e2b-7am6tmq6.js} +2 -2
- package/dist/{e2b-pw1nvtmh.js → e2b-thdcxtjd.js} +2 -2
- package/dist/{easter-egg-3d-xsc47jwf.js → easter-egg-3d-5cgynaja.js} +1 -1
- package/dist/{event-bus-101fenkh.js → event-bus-9vpk8gmq.js} +1 -1
- package/dist/{execute-gzmw1mnw.js → execute-t4e6m3rw.js} +1 -1
- package/dist/{external-channel-a5dsmxn4.js → external-channel-5b23fv8z.js} +2 -2
- package/dist/{grok-adapter-vj88xr23.js → grok-adapter-q9fghe5q.js} +10 -10
- package/dist/handlers-mqrym347.js +39 -0
- package/dist/{heartbeat-t2m9r3wa.js → heartbeat-tww6yx1w.js} +23 -23
- package/dist/{hook-xa677f8r.js → hook-dx0pkvar.js} +16 -9
- package/dist/{hook-8femx1bg.js → hook-pvmh9b6m.js} +6 -6
- package/dist/{http-xpmmq028.js → http-k2ejbt05.js} +199 -131
- package/dist/{index-s7ckdajq.js → index-2z710v4x.js} +10 -10
- package/dist/{index-dg2tmj99.js → index-dgz61nff.js} +20 -20
- package/dist/{index-syztqdt6.js → index-g6tbb6ve.js} +1 -1
- package/dist/index-h2ek08d6.js +40 -0
- package/dist/index-pqfwh9nn.js +41 -0
- package/dist/{index-cdzyfrsp.js → index-x5aktmp8.js} +1 -1
- package/dist/{keepalive-3nr4st3r.js → keepalive-nhvpw10z.js} +4 -4
- package/dist/lead-jb6sf69z.js +78 -0
- package/dist/{maintenance-verwpe2c.js → maintenance-agakc519.js} +1 -1
- package/dist/{oauth-refresh-sweep-9q2t0y3q.js → oauth-refresh-sweep-4dcbhtn0.js} +3 -3
- package/dist/{onboard-aytqedmq.js → onboard-4n2kwa4v.js} +3 -3
- package/dist/{opencode-adapter-f4hryjny.js → opencode-adapter-3s7ax02e.js} +7 -7
- package/dist/{otel-impl-hckw4wt1.js → otel-impl-tfa12080.js} +2 -2
- package/dist/{pi-mono-adapter-hxby0ce1.js → pi-mono-adapter-ytp7gz8b.js} +22 -11
- package/dist/{pricing-refresh-5nvme3sm.js → pricing-refresh-3cqx3f3x.js} +3 -3
- package/dist/{rbac-roles-pd8c26m1.js → rbac-roles-9fae5rnv.js} +1 -1
- package/dist/{rbac-roles-vbpy21mg.js → rbac-roles-y6zbfzve.js} +2 -2
- package/dist/{render-v2-7nqgvk2q.js → render-v2-emawjvc4.js} +3 -3
- package/dist/{resume-b6djcj3c.js → resume-zhgts7h7.js} +10 -8
- package/dist/{runtime-txrxc9za.js → runtime-xe3aqy4x.js} +1 -1
- package/dist/{session-access-fc3f9y12.js → session-access-cm823e06.js} +4 -4
- package/dist/{setup-n39szm6b.js → setup-tkp99w1e.js} +1 -1
- package/dist/{virtual-modules-wyp2k6z3.js → virtual-modules-4r3zkc20.js} +2 -2
- package/dist/{work-objects-jem2fre0.js → work-objects-f722h263.js} +23 -23
- package/dist/worker-p7f336rq.js +78 -0
- package/dist/{x-8ewt8gxn.js → x-y45mthwn.js} +2 -2
- package/openapi.json +99 -52
- package/package.json +2 -2
- package/src/apps/action-runner.ts +146 -0
- package/src/apps/row-store.ts +4 -2
- package/src/apps/script-types.ts +1 -1
- package/src/be/db.ts +14 -4
- package/src/be/fleet-benchmark-stats.ts +10 -5
- package/src/be/models-catalog.ts +4 -0
- package/src/be/onboarding.ts +6 -0
- package/src/be/scripts/typecheck.ts +13 -0
- package/src/be/swarm-config-guard.ts +10 -1
- package/src/be/telemetry-enable.ts +1 -1
- package/src/commands/provider-credentials.ts +12 -2
- package/src/commands/runner.ts +3 -0
- package/src/heartbeat/heartbeat.ts +2 -2
- package/src/hooks/codex-hook.ts +6 -2
- package/src/hooks/hook.ts +7 -0
- package/src/hooks/pr-body-guard.ts +38 -11
- package/src/hooks/pr-room-guard.ts +88 -0
- package/src/http/agents.ts +1 -0
- package/src/http/apps.ts +84 -181
- package/src/http/fleet-benchmark.ts +79 -30
- package/src/http/global-config.ts +7 -0
- package/src/http/ranking.ts +24 -40
- package/src/http/tasks.ts +2 -1
- package/src/http/telemetry-ui.ts +1 -1
- package/src/http/used-by.ts +55 -19
- package/src/http/users.ts +2 -2
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +15 -0
- package/src/providers/reasoning-effort.ts +2 -1
- package/src/providers/types.ts +2 -0
- package/src/ranking/telemetry-ranking.ts +5 -33
- package/src/scripts-runtime/sdk-allowlist.ts +7 -0
- package/src/scripts-runtime/types/stdlib.d.ts +31 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +31 -0
- package/src/server.ts +4 -0
- package/src/telemetry-context.ts +19 -1
- package/src/telemetry-contract/EVENTS.md +42 -8
- package/src/telemetry-contract/SOURCE.json +6 -5
- package/src/telemetry-contract/catalog.json +225 -5
- package/src/telemetry-contract/ranking/fixtures/valid/no-claim.json +10 -0
- package/src/telemetry-contract/ranking/listing.v1.schema.json +2 -2
- package/src/telemetry-contract/types.gen.ts +225 -27
- package/src/telemetry-identity.ts +47 -9
- package/src/telemetry-snapshot.ts +9 -1
- package/src/telemetry-ui-events.ts +9 -2
- package/src/telemetry.ts +14 -3
- package/src/tests/app-action-run-tool.test.ts +178 -0
- package/src/tests/app-row-tools.test.ts +360 -0
- package/src/tests/check-pr-body.test.ts +0 -23
- package/src/tests/credential-check.test.ts +38 -0
- package/src/tests/fleet-benchmark.test.ts +122 -2
- package/src/tests/http-users.test.ts +62 -1
- package/src/tests/model-catalog-table.test.ts +63 -0
- package/src/tests/model-profiles-api.test.ts +19 -7
- package/src/tests/models-catalog.test.ts +50 -0
- package/src/tests/onboarding.test.ts +21 -0
- package/src/tests/org-website.test.ts +62 -0
- package/src/tests/pi-mono-adapter.test.ts +23 -0
- package/src/tests/pr-body-leaks.test.ts +4 -0
- package/src/tests/pr-room-guard.test.ts +242 -0
- package/src/tests/ranking-listing.test.ts +8 -23
- package/src/tests/ranking-route.test.ts +49 -47
- package/src/tests/reasoning-effort.test.ts +39 -3
- package/src/tests/runner-harness-telemetry-env.test.ts +56 -1
- package/src/tests/swarm-tool-result-gate.test.ts +2 -4
- package/src/tests/telemetry-context.test.ts +128 -2
- package/src/tests/telemetry-ui-route.test.ts +123 -0
- package/src/tests/tool-annotations.test.ts +3 -2
- package/src/tests/used-by-route.test.ts +144 -10
- package/src/tests/workflow-agent-task-retry.test.ts +130 -4
- package/src/tests/workflow-wait-recovery.test.ts +116 -4
- package/src/tools/app-action-run.ts +63 -0
- package/src/tools/app-rows.ts +234 -0
- package/src/tools/model-catalog/index.ts +1 -1
- package/src/tools/tool-config.ts +8 -0
- package/src/tools/utils.ts +1 -1
- package/src/tools/workflows/retry-workflow-run.ts +1 -1
- package/src/types.ts +17 -0
- package/src/utils/company-profile.ts +24 -0
- package/src/utils/org-website.ts +58 -21
- package/src/workflows/recovery.ts +10 -22
- package/src/workflows/resume.ts +16 -0
- package/src/workflows/task-step-routing.ts +47 -7
- package/templates/skills/apps/SKILL.md +41 -2
- package/templates/skills/apps/content.md +41 -2
- package/dist/handlers-zbs90bny.js +0 -39
- package/dist/index-8pwc1jc8.js +0 -40
- package/dist/index-nxa6me0q.js +0 -41
- package/dist/lead-td8h2sfn.js +0 -78
- package/dist/worker-wr6xgfr2.js +0 -78
- package/src/tests/check-ranking-entry.test.ts +0 -146
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Agent Swarm API",
|
|
5
|
-
"version": "2.4.
|
|
5
|
+
"version": "2.4.1",
|
|
6
6
|
"description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
@@ -613,6 +613,9 @@
|
|
|
613
613
|
"bedrock": {
|
|
614
614
|
"$ref": "#/components/schemas/AgentBedrockStatus"
|
|
615
615
|
},
|
|
616
|
+
"opencodeGo": {
|
|
617
|
+
"$ref": "#/components/schemas/AgentOpencodeGoStatus"
|
|
618
|
+
},
|
|
616
619
|
"acp": {
|
|
617
620
|
"$ref": "#/components/schemas/AgentAcpStatus"
|
|
618
621
|
}
|
|
@@ -766,6 +769,28 @@
|
|
|
766
769
|
"ready"
|
|
767
770
|
]
|
|
768
771
|
},
|
|
772
|
+
"AgentOpencodeGoStatus": {
|
|
773
|
+
"type": [
|
|
774
|
+
"object",
|
|
775
|
+
"null"
|
|
776
|
+
],
|
|
777
|
+
"properties": {
|
|
778
|
+
"probedAt": {
|
|
779
|
+
"type": "number"
|
|
780
|
+
},
|
|
781
|
+
"models": {
|
|
782
|
+
"type": "array",
|
|
783
|
+
"items": {
|
|
784
|
+
"type": "string"
|
|
785
|
+
},
|
|
786
|
+
"default": []
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
"default": null,
|
|
790
|
+
"required": [
|
|
791
|
+
"probedAt"
|
|
792
|
+
]
|
|
793
|
+
},
|
|
769
794
|
"AgentAcpStatus": {
|
|
770
795
|
"type": [
|
|
771
796
|
"object",
|
|
@@ -15336,7 +15361,7 @@
|
|
|
15336
15361
|
"/api/used-by": {
|
|
15337
15362
|
"post": {
|
|
15338
15363
|
"summary": "Grant or revoke the 'used by' logo consent",
|
|
15339
|
-
"description": "Records
|
|
15364
|
+
"description": "Records consent to show the organization's logo on agent-swarm.dev. A grant requires a valid contact email. It sends organization identity, contact details, and an optional quote to the proxy for manual review. This explicit admin action works when telemetry is off. A revoke clears the stored contact details and quote.",
|
|
15340
15365
|
"tags": [
|
|
15341
15366
|
"Telemetry"
|
|
15342
15367
|
],
|
|
@@ -15353,6 +15378,26 @@
|
|
|
15353
15378
|
"properties": {
|
|
15354
15379
|
"granted": {
|
|
15355
15380
|
"type": "boolean"
|
|
15381
|
+
},
|
|
15382
|
+
"contactEmail": {
|
|
15383
|
+
"type": "string",
|
|
15384
|
+
"maxLength": 320,
|
|
15385
|
+
"format": "email"
|
|
15386
|
+
},
|
|
15387
|
+
"contactFunction": {
|
|
15388
|
+
"type": "string",
|
|
15389
|
+
"enum": [
|
|
15390
|
+
"engineer",
|
|
15391
|
+
"eng_lead",
|
|
15392
|
+
"founder",
|
|
15393
|
+
"product",
|
|
15394
|
+
"ops",
|
|
15395
|
+
"other"
|
|
15396
|
+
]
|
|
15397
|
+
},
|
|
15398
|
+
"quote": {
|
|
15399
|
+
"type": "string",
|
|
15400
|
+
"maxLength": 280
|
|
15356
15401
|
}
|
|
15357
15402
|
},
|
|
15358
15403
|
"required": [
|
|
@@ -15386,7 +15431,7 @@
|
|
|
15386
15431
|
}
|
|
15387
15432
|
},
|
|
15388
15433
|
"400": {
|
|
15389
|
-
"description": "
|
|
15434
|
+
"description": "Invalid contact details, or missing organization name or website",
|
|
15390
15435
|
"content": {
|
|
15391
15436
|
"application/json": {
|
|
15392
15437
|
"schema": {
|
|
@@ -15431,7 +15476,7 @@
|
|
|
15431
15476
|
"/api/ranking": {
|
|
15432
15477
|
"get": {
|
|
15433
15478
|
"summary": "Public ranking state",
|
|
15434
|
-
"description": "Whether this install can join the public agent-swarm.dev ranking (telemetry on, organization name and website set), whether it is opted in, and its stored listing.
|
|
15479
|
+
"description": "Whether this install can join the public agent-swarm.dev ranking (telemetry on, organization name and website set), whether it is opted in, and its stored listing. Only a config admin can read it.",
|
|
15435
15480
|
"tags": [
|
|
15436
15481
|
"Telemetry"
|
|
15437
15482
|
],
|
|
@@ -15491,9 +15536,6 @@
|
|
|
15491
15536
|
1
|
|
15492
15537
|
]
|
|
15493
15538
|
},
|
|
15494
|
-
"claim": {
|
|
15495
|
-
"type": "string"
|
|
15496
|
-
},
|
|
15497
15539
|
"name": {
|
|
15498
15540
|
"type": "string"
|
|
15499
15541
|
},
|
|
@@ -15535,7 +15577,6 @@
|
|
|
15535
15577
|
},
|
|
15536
15578
|
"required": [
|
|
15537
15579
|
"v",
|
|
15538
|
-
"claim",
|
|
15539
15580
|
"name",
|
|
15540
15581
|
"domain",
|
|
15541
15582
|
"category",
|
|
@@ -15548,18 +15589,6 @@
|
|
|
15548
15589
|
"listingMatchesDomain": {
|
|
15549
15590
|
"type": "boolean"
|
|
15550
15591
|
},
|
|
15551
|
-
"fileJson": {
|
|
15552
|
-
"type": [
|
|
15553
|
-
"string",
|
|
15554
|
-
"null"
|
|
15555
|
-
]
|
|
15556
|
-
},
|
|
15557
|
-
"prUrl": {
|
|
15558
|
-
"type": [
|
|
15559
|
-
"string",
|
|
15560
|
-
"null"
|
|
15561
|
-
]
|
|
15562
|
-
},
|
|
15563
15592
|
"verifyUrl": {
|
|
15564
15593
|
"type": [
|
|
15565
15594
|
"string",
|
|
@@ -15576,8 +15605,6 @@
|
|
|
15576
15605
|
"domain",
|
|
15577
15606
|
"listing",
|
|
15578
15607
|
"listingMatchesDomain",
|
|
15579
|
-
"fileJson",
|
|
15580
|
-
"prUrl",
|
|
15581
15608
|
"verifyUrl"
|
|
15582
15609
|
]
|
|
15583
15610
|
}
|
|
@@ -15610,7 +15637,7 @@
|
|
|
15610
15637
|
"/api/ranking/opt-in": {
|
|
15611
15638
|
"post": {
|
|
15612
15639
|
"summary": "Opt this install into the public ranking",
|
|
15613
|
-
"description": "Builds the telemetry_ranking listing from the organization name and website plus the chosen category, stores it, turns PUBLIC_RANKING_ENABLED on and sends ranking.opted_in.
|
|
15640
|
+
"description": "Builds the telemetry_ranking listing from the organization name and website plus the chosen category, stores it, turns PUBLIC_RANKING_ENABLED on and sends ranking.opted_in. That is the whole opt-in: the install shows on agent-swarm.dev/ranking at the next hourly refresh.",
|
|
15614
15641
|
"tags": [
|
|
15615
15642
|
"Telemetry"
|
|
15616
15643
|
],
|
|
@@ -15673,9 +15700,6 @@
|
|
|
15673
15700
|
"domain": {
|
|
15674
15701
|
"type": "string"
|
|
15675
15702
|
},
|
|
15676
|
-
"claim": {
|
|
15677
|
-
"type": "string"
|
|
15678
|
-
},
|
|
15679
15703
|
"listing": {
|
|
15680
15704
|
"type": "object",
|
|
15681
15705
|
"properties": {
|
|
@@ -15685,9 +15709,6 @@
|
|
|
15685
15709
|
1
|
|
15686
15710
|
]
|
|
15687
15711
|
},
|
|
15688
|
-
"claim": {
|
|
15689
|
-
"type": "string"
|
|
15690
|
-
},
|
|
15691
15712
|
"name": {
|
|
15692
15713
|
"type": "string"
|
|
15693
15714
|
},
|
|
@@ -15729,7 +15750,6 @@
|
|
|
15729
15750
|
},
|
|
15730
15751
|
"required": [
|
|
15731
15752
|
"v",
|
|
15732
|
-
"claim",
|
|
15733
15753
|
"name",
|
|
15734
15754
|
"domain",
|
|
15735
15755
|
"category",
|
|
@@ -15739,22 +15759,13 @@
|
|
|
15739
15759
|
"updatedAt"
|
|
15740
15760
|
]
|
|
15741
15761
|
},
|
|
15742
|
-
"fileJson": {
|
|
15743
|
-
"type": "string"
|
|
15744
|
-
},
|
|
15745
|
-
"prUrl": {
|
|
15746
|
-
"type": "string"
|
|
15747
|
-
},
|
|
15748
15762
|
"verifyUrl": {
|
|
15749
15763
|
"type": "string"
|
|
15750
15764
|
}
|
|
15751
15765
|
},
|
|
15752
15766
|
"required": [
|
|
15753
15767
|
"domain",
|
|
15754
|
-
"claim",
|
|
15755
15768
|
"listing",
|
|
15756
|
-
"fileJson",
|
|
15757
|
-
"prUrl",
|
|
15758
15769
|
"verifyUrl"
|
|
15759
15770
|
]
|
|
15760
15771
|
}
|
|
@@ -15807,7 +15818,7 @@
|
|
|
15807
15818
|
"/api/ranking/opt-out": {
|
|
15808
15819
|
"post": {
|
|
15809
15820
|
"summary": "Leave the public ranking",
|
|
15810
|
-
"description": "Turns PUBLIC_RANKING_ENABLED off and sends ranking.opted_out, so workers stop sending ranking.usage.
|
|
15821
|
+
"description": "Turns PUBLIC_RANKING_ENABLED off and sends ranking.opted_out, so workers stop sending ranking.usage. The install leaves agent-swarm.dev/ranking at the next hourly refresh.",
|
|
15811
15822
|
"tags": [
|
|
15812
15823
|
"Telemetry"
|
|
15813
15824
|
],
|
|
@@ -15829,17 +15840,10 @@
|
|
|
15829
15840
|
"enum": [
|
|
15830
15841
|
false
|
|
15831
15842
|
]
|
|
15832
|
-
},
|
|
15833
|
-
"leaveUrl": {
|
|
15834
|
-
"type": [
|
|
15835
|
-
"string",
|
|
15836
|
-
"null"
|
|
15837
|
-
]
|
|
15838
15843
|
}
|
|
15839
15844
|
},
|
|
15840
15845
|
"required": [
|
|
15841
|
-
"enabled"
|
|
15842
|
-
"leaveUrl"
|
|
15846
|
+
"enabled"
|
|
15843
15847
|
]
|
|
15844
15848
|
}
|
|
15845
15849
|
}
|
|
@@ -54216,7 +54220,8 @@
|
|
|
54216
54220
|
"type": "string",
|
|
54217
54221
|
"enum": [
|
|
54218
54222
|
"banner",
|
|
54219
|
-
"settings"
|
|
54223
|
+
"settings",
|
|
54224
|
+
"benchmark"
|
|
54220
54225
|
],
|
|
54221
54226
|
"default": "banner"
|
|
54222
54227
|
}
|
|
@@ -55323,7 +55328,7 @@
|
|
|
55323
55328
|
"/api/fleet-benchmark": {
|
|
55324
55329
|
"get": {
|
|
55325
55330
|
"summary": "Compare this swarm with similar swarms",
|
|
55326
|
-
"description": "
|
|
55331
|
+
"description": "Compares local task volume and success rate with fleet percentiles over the last 30 days. Comparisons require telemetry, an organization name, and a known proxy ingest date. A website, team size, and use case enable full comparisons with peer filters. The response includes the proxy's peer group when available. With telemetry off, it returns local DB counts without a proxy request. The fleet cache key includes the peer filters.",
|
|
55327
55332
|
"tags": [
|
|
55328
55333
|
"Telemetry"
|
|
55329
55334
|
],
|
|
@@ -55350,6 +55355,41 @@
|
|
|
55350
55355
|
"unavailable"
|
|
55351
55356
|
]
|
|
55352
55357
|
},
|
|
55358
|
+
"level": {
|
|
55359
|
+
"type": "string",
|
|
55360
|
+
"enum": [
|
|
55361
|
+
"basic",
|
|
55362
|
+
"full"
|
|
55363
|
+
]
|
|
55364
|
+
},
|
|
55365
|
+
"peerGroup": {
|
|
55366
|
+
"type": [
|
|
55367
|
+
"object",
|
|
55368
|
+
"null"
|
|
55369
|
+
],
|
|
55370
|
+
"properties": {
|
|
55371
|
+
"teamSize": {
|
|
55372
|
+
"type": [
|
|
55373
|
+
"string",
|
|
55374
|
+
"null"
|
|
55375
|
+
]
|
|
55376
|
+
},
|
|
55377
|
+
"useCase": {
|
|
55378
|
+
"type": [
|
|
55379
|
+
"string",
|
|
55380
|
+
"null"
|
|
55381
|
+
]
|
|
55382
|
+
},
|
|
55383
|
+
"orgs": {
|
|
55384
|
+
"type": "integer"
|
|
55385
|
+
}
|
|
55386
|
+
},
|
|
55387
|
+
"required": [
|
|
55388
|
+
"teamSize",
|
|
55389
|
+
"useCase",
|
|
55390
|
+
"orgs"
|
|
55391
|
+
]
|
|
55392
|
+
},
|
|
55353
55393
|
"local": {
|
|
55354
55394
|
"type": [
|
|
55355
55395
|
"object",
|
|
@@ -55455,6 +55495,8 @@
|
|
|
55455
55495
|
},
|
|
55456
55496
|
"required": [
|
|
55457
55497
|
"state",
|
|
55498
|
+
"level",
|
|
55499
|
+
"peerGroup",
|
|
55458
55500
|
"local",
|
|
55459
55501
|
"minFinishedTasks",
|
|
55460
55502
|
"generatedAt",
|
|
@@ -55744,7 +55786,8 @@
|
|
|
55744
55786
|
"minLength": 1
|
|
55745
55787
|
},
|
|
55746
55788
|
"email": {
|
|
55747
|
-
"type": "string"
|
|
55789
|
+
"type": "string",
|
|
55790
|
+
"format": "email"
|
|
55748
55791
|
},
|
|
55749
55792
|
"role": {
|
|
55750
55793
|
"type": "string"
|
|
@@ -56524,7 +56567,11 @@
|
|
|
56524
56567
|
"minLength": 1
|
|
56525
56568
|
},
|
|
56526
56569
|
"email": {
|
|
56527
|
-
"type":
|
|
56570
|
+
"type": [
|
|
56571
|
+
"string",
|
|
56572
|
+
"null"
|
|
56573
|
+
],
|
|
56574
|
+
"format": "email"
|
|
56528
56575
|
},
|
|
56529
56576
|
"role": {
|
|
56530
56577
|
"type": "string"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-swarm.dev",
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"dependencies": {
|
|
201
201
|
"@agentclientprotocol/sdk": "1.9.0",
|
|
202
202
|
"@ai-sdk/openai": "^3.0.41",
|
|
203
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
203
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.303",
|
|
204
204
|
"@anthropic-ai/sdk": "^0.135.0",
|
|
205
205
|
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
206
206
|
"@aws-sdk/client-bedrock": "3.1048.0",
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { normalizeAssetKey } from "../assets/key";
|
|
2
|
+
import { getLeadAgent } from "../be/db";
|
|
3
|
+
import { getScriptById } from "../be/scripts/db";
|
|
4
|
+
import { getSavedScriptOwnerAgentId, runSavedScriptAsAgent } from "../be/scripts/run-saved";
|
|
5
|
+
import { resolveTemplate } from "../prompts/resolver";
|
|
6
|
+
import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
|
|
7
|
+
import { scrubObject } from "../utils/secret-scrubber";
|
|
8
|
+
import type { AppActionCaller } from "./action-caller";
|
|
9
|
+
import type { AppRecord } from "./store";
|
|
10
|
+
import { runAppSync } from "./sync";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* One `error` string for a sync result, or undefined when every pass succeeded.
|
|
14
|
+
* Each failed pair is named so a multi-pair sync says which one broke; the pass
|
|
15
|
+
* list in `result.passes` carries the rest.
|
|
16
|
+
*/
|
|
17
|
+
function syncPassError(sync: Awaited<ReturnType<typeof runAppSync>>): string | undefined {
|
|
18
|
+
const failed = sync.passes.filter((pass) => pass.error !== undefined);
|
|
19
|
+
if (failed.length === 0) return undefined;
|
|
20
|
+
return failed.map((pass) => `${pass.model}.${pass.source}: ${pass.error}`).join("; ");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function runAppAction({
|
|
24
|
+
app,
|
|
25
|
+
name,
|
|
26
|
+
input = {},
|
|
27
|
+
caller,
|
|
28
|
+
actor,
|
|
29
|
+
}: {
|
|
30
|
+
app: AppRecord;
|
|
31
|
+
name: string;
|
|
32
|
+
input?: Record<string, unknown>;
|
|
33
|
+
caller: AppActionCaller;
|
|
34
|
+
actor: string;
|
|
35
|
+
}) {
|
|
36
|
+
const actions = app.definition.actions;
|
|
37
|
+
if (!actions || !Object.hasOwn(actions, name)) {
|
|
38
|
+
return { status: 404 as const, body: { error: "app action not found" } };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const action = actions[name]!;
|
|
42
|
+
|
|
43
|
+
if (action.kind === "script") {
|
|
44
|
+
const script = await getScriptById(action.scriptId);
|
|
45
|
+
if (!script) {
|
|
46
|
+
return {
|
|
47
|
+
status: 400 as const,
|
|
48
|
+
body: {
|
|
49
|
+
error: "invalid app action",
|
|
50
|
+
issues: [
|
|
51
|
+
{
|
|
52
|
+
path: `actions.${name}.scriptId`,
|
|
53
|
+
message: `script "${action.scriptId}" no longer exists`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Script actions use the owner's bindings. Definition validation checks
|
|
61
|
+
// which scripts an agent can wire into an app.
|
|
62
|
+
const runAsAgentId = getSavedScriptOwnerAgentId(script);
|
|
63
|
+
if (!runAsAgentId) {
|
|
64
|
+
return {
|
|
65
|
+
status: 400 as const,
|
|
66
|
+
body: { error: "agentId is required: this script has no owning agent to run as" },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const output = await runSavedScriptAsAgent({
|
|
71
|
+
script,
|
|
72
|
+
input: { ...action.args, ...input, app: { id: app.id }, caller },
|
|
73
|
+
agentId: runAsAgentId,
|
|
74
|
+
});
|
|
75
|
+
const ok = output.exitCode === 0 && !output.error && !output.runtimeError;
|
|
76
|
+
const error = ok
|
|
77
|
+
? undefined
|
|
78
|
+
: output.runtimeError
|
|
79
|
+
? `${output.runtimeError.name}: ${output.runtimeError.message}`
|
|
80
|
+
: (output.error ?? `Script exited with code ${output.exitCode}`);
|
|
81
|
+
return {
|
|
82
|
+
status: 200 as const,
|
|
83
|
+
body: scrubObject({
|
|
84
|
+
ok,
|
|
85
|
+
result: output.result,
|
|
86
|
+
stdout: output.stdout,
|
|
87
|
+
...(error === undefined ? {} : { error }),
|
|
88
|
+
durationMs: output.durationMs,
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (action.kind === "sync") {
|
|
94
|
+
const startedAt = Date.now();
|
|
95
|
+
const sync = await runAppSync({
|
|
96
|
+
appId: app.id,
|
|
97
|
+
...(action.model === undefined ? {} : { model: action.model }),
|
|
98
|
+
...(action.source === undefined ? {} : { source: action.source }),
|
|
99
|
+
invokedBy: actor,
|
|
100
|
+
});
|
|
101
|
+
const durationMs = Date.now() - startedAt;
|
|
102
|
+
if (sync.issues && sync.issues.length > 0) {
|
|
103
|
+
return { status: 400 as const, body: { error: "invalid sync action", issues: sync.issues } };
|
|
104
|
+
}
|
|
105
|
+
// Deliberately the SCRIPT-action response shape, minus `taskId`:
|
|
106
|
+
// app-surface.tsx branches on `taskId` first, so omitting it gives the
|
|
107
|
+
// dashboard running -> ok/error + refetchAll() with zero UI changes.
|
|
108
|
+
const error = syncPassError(sync);
|
|
109
|
+
return {
|
|
110
|
+
status: 200 as const,
|
|
111
|
+
body: scrubObject({
|
|
112
|
+
ok: sync.ok,
|
|
113
|
+
result: { passes: sync.passes },
|
|
114
|
+
...(error === undefined ? {} : { error }),
|
|
115
|
+
durationMs,
|
|
116
|
+
}),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const lead = action.agentId ? null : await getLeadAgent();
|
|
121
|
+
const taskPrompt = resolveTemplate("task.app.action", {
|
|
122
|
+
prompt: action.prompt,
|
|
123
|
+
app_id: app.id,
|
|
124
|
+
action_name: name,
|
|
125
|
+
input_json: JSON.stringify(input),
|
|
126
|
+
caller_json: JSON.stringify(caller),
|
|
127
|
+
});
|
|
128
|
+
const task = await createTaskWithSiblingAwareness(
|
|
129
|
+
taskPrompt.text,
|
|
130
|
+
{
|
|
131
|
+
source: "api",
|
|
132
|
+
agentId: action.agentId ?? lead?.id,
|
|
133
|
+
routingReason: action.agentId ? "human_pinned" : lead ? "skill" : undefined,
|
|
134
|
+
routingSource: action.agentId || lead ? "engine_default" : undefined,
|
|
135
|
+
// App-spawned tasks group under the app's asset namespace so a
|
|
136
|
+
// swarm-tasks source can pull them back via config.assetKey.
|
|
137
|
+
key: normalizeAssetKey(`shared/app:${app.id}/action:${name}/`),
|
|
138
|
+
...(actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}),
|
|
139
|
+
},
|
|
140
|
+
{ origin: "app" },
|
|
141
|
+
);
|
|
142
|
+
return {
|
|
143
|
+
status: 200 as const,
|
|
144
|
+
body: { ok: true as const, taskId: task.id, status: task.status },
|
|
145
|
+
};
|
|
146
|
+
}
|
package/src/apps/row-store.ts
CHANGED
|
@@ -109,7 +109,7 @@ function indexKeys(model: string, definition: ModelDef, row: AppRow): string[] {
|
|
|
109
109
|
return keys;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function validValue(column: ColumnDef, value: unknown): boolean {
|
|
112
|
+
export function validValue(column: ColumnDef, value: unknown): boolean {
|
|
113
113
|
if (value === null) return column.required !== true;
|
|
114
114
|
if (column.kind === "string") return typeof value === "string";
|
|
115
115
|
if (column.kind === "number") return typeof value === "number" && Number.isFinite(value);
|
|
@@ -526,18 +526,20 @@ export async function rebuildAppColumnIndexUnlocked(
|
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
+
/** `matches` re-checks the row under the lock; a row that no longer matches is kept. */
|
|
529
530
|
export function deleteAppRow(
|
|
530
531
|
appId: string,
|
|
531
532
|
model: string,
|
|
532
533
|
_definition: ModelDef,
|
|
533
534
|
rowId: string,
|
|
535
|
+
matches?: (row: AppRow) => boolean,
|
|
534
536
|
): Promise<boolean> {
|
|
535
537
|
return withMutationLock(appId, model, async () => {
|
|
536
538
|
const currentDefinition = await currentModelDefinition(appId, model);
|
|
537
539
|
if (!currentDefinition) return false;
|
|
538
540
|
const namespace = appsNamespace(appId);
|
|
539
541
|
const row = await getAppRow(appId, model, rowId);
|
|
540
|
-
if (!row) return false;
|
|
542
|
+
if (!row || (matches && !matches(row))) return false;
|
|
541
543
|
for (const key of indexKeys(model, currentDefinition, row)) await deleteKv(namespace, key);
|
|
542
544
|
await deleteKv(namespace, rowKey(model, rowId));
|
|
543
545
|
return true;
|
package/src/apps/script-types.ts
CHANGED
|
@@ -206,7 +206,7 @@ function renderApp(app: AppRecord, namespace: string): string {
|
|
|
206
206
|
export namespace ${namespace} {
|
|
207
207
|
${renderedModels.map((model) => model.source).join("\n\n")}
|
|
208
208
|
|
|
209
|
-
/** Declared actions
|
|
209
|
+
/** Scripts can write rows. Declared actions are callable through REST or MCP only. */
|
|
210
210
|
export type ActionName = ${actionType};
|
|
211
211
|
|
|
212
212
|
/** Script action arguments include server-stamped app and caller context. */
|
package/src/be/db.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { realtimeBus } from "../realtime/bus";
|
|
11
11
|
import { slackChannelFromContextKey } from "../tasks/slack-routing";
|
|
12
12
|
import { _resolveIntegrationType, emitIntegrationConnected, telemetry } from "../telemetry";
|
|
13
|
-
import { scheduleOrgDomainRecompute } from "../telemetry-identity";
|
|
13
|
+
import { invalidateTelemetryUserRole, scheduleOrgDomainRecompute } from "../telemetry-identity";
|
|
14
14
|
import {
|
|
15
15
|
emitTaskTelemetry,
|
|
16
16
|
type TaskTelemetryEvent,
|
|
@@ -12354,7 +12354,7 @@ export async function updateUser(
|
|
|
12354
12354
|
id: string,
|
|
12355
12355
|
data: Partial<{
|
|
12356
12356
|
name: string;
|
|
12357
|
-
email: string;
|
|
12357
|
+
email: string | null;
|
|
12358
12358
|
role: string;
|
|
12359
12359
|
notes: string;
|
|
12360
12360
|
emailAliases: string[];
|
|
@@ -12419,7 +12419,12 @@ export async function updateUser(
|
|
|
12419
12419
|
`UPDATE users SET ${sets.join(", ")} WHERE id = ? RETURNING *`,
|
|
12420
12420
|
params,
|
|
12421
12421
|
);
|
|
12422
|
-
if (row)
|
|
12422
|
+
if (row) {
|
|
12423
|
+
getDbClient().afterCommit(() => {
|
|
12424
|
+
invalidateTelemetryUserRole(id);
|
|
12425
|
+
scheduleOrgDomainRecompute();
|
|
12426
|
+
});
|
|
12427
|
+
}
|
|
12423
12428
|
return row ? rowToUser(row) : null;
|
|
12424
12429
|
}
|
|
12425
12430
|
|
|
@@ -12556,7 +12561,12 @@ export async function deleteUser(id: string, replacementUserId?: string): Promis
|
|
|
12556
12561
|
await reclassifyTaskHumanFree(reclassifySeedIds);
|
|
12557
12562
|
|
|
12558
12563
|
const result = await tx.run("DELETE FROM users WHERE id = ?", [id]);
|
|
12559
|
-
if (result.changes > 0)
|
|
12564
|
+
if (result.changes > 0) {
|
|
12565
|
+
getDbClient().afterCommit(() => {
|
|
12566
|
+
invalidateTelemetryUserRole(id);
|
|
12567
|
+
scheduleOrgDomainRecompute();
|
|
12568
|
+
});
|
|
12569
|
+
}
|
|
12560
12570
|
return result.changes > 0;
|
|
12561
12571
|
});
|
|
12562
12572
|
}
|
|
@@ -5,15 +5,20 @@
|
|
|
5
5
|
* registered agent count (the same count `org.snapshot` reports as
|
|
6
6
|
* `agents_total`).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Comparisons require a known ingest start. With telemetry off, callers can
|
|
9
|
+
* use the local 30-day window without an ingest anchor.
|
|
10
10
|
*/
|
|
11
|
-
import { fleetCountStart, type LocalFleetStats } from "../fleet-benchmark";
|
|
11
|
+
import { FLEET_WINDOW_DAYS, fleetCountStart, type LocalFleetStats } from "../fleet-benchmark";
|
|
12
12
|
import { getDbClient } from "./db/runtime";
|
|
13
13
|
import { getTelemetryIngestAnchor } from "./telemetry-ingest-anchor";
|
|
14
14
|
|
|
15
|
-
export async function getLocalFleetStats(
|
|
16
|
-
|
|
15
|
+
export async function getLocalFleetStats(
|
|
16
|
+
now = new Date(),
|
|
17
|
+
{ requireIngestAnchor = true } = {},
|
|
18
|
+
): Promise<LocalFleetStats | null> {
|
|
19
|
+
const start = requireIngestAnchor
|
|
20
|
+
? fleetCountStart(await getTelemetryIngestAnchor(), now)
|
|
21
|
+
: new Date(now.getTime() - FLEET_WINDOW_DAYS * 86_400_000);
|
|
17
22
|
if (!start) return null;
|
|
18
23
|
const since = start.toISOString();
|
|
19
24
|
const client = getDbClient();
|
package/src/be/models-catalog.ts
CHANGED
|
@@ -27,6 +27,10 @@ export const CATALOG_PROVIDER_IDS = [
|
|
|
27
27
|
"openai",
|
|
28
28
|
"amazon-bedrock",
|
|
29
29
|
"opencode",
|
|
30
|
+
// OpenCode Go is opencode's first-party subscription provider, a sibling of
|
|
31
|
+
// its Zen section (`opencode`). models.dev lists it, so projecting it gives
|
|
32
|
+
// `opencode-go/<model>` ids their context window and reasoning facts.
|
|
33
|
+
"opencode-go",
|
|
30
34
|
...openAICompatibleProviderIds(),
|
|
31
35
|
] as const;
|
|
32
36
|
|
package/src/be/onboarding.ts
CHANGED
|
@@ -498,6 +498,12 @@ function deriveState(
|
|
|
498
498
|
if (state.steps.connect.status !== "done") {
|
|
499
499
|
changed = completeStep(state, "connect", "api_key", true, events) || changed;
|
|
500
500
|
}
|
|
501
|
+
// A name saved anywhere (setup, the org-name popup, Settings, the API) names
|
|
502
|
+
// the swarm. The old setup default "Your Swarm" does not count.
|
|
503
|
+
const orgName = process.env.SWARM_ORG_NAME?.trim();
|
|
504
|
+
if (state.steps.name.status !== "done" && orgName && orgName !== "Your Swarm") {
|
|
505
|
+
changed = completeStep(state, "name", "custom_name", true, events) || changed;
|
|
506
|
+
}
|
|
501
507
|
if (
|
|
502
508
|
state.steps.ai.status !== "done" &&
|
|
503
509
|
signals.providers.some((entry) => entry.state === "verified")
|
|
@@ -419,6 +419,19 @@ export interface SwarmSdk {
|
|
|
419
419
|
query: string;
|
|
420
420
|
params?: Record<string, string | number | boolean>;
|
|
421
421
|
}): Promise<unknown>;
|
|
422
|
+
app_rows_list(args: {
|
|
423
|
+
appId: string;
|
|
424
|
+
model: string;
|
|
425
|
+
equals?: Record<string, string | number | boolean>;
|
|
426
|
+
sort?: \`\${string}:asc\` | \`\${string}:desc\`;
|
|
427
|
+
limit?: number;
|
|
428
|
+
}): Promise<unknown>;
|
|
429
|
+
app_row_get(args: { appId: string; model: string; rowId: string }): Promise<unknown>;
|
|
430
|
+
app_row_create(args: { appId: string; model: string; values: Record<string, unknown> }): Promise<unknown>;
|
|
431
|
+
app_rows_create(args: { appId: string; model: string; rows: Record<string, unknown>[] }): Promise<unknown>;
|
|
432
|
+
app_row_patch(args: { appId: string; model: string; rowId: string; values: Record<string, unknown> }): Promise<unknown>;
|
|
433
|
+
app_row_delete(args: { appId: string; model: string; rowId: string }): Promise<unknown>;
|
|
434
|
+
app_rows_delete(args: { appId: string; model: string; equals: Record<string, string | number | boolean>; limit?: number }): Promise<unknown>;
|
|
422
435
|
app_rollback(args: {
|
|
423
436
|
appId: string;
|
|
424
437
|
version: number;
|