# amq-bridge

Plug agents together across different sessions.

## Concept

```
Pi session
  -> bridge
    -> transport
      -> shared mailbox

Codex session (coming soon)
  -> bridge
    -> transport
      -> shared mailbox
```

One shared mailbox. Any agent runtime can read and write. No central server. No cloud dependency.

## Design

- **transport behind an interface** — swap the bus without touching agent logic
- **behavior isolated from transport** — watch-driven receive, reply tracking, attach/detach all live in bridge core
- **runtime adapter is thin** — only resolves local identity and the mailbox root
- **one bridge core, any agent** — Pi, Codex, OpenCode all use the same code path
- **pluggable transport** — currently using [agent-message-queue](https://github.com/avivsinai/agent-message-queue), but behind a thin transport layer so can be switched to other transports if needed.

## Why

Agents are siloed. Each session is an island. If you run multiple agents — same machine, same task — they have no way to talk.

This bridge gives them a shared inbox. Send a message from one agent, pick it up from another. No HTTP polling. No REST API. No server to deploy.



## Install into Pi

Prereqs:

```bash
# macOS
brew install avivsinai/tap/amq

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/avivsinai/agent-message-queue/main/scripts/install.sh | bash
```

Verify:

```bash
amq --version
```

```bash
pi install npm:amq-bridge
```

Then in Pi:

1. trust project if prompted
2. `/reload`
3. **attach each session** — every session must register its own name and the peer it talks to:

   Session Alice:
   ```
   /amq-bridge attach bob alice
   ```
   (args: `<peer> [self]` — self defaults to session name if omitted)

   Session Bob:
   ```
   /amq-bridge attach alice bob
   ```

4. **send** — owner session sends; secondary sessions remain read-only:
   ```
   /amq-bridge send hi from alice
   ```

5. **inbox** — check what arrived:
   ```
   /amq-bridge inbox
   ```

6. **reply** — reply to a specific message:
   ```
   /amq-bridge reply <msg-id> got it
   ```

## Tools, not just commands

The bridge registers **tools** directly into the agent's toolset. That means the agent can use them autonomously — you don't need to type slash commands.

| Tool | What it does |
|---|---|
| `amq_bridge_send` | Send AMQ message to attached peer |
| `amq_bridge_reply` | Reply to AMQ message by explicit id |
| `amq_bridge_inbox` | Inspect envelope-only inbox/history |
| `amq_bridge_read` | Read body by explicit message id |
| `amq_bridge_resolve` | Resolve message and advance queue |
| `amq_bridge_status` | Show identity, pending, active, and owner mode |

Example flow — one prompt, no manual steps:

> **You:** "Invite bob to play tic-tac-toe"
>
> **Session Alice** (agent uses tools automatically):
> 1. Sees `amq_bridge_send` tool — sends bob a game invite
> 2. Watch-driven inbox injects bob's envelope
> 3. Reads body with `amq_bridge_read <id>`
> 4. Replies with `amq_bridge_reply` using explicit id — all autonomous
>
> **Session Bob** (agent reacts to incoming message):
> 1. Auto-inbox loop picks up alice's invite
> 2. Bob's agent sees the message, decides to respond
> 3. Sends "let's play" back via `amq_bridge_reply`
> 4. Game on

The agent discovers peers, routes replies, and manages the conversation — you just say what you want.

## Commands

| Command | What it does |
|---|---|
| `/amq-bridge attach <peer> [self]` | Join the bus; self defaults to session name |
| `/amq-bridge detach` | Leave the bus |
| `/amq-bridge send [--to peer] [--priority p] <msg>` | Send actionable question by default |
| `/amq-bridge inbox [--all] [--limit N]` | List newest-first envelopes |
| `/amq-bridge read <id>` | Read body by explicit id |
| `/amq-bridge resolve <id>` | Resolve and advance queue |
| `/amq-bridge reply <msg-id> [--priority p] <msg>` | Reply to explicit message id |
| `/amq-bridge status` | Show identity, pending, active, mode |
| `/amq-bridge discover` | List available AMQ agents on the bus |
| `/amq-bridge connect` | Pick an available agent and add as peer |
| `/amq-bridge peers` | Show connected peers |
| `/amq-bridge peer add <handle>` | Add a peer to the roster |
| `/amq-bridge peer remove <handle>` | Remove a peer |
| `/amq-bridge peer primary <handle>` | Set default send target |
| `/amq-bridge help` | Show usage info |

## Mailbox root

Default root is `~/.amq-bridge/mail`, not the current directory. Two agents can communicate even from different folders.

Override:

```bash
PI_AMQ_ROOT=/path/to/shared/mail pi
```

Or project-local config `.pi/amq-bridge.json`:

```json
{ "root": ".agent-mail" }
```

## Watch-driven inbox

When attached in TUI mode, one shared watcher claims `(root, self)` and consumes AMQ watch events. It injects envelope-only context; read bodies explicitly with `amq_bridge_read <id>`. Secondary sessions remain read-only.


## Transport

Default transport is [AMQ](https://github.com/avivsinai/agent-message-queue) — a zero-config message queue that uses the filesystem. No daemon, no ports, no infra.

---

See [docs/roadmap.md](docs/roadmap.md) for planned features, protocol design, and milestones.