Skip to content
lydakisPublic

About

Run many coding agents at once from one small Rust daemon. Named bots you can resume, fork, steer, and stream as JSON events. Built for programs first.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

agent

Run many coding agents at once from one small daemon. Each agent is a named bot with a durable conversation: continue it later, fork it from any earlier point, steer it mid-turn, or follow it live as a stream of JSON events. Bots delegate by running the same agent command you do.

Agent is built for programs first. A script, a CI job, an app, or another bot drives it through a CLI whose default output is JSON Lines, or through the daemon's socket protocol. --pretty gives people a readable view of the same events.

agent run --pretty --new --bot lead -- "Fix the failing test, and have a helper check the README"

The lead bot starts a docs bot with agent run --detach, runs the tests, collects the helper's finding with wait, fixes a rounding bug, and summarizes. agent ls then lists both bots.

lead hands the README check to a second bot, runs the tests, collects the helper's answer, then fixes the bug. The model's words are scripted for this recording; the daemon, the bots, and every tool call are real. Record it yourself.

Install

Agent runs on macOS and Linux. Build it from source with Rust; rustup fetches the toolchain pinned in rust-toolchain.toml.

git clone https://github.com/lydakis/agent
cd agent
cargo install --locked --path .

That puts agent in ~/.cargo/bin. With Homebrew, brew install lydakis/agent/agent builds the same from a release's source; brew install lydakis/agent/sonny adds Sonny, the terminal client, and pulls in agent and ripgrep with it. If Homebrew refuses the tap as untrusted, run brew trust lydakis/agent first.

On Linux without Homebrew (which does not run on ARM Linux), install Sonny and its daemon from the latest release's static build, checked against its published sha256:

curl -fsSL https://raw.githubusercontent.com/lydakis/agent/main/install.sh | sh

It unpacks sonny-VERSION-linux-ARCH.tar.gz (x86_64 or aarch64) under ~/.local/opt and links ~/.local/bin/sonny; PREFIX installs elsewhere and SONNY_VERSION picks a release. install.sh is short enough to read first.

Quickstart

Set the key for any provider you use, and pick a default model as PROVIDER/MODEL:

export OPENAI_API_KEY=...       # models named openai/MODEL
export ANTHROPIC_API_KEY=...    # anthropic/MODEL
export OPENROUTER_API_KEY=...   # openrouter/VENDOR/MODEL
export AGENT_MODEL=anthropic/claude-opus-5-5

For Amazon Bedrock, use your usual AWS credentials (AWS_PROFILE, SSO, or keys in the environment); no region is needed. A Bedrock API key in AWS_BEARER_TOKEN_BEDROCK works too, with AWS_REGION set to the key's region. Start the daemon with --provider bedrock and name Claude models by their cross-region inference profile, like bedrock/global.anthropic.claude-opus-5-5, which AWS routes to whichever region holds the model (from any source region the profile supports), or --provider bedrock-openai for bedrock-openai/openai.gpt-6-sol. AGENT_PROVIDER takes the place of --provider for any provider, so export AGENT_PROVIDER=bedrock AGENT_MODEL=bedrock/global.anthropic.claude-sonnet-5 needs no flags. To keep them instead, put provider = "bedrock" and model = "bedrock/global.anthropic.claude-sonnet-5" in ~/.agent/config.toml; the shell's variables come first. For a ChatGPT Go, Plus or Pro plan, run agent login chatgpt once and start the daemon with --provider chatgpt; it signs in through OpenAI's Sign in with ChatGPT and keeps the token fresh itself. agent models --discover writes ~/.agent/models from what your providers list; edit it down to the models Sonny and your agents should offer.

Each bot has its own model, so bots on different providers can run side by side in one daemon. Other OpenAI Responses-compatible gateways can be added with --provider; see providers and models.

From your project directory, start a bot:

agent run --pretty --new --bot scout -- "What does this repository do?"

The first command starts the daemon in the background. Bots and their history live in ~/.agent/state.sqlite, so they survive restarts of the daemon and of your machine. Leave out --pretty to get the raw event stream.

Continue a bot

Name the bot again to give it its next turn in the same conversation:

agent run --pretty --bot scout -- "Which parts are tested?"

A bot keeps the model, instructions, and tools it was created with until a client changes them. --model on a later turn overrides the model for that turn only. Between turns, a client can give a bot a new model of the same provider, new instructions, or new approval gates with the socket protocol's configure, as Sonny does when you switch a lead's model or its skills and memory change; see the software protocol.

Leave it running and come back

Press Ctrl-C at any time; the turn keeps running in the daemon. Reattach to replay what you missed and follow it to the end:

agent follow --pretty --bot scout

To start without waiting, use --detach. It prints a JSON handle that a script can wait on:

handle=$(agent run --detach --bot scout -- "Run the test suite and summarize the failures" | jq -r .handle)
agent wait "$handle"

agent ls --pretty lists every bot and what it's doing. agent follow --all streams events from all of them.

Steer or stop a running bot

Send more instructions into the turn that's already running:

agent run --bot scout --delivery steer -- "Skip the integration tests"

Or stop it: agent interrupt --bot scout. A busy bot rejects new work unless you choose --delivery queue or steer. A queued message it has not started can be taken back with agent interrupt --bot scout --turn N.

Let bots delegate

Bots delegate the way the demo shows: from their shell tool they run agent run --detach --new --bot NAME -- TASK, keep working, and collect the result with their wait tool. The default instructions teach them this. Every bot is a peer with the same commands; a bot that starts another doesn't own it, and you can talk to either one directly.

A waiting bot holds no execution capacity: while it waits, it costs a row in the store and an entry in the daemon's registry, not a process.

To give a bot your project's conventions, add --agents when you create it. Agent then composes its instructions from every AGENTS.md and .agents/AGENTS.md from the workspace up to the filesystem root, plus ~/.agents/AGENTS.md, indexes of skills in .agents/skills/ and profiles in .agents/agents/, and the memory indexes in ~/.agents/memory. --profile ROLE starts a bot in one of those roles. See client policy.

Fork from an earlier point

Try an alternative without losing the original conversation:

agent fork --source scout --bot scout-b
agent run --pretty --bot scout-b -- "Try it with a streaming parser instead"

Without --checkpoint, the fork starts from the source's latest state. To branch from an earlier turn, pass the checkpoint that agent wait turn:scout/N reports for it. Each branch continues independently.

Use it from a program

Output is JSON by default: run and follow stream one event per line (text, thinking, tool calls and results, usage, state changes), and the other commands print one JSON value or nothing. Exit codes are stable: 0 success, 1 failed or incomplete, 2 invalid usage, and 75 when agent serve finds another daemon already owns the store. The CLI contract has the details.

Programs that want a persistent connection can speak the daemon's JSONL socket protocol directly; client/ is a Rust client for it. See the software protocol.

Sonny

Sonny is a terminal client over the same socket. Opened in a folder, it is that project's lead: it starts tasks, each in its own copy of the folder, lays them out in Rex or Herdr, and hears what they did. It also gives every agent triggers, memory and skills.

brew install lydakis/agent/sonny        # or, on Linux, install.sh above
sonny                                   # in your project's folder

The first run asks how your agents reach a model (a ChatGPT plan, an Anthropic, OpenAI or OpenRouter key, or Bedrock with your AWS profile) and which model new projects use. As Codex does, it keeps the settings in ~/.agent/config.toml and any key in ~/.agent/env, readable only by you, which Sonny applies to the daemon and everything else it starts, so nothing goes in your shell profile. Bots search the web where their provider offers it, as Codex's do: OpenAI with an API key, Anthropic, and GPT on Bedrock. Put web_search = "disabled" in config.toml to leave it out of new bots.

How fast is it?

Performance is the point of the project, and every claim links to its measurement. Current evidence is the up-to-date summary: runtime efficiency, task results against Codex and Claude Code, and operational behavior. In the September 15–16 fleet checks, one daemon ran 1,024 overlapping bot turns on real providers, held 64 for five minutes without drift, and pushed 10,000 bots through one API key at the provider's own rate with no failures (live fleet check). Overlap includes queued work, not necessarily simultaneous provider streams. Those were short-context turns: they show a lightweight runtime, not coding-agent capacity at that scale.

The same synthetic conversation work through five harnesses, 32 agents at once, each doing three turns that add 64 KiB of text and stream back 5 KiB (full screen, 2026-10-28, 4-vCPU Linux VM, medians of three runs; Agent 0.4.1, daemon source identical to main 3a9f7df).

Harness Peak memory CPU time Turn p99
Agent 29 MiB 0.7 s 0.61 s
Pi 0.85.1 159 MiB 1.9 s 0.78 s
Codex 0.153.1 246 MiB 40.1 s 10.2 s*
opencode 1.18.32 958 MiB 24.7 s 6.2 s
Claude Code 2.1.267 6,490 MiB 42.4 s 3.5 s*

Read this as an exploratory screen, not a ranking. The harnesses do different amounts of work: Agent commits every turn to SQLite, opencode keeps its own store, and the others hold conversations in memory; no tools were called. Claude Code runs one process per agent, and its memory is summed across those processes. Turn time includes 0.5 s of scripted streaming. * Codex reached only 7 to 9 of the 32 concurrent streams on this machine, and Claude Code 24 to 29.

The performance tools reproduce these runs against the same synthetic provider, and docs/ holds the design record and measurements behind every decision.

Status

Agent is an experiment with no users yet. It supports the OpenAI Responses and Anthropic Messages APIs, with streamed thinking, usage, and prompt-cache accounting; long conversations are compacted while the full history is kept. MCP and handing a conversation across providers are not implemented. Protocols, CLI defaults, and the store format may change between revisions; stores migrate forward automatically.

Agent runs bots; it doesn't create workspaces, manage Git branches, or choose machines. Those stay with the caller. To run work on another machine, see Errand.

Bots run their tools with your permissions, directly on your machine. Agent provides no sandbox; run it inside one if you need isolation.

When you need more

License

Licensed under either of Apache License 2.0 or MIT license, at your option.

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in this project, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Run many coding agents at once from one small Rust daemon. Named bots you can resume, fork, steer, and stream as JSON events. Built for programs first.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages