Skip to content
 
 

Repository files navigation

agentbus

Coordination infrastructure for multi-agent software production: an append-only message bus with mandatory provenance, a selectable vector lane, a production runtime, a native traffic viewer, and a local speech layer.

version 0.2.0 platform Linux Python 3.10 or later C++17 license Apache 2.0

busview rendering the shipped example run in the graphite theme

busview rendering the shipped example run, examples/example-run.jsonl, in the graphite theme. One lane per run file and one track per agent, with marks placed by message time and shaped by message kind, the kind legend beneath the lanes, and the machine floor along the bottom.

Parallel agents working on one task are blind to one another by default. They duplicate findings, judge the same result differently with no channel to reconcile, and return transcripts instead of claims. agentbus addresses that with one shared, append-only JSONL file per run, a set of path-explicit command line tools that write to it under validation, a documented team and working order for using it, and two observation layers: a viewer for the eye and a speech layer for the ear. The core is agnostic about the agent system in use; the adapters are onboarding.

Contents

The message bus

A run is one append-only JSONL file, and every agent on the work writes to it. Schema version 2 defines eight types: finding, rank, question, answer, handoff, cost, note, and correction. The optional context envelope object ties traffic to a work item, repository revision, files, symbols, artifacts, and a concrete agent instance. meta carries free-form runtime metadata. Each role inherits its unambiguous latest context. When workers share a role name, pass --agent-instance ID; the writer then inherits only that instance's context and otherwise omits ambiguous scope instead of taking the latest parallel writer's context.

Findings carry mandatory provenance. A computed finding requires evidence plus inspectable refs or context artifacts, a fetched finding requires references, and testimony requires its source. Verification is a separate structured state so a provenance label cannot stand in for independent review. Ranks declare a dimension and a dimension-specific value, and resolvers name the earlier rank ids they settle. Corrections use explicit corrects, supersedes, or retracts semantics, preserving audit history while bus-state provides a deterministic current-state projection.

Validation happens before the append. bus-append holds an exclusive advisory lock across reading the run, choosing the next sequence, validating the candidate, and appending it. Checked writes handle short system calls, and --fsync can require storage durability before success is reported. Concurrent local writers therefore cannot allocate the same sequence or validate against a stale snapshot. Messages written by other means are still caught by bus-lint afterwards. The core tools require no installation step and no packages beyond the Python standard library.

Layout: tools/. Documentation: SCHEMA.md, which is the codebook for the envelope, the message types, the sidecar format, and the validation rulings that live traffic forced.

Beads is the control plane

This fork deliberately uses Beads alongside agentbus. They own different state:

Beads agentbus
epic, story, owner, status, dependency, acceptance criteria finding, evidence, disagreement, review, handoff, cost

Beads decides what work exists and who owns it. agentbus records what the agents learned and produced while doing that work. Put the bead id in context.work_item; do not duplicate task status or dependencies in bus prose. The checked-in AGENTS.md, CLAUDE.md, .agents/, .claude/, and .codex/ files load the Beads workflow for supported agent runtimes. A bus is not a scheduler, lease manager, process supervisor, or replacement for the Beads hierarchy.

The vector lane

bus-embed computes sentence embeddings for the findings on a run into a sidecar file, so agents can detect duplicates and recall related work semantically rather than by keyword. The embedding model is selectable. bus-model lists a curated registry, with all-MiniLM-L6-v2 as the default and bge-base-en-v1.5 as a stronger option, fetches a chosen model from Hugging Face pinned to a commit revision, records the digests it downloaded, and sets the active model. Any Hugging Face repository carrying ONNX weights and a tokenizer can be installed by naming its pooling explicitly.

A vector is a derived index and never a message: the canonical content is always the claim text, the same model and the same text must yield the same vector, and a language model never writes one. The model identity is recorded in every sidecar line, and vectors made by different models are never compared. Concurrent embedding workers synchronize sidecar updates through a stable lock, reread under that lock, and avoid duplicate or partial rows. Corrections and retractions update which findings appear in semantic results without deleting historical vector rows. The lane is optional, and a bus works without it.

Layout: tools/bus-embed, tools/bus-model, models/. Documentation: models/README.md, which carries the registry table, the measured separation and throughput figures for both models, and the digests of every file fetched.

The runtime

The bus carries messages; dispatch supplies the team and the order of work. Six roles are defined. Five ship as ready-to-install agent definitions, each setting an output register, rules of honesty, bus duties, housekeeping duties, and a voice: engineer, reviewer, researcher, writer, and archivist. The sixth, the orchestrator, is the main session itself, and its duties are defined by the run order rather than by an agent file.

RUN-ORDER.md documents one production cycle: open a run on the bus, plan, dispatch parallel work with explicit and disjoint scopes, integrate centrally, verify with a reviewer that did not build the work, document, run an acceptance check, and close with cost lines and a lint of the run file. Everything under dispatch/ is a default intended to be edited.

Layout: dispatch/. Documentation: dispatch/README.md and dispatch/RUN-ORDER.md.

The voice layer

Agent work is narrated aloud, one short line per meaningful step, so an operator can follow a multi-agent session by ear instead of reading every transcript as it arrives. Each role speaks in its own voice, which identifies the speaker before the words register. voice/say is the single speech path: Piper for synthesis with espeak-ng as the fallback, playback through pw-play, paplay, or aplay in that order, and three modes covering a global queue, per-voice overlap, and interrupt-latest. Speech is a status channel rather than part of the work, so say returns immediately and every failure is handled by falling back rather than by failing.

Synthesis and playback are local. No audio and no text leaves the machine, and voice models are fetched rather than vendored.

Layout: voice/. Documentation: voice/README.md.

busview

busview is a single-window native dashboard that renders bus traffic live, one lane per run file and one track per agent, with marks placed by message time and distinguished by glyph, a rank joined to the message it judges by a right-angled connector, and a quiet strip of machine vitals along the bottom. Brightness carries recency under a ceiling set by provenance, so a recalled claim never looks as solid as a verified one however recently it was written. A malformed line is never skipped: it is drawn as a damage glyph in the error red, with its raw bytes shown, sanitised, on hover.

It is read-only. It opens files, renders them, and changes nothing. The only file it writes is the ImGui layout file in the working directory.

Layout: viewer/. Documentation: viewer/README.md, which covers the build, the bus directory resolution, the panels, and the graphite palette.

Adapters

The core is agnostic; the adapters are onboarding, and the tools in tools/ work without any of them.

  • Claude Code, the proven ground: an installer that places the bus practice, the run order, the five agent definitions, the speech command, and three hooks into a target project's .claude/ directory. It refuses to overwrite an existing file, and on refusal installs nothing at all, so a refusal never leaves a project half configured. It prints the settings block to add rather than editing settings.json itself. See adapters/claude-code/README.md.
  • Codex: a single snippet carrying the same practice in the same command line terms, for a project's AGENTS.md. Claims about how Codex consumes configuration are recorded with their source and verification status. See adapters/codex/README.md.
  • Any other system: a host-agnostic snippet, and the route to reach for when no adapter exists. The requirement is short. An agent system can use the bus if its agents can run a shell command and read a Markdown file. See adapters/hermes/README.md.

Repository layout

Path Contents
SCHEMA.md the codebook: envelope, message types, vector lane, validation rulings
DESIGN.md the design document: what each layer addresses and the contracts it holds
tools/ bus-lint, bus-new, bus-append, bus-state, bus-bench, bus-embed, bus-model, buslib.py
models/ embedding model documentation, the registry, and a fetch wrapper
dispatch/ the runtime: the agents/ roster, RUN-ORDER.md, and the run skill
voice/ say, voices.conf, install-voices.sh, test.sh, and hook examples
adapters/ claude-code/, codex/, hermes/
viewer/ busview: sources, the data-layer test binary, and vendored Dear ImGui
examples/ a synthetic example run that lints clean
tests/ the tool test suite
docs/ images used by this file
AGENTS.md, CLAUDE.md, .agents/, .claude/, .codex/ Beads workflow instructions and runtime hooks

Quick start

Clone the repository and work from its root. The bus itself has no build step and no installation.

git clone https://github.com/CGIC-AI/agentbus.git
cd agentbus

If Beads is installed, bd prime loads the durable work graph before a multi-agent run. Use the claimed bead id as context.work_item in the commands below.

Start by validating the shipped example, which exercises every message type:

$ tools/bus-lint examples/example-run.jsonl
0 errors, 0 warnings, 15 messages checked

Then create a run of your own. bus-new prints the path it created, and the file name carries the date on which it was created:

$ tools/bus-new parser-audit
bus/runs/2026-08-02-parser-audit.jsonl

Append a message to it. bus-append supplies the sequence number and the timestamp, validates the result, and prints the id of the message it wrote:

$ tools/bus-append bus/runs/*-parser-audit.jsonl \
    --agent engineer --type finding \
    --context '{"work_item":"parser-audit","repo":"my-project","head_revision":"def456","files":["src/parser.py"]}' \
    --body '{"claim":"The parser rejects a trailing comma in an object.","evidence":"tests/test_parser.py, 3 cases, all passing","refs":["tests/test_parser.py"],"provenance":"computed","confidence":0.9}'
engineer-1
$ tools/bus-lint bus/runs/*-parser-audit.jsonl
0 errors, 0 warnings, 1 messages checked

That is the whole core. The remaining layers are optional and independent of one another.

Project the correction-aware current state or measure representative run sizes with:

tools/bus-state --json bus/runs/*-parser-audit.jsonl
tools/bus-bench --sizes 100,1000,10000

JSONL is the authoritative local audit record for bounded runs. Keep latency-sensitive runs below 1,000 messages and roll over before 10,000; the full duplicate scan is already an offline operation at that ceiling. bus-bench makes append, lint, vector, viewer, and memory costs visible before a workload grows large enough to need an indexed store.

The vector lane needs an embedding model, which is fetched rather than vendored. The default is 87 MiB:

tools/bus-model fetch all-MiniLM-L6-v2
tools/bus-embed test

bus-embed test reports the active model's identity and dimension, the cosine it scores on a paraphrase pair and on an unrelated pair, and its measured throughput. See models/README.md.

The voice layer needs Piper and the voice model files, which the installer fetches into ~/.local/share/agentbus/voices:

voice/install-voices.sh
voice/say -n -r engineer "voice channel ready"

The second command is a dry run: it prints the resolved voice, synthesizer, mode, and player, and speaks nothing, which is the quickest way to find out why a line came out in the wrong voice. See voice/README.md.

Claude Code projects are configured by the adapter's installer, which reports the manual steps it deliberately leaves to you:

adapters/claude-code/install.sh /path/to/your/project

See adapters/claude-code/README.md.

busview is built with CMake. The third command runs the headless data-layer checks, which need no display:

$ cmake -S viewer -B viewer/build
$ cmake --build viewer/build -j
$ ./viewer/build/busview_test
All viewer data-layer checks passed.

On a machine with a display, the following renders eight frames against the example run and exits, which is the launch check for an automated environment:

BUSVIEW_SELFTEST_FRAMES=8 ./viewer/build/busview --bus examples

See viewer/README.md for running it interactively and for how the bus directory is resolved.

Tests

Three suites cover the package. Each exits 0 on success and names what failed otherwise.

python3 -m unittest discover -s tests -p 'test_*.py'  # validation, concurrency, state, and benchmarks
./viewer/build/busview_test    # strict JSON, the bus model, the encoding law, the floor thresholds
voice/test.sh                  # the command line surface, voice resolution, and all three modes

voice/test.sh skips the group that needs a real synthesizer when no voice model is installed, and prints the reason and the remedy alongside the result. A skip is reported separately from a failure.

Requirements

Linux is the platform agentbus is built and tested on.

Layer Requirements
core tools Python 3.10 or later. Standard library only, with nothing to install
vector lane onnxruntime, numpy, and tokenizers, plus one fetched embedding model
voice Piper, installed by voice/install-voices.sh as the pip package piper-tts; espeak-ng for the fallback; one of pw-play, paplay, or aplay for playback; curl or wget
viewer a C++17 compiler, CMake 3.16 or later, GLFW, an OpenGL implementation, and pkg-config. Dear ImGui is vendored and needs no package

The figures reported in this file were produced on one Linux machine with GNU g++ 13.3.0, CMake 3.28.3, and Python 3.12.3.

Design notes

DESIGN.md states the problem each layer addresses and the contracts it holds. SCHEMA.md specifies the version 2 wire format. Three commitments run through every layer, and they are functional rather than decorative.

  • Provenance is marked at write time. A language model cannot reliably distinguish, from the inside, what it computed from what it recalled, and a deferred check tends not to happen.
  • Failures are reported verbatim. A test that fails is quoted rather than summarised into optimism, and this binds the orchestrator's own integration steps as much as any worker's.
  • The audit trail is append-only. A run file that has been quietly rewritten is worse than one that records a mistake, because it can no longer be trusted about anything.

License

agentbus is released under the Apache License, Version 2.0. The full text is in LICENSE, and NOTICE records every third-party component with the duty it places on you.

The short version. One dependency is included in this repository: Dear ImGui, under the MIT license, vendored with its license text under viewer/third_party/imgui/. The synthesizers the voice layer speaks through, Piper and espeak-ng, are GPL-3.0-or-later and are run as separate programs rather than linked or distributed, which places no obligation on this project's code. The optional Python dependencies of the vector lane are permissively licensed and are installed by you, not shipped by us.

No model is distributed here. The embedding models and voice models are downloaded from Hugging Face when you ask for them, and their terms are the terms you accept in doing so. The two embedding models offered are Apache-2.0 and MIT. Every voice installed by default is in the public domain, chosen deliberately: the same catalogue contains voices under non-commercial and research-only terms, and those do not belong in a permissively licensed product. A voice you install yourself with --voice carries its own terms, which are often narrower, and the installer prints the license of what it is about to fetch. Those terms restrict use, not only redistribution.


Federated Industrial Laboratories, 2026.

About

Coordination infrastructure for multi-agent software production: an append-only message bus with mandatory provenance, a selectable vector lane, a production runtime, a native traffic viewer, and a local speech layer.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages