Local multi-agent collaboration — shared threads, roles, and human-in-the-loop.
Model-agnostic runtime for teams of LLM agents that keep working while teammate messages arrive.
agent-augury is a local Python runtime for running several LLM agents as a team:
- shared conversation threads with
@mentionsand broadcast - non-blocking delivery — agents keep working; messages land at the next
step() - assignable roles, optional P1–P5 collaboration protocol
- you as a first-class participant (
ask_user, Ink UI, Discord/Slack mirrors) - model-agnostic backends (OpenAI-compatible, Nous API key / OAuth)
Install it, configure agents in YAML (or the wizard), and run a session from the terminal.
You (Ink / Discord / …)
│
Session + Gateway
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Agent A Agent B Agent N
(any model) (any model) (any model)
│ │ │
└────────────────┼────────────────┘
▼
Message Server (SSOT)
Agents talk through three primitives:
| Primitive | Behavior |
|---|---|
create_thread(name, participants) |
Open a named thread |
send_message(thread, content, mentions) |
Fire-and-forget post (mentions empty = broadcast) |
read_resource() |
Snapshot threads/messages when needed |
Messages are pushed into each target's inbox. On the next step(), the runtime drains that inbox into the agent's context — no blocking “wait for reply” loop.
In the Ink Surface you can direct a mid-session note with @agent-id … (omit @ to broadcast).
Give each agent a persona from config:
roles:
orchestrator:
prompt: |
You are the orchestrator. Decompose work, coordinate, and integrate results.
architect:
prompt: |
You are the architect. Design structure, tech stack, and trade-offs.
agents:
- id: agent-1
role: orchestrator
backend: { ... }role: <name>uses a preset;role_custom: "..."is inline.- Agent ids must be unique (case-insensitive). The id
humanis reserved.
You are a first-class participant:
- Agents can call
ask_user(question, options?)mid-session - Your reply (and free-form
@agent-idnotes) use the same inbox path as agent messages - On a TTY with Node.js, Ink is the interactive Surface (always-on input)
agent-augury --config session.yamlOptional Discord bots / webhook mirrors and Slack webhooks are observe (or opt-in inbound) surfaces — protocol state stays in the message server.
A five-phase flow is available when you enable protocol: in config:
P1 EXPLORE → P2 SPLIT → P3 EXECUTE → P4 REVIEW → P5 SUBMIT
Gates require explicit group approval before advancing. Use it when you want structured team work; omit it for free-form multi-agent sessions.
Backends share one interface. Mix providers per agent:
- OpenAI-compatible APIs (including OpenRouter)
- Nous Portal (API key)
- Nous Portal (OAuth device code)
type: fakeonly with--demo(tests / offline examples)
Secrets stay in environment variables; YAML stores env names only.
pip install agent-auguryInk Surface (required for the interactive TUI):
- Install Node.js >= 22 so
npmis on yourPATH(nodejs.org). - Run
agent-augury— the wheel bundlesfronts/inksources; on first launch they are copied to a user cache andnpm installruns there. - Optional overrides:
AUGURY_INK_DIR— use a specific Ink front directory (e.g. a git checkout offronts/ink)AUGURY_PROJECT_ROOT— repo root when developing from a cloneAUGURY_CACHE_DIR— base directory for the Ink cache (default: platform cache)
Developers working from this repository can use an editable install (uv sync / pip install -e .); the checkout’s fronts/ink is picked up automatically.
agent-auguryagent-augury --config examples/consensus_openai.yamlOffline / CI-style example (scripted backends):
agent-augury --demo --config examples/demo.yamlProtocol example:
agent-augury --demo --config examples/p1_to_p5_protocol.yamlBoot Core without the Ink TUI — useful when Discord/Slack is the human window (or for CI). This is a launcher, not another chat Surface:
agent-augury --headless
agent-augury --headless --reconfigure # re-run wizard, then headless
agent-augury --headless --config session.yaml # explicit pathWith no --config, uses the wizard default
(~/.agent-augury/agent-augury-session.yaml). With bots[].inbound: true,
channel messages start the next turn after idle. Stop with Ctrl+C.
Use --no-auto-start to wait for the first inbound message instead of running
the config task immediately.
Dangerous local tools can require a human grant before side effects run
(fail-closed; no blocking await — the agent gets pending_approval and continues).
Defaults (override under tools.approval in YAML):
| Class | Tools | Default |
|---|---|---|
shell |
run_command |
dangerous (Hermes-like: only destructive patterns) |
file_write |
write_file / edit_file / append_file |
off (allowed_roots still applies) |
web |
web_search / fetch_url |
off |
tools:
approval:
shell: dangerous # require | dangerous | off
file_write: off # require | off (dangerous ≡ require for file_write)
web: off
ttl_seconds: 600
# bypass: true # tests only — never in productionrequire: every call in that class needs Approve/Denydangerous(shell): only patterns likerm -rf /,curl|sh,dd of=/dev/…, force-push, etc.off: no approval prompts (still subject to shell allow/block andallowed_roots)- Ink: approval card → type
1/approveor2/deny - Discord inbound (
bots[].inbound: true): Approve/Deny buttons per request (preferred); text1/2= oldest pending only --demo: bypasses approval (scripted / CI runs)- Observe-only mirrors are not an approval channel; with no interact surface, gated tools are denied (
no_approval_channel)
Design notes: docs/architecture/TOOL_HUMAN_APPROVAL_DESIGN.md
| Flag | Description |
|---|---|
--config <yaml> |
Run from YAML (skips wizard) |
--demo |
Allow type: fake backends (offline / tests) |
--reconfigure |
Re-run wizard (with --headless: then boot Core without Ink) |
--output <path> |
Wizard output path (only without --config) |
--quiet |
Suppress live event noise |
--ink |
Ink Surface (default when available) |
--ink-hello |
Ink hello against the Gateway (no full session) |
--headless |
Boot Core without Ink (default: wizard session YAML) |
--no-auto-start |
With --headless: wait for human.send before first run |
- Keep working while listening — teammate traffic must not force a blocking wait.
- No single agent is SSOT — the message server owns shared state.
- Surfaces are views — Discord/Slack/Ink observe or interact; they do not own protocol state.
- Models are swappable — communication rules live in the runtime, not one vendor SDK.
- Humans participate — ask, answer, and
@mentionmid-session without special-casing the protocol. - Stay observable — tools, steps, and messages stream on the Wire bus for UIs and mirrors.
See DESIGN.md for implementation history and protocol details.
Apache-2.0
