Generic message bus transport — Unix Socket message routing, session management, heartbeat
Project description
hermes-bus
Role in the Hermes messaging ecosystem: hermes-bus is the transport layer — a Unix Socket IPC daemon that routes JSON messages between endpoints. It is the backbone. The other two packages in the ecosystem are:
- hermes-notify — CLI senders (
notify-hermes,notify-agent) that inject messages into the bus or tmux sessions - hermes-bus-plugin — receive-side agent plugin that consumes bus messages and routes them to terminal output, LLM context injection, or command execution
Together: notify → bus → plugin. The bus itself is transport-only — it knows nothing about audio, display, LLM context, or chat platforms.
Hermes Messaging Ecosystem
The ecosystem has four layers:
Layer 1 — CLI / User Space Layer 3 — Agent / Plugin
┌──────────────────────┐ ┌──────────────────────────┐
│ notify-hermes │──┐ │ hermes-bus-plugin │
│ notify-agent ──→ tmux│ │ │ print → terminal │
│ (hermes-notify) │ │ │ context → LLM injection │
└──────────────────────┘ │ │ command → subprocess │
▼ │ channel → Gateway │
Layer 2 — Transport ┌──────────┐└────────────┬─────────────┘
┌──────────────────┐ │hermes-bus│ │
│ Unix Socket IPC │────→│ message │──────────────┘
│ JSON routing │ │ daemon │
│ session mgmt │ └──────────┘ Layer 4 — Gateway
└──────────────────┘ ┌──────────────────┐
(hermes-bus) │ Platform Adapters│
│ WeChat · Feishu │
│ WeCom · DingTalk │
└──────────────────┘
| Layer | Package | Role |
|---|---|---|
| 1 — CLI | hermes-notify | Send messages into the ecosystem (notify-hermes, notify-agent) |
| 2 — Transport | hermes-bus | Route JSON messages between endpoints via Unix Socket |
| 3 — Plugin | hermes-bus-plugin | Receive-side agent plugin: print, LLM context injection, command execution, channel routing |
| 4 — Gateway | (downstream) | Platform adapters deliver replies to end users. Zero agent code changes |
Install
pip install hermes-bus
Or from source:
git clone https://github.com/mlinquan/hermes-bus.git
cd hermes-bus && pip install -e .
CLI
# Daemon management
hermes-busd start # Start the bus daemon
hermes-busd stop # Stop the daemon
hermes-busd status # Check daemon + connected endpoints
hermes-busd restart # Restart the daemon
# Foreground server (for debugging)
hermes-bus-server
Python API
from hermes_bus.client import BusClient, send_message
# Long-lived: register as an endpoint and receive messages
client = BusClient("my-service")
client.connect()
for msg in client.poll():
print(msg)
# Short-lived: fire-and-forget
send_message("target-service", {"text": "hello", "type": "ack"})
Architecture
client.py ──── Unix Socket ──── server.py
(BusClient) (BusServer)
- Register endpoint - Session management
- Heartbeat (60s) - Message routing
- Auto-reconnect - Hook triggers
- Thread-safe message queue
busd.py — Daemon manager: start / stop / status / restart
Protocol
4-byte big-endian length prefix + JSON body. Max payload: 10 MB.
Long-lived connections register an endpoint name and can send/receive. Short-lived connections send one message and disconnect — no registration, no endpoint_map pollution.
Hooks
After each message is routed, hook scripts are triggered asynchronously. Resolution priority:
HERMES_BUS_HOOKSenv var (comma-separated or JSON array of script paths)hooks.yamlconfig file- Default: none (routing handled by hermes-bus-plugin)
Each hook receives the full message JSON on stdin. Hook execution is non-blocking — the bus continues routing.
Message Format
All bus messages use 4-byte big-endian length prefix + JSON body. Max payload: 10 MB.
Envelope (wire format)
┌──────────────────┬──────────────────────────────────┐
│ 4 bytes (BE) │ JSON body (up to 10 MB) │
│ payload length │ UTF-8 encoded │
└──────────────────┴──────────────────────────────────┘
Message structure
{
"type": "message",
"to": "target-endpoint",
"from": "sender-endpoint",
"ts": 1716307200.123,
"body": {
"text": "Human-readable message content",
"type": "task_done",
"channel": "feishu:oc_abc123"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | yes | Message type: message, register, ping, pong, list_endpoints |
to |
string | yes (for message) |
Target endpoint name |
from |
string | auto | Sender endpoint name (set by bus for registered endpoints) |
ts |
float | auto | Unix timestamp (set by bus on receipt) |
body |
object | no | Application payload — see below |
body.text |
string | no | Human-readable message text |
body.type |
string | no | Application-level type: directive, ack, task_start, progress, task_done, plan_ready, task_error, need_decision |
body.channel |
string | no | Reply routing token (platform:chat_id). Carried through the chain unmodified |
Special message types
type |
Direction | Description |
|---|---|---|
register |
client → server | Register as a named endpoint |
registered |
server → client | Registration acknowledgement with session_id |
ping |
client → server | Heartbeat (sent every 55s by long-lived connections) |
pong |
server → client | Heartbeat response |
list_endpoints |
client → server | Request connected endpoint list |
endpoint_list |
server → client | Response with current endpoints |
message |
bidirectional | Application message (routed by to field) |
Message lifecycle
Client sends: {"type":"message","to":"lead-agent","body":{"text":"hello","type":"ack"}}
│
Bus server: Registers timestamp, resolves target endpoint, delivers │
▼
Target receives: {"type":"message","from":"worker-alpha","to":"lead-agent",
"ts":1716307200.123,"body":{"text":"hello","type":"ack"}}
The bus adds from (if not set by sender) and ts fields during routing. The body object is passed through unmodified — the bus never inspects or alters application payload.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_bus-0.5.0.tar.gz.
File metadata
- Download URL: hermes_bus-0.5.0.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
511fc0c3f0a0b173647faad41813679bb14fac0036ee2637e5c69a1dfff1f8c6
|
|
| MD5 |
b33d00152848efc17b9aad8461efcadb
|
|
| BLAKE2b-256 |
b3135f6758ae9e60ae433f5f9764c65899cc70491a054e5db898fbfd0305cbe9
|
File details
Details for the file hermes_bus-0.5.0-py3-none-any.whl.
File metadata
- Download URL: hermes_bus-0.5.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
daf6fc60669ede59aa8e60f36f849f3251c53d2939a18ac054febded8c30737f
|
|
| MD5 |
925a3411b2666ea35bf1904a75f7eeba
|
|
| BLAKE2b-256 |
75e5a3c7da2cb9e9f97180ae684bdc2b0eeef8829ac4fa3c0c0f35824af48f33
|