New reference docs: - agents/ref-btmsg.md: inter-agent messaging schema and CLI - agents/ref-bttask.md: kanban task board operations - providers/ref-providers.md: Claude/Codex/Ollama/Aider comparison - config/ref-settings.md: (already committed) New guides: - contributing/dual-repo-workflow.md: community vs commercial repos - plugins/guide-developing.md: Web Worker sandbox API and publishing New pro docs: - pro/features/knowledge-base.md: persistent memory + symbol graph - pro/features/git-integration.md: context injection + branch policy - pro/marketplace/README.md: 13 plugins catalog Split files: - architecture/data-model.md: from architecture.md (schemas, layout) - production/hardening.md: from production.md (supervisor, sandbox, WAL) - production/features.md: from production.md (FTS5, plugins, secrets, audit)
5.6 KiB
btmsg Reference
btmsg is the inter-agent messaging system for Agents Orchestrator. It enables management agents (Tier 1) and project agents (Tier 2) to communicate via direct messages and broadcast channels.
Overview
btmsg uses a shared SQLite database at ~/.local/share/agor/btmsg.db. Both the
Python CLI tools (used by agents) and the Rust backend (Tauri app) access the
same database concurrently. WAL mode and a 5-second busy timeout handle
contention.
Agents must register before sending or receiving messages. Registration creates
an entry in the agents table with the agent's ID, name, role, group, and tier.
Database schema
agents
| Column | Type | Description |
|---|---|---|
id |
TEXT PK | Unique agent identifier |
name |
TEXT | Display name |
role |
TEXT | Agent role (manager, architect, tester, reviewer, or project) |
group_id |
TEXT | Group this agent belongs to |
tier |
INTEGER | 1 = management, 2 = project |
model |
TEXT | Model identifier (nullable) |
status |
TEXT | Current status (active, sleeping, stopped) |
messages
| Column | Type | Description |
|---|---|---|
id |
TEXT PK | UUID |
from_agent |
TEXT FK | Sender agent ID |
to_agent |
TEXT FK | Recipient agent ID |
content |
TEXT | Message body |
read |
INTEGER | 0 = unread, 1 = read |
reply_to |
TEXT | Parent message ID (nullable, for threading) |
sender_group_id |
TEXT | Sender's group ID (nullable, added by migration) |
created_at |
TEXT | ISO timestamp |
channels
| Column | Type | Description |
|---|---|---|
id |
TEXT PK | Channel identifier |
name |
TEXT | Channel name (e.g. #review-queue) |
group_id |
TEXT | Group this channel belongs to |
created_by |
TEXT FK | Agent that created the channel |
created_at |
TEXT | ISO timestamp |
contacts
ACL table controlling which agents can see and message each other.
heartbeats
Liveness tracking. Agents send periodic heartbeats; the health store uses these to detect stalled agents.
dead_letter_queue
Messages that could not be delivered (recipient not found, agent stopped). Surfaced in the agent health monitoring UI.
audit_log
Records agent actions for compliance and debugging. Entries include agent ID, action type, target, and timestamp.
seen_messages
Per-message read tracking with session-level granularity.
| Column | Type | Description |
|---|---|---|
session_id |
TEXT | Reading session identifier |
message_id |
TEXT FK | Message that was seen |
seen_at |
INTEGER | Unix timestamp |
Primary key: (session_id, message_id). This enables per-message acknowledgment
rather than bulk "mark all read" operations.
CLI usage
The btmsg CLI is a Python script installed at ~/.local/bin/btmsg. Agents
invoke it via shell commands in their sessions. The BTMSG_AGENT_ID environment
variable identifies the calling agent.
Register an agent
btmsg register --id mgr-1 --name "Manager" --role manager \
--group my-team --tier 1
Send a direct message
btmsg send --to architect-1 --content "Review the auth module architecture"
Send to a channel
btmsg channel-post --channel review-queue \
--content "Task T-42 moved to review"
Read unread messages
btmsg read
Returns all unread messages for the agent identified by BTMSG_AGENT_ID.
List channels
btmsg channels
Send a heartbeat
btmsg heartbeat
Updates the agent's liveness timestamp. The health store marks agents as stalled
if no heartbeat arrives within the configured stallThresholdMin.
Mark messages as seen
btmsg ack --message-id <uuid>
Records an entry in seen_messages for per-message tracking.
Role permissions
Agent capabilities depend on their role:
| Capability | Manager | Architect | Tester | Reviewer | Project |
|---|---|---|---|---|---|
| Send DMs | Yes | Yes | Yes | Yes | Yes |
| Read own DMs | Yes | Yes | Yes | Yes | Yes |
| Post to channels | Yes | Yes | Yes | Yes | Yes |
| Create channels | Yes | No | No | No | No |
| Delete messages | Yes | No | No | No | No |
| List all agents | Yes | Yes | Yes | Yes | Read-only |
| Update agent status | Yes | No | No | No | No |
The Manager role has full CRUD on all btmsg resources. Other roles can read messages addressed to them and post to channels.
Rust backend integration
The Tauri backend reads btmsg data via src-tauri/src/btmsg.rs. Key functions:
get_agents(group_id)-- List agents with unread countsunread_count(agent_id)-- Unread message countunread_messages(agent_id)-- Full unread message list with sender metadataget_feed(group_id)-- Recent messages across the groupget_channels(group_id)-- List channels with member countsget_channel_messages(channel_id)-- Messages in a channel
All queries use named column access (row.get("column_name")) and return
#[serde(rename_all = "camelCase")] structs for direct JSON serialization to the
frontend.
Frontend
The frontend accesses btmsg through src/lib/adapters/btmsg-bridge.ts, which
wraps Tauri IPC commands. The CommsTab component in ProjectBox displays messages
and channels for management agents.
Review queue integration
When a task transitions to review status via bttask, the system auto-posts a
notification to the #review-queue channel. The ensure_review_channels
function creates #review-queue and #review-log idempotently. See
bttask reference for details.