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)
Package layout (import paths; no legacy shims):
agent_augury.core.* # Session, MessageServer, agent/, protocol/, checkpoint
agent_augury.channels.* # discord/, slack/, chat formatting
agent_augury.gateway.* # Wire bus, Ink/headless bridges
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 (PROPOSE: / APPROVE: via send_message on the gate thread — prose alone does not count) before advancing. Use it when you want structured team work; omit it for free-form multi-agent sessions.
When protocol: is enabled, the runtime pre-opens gate threads (plan, execution, …) and human. Agents should reuse those thread ids; inventing new thread names during P1–P5 is rejected.
Optional token-saving attention budget (off by default):
attention:
enabled: true # default false
# display.chat / surfaces.* are separate (chat UI density)See docs/architecture/AGENT_RELEVANCE_BUDGET_DESIGN.md.
Optional human phase approval (after agents agree, wait for you):
protocol:
gates:
P2_SPLIT: plan
P3_EXECUTE: execution
P4_REVIEW: review
P5_SUBMIT: submission
human_approval:
P5_SUBMIT: true # defaults: all phases falseFlow: agents APPROVE: among themselves → Wire session.human_approval_pending → you reply APPROVE: / REJECT: (Ink or Discord inbound). Separate from tool-approval buttons. See docs/architecture/HUMAN_APPROVAL_GATE_DESIGN.md.
Dynamic roster (0.7.2+) — the agents you configure are a pool; how many actually run is decided per turn:
protocol:
participants: [agent-1, agent-2, agent-3, agent-4] # the pool
roster:
start: 2 # how many explore in P1 (default min(2, pool)). -1 = all
max: 8 # cap per phase (default: pool size)P1 starts with start agents; P2's ASSIGN / SPLIT: none lines then set who runs P3–P5 — naming a pooled agent that is not yet active wakes it. Benched agents get no task and cost nothing.
Behaviour change in 0.7.2: with a
protocol:section and noroster:,startdefaults to 2 — previously every configured agent ran every turn. Setstart: -1to keep the old behaviour. Research backing and design:docs/architecture/DYNAMIC_ROSTER_DESIGN.md.
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)AUGURY_FILE_ROOT— directory the agents' file tools may read/write (default: the directory you launched from). The session prints the effective root on startup; a path outside it is refused and logged.AUGURY_INK_DEBUG—1dumps every Wire line (both directions, sensitive values masked) to.augury-ink-debug.logunderAUGURY_FILE_ROOT; set it to a path to choose the file. Off by default.
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.
Interrupt + process exit used to wipe agent memory. Checkpoints now persist under
~/.agent-augury/sessions/<id>/ (conversation, protocol phase, MessageServer DB,
pending approvals).
- Default on for headless and Ink (
--demodisables) - Reboot → hydrate → idle-wait; next message is appended (even if identical)
- Fresh work:
--new-sessionorAGENT_AUGURY_NEW_SESSION=1 - Pin id:
--session <id>/AGENT_AUGURY_SESSION - Manage:
agent-augury sessions list|show|rm· corrupt →sessions/quarantine/
session:
checkpoint:
enabled: true
resume: auto # auto | ask | never
dir: ~/.agent-augury/sessions
approvals_persist: true
compact:
enabled: true
soft_limit_chars: 200000
llm_summary: false # optional: summarize via agent backend on async flushagent-augury sessions list
agent-augury sessions show <id>
agent-augury sessions rm <id> --yes
agent-augury sessions quarantine listDangerous 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 |
dangerous (paths that arm later execution; allowed_roots still applies) |
web |
web_search / fetch_url |
off |
tools:
approval:
shell: dangerous # require | dangerous | off
file_write: dangerous # require | dangerous | off
web: off
ttl_seconds: 600
# bypass: true # tests only — never in productiondangerous for file_write gates writes that turn a later innocuous action
into code execution — .git/ internals (untracked, so git diff never shows
them), CI configs, .envrc/.env, shell rc files — and lets ordinary project
writes through unattended. Use require to gate every write.
require: 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-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 |
--new-session |
Ignore LATEST checkpoint; start fresh |
--session <id> |
Resume or bind to this session id |
Removed in 0.7.4:
--ink. It never changed anything — Ink is the default whenever a TTY and Node are available; use--headlessto opt out. Drop it from scripts: the CLI now rejects unknown flags instead of abbreviating them.
- 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
