An Elixir/OTP orchestrator for managing swarms of subzeroclaw agents with pluggable backends, arbitrary directed-graph topologies, per-agent skills, and fault tolerance via OTP supervision trees.
π Full documentation lives in
docs/. This page is an overview and quick start; each topic has its own guide.
- Pluggable backends β Local (Port), Docker (NixOS containers), SSH, Bwrap (bubblewrap), Mock.
- Arbitrary topologies β define directed graphs for inter-agent communication.
- Per-agent skills β markdown skill files deployed per agent, with
{{agent_name}}/{{swarm_name}}/{{workspace}}templating. - Objects β non-agentic Elixir components that participate in the topology and run deterministic code.
- Bwrap sandboxing β lightweight bubblewrap isolation for large agent pools on a single NixOS machine.
- NixOS-based containers β minimal, declarative images carrying only the tools each agent needs.
- File-based messaging β reliable delivery to sandboxed agents via
.inbox/and.outbox/. - Daemon-based swarms β swarms run as independent OS processes, coordinated through SQLite.
- REST API + WebSocket β full programmatic control and real-time event streaming (JSON only, CORS enabled).
- Runtime scaling β grow or shrink agent groups in a live swarm.
- Centralized observability β query and stream events and logs via CLI or API.
- Mock backend β test swarm logic without any LLM calls.
- Fault tolerance β OTP supervision for resilient operation.
Swarms run as independent daemon processes, separate from the optional API
server. The API server and CLI coordinate with running daemons through a SQLite
database (.genswarms/swarms.db): they query state and queue tasks, and each
daemon polls that queue.
External frontend / scripts Phoenix API server (optional)
(React, Vue, curl, β¦) β
β HTTP / WebSocket βββ REST API (/api/*)
βββββββββββββββββββββββββββββββββββββ€ββ WebSocket (/swarm)
β βββ reads/writes SQLite
β
β Daemon process (genswarms start)
β βββ SwarmManager
βββ (optional) βββββββββββββββββββββββ€ββ Agents / Objects / Backends
βββ reads/writes SQLite
β
.genswarms/swarms.db (state + task queue)
For the real OTP supervision tree and the per-swarm process layout, see docs/architecture.md.
Genswarms requires Elixir 1.14+ and Erlang/OTP 27+ (mix.exs pins
elixir: "~> 1.14"). The Nix dev shell pins the exact versions used in CI β
Elixir 1.17 / Erlang 27 / Node 20 β so it is the recommended setup.
# With Nix (recommended): enter the dev shell
nix develop
# Install dependencies
mix deps.get
# Build the genswarms CLI escript (creates ./genswarms)
mix escript.build
# Optionally install it on your PATH
cp genswarms ~/.local/bin/ # or: sudo cp genswarms /usr/local/bin/Node.js 20 is only needed if you build agent container images.
See docs/getting-started.md for the full setup, container builds, and environment variables.
# 1. Start the API server (background)
genswarms up
# 2. Create a new project with example configs
genswarms init my-project
cd my-project
cp .env.example .env # then add your API keys
# 3. Start a swarm from a config file (runs as a daemon)
genswarms start swarms/example_swarm.exs
# 4. Check status
genswarms status # server + all swarms
genswarms status example-swarm # one swarm's details
# 5. Send a task to an agent
genswarms task example-swarm researcher "Find papers on transformers"
# 6. Stream logs
genswarms logs example-swarm # all agents
genswarms logs example-swarm researcher # one agent
genswarms logs example-swarm -f # follow
# 7. Stop the swarm, or everything
genswarms stop example-swarm
genswarms downEvery subcommand is also available as a Mix task, e.g. mix genswarms.status.
A few lifecycle commands are Mix-task only today β see the note under
CLI overview.
These commands are wired into the genswarms escript binary:
| Command | Description |
|---|---|
genswarms up / down |
Start / stop the API server (up is an alias for dashboard start; down stops the server and all swarms) |
genswarms dashboard [start|stop|status] |
Manage the API/dashboard server explicitly |
genswarms init [dir] |
Scaffold a new project |
genswarms start <config> |
Start a swarm as a daemon (--foreground to run inline) |
genswarms stop <name> / restart <name> |
Swarm lifecycle (restart --delete for a clean slate) |
genswarms status [name] |
Show server and swarm status |
genswarms task <swarm> <agent> <msg> |
Send a task to an agent |
genswarms msg <swarm> <from> <to> <msg> |
Route a message between agents |
genswarms logs [swarm] [agent] |
Stream agent logs |
genswarms events |
Query and stream events |
genswarms scale <swarm> <base> <n> |
Scale an agent group |
genswarms snapshot / overlay |
Snapshots and bwrap overlays |
genswarms build [--all] |
Build agent container images via nix |
genswarms env [list|get|set] |
Manage environment variables |
genswarms config validate <file> / check <file> |
Validate a config |
genswarms list-skills |
List available skills |
Mix-task only commands. The following are not dispatched by the genswarms
escript β running genswarms pause β¦ falls through to "Unknown command". Invoke
them through Mix instead:
| Command | Description |
|---|---|
mix genswarms.pause <name> / mix genswarms.resume <name> |
Freeze / unfreeze the swarm's Docker containers |
mix genswarms.delete <name> |
Delete a swarm and all its data (--force to skip the prompt) |
mix genswarms.clean |
Remove stopped/crashed swarms (--all also clears events) |
mix genswarms.restart_agent <swarm> <agent> |
Restart a single agent (requires the API server) |
Many additional runtime operations (restart a single agent, pause/resume, add/remove agents, edit skills, fetch topology) are exposed through the REST API rather than the CLI.
See the full CLI reference for every command, flag, and example.
A swarm is defined by agents, optional objects, and a topology. Configs may be
.exs, .json, or .yaml.
%{
name: "example-swarm",
agents: [
%{name: :researcher, backend: :local, skills: ["web.md"], model: "anthropic/claude-sonnet-4"},
%{name: :coder, backend: {:docker, "coder"}, skills: ["code.md"], presets: [:base, :code]}
],
objects: [
%{name: :evaluator, handler: MyApp.Objects.Evaluator, config: %{}}
],
topology: [
{:researcher, :coder},
{:coder, :evaluator},
{:evaluator, :researcher}
]
}The full DSL β every agent/object key, backend value forms, and bwrap config separation β is documented in docs/configuration.md.
| Backend | Config value | Use for |
|---|---|---|
| Local | :local |
Development, single-host agents |
| Docker | {:docker, "name"} |
Isolated NixOS-based containers |
| SSH | {:ssh, "user@host"} |
Remote / bare-metal agents |
| Bwrap | :bwrap |
Lightweight sandboxes at large scale |
| Mock | {:mock, %{script: [...]}} |
Testing without LLM calls |
See docs/backends.md and docs/containers.md.
Getting started
- Getting started β install, first swarm, environment variables
- Configuration β the swarm config DSL
- CLI reference β every command and flag
Core concepts
- Architecture β supervision tree, daemon model, deployment
- Messaging & routing β
@agent:syntax, topology, inbox/outbox - Objects β non-agentic components
- Skills β per-agent skills and templating
Backends & deployment
- Backends β Local / Docker / SSH / Bwrap / Mock
- Containers β NixOS images, tool presets, bwrap internals
APIs
- REST API β the JSON HTTP API
- WebSocket API β real-time streams
- Programmatic usage β Genswarms as an Elixir library
Operations
- Observability β events, logging, telemetry
- Testing β unit tests, e2e harness, mock backend
- Troubleshooting β common problems
mix test # run the test suite
mix test --cover # with coverage
mix format # format code
mix phx.server # run the API server in the foregroundSee docs/testing.md for the e2e harness (mix genswarms.test)
and mock-backend testing.
See LICENSE.