Multi-Agent CLI Orchestration Research Platform
Project description
zwarm
Multi-agent CLI for orchestrating coding agents. Spawn, manage, and converse with multiple Codex sessions in parallel.
Installation
# From the workspace
cd /path/to/labs
uv sync
# Or install directly
uv pip install -e ./zwarm
Requirements:
- Python 3.13+
codexCLI installed and authenticated
Environment:
export OPENAI_API_KEY="sk-..." # Required for Codex
export WEAVE_PROJECT="entity/zwarm" # Optional: Weave tracing
Two Modes
zwarm has two ways to orchestrate coding agents:
| Mode | Who's in charge | Use case |
|---|---|---|
zwarm interactive |
You | Manual control, experimentation |
zwarm orchestrate |
LLM | Autonomous task execution |
Both use the same underlying session manager - the orchestrator LLM has access to the exact same tools you do.
Interactive Mode
You are the orchestrator. Spawn sessions, check on them, continue conversations.
zwarm interactive
Commands
| Command | Description |
|---|---|
spawn "task" |
Start a session (waits for completion) |
spawn --async "task" |
Start async (returns immediately) |
spawn -d /path "task" |
Start in specific directory |
ls |
List all sessions |
? <id> |
Quick peek: status + latest message |
show <id> |
Full details: all messages, tokens, etc. |
c <id> "msg" |
Continue conversation (waits) |
ca <id> "msg" |
Continue async (returns immediately) |
kill <id> |
Stop a running session |
rm <id> |
Delete session entirely |
killall |
Stop all running sessions |
clean |
Remove sessions older than 7 days |
q |
Quit |
Example Session
$ zwarm interactive
> spawn "Add a login function to auth.py"
✓ Started session a1b2c3d4, waiting...
[a1b2c3d4] codex (completed) - 32s
Response: I've added a login function with JWT support...
> spawn --async "Fix the type errors in utils.py"
✓ Session: b2c3d4e5 (running in background)
> spawn --async "Add unit tests for auth.py"
✓ Session: c3d4e5f6 (running in background)
> ls
1 running | 2 done
ID │ │ T │ Task │ Updated │ Last Message
a1b2c3d4 │ ✓ │ 1 │ Add a login function... │ 2m │ I've added a login function...
b2c3d4e5 │ ✓ │ 1 │ Fix the type errors... │ 30s ★ │ Fixed 3 type errors in...
c3d4e5f6 │ ● │ 1 │ Add unit tests... │ 5s │ (working...)
> ? b2c3d4e5
✓ b2c3d4e5 Fixed 3 type errors: Optional[str] -> str | None, added missing...
> c a1b2c3d4 "Now add password hashing with bcrypt"
Continuing session a1b2c3d4...
[a1b2c3d4] codex (completed) - 28s
Response: Done! I've updated the login function to use bcrypt...
> rm b2c3d4e5
✓ Deleted session b2c3d4e5
> q
Session Status Icons
| Icon | Status |
|---|---|
● |
Running |
✓ |
Completed |
✗ |
Failed |
○ |
Killed |
★ |
Recently completed (< 60s) |
Orchestrate Mode
An LLM is the orchestrator. Give it a task and it delegates to coding agents.
zwarm orchestrate --task "Build a REST API with authentication"
The orchestrator LLM uses the same tools available in interactive mode:
| Tool | Description |
|---|---|
delegate(task, ...) |
Start a new session |
converse(id, msg) |
Continue a conversation |
peek_session(id) |
Quick status check |
check_session(id) |
Full session details |
list_sessions() |
List all sessions with needs_attention flags |
end_session(id, delete=False) |
Kill/delete a session |
Task Input
# Direct
zwarm orchestrate --task "Build a REST API"
# From file
zwarm orchestrate --task-file task.md
# From stdin
echo "Fix the bug in auth.py" | zwarm orchestrate
Configuration
zwarm looks for config in this order:
--configflag.zwarm/config.tomlconfig.tomlin working directory
Minimal Config
[weave]
enabled = true
project = "your-entity/zwarm"
[executor]
adapter = "codex_mcp"
model = "gpt-5.1-codex-mini"
Full Config Reference
[orchestrator]
lm = "gpt-5-mini"
max_steps = 100
[orchestrator.compaction]
enabled = true
max_tokens = 100000
threshold_pct = 0.85
target_pct = 0.7
[executor]
adapter = "codex_mcp"
model = "gpt-5.1-codex-mini"
sandbox = "workspace-write"
timeout = 300
[weave]
enabled = true
project = "your-entity/zwarm"
[watchers]
enabled = true
watchers = [
{ name = "progress" },
{ name = "budget", config = { max_steps = 50, max_sessions = 10 } },
{ name = "delegation_reminder", config = { threshold = 10 } },
]
Session Management
Sessions are the core abstraction. Each session is a conversation with a Codex agent.
Lifecycle
spawn → running → completed/failed
↓
continue → running → completed
↓
continue → ...
Storage
.zwarm/sessions/<uuid>/
├── meta.json # Status, task, model, messages, tokens
└── turns/
├── turn_1.jsonl # Raw codex output for turn 1
├── turn_2.jsonl # Output after first continue
└── ...
Sync vs Async
| Mode | Spawn | Continue | Use case |
|---|---|---|---|
| Sync | spawn "task" |
c id "msg" |
Sequential work, immediate feedback |
| Async | spawn --async "task" |
ca id "msg" |
Parallel work, batch processing |
Async sessions return immediately. Poll with ls or ? to check status.
Watchers
Watchers monitor agent behavior and intervene when needed.
| Watcher | Purpose |
|---|---|
progress |
Detects stuck/spinning agents |
budget |
Enforces step/session limits |
scope |
Detects scope creep |
delegation_reminder |
Nudges orchestrator to delegate |
Configure in config.toml:
[watchers]
enabled = true
watchers = [
{ name = "progress" },
{ name = "budget", config = { max_steps = 50 } },
]
CLI Reference
zwarm init # Initialize .zwarm/ in current directory
zwarm interactive # Start interactive REPL
zwarm orchestrate # Start LLM orchestrator
zwarm exec # Run single executor directly (testing)
zwarm status # Show current state
zwarm history # Show event history
zwarm clean # Remove old sessions
Project Structure
zwarm/
├── src/zwarm/
│ ├── sessions/ # Session management (core)
│ │ ├── manager.py # CodexSessionManager
│ │ └── __init__.py
│ ├── tools/
│ │ └── delegation.py # Orchestrator tools (delegate, converse, etc.)
│ ├── cli/
│ │ └── main.py # CLI commands and interactive REPL
│ ├── core/
│ │ ├── config.py # Configuration loading
│ │ ├── compact.py # Context window management
│ │ └── state.py # State persistence
│ ├── watchers/ # Trajectory alignment
│ └── orchestrator.py # Orchestrator agent
├── docs/
│ └── INTERNALS.md # Technical architecture
└── README.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zwarm-3.2.0.tar.gz.
File metadata
- Download URL: zwarm-3.2.0.tar.gz
- Upload date:
- Size: 108.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71a234067d8724625b2b4ef4da4d5dcc5c59b602ee9f2f2e94b2808f39d4ea27
|
|
| MD5 |
9315b98b5ac9100bc10a0841641f434a
|
|
| BLAKE2b-256 |
431b35f1b4fcd59236723c3744b2799c30eef65209ffdc7e4655a63cecd0e230
|
File details
Details for the file zwarm-3.2.0-py3-none-any.whl.
File metadata
- Download URL: zwarm-3.2.0-py3-none-any.whl
- Upload date:
- Size: 126.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b540250b8d9b259b3c3b9226eb77a2ad31e81eecf2a5344208212ffbd5dddd5
|
|
| MD5 |
1e75e7d20d0554ffd8e4a6657df1bc32
|
|
| BLAKE2b-256 |
88339f5aea3efcb8d5c71575586a4018ecf65ec02f59f30e3d80633cfc4b5a03
|