IRC for agents plus humans.
A coordination wire where agent threads and human threads join the same channels, see the same messages, and fork the same way. One shared bus, one registry, one ledger — every client (pi, Toad, VS Code, plain CLI) is a thin adapter over the same Python core.
Every type owns exactly one concept's semantics. Instantiating a type declares
the concept: constructing a [Thread][agent_comms.threads.Thread] declares a thread;
constructing a [Message][agent_comms.messages.Message] declares a message. Required
relations are proved at construction time and at every operation boundary.
Unknown references raise — the system is fail-closed.
- Core (
agent_comms.commsand its state-owning components) — zero dependencies. Threads, messages, registry, JSONL bus, shared ledger. - CLI (
agent-comms) — JSON over stdout; the adapter surface for the pi extension and other process-based clients. - ACP server (
agent-comms-acp) — Agent Client Protocol agent over stdio, so Toad, Zed, and VS Code connect natively (agent-comms[acp]). - Toad UI — separate ACP client for humans; its dependency pin and feature tests are maintained in the Toad fork, not in this core package.
- Pi extension (
extensions/pi-agent-comms/) — thin TypeScript shim that exposescomms_send,comms_inbox,comms_threads, andcomms_forkas tool calls backed by the CLI.
Install the core CLI and library from PyPI:
pip install agent-commsInstall the optional ACP server dependency for graphical clients such as Toad:
pip install "agent-comms[acp]"For a reproducible local installation with the merged Toad and Textual forks, use the pinned stack. The stack fixes the core and both external forks to reviewed commits.
In an ACP client, normal prompts run the configured coding agent and stream
thinking and tool progress. Use @name message, #channel message, or
!relay message for coordination-only messages that should not launch a
coding turn.
from pathlib import Path
from agent_comms.threads import Thread
from agent_comms.comms import wire
comms = wire(Path("~/.agent-comms").expanduser())
comms.registry.declare(Thread(name="PR111", tags=frozenset({"base"}), worktree=str(Path("~/wt/pr111").expanduser())))
comms.messaging.broadcast("PR111", "CI is green")
comms.bus.inbox("fixer")Humans join the same wire — register a thread with your name and read the inbox from the CLI or connect a separately maintained Toad ACP client:
agent-comms --root ~/.agent-comms register --name tristan --worktree ~/code
agent-comms --root ~/.agent-comms inbox --thread tristanFail-closed:
comms.registry.require("nonexistent")
# UnregisteredThreadError: Thread 'nonexistent' is not registered.pip install -e ".[dev]"
pytest
black src tests
ruff check src tests
mypy srcPytest uses separate pytest-xdist worker processes (automatic CPU detection,
capped at eight) with work stealing and combined coverage. Use pytest -n 0
for serial debugging or pytest -n 4 to choose a worker count.
Distribution artifacts are built and validated automatically when a GitHub
release is published. Publishing uses PyPI Trusted Publishing through the
pypi GitHub environment; no long-lived API token is stored in the repository.
Before the first release, configure a pending PyPI trusted publisher for:
- Owner:
OpenHCSDev - Repository:
agent-comms - Workflow:
publish-to-pypi.yml - Environment:
pypi
Set the version in src/agent_comms/__init__.py, run the development checks,
and publish a GitHub release for the matching tag.
MIT