swarmory 0.1.0a1__tar.gz

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.
Files changed (67) hide show
  1. swarmory-0.1.0a1/.gitignore +17 -0
  2. swarmory-0.1.0a1/AGENTS.md +4 -0
  3. swarmory-0.1.0a1/CLAUDE.md +1 -0
  4. swarmory-0.1.0a1/LICENSE +21 -0
  5. swarmory-0.1.0a1/PKG-INFO +320 -0
  6. swarmory-0.1.0a1/README.md +301 -0
  7. swarmory-0.1.0a1/agent/agent.sh +158 -0
  8. swarmory-0.1.0a1/agent/prompt.md +32 -0
  9. swarmory-0.1.0a1/agent/report.md +52 -0
  10. swarmory-0.1.0a1/agent/swarm.py +387 -0
  11. swarmory-0.1.0a1/assets/how-it-works.svg +91 -0
  12. swarmory-0.1.0a1/assets/logo.svg +37 -0
  13. swarmory-0.1.0a1/hub/hub.py +426 -0
  14. swarmory-0.1.0a1/hub/mcp.py +164 -0
  15. swarmory-0.1.0a1/hub/proxy.py +240 -0
  16. swarmory-0.1.0a1/hub/team.py +500 -0
  17. swarmory-0.1.0a1/hub/view.html +2285 -0
  18. swarmory-0.1.0a1/missions/eval-factory/BRIEF.md +37 -0
  19. swarmory-0.1.0a1/missions/eval-factory/setup.sh +11 -0
  20. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/SKILL.md +150 -0
  21. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/collaboration.md +37 -0
  22. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/difficulty.md +79 -0
  23. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/environments.md +98 -0
  24. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/example.md +103 -0
  25. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/frontier-notes.md +209 -0
  26. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/ideation.md +135 -0
  27. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/improving-an-agent.md +59 -0
  28. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/integrity.md +113 -0
  29. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/measuring.md +92 -0
  30. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/running.md +88 -0
  31. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/testing.md +94 -0
  32. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/verifiers.md +293 -0
  33. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/references/verifying.md +136 -0
  34. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/scripts/lint_task.py +172 -0
  35. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/scripts/preflight_agent.py +35 -0
  36. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/scripts/probe_odds.py +98 -0
  37. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/scripts/summarize_runs.py +102 -0
  38. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/scripts/verify_task.py +360 -0
  39. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/auditor-brief.md +21 -0
  40. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/critic-brief.md +27 -0
  41. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/hacker-brief.md +35 -0
  42. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/idea-card.md +31 -0
  43. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/reader-brief.md +31 -0
  44. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/run-spec.md +37 -0
  45. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/environment/Dockerfile +9 -0
  46. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/instruction.md +7 -0
  47. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/preflight/preflight_checks.sh +23 -0
  48. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/solution/solve.sh +3 -0
  49. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/task.toml +28 -0
  50. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/Dockerfile +4 -0
  51. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/cases/empty/expected.json +1 -0
  52. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/cases/exploit-enumerate/expected.json +1 -0
  53. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/cases/garbage/expected.json +1 -0
  54. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/cases/near-miss/expected.json +1 -0
  55. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/cases/reference/expected.json +1 -0
  56. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/conftest.py +2 -0
  57. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/key.json +1 -0
  58. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/test.sh +7 -0
  59. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/test_cases.py +55 -0
  60. swarmory-0.1.0a1/missions/eval-factory/skills/eval-factory/templates/task/tests/verifier.py +47 -0
  61. swarmory-0.1.0a1/missions/eval-factory/team.toml +10 -0
  62. swarmory-0.1.0a1/modal_run.py +371 -0
  63. swarmory-0.1.0a1/providers/openrouter.conf +6 -0
  64. swarmory-0.1.0a1/pyproject.toml +49 -0
  65. swarmory-0.1.0a1/skills/swarmory/SKILL.md +218 -0
  66. swarmory-0.1.0a1/src/swarmory_cli/__init__.py +16 -0
  67. swarmory-0.1.0a1/swarmory.py +889 -0
@@ -0,0 +1,17 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ node_modules/
5
+ .env
6
+ .env.*
7
+ *.pem
8
+ *.key
9
+ *.crt
10
+ credentials.json
11
+ token.json
12
+ output/
13
+ .DS_Store
14
+ runs/
15
+ dist/
16
+ *.egg-info/
17
+ !skills/eval-factory/templates/task/tests/cases/*/output/
@@ -0,0 +1,4 @@
1
+ To set up, run or watch a swarm for someone, or to write a mission, follow
2
+ [skills/swarmory/SKILL.md](skills/swarmory/SKILL.md).
3
+
4
+ To build eval tasks, follow [skills/eval-factory/SKILL.md](skills/eval-factory/SKILL.md).
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 swarmory contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,320 @@
1
+ Metadata-Version: 2.5
2
+ Name: swarmory
3
+ Version: 0.1.0a1
4
+ Summary: Harness for multi-agent swarms, run locally or in the cloud.
5
+ Project-URL: Homepage, https://github.com/vtrivedy/swarmory
6
+ Project-URL: Repository, https://github.com/vtrivedy/swarmory
7
+ Project-URL: Issues, https://github.com/vtrivedy/swarmory/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: modal==1.6.3
18
+ Description-Content-Type: text/markdown
19
+
20
+ <p align="center">
21
+ <img src="assets/logo.svg" width="110" alt="swarmory">
22
+ </p>
23
+ <h1 align="center">swarmory</h1>
24
+ <p align="center">Harness for multi-agent swarms, run locally or in the cloud.</p>
25
+ <p align="center">
26
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT license"></a>
27
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue?style=flat-square" alt="Python 3.11+">
28
+ <img src="https://img.shields.io/badge/agents-Claude%20Code%20%7C%20Codex-blue?style=flat-square" alt="Claude Code and Codex agents">
29
+ <a href="#on-modal"><img src="https://img.shields.io/badge/cloud-Modal-blue?style=flat-square" alt="Runs on Modal"></a>
30
+ </p>
31
+
32
+ <br>
33
+
34
+ - **Built for agent teams.** Slack-style channels and DMs, a Linear-style task board, and a shared git repo.
35
+ - **Long missions.** Agents work autonomously on a task you define, for hours.
36
+ - **Humans in the loop.** Watch every action live, and send your own messages to guide the swarm.
37
+ - **Survives crashes.** A supervisor restarts any agent or hub that dies, and the work picks up where it stopped.
38
+ - **Any model family.** Mix Claude Code and Codex agents, and study how they coordinate.
39
+
40
+ <p align="center"><img src="assets/how-it-works.svg" width="720" alt="The hub in the middle holds chat, board, git, the model proxy and the viewer. You, up to 20 agents and anyone with the watch link connect to it. A supervisor restarts what crashes."></p>
41
+
42
+ ## Alpha install
43
+
44
+ The first PyPI alpha provides the existing CLI. Install it with:
45
+
46
+ ```sh
47
+ uv tool install swarmory==0.1.0a1
48
+ swarmory --help
49
+ swarmory start /absolute/path/to/mission --team codex=2 --hours 0.5
50
+ ```
51
+
52
+ You still need git, the coding CLIs your team uses, and their model credentials as described below. `swarm` is also
53
+ installed, for joining and talking to a team. Installed runs are saved in `~/.local/share/swarmory/runs`; set
54
+ `SWARMORY_RUNS` to choose another folder. In the instructions below, `swarmory` replaces `uv run swarmory.py`.
55
+
56
+ Automatic skill installation is not part of this alpha. For the agent-guided workflow and example missions, use
57
+ the checkout below. Running from the checkout continues to save runs in its `runs/` folder by default.
58
+
59
+ ## Quick start
60
+
61
+ Open this repo in Claude Code or Codex and ask for a swarm:
62
+
63
+ ```sh
64
+ git clone https://github.com/vtrivedy/swarmory.git && cd swarmory
65
+ claude "set up a swarm to build a todo CLI, two Claude agents and one Codex, for half an hour"
66
+ ```
67
+
68
+ It writes the mission, shows you the command before it spends anything, starts the team, and gives you a link to
69
+ watch. To do each step yourself, see [Run it](#run-it).
70
+
71
+ ## Build evals with a swarm
72
+
73
+ Swarmory ships an example mission, [`missions/eval-factory`](missions/eval-factory). Two agents build four Harbor
74
+ tasks that test one agent capability, using the [eval-factory skill](skills/eval-factory/SKILL.md), and a third tries
75
+ to break them. Change the capability in its `BRIEF.md` to build evals for yours. To check each task on Modal without
76
+ a model, agents need a Modal token. To run models on the tasks, they also need a model key. You
77
+ [grant](#granting-agents-more) both at start:
78
+
79
+ ```sh
80
+ uv run swarmory.py start missions/eval-factory --hours 2 \
81
+ --grant MODAL_TOKEN_ID --grant MODAL_TOKEN_SECRET --grant EVALS_ANTHROPIC_API_KEY
82
+ ```
83
+
84
+ Without grants, the team still builds the tasks and runs each task's tests, which check that its verifier scores a
85
+ stored empty answer 0 and a stored reference answer 1.
86
+
87
+ ## The pieces
88
+
89
+ | | |
90
+ |---|---|
91
+ | **Mission** | A folder whose `BRIEF.md` says what to build and how to check it. The folder becomes the team's repo, except for `.env` and key files, what its `.gitignore` ignores, and a top-level `score.py`. Agents never see `score.py`. `score RUN` runs it to grade the run. |
92
+ | **Hub** | One per run, shared by the whole team: the chat (like Slack), the task board (like Linear), the git repo (like GitHub), the model proxy, and the viewer. |
93
+ | **Model proxy** | Part of the hub. Agents never get your API key or login. Swarmory gives each member a run token, a random password that logs that member in to the hub for this run. An agent sends its model calls to the hub with that token, and the hub swaps in your key or login, forwards the call, and counts the tokens the call used. |
94
+ | **Agents** | 1 to 20 Claude Code or Codex agents. Each agent has its own machine and its own clone of the team's repo, and pulls and pushes like an engineer on a laptop, so it never overwrites a teammate's half-written file. On Modal the machine is a sandbox. Locally it is a folder and a process. An agent sleeps between turns and wakes when a teammate needs it. |
95
+ | **Deadline** | Every run lasts the hours you give it. Agents see the minutes left, and only what's on main at the deadline counts. |
96
+ | **`swarm`** | The command line everyone on the team uses, agents and you. |
97
+ | **Viewer** | A read-only link to the whole run, live or after: chat, board, commits, and a replay. |
98
+ | **Supervisor** | Restarts what exits, at most once a minute, until the deadline. Each agent's conversation, memory and clone survive. |
99
+
100
+ ## Run it
101
+
102
+ You need [uv](https://docs.astral.sh/uv/), git, and the coding agents your team uses. Claude Code needs
103
+ `ANTHROPIC_API_KEY` in your shell, and Codex needs `OPENAI_API_KEY`. The example in step 2 uses both. With only
104
+ one, drop the other `--team`. To use a Claude or ChatGPT plan instead, see
105
+ [With a subscription](#with-a-subscription).
106
+
107
+ **1. Write a mission.**
108
+
109
+ ```sh
110
+ mkdir -p ~/missions/todo-cli
111
+ cat > ~/missions/todo-cli/BRIEF.md <<'END'
112
+ # A command-line todo app
113
+
114
+ ## Goal
115
+ `todo add TEXT`, `todo list` and `todo done N`, saved in todo.json.
116
+
117
+ ## How to check it
118
+ `bash check.sh` adds, lists and completes a few items, then prints `ok`. Write check.sh first.
119
+
120
+ ## How the work divides
121
+ Storage, the three commands, and check.sh: one issue each.
122
+ END
123
+ ```
124
+
125
+ **2. Start the team.** From this repo:
126
+
127
+ ```sh
128
+ uv run swarmory.py start ~/missions/todo-cli --team claude-code:claude-sonnet-5-5=2 --team codex:gpt-6.1-sol=1 \
129
+ --hours 0.5
130
+ ```
131
+
132
+ Each `--team` is `HARNESS[:MODEL]=COUNT`. The harness is `claude-code` (Claude Code) or `codex` (Codex), and the
133
+ model defaults to the harness's own. `start` starts the hub and three agents in the background, prints the run's
134
+ name, a link to watch the team and a line for joining, and returns. The run goes on until the half hour is up or
135
+ you run `uv run swarmory.py stop RUN`. Its logs are in `runs/RUN/`.
136
+
137
+ **3. Join the team.** Paste the joining line, then talk to the agents:
138
+
139
+ ```sh
140
+ python3 agent/swarm.py login http://127.0.0.1:PORT TOKEN # the line it printed
141
+ alias swarm="python3 $PWD/agent/swarm.py"
142
+ swarm # what's new, and the issues assigned to you
143
+ swarm send ada "what are you working on?"
144
+ ```
145
+
146
+ **4. Check on the run, and get the code.**
147
+
148
+ ```sh
149
+ uv run swarmory.py view RUN # a link to watch the chat, the board and who talks to whom, live
150
+ uv run swarmory.py status RUN # time left, and each agent's state, calls and tokens
151
+ uv run swarmory.py score RUN # the mission's score.py, run on main
152
+ uv run swarmory.py records RUN # every transcript, the hub's log and main, copied into one folder
153
+ uv run swarmory.py compare RUN... # runs side by side: messages, issues, wakes, pushes, commits, tokens
154
+ uv run swarmory.py report RUN # runs/RUN/report.html: what happened, every step tied to a record
155
+ git clone runs/RUN/hub/work.git # the team's repo, from a local run
156
+ git -c include.path=$HOME/.swarm/gitconfig clone hub:work.git # from the run you last logged in to
157
+ uv run swarmory.py stop RUN
158
+ ```
159
+
160
+ ### A team per member
161
+
162
+ Instead of `--team`, a mission can name its team in `team.toml`, with a harness, a model, a role and a name for each
163
+ agent:
164
+
165
+ ```toml
166
+ [[agent]]
167
+ name = "Turing"
168
+ harness = "claude-code"
169
+ model = "claude-opus-5-5"
170
+ role = "Plan the work as issues and review every push. Don't write code."
171
+
172
+ [[agent]]
173
+ harness = "codex"
174
+ model = "gpt-6.1-sol"
175
+ count = 3
176
+ ```
177
+
178
+ `harness` is required: `claude-code` (Claude Code) or `codex` (Codex). `model` defaults to the harness's own, and
179
+ `count` to 1. A role goes into that agent's prompt and into the team list every agent sees. A name is for one agent,
180
+ so it takes no `count`. The agent's id, which teammates DM and @mention, is its name in lowercase (`turing`). Agents
181
+ without a name are called Ada, Grace, Alan and so on. `--team` replaces the file for one run.
182
+
183
+ `args` passes more arguments to the harness's CLI as they are, for anything it takes: reasoning effort, tools,
184
+ settings, MCP servers. They follow swarmory's own, so they can override them, and swarmory doesn't check them.
185
+
186
+ ```toml
187
+ [[agent]]
188
+ harness = "claude-code"
189
+ args = ["--effort", "high", "--disallowedTools", "WebSearch"] # claude --help lists the rest
190
+
191
+ [[agent]]
192
+ harness = "codex"
193
+ args = ["-c", "model_reasoning_effort=high"] # codex exec --help lists the rest
194
+ ```
195
+
196
+ ## From an MCP client
197
+
198
+ `swarmory.py mcp` is an MCP server over stdio. Add it to Claude Code with:
199
+
200
+ ```sh
201
+ claude mcp add swarmory -- uv run --directory /path/to/swarmory swarmory.py mcp
202
+ ```
203
+
204
+ Use it when you drive swarmory from an app, such as Claude Desktop, rather than a shell. The agent gets each action as
205
+ a tool with structured results, and never sees your run token. Claude Desktop takes the same command in its config.
206
+ The tools are the commands (`launch`, `runs`, `status`, `watch`, `stop`, `score`, `records`) and the `swarm` verbs
207
+ (`send`, `read`, `issues`, `new`, `move`, `sleep`, `get` and the rest). Each team tool takes the run's id and acts as
208
+ you, the run's operator. `launch` runs `start` with the MCP server's environment, so for a local run, start the client
209
+ from a shell that has the keys. A run keeps going after the client quits.
210
+
211
+ ## On Modal
212
+
213
+ Each agent gets its own sandbox with its own clone of the repo, and can reach only Modal tunnel addresses
214
+ (`*.modal.host`), the hub's among them. The hub is a sandbox too, and holds your key.
215
+
216
+ ```sh
217
+ uvx modal secret create swarmory-openai OPENAI_API_KEY=... # once
218
+ uv run swarmory.py deploy # once, and after each update
219
+ uv run swarmory.py start ~/missions/todo-cli --team codex:gpt-6.1-sol=8 --hours 6 --modal
220
+ ```
221
+
222
+ For Claude Code, name the secret `swarmory-anthropic` and give it `ANTHROPIC_API_KEY`.
223
+
224
+ ## With a subscription
225
+
226
+ `--subscription` has the hub call with your Claude or ChatGPT login instead of API keys.
227
+
228
+ ```sh
229
+ claude setup-token # prints a long-lived token
230
+ codex login # writes ~/.codex/auth.json
231
+ export CLAUDE_CODE_OAUTH_TOKEN=... # the token setup-token printed
232
+ export CODEX_AUTH_JSON="$(cat ~/.codex/auth.json)"
233
+ uv run swarmory.py start ~/missions/todo-cli --subscription --team claude-code=2 --team codex=1 --hours 0.5
234
+ ```
235
+
236
+ On Modal, put the same variables in a secret named `swarmory-subscription`, or name yours with `--secret`.
237
+
238
+ ```sh
239
+ uvx modal secret create swarmory-subscription CLAUDE_CODE_OAUTH_TOKEN=... CODEX_AUTH_JSON="$(cat ~/.codex/auth.json)"
240
+ ```
241
+
242
+ What changes:
243
+
244
+ - **Only the hub holds your login, as it would a key.** Agents call through the hub with their run token, and
245
+ `status` counts their calls and tokens. The hub sends Claude Code's calls to Anthropic and Codex's to ChatGPT, the
246
+ way each sends them when it holds the login itself.
247
+ - **The hub never refreshes your ChatGPT login.** Codex replaces the refresh token each time it refreshes, so a hub
248
+ that refreshed would log out your own `codex`. Run any `codex` command just before `start`, so the access token is
249
+ fresh. A local `start` refuses a login that expires before the run ends.
250
+ - **Your plan's limits cover the whole team.** Every agent's calls use the one login.
251
+
252
+ ## Granting agents more
253
+
254
+ `--grant` copies environment variables, such as API keys and tokens, from you to every agent. Agents start with only
255
+ their run token, so this is how a mission gets the keys it needs: the eval mission's agents need a Modal token to
256
+ start machines and a model key for the models they test. Any environment variable can be granted.
257
+
258
+ - **Locally,** `--grant NAME` copies the variable `NAME` from your shell into every agent.
259
+ - **On Modal,** `--grant NAME` copies every variable in your Modal secret called `NAME` into every agent's sandbox.
260
+ An agent's sandbox reaches only Modal tunnel addresses, such as the hub's, so also give `--allow HOST` for each
261
+ outside service the keys are for, such as `api.modal.com`.
262
+
263
+ Agents can read and spend whatever you grant, so grant only keys you're willing to let them spend.
264
+
265
+ Each local agent has its own home folder, so it can't see your `~/.modal.toml`. Grant Modal as `MODAL_TOKEN_ID` and
266
+ `MODAL_TOKEN_SECRET`, which Modal's client and Harbor both read: the `token_id` and `token_secret` in that file.
267
+
268
+ ```sh
269
+ uv run swarmory.py start ~/missions/evals --grant MODAL_TOKEN_ID --grant MODAL_TOKEN_SECRET --grant EVALS_ANTHROPIC_API_KEY
270
+ uvx modal secret create evals-access MODAL_TOKEN_ID=... MODAL_TOKEN_SECRET=... # on Modal: then --grant evals-access
271
+ uv run swarmory.py start ~/missions/evals --modal --grant evals-access --allow api.modal.com
272
+ ```
273
+
274
+ ## Good to know
275
+
276
+ - **Agents wake only when they're needed.** A DM, a change on an issue they follow, or an `@mention` wakes one.
277
+ `@channel` or `@here` wakes a channel's members and `@all` the whole team. A plain channel post wakes no one.
278
+ Messages within 20 seconds of each other arrive as one wake, with their text. A sleeping agent makes no model calls.
279
+ On Modal its sandbox keeps running while it sleeps.
280
+ - **A run ends at `--hours` or on `stop RUN`.** `view`, `score` and `status` still work once it has ended.
281
+ `status` shows each agent's calls and tokens. Your provider's dashboard shows what you spent, and Modal's shows a
282
+ Modal run's compute.
283
+ - **An agent whose conversation keeps failing starts over.** After two failed sessions in a row, it starts a new
284
+ conversation with the brief, and its clone and the board are as it left them.
285
+ - **Anyone with the watch link sees the whole run, and can change nothing.** On Modal the link works from
286
+ anywhere. Locally it works on your machine, and `view RUN` still shows a run that has ended.
287
+ - **Locally, agents can do anything you can.** They run on your machine as you, with permission prompts off. On
288
+ Modal, each agent is in its own sandbox and never sees your keys or logins.
289
+
290
+ ## `swarm`
291
+
292
+ | | |
293
+ |---|---|
294
+ | `swarm` | what's new, your issues, time left |
295
+ | `swarm read [WHERE]` | unread messages: everywhere, or in one channel, DM or issue. `--all`: read or not |
296
+ | `swarm search WORDS` | the newest messages you can see that hold all these words |
297
+ | `swarm send WHERE TEXT` | post in a channel, DM a person, or comment on an issue. `--file PATH` attaches a file |
298
+ | `swarm get f3 [DIR]` | download a file someone shared |
299
+ | `swarm issues` · `swarm issue i4` | the board, or one issue and its thread |
300
+ | `swarm new TITLE` · `swarm assign i4 +ada` · `swarm move i4 done` | open, assign and close issues |
301
+ | `swarm join i4` · `swarm leave i4` | follow an issue, or stop its wakes until you comment, are assigned or @mentioned |
302
+ | `swarm who` | the team |
303
+
304
+ ## Inside the repo
305
+
306
+ ```
307
+ swarmory.py the command you run: start, status, view, score, records, report, compare, stop, runs, deploy, mcp
308
+ modal_run.py running on Modal
309
+ hub/ the hub: chat and board, git, the model proxy, the viewer, and the verbs as MCP tools
310
+ agent/ what runs on each agent's machine, including swarm
311
+ skills/ instructions for coding agents: setting up a run, building eval tasks
312
+ providers/ sending model calls somewhere other than Anthropic and OpenAI
313
+ tests/ unit tests, and a full run of a tiny mission
314
+ ```
315
+
316
+ To test a change, run `uvx pytest tests`, then `bash tests/e2e.sh`, which makes a few real model calls.
317
+
318
+ ## License
319
+
320
+ [MIT](LICENSE)
@@ -0,0 +1,301 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" width="110" alt="swarmory">
3
+ </p>
4
+ <h1 align="center">swarmory</h1>
5
+ <p align="center">Harness for multi-agent swarms, run locally or in the cloud.</p>
6
+ <p align="center">
7
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT license"></a>
8
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue?style=flat-square" alt="Python 3.11+">
9
+ <img src="https://img.shields.io/badge/agents-Claude%20Code%20%7C%20Codex-blue?style=flat-square" alt="Claude Code and Codex agents">
10
+ <a href="#on-modal"><img src="https://img.shields.io/badge/cloud-Modal-blue?style=flat-square" alt="Runs on Modal"></a>
11
+ </p>
12
+
13
+ <br>
14
+
15
+ - **Built for agent teams.** Slack-style channels and DMs, a Linear-style task board, and a shared git repo.
16
+ - **Long missions.** Agents work autonomously on a task you define, for hours.
17
+ - **Humans in the loop.** Watch every action live, and send your own messages to guide the swarm.
18
+ - **Survives crashes.** A supervisor restarts any agent or hub that dies, and the work picks up where it stopped.
19
+ - **Any model family.** Mix Claude Code and Codex agents, and study how they coordinate.
20
+
21
+ <p align="center"><img src="assets/how-it-works.svg" width="720" alt="The hub in the middle holds chat, board, git, the model proxy and the viewer. You, up to 20 agents and anyone with the watch link connect to it. A supervisor restarts what crashes."></p>
22
+
23
+ ## Alpha install
24
+
25
+ The first PyPI alpha provides the existing CLI. Install it with:
26
+
27
+ ```sh
28
+ uv tool install swarmory==0.1.0a1
29
+ swarmory --help
30
+ swarmory start /absolute/path/to/mission --team codex=2 --hours 0.5
31
+ ```
32
+
33
+ You still need git, the coding CLIs your team uses, and their model credentials as described below. `swarm` is also
34
+ installed, for joining and talking to a team. Installed runs are saved in `~/.local/share/swarmory/runs`; set
35
+ `SWARMORY_RUNS` to choose another folder. In the instructions below, `swarmory` replaces `uv run swarmory.py`.
36
+
37
+ Automatic skill installation is not part of this alpha. For the agent-guided workflow and example missions, use
38
+ the checkout below. Running from the checkout continues to save runs in its `runs/` folder by default.
39
+
40
+ ## Quick start
41
+
42
+ Open this repo in Claude Code or Codex and ask for a swarm:
43
+
44
+ ```sh
45
+ git clone https://github.com/vtrivedy/swarmory.git && cd swarmory
46
+ claude "set up a swarm to build a todo CLI, two Claude agents and one Codex, for half an hour"
47
+ ```
48
+
49
+ It writes the mission, shows you the command before it spends anything, starts the team, and gives you a link to
50
+ watch. To do each step yourself, see [Run it](#run-it).
51
+
52
+ ## Build evals with a swarm
53
+
54
+ Swarmory ships an example mission, [`missions/eval-factory`](missions/eval-factory). Two agents build four Harbor
55
+ tasks that test one agent capability, using the [eval-factory skill](skills/eval-factory/SKILL.md), and a third tries
56
+ to break them. Change the capability in its `BRIEF.md` to build evals for yours. To check each task on Modal without
57
+ a model, agents need a Modal token. To run models on the tasks, they also need a model key. You
58
+ [grant](#granting-agents-more) both at start:
59
+
60
+ ```sh
61
+ uv run swarmory.py start missions/eval-factory --hours 2 \
62
+ --grant MODAL_TOKEN_ID --grant MODAL_TOKEN_SECRET --grant EVALS_ANTHROPIC_API_KEY
63
+ ```
64
+
65
+ Without grants, the team still builds the tasks and runs each task's tests, which check that its verifier scores a
66
+ stored empty answer 0 and a stored reference answer 1.
67
+
68
+ ## The pieces
69
+
70
+ | | |
71
+ |---|---|
72
+ | **Mission** | A folder whose `BRIEF.md` says what to build and how to check it. The folder becomes the team's repo, except for `.env` and key files, what its `.gitignore` ignores, and a top-level `score.py`. Agents never see `score.py`. `score RUN` runs it to grade the run. |
73
+ | **Hub** | One per run, shared by the whole team: the chat (like Slack), the task board (like Linear), the git repo (like GitHub), the model proxy, and the viewer. |
74
+ | **Model proxy** | Part of the hub. Agents never get your API key or login. Swarmory gives each member a run token, a random password that logs that member in to the hub for this run. An agent sends its model calls to the hub with that token, and the hub swaps in your key or login, forwards the call, and counts the tokens the call used. |
75
+ | **Agents** | 1 to 20 Claude Code or Codex agents. Each agent has its own machine and its own clone of the team's repo, and pulls and pushes like an engineer on a laptop, so it never overwrites a teammate's half-written file. On Modal the machine is a sandbox. Locally it is a folder and a process. An agent sleeps between turns and wakes when a teammate needs it. |
76
+ | **Deadline** | Every run lasts the hours you give it. Agents see the minutes left, and only what's on main at the deadline counts. |
77
+ | **`swarm`** | The command line everyone on the team uses, agents and you. |
78
+ | **Viewer** | A read-only link to the whole run, live or after: chat, board, commits, and a replay. |
79
+ | **Supervisor** | Restarts what exits, at most once a minute, until the deadline. Each agent's conversation, memory and clone survive. |
80
+
81
+ ## Run it
82
+
83
+ You need [uv](https://docs.astral.sh/uv/), git, and the coding agents your team uses. Claude Code needs
84
+ `ANTHROPIC_API_KEY` in your shell, and Codex needs `OPENAI_API_KEY`. The example in step 2 uses both. With only
85
+ one, drop the other `--team`. To use a Claude or ChatGPT plan instead, see
86
+ [With a subscription](#with-a-subscription).
87
+
88
+ **1. Write a mission.**
89
+
90
+ ```sh
91
+ mkdir -p ~/missions/todo-cli
92
+ cat > ~/missions/todo-cli/BRIEF.md <<'END'
93
+ # A command-line todo app
94
+
95
+ ## Goal
96
+ `todo add TEXT`, `todo list` and `todo done N`, saved in todo.json.
97
+
98
+ ## How to check it
99
+ `bash check.sh` adds, lists and completes a few items, then prints `ok`. Write check.sh first.
100
+
101
+ ## How the work divides
102
+ Storage, the three commands, and check.sh: one issue each.
103
+ END
104
+ ```
105
+
106
+ **2. Start the team.** From this repo:
107
+
108
+ ```sh
109
+ uv run swarmory.py start ~/missions/todo-cli --team claude-code:claude-sonnet-5-5=2 --team codex:gpt-6.1-sol=1 \
110
+ --hours 0.5
111
+ ```
112
+
113
+ Each `--team` is `HARNESS[:MODEL]=COUNT`. The harness is `claude-code` (Claude Code) or `codex` (Codex), and the
114
+ model defaults to the harness's own. `start` starts the hub and three agents in the background, prints the run's
115
+ name, a link to watch the team and a line for joining, and returns. The run goes on until the half hour is up or
116
+ you run `uv run swarmory.py stop RUN`. Its logs are in `runs/RUN/`.
117
+
118
+ **3. Join the team.** Paste the joining line, then talk to the agents:
119
+
120
+ ```sh
121
+ python3 agent/swarm.py login http://127.0.0.1:PORT TOKEN # the line it printed
122
+ alias swarm="python3 $PWD/agent/swarm.py"
123
+ swarm # what's new, and the issues assigned to you
124
+ swarm send ada "what are you working on?"
125
+ ```
126
+
127
+ **4. Check on the run, and get the code.**
128
+
129
+ ```sh
130
+ uv run swarmory.py view RUN # a link to watch the chat, the board and who talks to whom, live
131
+ uv run swarmory.py status RUN # time left, and each agent's state, calls and tokens
132
+ uv run swarmory.py score RUN # the mission's score.py, run on main
133
+ uv run swarmory.py records RUN # every transcript, the hub's log and main, copied into one folder
134
+ uv run swarmory.py compare RUN... # runs side by side: messages, issues, wakes, pushes, commits, tokens
135
+ uv run swarmory.py report RUN # runs/RUN/report.html: what happened, every step tied to a record
136
+ git clone runs/RUN/hub/work.git # the team's repo, from a local run
137
+ git -c include.path=$HOME/.swarm/gitconfig clone hub:work.git # from the run you last logged in to
138
+ uv run swarmory.py stop RUN
139
+ ```
140
+
141
+ ### A team per member
142
+
143
+ Instead of `--team`, a mission can name its team in `team.toml`, with a harness, a model, a role and a name for each
144
+ agent:
145
+
146
+ ```toml
147
+ [[agent]]
148
+ name = "Turing"
149
+ harness = "claude-code"
150
+ model = "claude-opus-5-5"
151
+ role = "Plan the work as issues and review every push. Don't write code."
152
+
153
+ [[agent]]
154
+ harness = "codex"
155
+ model = "gpt-6.1-sol"
156
+ count = 3
157
+ ```
158
+
159
+ `harness` is required: `claude-code` (Claude Code) or `codex` (Codex). `model` defaults to the harness's own, and
160
+ `count` to 1. A role goes into that agent's prompt and into the team list every agent sees. A name is for one agent,
161
+ so it takes no `count`. The agent's id, which teammates DM and @mention, is its name in lowercase (`turing`). Agents
162
+ without a name are called Ada, Grace, Alan and so on. `--team` replaces the file for one run.
163
+
164
+ `args` passes more arguments to the harness's CLI as they are, for anything it takes: reasoning effort, tools,
165
+ settings, MCP servers. They follow swarmory's own, so they can override them, and swarmory doesn't check them.
166
+
167
+ ```toml
168
+ [[agent]]
169
+ harness = "claude-code"
170
+ args = ["--effort", "high", "--disallowedTools", "WebSearch"] # claude --help lists the rest
171
+
172
+ [[agent]]
173
+ harness = "codex"
174
+ args = ["-c", "model_reasoning_effort=high"] # codex exec --help lists the rest
175
+ ```
176
+
177
+ ## From an MCP client
178
+
179
+ `swarmory.py mcp` is an MCP server over stdio. Add it to Claude Code with:
180
+
181
+ ```sh
182
+ claude mcp add swarmory -- uv run --directory /path/to/swarmory swarmory.py mcp
183
+ ```
184
+
185
+ Use it when you drive swarmory from an app, such as Claude Desktop, rather than a shell. The agent gets each action as
186
+ a tool with structured results, and never sees your run token. Claude Desktop takes the same command in its config.
187
+ The tools are the commands (`launch`, `runs`, `status`, `watch`, `stop`, `score`, `records`) and the `swarm` verbs
188
+ (`send`, `read`, `issues`, `new`, `move`, `sleep`, `get` and the rest). Each team tool takes the run's id and acts as
189
+ you, the run's operator. `launch` runs `start` with the MCP server's environment, so for a local run, start the client
190
+ from a shell that has the keys. A run keeps going after the client quits.
191
+
192
+ ## On Modal
193
+
194
+ Each agent gets its own sandbox with its own clone of the repo, and can reach only Modal tunnel addresses
195
+ (`*.modal.host`), the hub's among them. The hub is a sandbox too, and holds your key.
196
+
197
+ ```sh
198
+ uvx modal secret create swarmory-openai OPENAI_API_KEY=... # once
199
+ uv run swarmory.py deploy # once, and after each update
200
+ uv run swarmory.py start ~/missions/todo-cli --team codex:gpt-6.1-sol=8 --hours 6 --modal
201
+ ```
202
+
203
+ For Claude Code, name the secret `swarmory-anthropic` and give it `ANTHROPIC_API_KEY`.
204
+
205
+ ## With a subscription
206
+
207
+ `--subscription` has the hub call with your Claude or ChatGPT login instead of API keys.
208
+
209
+ ```sh
210
+ claude setup-token # prints a long-lived token
211
+ codex login # writes ~/.codex/auth.json
212
+ export CLAUDE_CODE_OAUTH_TOKEN=... # the token setup-token printed
213
+ export CODEX_AUTH_JSON="$(cat ~/.codex/auth.json)"
214
+ uv run swarmory.py start ~/missions/todo-cli --subscription --team claude-code=2 --team codex=1 --hours 0.5
215
+ ```
216
+
217
+ On Modal, put the same variables in a secret named `swarmory-subscription`, or name yours with `--secret`.
218
+
219
+ ```sh
220
+ uvx modal secret create swarmory-subscription CLAUDE_CODE_OAUTH_TOKEN=... CODEX_AUTH_JSON="$(cat ~/.codex/auth.json)"
221
+ ```
222
+
223
+ What changes:
224
+
225
+ - **Only the hub holds your login, as it would a key.** Agents call through the hub with their run token, and
226
+ `status` counts their calls and tokens. The hub sends Claude Code's calls to Anthropic and Codex's to ChatGPT, the
227
+ way each sends them when it holds the login itself.
228
+ - **The hub never refreshes your ChatGPT login.** Codex replaces the refresh token each time it refreshes, so a hub
229
+ that refreshed would log out your own `codex`. Run any `codex` command just before `start`, so the access token is
230
+ fresh. A local `start` refuses a login that expires before the run ends.
231
+ - **Your plan's limits cover the whole team.** Every agent's calls use the one login.
232
+
233
+ ## Granting agents more
234
+
235
+ `--grant` copies environment variables, such as API keys and tokens, from you to every agent. Agents start with only
236
+ their run token, so this is how a mission gets the keys it needs: the eval mission's agents need a Modal token to
237
+ start machines and a model key for the models they test. Any environment variable can be granted.
238
+
239
+ - **Locally,** `--grant NAME` copies the variable `NAME` from your shell into every agent.
240
+ - **On Modal,** `--grant NAME` copies every variable in your Modal secret called `NAME` into every agent's sandbox.
241
+ An agent's sandbox reaches only Modal tunnel addresses, such as the hub's, so also give `--allow HOST` for each
242
+ outside service the keys are for, such as `api.modal.com`.
243
+
244
+ Agents can read and spend whatever you grant, so grant only keys you're willing to let them spend.
245
+
246
+ Each local agent has its own home folder, so it can't see your `~/.modal.toml`. Grant Modal as `MODAL_TOKEN_ID` and
247
+ `MODAL_TOKEN_SECRET`, which Modal's client and Harbor both read: the `token_id` and `token_secret` in that file.
248
+
249
+ ```sh
250
+ uv run swarmory.py start ~/missions/evals --grant MODAL_TOKEN_ID --grant MODAL_TOKEN_SECRET --grant EVALS_ANTHROPIC_API_KEY
251
+ uvx modal secret create evals-access MODAL_TOKEN_ID=... MODAL_TOKEN_SECRET=... # on Modal: then --grant evals-access
252
+ uv run swarmory.py start ~/missions/evals --modal --grant evals-access --allow api.modal.com
253
+ ```
254
+
255
+ ## Good to know
256
+
257
+ - **Agents wake only when they're needed.** A DM, a change on an issue they follow, or an `@mention` wakes one.
258
+ `@channel` or `@here` wakes a channel's members and `@all` the whole team. A plain channel post wakes no one.
259
+ Messages within 20 seconds of each other arrive as one wake, with their text. A sleeping agent makes no model calls.
260
+ On Modal its sandbox keeps running while it sleeps.
261
+ - **A run ends at `--hours` or on `stop RUN`.** `view`, `score` and `status` still work once it has ended.
262
+ `status` shows each agent's calls and tokens. Your provider's dashboard shows what you spent, and Modal's shows a
263
+ Modal run's compute.
264
+ - **An agent whose conversation keeps failing starts over.** After two failed sessions in a row, it starts a new
265
+ conversation with the brief, and its clone and the board are as it left them.
266
+ - **Anyone with the watch link sees the whole run, and can change nothing.** On Modal the link works from
267
+ anywhere. Locally it works on your machine, and `view RUN` still shows a run that has ended.
268
+ - **Locally, agents can do anything you can.** They run on your machine as you, with permission prompts off. On
269
+ Modal, each agent is in its own sandbox and never sees your keys or logins.
270
+
271
+ ## `swarm`
272
+
273
+ | | |
274
+ |---|---|
275
+ | `swarm` | what's new, your issues, time left |
276
+ | `swarm read [WHERE]` | unread messages: everywhere, or in one channel, DM or issue. `--all`: read or not |
277
+ | `swarm search WORDS` | the newest messages you can see that hold all these words |
278
+ | `swarm send WHERE TEXT` | post in a channel, DM a person, or comment on an issue. `--file PATH` attaches a file |
279
+ | `swarm get f3 [DIR]` | download a file someone shared |
280
+ | `swarm issues` · `swarm issue i4` | the board, or one issue and its thread |
281
+ | `swarm new TITLE` · `swarm assign i4 +ada` · `swarm move i4 done` | open, assign and close issues |
282
+ | `swarm join i4` · `swarm leave i4` | follow an issue, or stop its wakes until you comment, are assigned or @mentioned |
283
+ | `swarm who` | the team |
284
+
285
+ ## Inside the repo
286
+
287
+ ```
288
+ swarmory.py the command you run: start, status, view, score, records, report, compare, stop, runs, deploy, mcp
289
+ modal_run.py running on Modal
290
+ hub/ the hub: chat and board, git, the model proxy, the viewer, and the verbs as MCP tools
291
+ agent/ what runs on each agent's machine, including swarm
292
+ skills/ instructions for coding agents: setting up a run, building eval tasks
293
+ providers/ sending model calls somewhere other than Anthropic and OpenAI
294
+ tests/ unit tests, and a full run of a tiny mission
295
+ ```
296
+
297
+ To test a change, run `uvx pytest tests`, then `bash tests/e2e.sh`, which makes a few real model calls.
298
+
299
+ ## License
300
+
301
+ [MIT](LICENSE)