# 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 ```bash btmsg register --id mgr-1 --name "Manager" --role manager \ --group my-team --tier 1 ``` ### Send a direct message ```bash btmsg send --to architect-1 --content "Review the auth module architecture" ``` ### Send to a channel ```bash btmsg channel-post --channel review-queue \ --content "Task T-42 moved to review" ``` ### Read unread messages ```bash btmsg read ``` Returns all unread messages for the agent identified by `BTMSG_AGENT_ID`. ### List channels ```bash btmsg channels ``` ### Send a heartbeat ```bash 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 ```bash btmsg ack --message-id ``` 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 counts - `unread_count(agent_id)` -- Unread message count - `unread_messages(agent_id)` -- Full unread message list with sender metadata - `get_feed(group_id)` -- Recent messages across the group - `get_channels(group_id)` -- List channels with member counts - `get_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](ref-bttask.md) for details.