Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bullpen

A durable agent harness in Rust.
Agents as managed, resumable workers — not fire-and-forget processes.

CI Rust 1.97 License MIT Status v0

Dispatching three agents from bullpen agents, watching them complete, peeking at one's answer, and seeing the sessions persist

A bullpen is a roster of warmed-up relievers you call in, pull back, and send out again. That is the whole thesis: agent runs should survive the process that started them.

Why it's different

Every step is durable the moment it happens. Sessions live in one SQLite database (WAL), not in the memory of whatever process launched them. Kill bullpen mid-run — crash, kill -9, power loss — and the next invocation recovers: interrupted tool calls are marked, the transcript is closed cleanly, and the session resumes where it stopped.

No daemon, no supervisor. A background session is just a detached bullpen run coordinating through the store. The dashboard is a read-and- dispatch view over that store — close it and the work keeps going, because nothing was ever supervising it.

The sandbox is a feature, not a footnote. --sandbox confines writes to the workspace on every platform and, on macOS, runs shell commands and their children under Seatbelt. --sandbox-strict also cuts network.

Install

cargo install --path crates/cli

Rust 1.97+ (pinned in rust-toolchain.toml, so rustup fetches the right one automatically).

Quickstart

Point it at a provider — any one of these is enough:

export ANTHROPIC_API_KEY=sk-ant-...   # streams tokens live
bullpen login openrouter              # official OAuth PKCE
bullpen login codex                   # ChatGPT subscription, device-code flow

Already have the Codex CLI logged in? bullpen borrows its session from ~/.codex/auth.json read-only — nothing to configure, and it never refreshes that token so it can't invalidate the other tool's login.

Then work:

cd your-project
bullpen run "find the failing test and explain why it fails"
bullpen run --sandbox "refactor the retry logic"     # confine writes
bullpen run -v "..."                                 # tool activity on stderr
bullpen run --json "..."                             # NDJSON event stream on stdout

Sessions are resumable by id prefix, with the provider they were created with:

bullpen sessions                       # what have I got
bullpen sessions --json                # same, machine-readable
bullpen run -r 6ee4acc9 "now write the fix"

Run many at once

bullpen run --bg "audit the auth module"   # detached, returns immediately
bullpen run --bg --worktree "refactor it"  # …in its own git worktree
bullpen agents                             # the dashboard in the GIF above
bullpen logs 6ee4acc9                      # tail a background session

bullpen agents groups sessions by state — Working (running, live pid), Failed (running, dead pid — it crashed), Completed, Idle — and lets you dispatch from the input line, Space to peek at output, Esc to quit. Quitting stops nothing.

Plain --bg sessions share your checkout, so two of them edit the same files. --worktree gives a session a git worktree of its own on a run-unique bullpen/<id> branch, under $BULLPEN_HOME/worktrees/<session>; the path shows up in bullpen sessions, in bullpen sessions --json, and in the peek panel, and bullpen run -r <id> returns to it from anywhere. Outside a git repository the flag fails rather than quietly sharing the checkout. Nothing removes a worktree or its branch — not on success, not on failure, not later. A worktree can hold the only copy of what an agent did, so cleaning up is yours to decide.

The pen

The model can delegate bounded work to child agents through the agent tool: inspect for read-only reconnaissance, work for the full toolset. Children are ordinary sessions — durable, budgeted, listed by bullpen sessions, resumable — with deterministic identities, so a replayed delegation reattaches to its child instead of running it twice.

Providers

Provider Wire format Auth Verified
anthropic Anthropic messages ANTHROPIC_API_KEY wire-level tests
codex OpenAI Responses (SSE) bullpen login codex, or borrow the Codex CLI live, incl. tools + resume
openrouter OpenAI chat-completions bullpen login openrouter or OPENROUTER_API_KEY live, incl. tools
glm Anthropic-compatible GLM_API_KEY config-only
kimi Anthropic-compatible KIMI_API_KEY config-only

Adapters are organized by wire format rather than vendor, which is why compatible hosts are configuration instead of code.

Built-in tools: bash, read_file, write_file, edit_file, grep, glob — plus agent when the pen is enabled.

Where state lives

~/.bullpen/bullpen.db — SQLite in WAL mode, holding an append-only entry tree (the conversation) plus a separate execution log (the orchestration). Delete every execution record and you still have a complete, valid conversation.

Reading it while sessions run needs the immutable flag, since WAL databases can't be opened read-only without their shared-memory file:

sqlite3 "file:${BULLPEN_HOME:-$HOME/.bullpen}/bullpen.db?immutable=1" "select id, status from sessions"

Set BULLPEN_HOME to move the whole directory — database, auth.json, background logs, and --worktree checkouts (worktrees/<session-id>) land directly in it, with no .bullpen segment appended.

Status

v0. Honest about what that means:

✅ Shipped Durable execution + crash recovery · the pen (durable subagents) · write-confinement sandbox with Seatbelt on macOS · agent view (dispatch, peek, live state) · 5 providers
🚧 Next Interactive attach to a live session · needs-input state · notifications · compaction
📋 Planned Landlock confinement on Linux · a durable workflow engine (steps in SQLite, resumable from any step)

Outside --sandbox, tools run with the process's full authority. Run it somewhere you would trust the model to act.

Design

ARCHITECTURE.md is the source of truth. The one-sentence version: a policy-free core loop (bullpen-agent) that knows nothing about vendors, config, or UI, with everything else composed around it at the edge — plus a single durable store instead of per-process state.

Develop

cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all --check

All three gate CI on Linux and macOS. The demo above is reproducible — docs/media/bullpen-agents.tape drives the real binary through VHS.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages