agent-relay 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -730
- package/dist/cli/index.d.ts +6 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +109 -1521
- package/dist/cli/index.js.map +1 -1
- package/dist/daemon/server.d.ts +8 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +23 -7
- package/dist/daemon/server.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/storage/adapter.d.ts +43 -0
- package/dist/storage/adapter.d.ts.map +1 -1
- package/dist/storage/adapter.js +105 -1
- package/dist/storage/adapter.js.map +1 -1
- package/dist/storage/sqlite-adapter.d.ts +1 -0
- package/dist/storage/sqlite-adapter.d.ts.map +1 -1
- package/dist/storage/sqlite-adapter.js +26 -0
- package/dist/storage/sqlite-adapter.js.map +1 -1
- package/dist/utils/project-namespace.d.ts +46 -0
- package/dist/utils/project-namespace.d.ts.map +1 -0
- package/dist/utils/project-namespace.js +111 -0
- package/dist/utils/project-namespace.js.map +1 -0
- package/dist/wrapper/client.d.ts +1 -1
- package/dist/wrapper/client.d.ts.map +1 -1
- package/dist/wrapper/client.js +1 -1
- package/dist/wrapper/client.js.map +1 -1
- package/dist/wrapper/index.d.ts +0 -1
- package/dist/wrapper/index.d.ts.map +1 -1
- package/dist/wrapper/index.js +2 -3
- package/dist/wrapper/index.js.map +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +5 -0
- package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
- package/dist/wrapper/tmux-wrapper.js +94 -19
- package/dist/wrapper/tmux-wrapper.js.map +1 -1
- package/docs/AGENTS.md +386 -0
- package/docs/CLI-SIMPLIFICATION-COMPLETE.md +48 -0
- package/docs/CONTRIBUTING.md +151 -0
- package/docs/TMUX_IMPLEMENTATION_NOTES.md +364 -0
- package/docs/removable-code-analysis.md +24 -0
- package/install.sh +10 -2
- package/package.json +3 -4
- package/dist/games/index.d.ts +0 -2
- package/dist/games/index.d.ts.map +0 -1
- package/dist/games/index.js +0 -2
- package/dist/games/index.js.map +0 -1
- package/dist/games/tictactoe.d.ts +0 -24
- package/dist/games/tictactoe.d.ts.map +0 -1
- package/dist/games/tictactoe.js +0 -160
- package/dist/games/tictactoe.js.map +0 -1
- package/dist/supervisor/inbox.d.ts +0 -38
- package/dist/supervisor/inbox.d.ts.map +0 -1
- package/dist/supervisor/inbox.js +0 -162
- package/dist/supervisor/inbox.js.map +0 -1
- package/dist/supervisor/index.d.ts +0 -10
- package/dist/supervisor/index.d.ts.map +0 -1
- package/dist/supervisor/index.js +0 -10
- package/dist/supervisor/index.js.map +0 -1
- package/dist/supervisor/spawner.d.ts +0 -54
- package/dist/supervisor/spawner.d.ts.map +0 -1
- package/dist/supervisor/spawner.js +0 -282
- package/dist/supervisor/spawner.js.map +0 -1
- package/dist/supervisor/state.d.ts +0 -132
- package/dist/supervisor/state.d.ts.map +0 -1
- package/dist/supervisor/state.js +0 -465
- package/dist/supervisor/state.js.map +0 -1
- package/dist/supervisor/supervisor.d.ts +0 -67
- package/dist/supervisor/supervisor.d.ts.map +0 -1
- package/dist/supervisor/supervisor.js +0 -263
- package/dist/supervisor/supervisor.js.map +0 -1
- package/dist/supervisor/types.d.ts +0 -139
- package/dist/supervisor/types.d.ts.map +0 -1
- package/dist/supervisor/types.js +0 -12
- package/dist/supervisor/types.js.map +0 -1
- package/dist/webhook/spawner.d.ts +0 -79
- package/dist/webhook/spawner.d.ts.map +0 -1
- package/dist/webhook/spawner.js +0 -288
- package/dist/webhook/spawner.js.map +0 -1
- package/dist/wrapper/pty-wrapper.d.ts +0 -125
- package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
- package/dist/wrapper/pty-wrapper.js +0 -494
- package/dist/wrapper/pty-wrapper.js.map +0 -1
- /package/{CHANGELOG.md → docs/CHANGELOG.md} +0 -0
- /package/{PROTOCOL.md → docs/PROTOCOL.md} +0 -0
package/README.md
CHANGED
|
@@ -1,789 +1,115 @@
|
|
|
1
1
|
# agent-relay
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://codecov.io/gh/khaliqgant/agent-relay)
|
|
3
|
+
Real-time messaging between AI agents.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Installation
|
|
9
|
-
|
|
10
|
-
### One-Line Install (Recommended)
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
curl -fsSL https://raw.githubusercontent.com/khaliqgant/agent-relay/main/install.sh | bash
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
This installs to `~/.agent-relay` and adds `agent-relay` to your PATH.
|
|
17
|
-
|
|
18
|
-
### Install Options
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
# Custom install directory
|
|
22
|
-
AGENT_RELAY_DIR=/opt/agent-relay curl -fsSL https://...install.sh | bash
|
|
23
|
-
|
|
24
|
-
# Install and start daemon immediately
|
|
25
|
-
AGENT_RELAY_START=true curl -fsSL https://...install.sh | bash
|
|
26
|
-
|
|
27
|
-
# Quiet mode (for agents/scripts)
|
|
28
|
-
AGENT_RELAY_QUIET=true curl -fsSL https://...install.sh | bash
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Manual Install
|
|
5
|
+
## Install
|
|
32
6
|
|
|
33
7
|
```bash
|
|
34
|
-
|
|
35
|
-
cd agent-relay
|
|
36
|
-
npm install
|
|
37
|
-
npm run build
|
|
8
|
+
npm install -g agent-relay
|
|
38
9
|
```
|
|
39
10
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- Node.js >= 18 (20+ recommended)
|
|
43
|
-
- macOS or Linux (Unix domain sockets)
|
|
44
|
-
|
|
45
|
-
## Troubleshooting
|
|
46
|
-
|
|
47
|
-
### `node-pty` / native module errors
|
|
48
|
-
|
|
49
|
-
If you see errors like `NODE_MODULE_VERSION ...` or `compiled against a different Node.js version`, rebuild native deps:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npm rebuild node-pty
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### `listen EPERM: operation not permitted`
|
|
56
|
-
|
|
57
|
-
If your environment restricts creating sockets under `/tmp` (some sandboxes/containers do), pick a socket path you can write to:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npx agent-relay start -f -s ./agent-relay.sock
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Why We Built This
|
|
64
|
-
|
|
65
|
-
As AI agents become more capable, there's a growing need for them to collaborate in real-time. Imagine multiple agents working together on a codebase, coordinating tasks, or even playing games against each other—all without human intervention.
|
|
66
|
-
|
|
67
|
-
**The problem:** How do you get agents running in separate terminal sessions to talk to each other seamlessly?
|
|
68
|
-
|
|
69
|
-
## For Humans: When You’d Use agent-relay
|
|
70
|
-
|
|
71
|
-
Use agent-relay when you want **fast, local, real-time coordination** between multiple CLI-based agents without adopting a larger framework.
|
|
72
|
-
|
|
73
|
-
Common scenarios:
|
|
74
|
-
- **Multi-terminal agent swarms** where each agent runs in its own terminal and needs to exchange messages quickly.
|
|
75
|
-
- **Turn-based / tight-loop coordination** (games, schedulers, orchestrators) where polling latency becomes noticeable.
|
|
76
|
-
- **“Wrap anything” workflows** where you don’t control the agent implementation but you can run it as a CLI process.
|
|
77
|
-
|
|
78
|
-
Tradeoffs to know up front:
|
|
79
|
-
- Local IPC only (Unix domain sockets); no cross-host networking.
|
|
80
|
-
- Best-effort delivery today (no persistence/guaranteed retries yet).
|
|
81
|
-
|
|
82
|
-
### Existing Solutions (and why they're great)
|
|
83
|
-
|
|
84
|
-
We built agent-relay with deep respect for existing solutions that inspired this work:
|
|
85
|
-
|
|
86
|
-
#### [mcp_agent_mail](https://github.com/Dicklesworthstone/mcp_agent_mail)
|
|
87
|
-
A thoughtful MCP-based agent communication system. Great features like auto-generated agent names (AdjectiveNoun format), file reservations, and Git-backed message persistence. If you're already in the MCP ecosystem, this is an excellent choice.
|
|
88
|
-
|
|
89
|
-
**Why choose agent-relay over mcp_agent_mail:** When you specifically want **low-latency, real-time, local IPC** and a **PTY wrapper** that can intercept output from *any* CLI agent without requiring MCP integration.
|
|
90
|
-
|
|
91
|
-
**Why choose mcp_agent_mail instead:** When you want **message persistence/auditability**, **file reservations**, and a workflow already built around MCP-style tooling.
|
|
92
|
-
|
|
93
|
-
#### [swarm-tools/swarm-mail](https://github.com/joelhooks/swarm-tools/tree/main/packages/swarm-mail)
|
|
94
|
-
Part of the swarm-tools ecosystem, providing inter-agent messaging. Well-designed for swarm coordination patterns.
|
|
95
|
-
|
|
96
|
-
**Why choose agent-relay over swarm-mail:** When you want **push-style delivery** and sub-second responsiveness; file-based polling can be great for robustness, but it’s not ideal for tight coordination loops.
|
|
97
|
-
|
|
98
|
-
**Why choose swarm-mail instead:** When you prefer **filesystem-backed messaging** (easy inspection, simple operations) and millisecond-level latency isn’t a requirement.
|
|
99
|
-
|
|
100
|
-
### Our Approach
|
|
101
|
-
|
|
102
|
-
agent-relay takes a different path:
|
|
103
|
-
- **Unix domain sockets** for sub-5ms latency
|
|
104
|
-
- **PTY wrapper** that works with any CLI (Claude, Codex, Gemini, etc.)
|
|
105
|
-
- **No protocol dependencies** - just wrap your command and go
|
|
106
|
-
- **Pattern detection** in terminal output (`@relay:` syntax)
|
|
107
|
-
- **Built-in game support** as a proof-of-concept for real-time coordination
|
|
108
|
-
|
|
109
|
-
## Features
|
|
110
|
-
|
|
111
|
-
- **Real-time messaging** via Unix domain sockets (<5ms latency)
|
|
112
|
-
- **PTY wrapper** for any CLI agent (Claude Code, Codex CLI, Gemini CLI)
|
|
113
|
-
- **Auto-generated agent names** (AdjectiveNoun format, like mcp_agent_mail)
|
|
114
|
-
- **Best-effort delivery** with per-stream ordering (ACK protocol defined, reliability optional)
|
|
115
|
-
- **Topic-based pub/sub** for game coordination and channels
|
|
116
|
-
- **Hearts game engine** as proof-of-concept for multi-agent interaction (see `src/games/hearts.ts`)
|
|
11
|
+
**Requirements:** Node.js 20+, tmux
|
|
117
12
|
|
|
118
13
|
## Quick Start
|
|
119
14
|
|
|
120
|
-
### Option 1: One-Line Install (Recommended)
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Install agent-relay
|
|
124
|
-
curl -fsSL https://raw.githubusercontent.com/khaliqgant/agent-relay/main/install.sh | bash
|
|
125
|
-
|
|
126
|
-
# Start the daemon
|
|
127
|
-
agent-relay start -f
|
|
128
|
-
|
|
129
|
-
# In another terminal, wrap an agent (name auto-generated)
|
|
130
|
-
agent-relay wrap "claude"
|
|
131
|
-
# Output: Agent name: SilverMountain
|
|
132
|
-
|
|
133
|
-
# In another terminal, wrap another agent
|
|
134
|
-
agent-relay wrap "codex"
|
|
135
|
-
# Output: Agent name: BlueFox
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### Option 2: From Source
|
|
139
|
-
|
|
140
|
-
```bash
|
|
141
|
-
git clone https://github.com/khaliqgant/agent-relay.git
|
|
142
|
-
cd agent-relay
|
|
143
|
-
npm install && npm run build
|
|
144
|
-
|
|
145
|
-
# Start the daemon
|
|
146
|
-
npx agent-relay start -f
|
|
147
|
-
|
|
148
|
-
# In another terminal, wrap an agent
|
|
149
|
-
npx agent-relay wrap "claude"
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Sending Messages Between Agents
|
|
153
|
-
|
|
154
|
-
Once agents are wrapped, they can send messages to each other:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
# Direct message (from agent terminal)
|
|
158
|
-
@relay:BlueFox Hello from SilverMountain!
|
|
159
|
-
|
|
160
|
-
# Broadcast to all agents
|
|
161
|
-
@relay:* Anyone online?
|
|
162
|
-
|
|
163
|
-
# Messages appear in recipient's terminal as:
|
|
164
|
-
# [MSG] from SilverMountain: Hello from SilverMountain!
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Enable Your Agents
|
|
168
|
-
|
|
169
|
-
Copy [`AGENTS.md`](./AGENTS.md) to your project so AI agents know how to use agent-relay:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
curl -fsSL https://raw.githubusercontent.com/khaliqgant/agent-relay/main/AGENTS.md > AGENTS.md
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
This file contains instructions that AI agents can read to learn how to send/receive messages.
|
|
176
|
-
|
|
177
|
-
## Common Use Cases
|
|
178
|
-
|
|
179
|
-
### 1. Pair Programming: Code + Review
|
|
180
|
-
|
|
181
|
-
Two agents collaborating on a codebase - one writes code, the other reviews:
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
# Terminal 1: Start daemon
|
|
185
|
-
agent-relay start -f
|
|
186
|
-
|
|
187
|
-
# Terminal 2: Code writer agent
|
|
188
|
-
agent-relay wrap -n Coder "claude"
|
|
189
|
-
# Agent starts working, then sends:
|
|
190
|
-
# @relay:Reviewer I've implemented the auth module. Please review src/auth.ts
|
|
191
|
-
|
|
192
|
-
# Terminal 3: Reviewer agent
|
|
193
|
-
agent-relay wrap -n Reviewer "claude"
|
|
194
|
-
# Receives the message and reviews the code
|
|
195
|
-
# @relay:Coder Found an issue in line 45: missing input validation
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### 2. Multi-Agent Task Distribution
|
|
199
|
-
|
|
200
|
-
A coordinator distributing tasks to worker agents:
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
# Set up workers with file-based inboxes
|
|
204
|
-
mkdir -p /tmp/workers
|
|
205
|
-
agent-relay inbox-write -t Worker1 -f Coordinator -m "Process files in /data/batch1" -d /tmp/workers
|
|
206
|
-
agent-relay inbox-write -t Worker2 -f Coordinator -m "Process files in /data/batch2" -d /tmp/workers
|
|
207
|
-
|
|
208
|
-
# Each worker polls their inbox
|
|
209
|
-
agent-relay inbox-poll -n Worker1 -d /tmp/workers --clear
|
|
210
|
-
# Worker1 sees: Process files in /data/batch1
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### 3. Turn-Based Game (Tic-Tac-Toe)
|
|
214
|
-
|
|
215
|
-
Two agents playing a game with coordinated turns:
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
# Quick setup
|
|
219
|
-
agent-relay tictactoe-setup -d /tmp/ttt --player-x AgentX --player-o AgentO
|
|
220
|
-
|
|
221
|
-
# Terminal 1: Player X reads instructions
|
|
222
|
-
cat /tmp/ttt/AgentX/INSTRUCTIONS.md
|
|
223
|
-
|
|
224
|
-
# Terminal 2: Player O reads instructions
|
|
225
|
-
cat /tmp/ttt/AgentO/INSTRUCTIONS.md
|
|
226
|
-
|
|
227
|
-
# Agents communicate moves via inbox:
|
|
228
|
-
agent-relay inbox-write -t AgentO -f AgentX -m "MOVE: center" -d /tmp/ttt
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### 4. Live Collaboration Session
|
|
232
|
-
|
|
233
|
-
Multiple agents working together with real-time socket communication:
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
# Start daemon
|
|
237
|
-
agent-relay start -f
|
|
238
|
-
|
|
239
|
-
# Wrap multiple agents (3 terminals)
|
|
240
|
-
agent-relay wrap "claude" # -> GreenLake
|
|
241
|
-
agent-relay wrap "codex" # -> BlueRiver
|
|
242
|
-
agent-relay wrap "gemini-cli" # -> RedMountain
|
|
243
|
-
|
|
244
|
-
# Any agent can message others:
|
|
245
|
-
# @relay:BlueRiver Can you handle the database migration?
|
|
246
|
-
# @relay:* I'm starting on the frontend components
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
> **More examples:** See the [`examples/`](./examples) directory for complete working examples including setup scripts.
|
|
250
|
-
|
|
251
|
-
## Architecture
|
|
252
|
-
|
|
253
|
-
```
|
|
254
|
-
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
255
|
-
│ Claude Agent │ │ Codex Agent │ │ Gemini Agent │
|
|
256
|
-
│ (Terminal 1) │ │ (Terminal 2) │ │ (Terminal 3) │
|
|
257
|
-
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
|
|
258
|
-
│ │ │
|
|
259
|
-
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
|
|
260
|
-
│ Wrapper │ │ Wrapper │ │ Wrapper │
|
|
261
|
-
└────┬────┘ └────┬────┘ └────┬────┘
|
|
262
|
-
│ │ │
|
|
263
|
-
└───────────────────────┼───────────────────────┘
|
|
264
|
-
│
|
|
265
|
-
Unix Domain Socket
|
|
266
|
-
│
|
|
267
|
-
┌────────────┴────────────┐
|
|
268
|
-
│ agent-relay daemon │
|
|
269
|
-
│ - Message Router │
|
|
270
|
-
│ - Topic Subscriptions │
|
|
271
|
-
│ - Game Coordinator │
|
|
272
|
-
└─────────────────────────┘
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Agent Communication Syntax
|
|
276
|
-
|
|
277
|
-
Agents communicate using two formats embedded in their terminal output:
|
|
278
|
-
|
|
279
|
-
### Inline Format (single line)
|
|
280
|
-
```
|
|
281
|
-
@relay:BlueFox Your turn to play the 7 of hearts
|
|
282
|
-
@relay:* Broadcasting to all agents
|
|
283
|
-
@thinking:* I'm considering playing the Queen...
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Block Format (structured JSON)
|
|
287
|
-
```
|
|
288
|
-
[[RELAY]]
|
|
289
|
-
{
|
|
290
|
-
"to": "BlueFox",
|
|
291
|
-
"type": "action",
|
|
292
|
-
"body": "Playing my card",
|
|
293
|
-
"data": { "card": "7♥", "action": "play_card" }
|
|
294
|
-
}
|
|
295
|
-
[[/RELAY]]
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Escaping
|
|
299
|
-
To output literal `@relay:` without triggering the parser:
|
|
300
|
-
```
|
|
301
|
-
\@relay: This won't be parsed as a command
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## CLI Commands
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
# Start the relay daemon (foreground)
|
|
308
|
-
npx agent-relay start -f
|
|
309
|
-
|
|
310
|
-
# Start daemon with custom socket path
|
|
311
|
-
npx agent-relay start -s /tmp/my-relay.sock
|
|
312
|
-
|
|
313
|
-
# Stop the daemon
|
|
314
|
-
npx agent-relay stop
|
|
315
|
-
|
|
316
|
-
# Wrap an agent (name auto-generated)
|
|
317
|
-
npx agent-relay wrap "claude"
|
|
318
|
-
|
|
319
|
-
# Wrap an agent with explicit name
|
|
320
|
-
npx agent-relay wrap -n my-agent "claude"
|
|
321
|
-
|
|
322
|
-
# Wrap with legacy PTY mode (if needed)
|
|
323
|
-
npx agent-relay wrap --pty -n PlayerX "claude"
|
|
324
|
-
|
|
325
|
-
# Check status
|
|
326
|
-
npx agent-relay status
|
|
327
|
-
|
|
328
|
-
# Send a test message
|
|
329
|
-
npx agent-relay send -t recipient -m "Hello"
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Tmux Mode (Default)
|
|
333
|
-
|
|
334
|
-
By default, `agent-relay wrap` uses tmux mode for better stability in multi-agent coordination:
|
|
335
|
-
|
|
336
15
|
```bash
|
|
337
16
|
# Terminal 1: Start daemon
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
# Terminal 2: Start first agent (tmux mode is default)
|
|
341
|
-
agent-relay wrap -n PlayerX "claude"
|
|
342
|
-
|
|
343
|
-
# Terminal 3: Start second agent
|
|
344
|
-
agent-relay wrap -n PlayerO "codex"
|
|
345
|
-
```
|
|
17
|
+
relay up
|
|
346
18
|
|
|
347
|
-
|
|
348
|
-
-
|
|
349
|
-
- Attaches your terminal directly to the session
|
|
350
|
-
- Background polling captures output and parses `@relay:` commands
|
|
351
|
-
- Incoming messages are injected via `tmux send-keys`
|
|
19
|
+
# Terminal 2: Start an agent
|
|
20
|
+
relay -n Alice claude
|
|
352
21
|
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
- `--log-interval <ms>` to throttle debug output
|
|
356
|
-
- `--inject-idle-ms <ms>` to change the idle window before injecting messages (default 1500ms)
|
|
357
|
-
- `--inject-retry-ms <ms>` to adjust how often we re-check for an idle window (default 500ms)
|
|
358
|
-
|
|
359
|
-
**Legacy PTY mode:**
|
|
360
|
-
If you need the old direct PTY mode, use the `--pty` flag:
|
|
361
|
-
```bash
|
|
362
|
-
agent-relay wrap --pty -n MyAgent "claude"
|
|
22
|
+
# Terminal 3: Start another agent
|
|
23
|
+
relay -n Bob codex
|
|
363
24
|
```
|
|
364
25
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
By default, scroll wheel is sent to the application inside tmux. To scroll through history:
|
|
368
|
-
|
|
369
|
-
1. **Enter copy mode**: Press `Ctrl+b` then `[`
|
|
370
|
-
2. Scroll with arrow keys, Page Up/Down, or mouse wheel
|
|
371
|
-
3. Press `q` to exit copy mode
|
|
372
|
-
|
|
373
|
-
**Or enable mouse scrolling** (add to `~/.tmux.conf`):
|
|
374
|
-
```bash
|
|
375
|
-
set -g mouse on
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
Then reload: `tmux source-file ~/.tmux.conf`
|
|
379
|
-
|
|
380
|
-
**Compatibility:** Works with any CLI that accepts text input (Claude, Codex, Gemini, etc.)
|
|
26
|
+
Agents communicate by outputting `@relay:` patterns:
|
|
381
27
|
|
|
382
|
-
### File-Based Inbox Commands
|
|
383
|
-
|
|
384
|
-
For scenarios where PTY wrapping isn't ideal (scripts, automation, or agents that read files):
|
|
385
|
-
|
|
386
|
-
```bash
|
|
387
|
-
# Write to an agent's inbox (supports broadcast with *)
|
|
388
|
-
agent-relay inbox-write -t AgentName -f SenderName -m "Your message" -d /tmp/my-dir
|
|
389
|
-
agent-relay inbox-write -t "*" -f SenderName -m "Broadcast!" -d /tmp/my-dir
|
|
390
|
-
|
|
391
|
-
# Read an agent's inbox (non-blocking)
|
|
392
|
-
agent-relay inbox-read -n AgentName -d /tmp/my-dir
|
|
393
|
-
agent-relay inbox-read -n AgentName -d /tmp/my-dir --clear # Clear after reading
|
|
394
|
-
|
|
395
|
-
# Block until inbox has messages (useful for agent loops)
|
|
396
|
-
agent-relay inbox-poll -n AgentName -d /tmp/my-dir --clear
|
|
397
|
-
agent-relay inbox-poll -n AgentName -d /tmp/my-dir -t 30 # 30s timeout
|
|
398
|
-
|
|
399
|
-
# List all agents in a data directory
|
|
400
|
-
agent-relay inbox-agents -d /tmp/my-dir
|
|
401
28
|
```
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
```markdown
|
|
405
|
-
## Message from SenderName | 2024-01-15T10:30:00Z
|
|
406
|
-
Your message content here
|
|
29
|
+
@relay:Bob Hey, can you review my changes?
|
|
30
|
+
@relay:* Broadcasting to everyone
|
|
407
31
|
```
|
|
408
32
|
|
|
409
|
-
|
|
33
|
+
## CLI
|
|
410
34
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
35
|
+
| Command | Description |
|
|
36
|
+
|---------|-------------|
|
|
37
|
+
| `relay <cmd>` | Wrap agent with messaging |
|
|
38
|
+
| `relay -n Name <cmd>` | Wrap with specific name |
|
|
39
|
+
| `relay up` | Start daemon + dashboard |
|
|
40
|
+
| `relay down` | Stop daemon |
|
|
41
|
+
| `relay status` | Check if running |
|
|
42
|
+
| `relay read <id>` | Read truncated message |
|
|
416
43
|
|
|
417
|
-
|
|
418
|
-
agent-relay team-setup -f team-config.json -d /tmp/my-team
|
|
44
|
+
## How It Works
|
|
419
45
|
|
|
420
|
-
|
|
421
|
-
|
|
46
|
+
1. `relay up` starts a daemon that routes messages via Unix socket
|
|
47
|
+
2. `relay <cmd>` wraps your agent in tmux, parsing output for `@relay:` patterns
|
|
48
|
+
3. Messages are injected into recipient terminals in real-time
|
|
422
49
|
|
|
423
|
-
# List all agents in the team
|
|
424
|
-
agent-relay team-list -d /tmp/my-team
|
|
425
|
-
|
|
426
|
-
# Show team status with message counts
|
|
427
|
-
agent-relay team-status -d /tmp/my-team
|
|
428
|
-
|
|
429
|
-
# Send a message to teammate(s)
|
|
430
|
-
agent-relay team-send -n SenderName -t RecipientName -m "Hello" -d /tmp/my-team
|
|
431
|
-
agent-relay team-send -n SenderName -t "*" -m "Broadcast" -d /tmp/my-team
|
|
432
|
-
|
|
433
|
-
# Check your inbox (blocking wait)
|
|
434
|
-
agent-relay team-check -n AgentName -d /tmp/my-team
|
|
435
|
-
agent-relay team-check -n AgentName -d /tmp/my-team --no-wait # Non-blocking
|
|
436
|
-
|
|
437
|
-
# Join an existing team (self-register)
|
|
438
|
-
agent-relay team-join -n AgentName -r "Role" -d /tmp/my-team
|
|
439
|
-
|
|
440
|
-
# Start team with auto-spawning
|
|
441
|
-
agent-relay team-start -f team-config.json -d /tmp/my-team
|
|
442
50
|
```
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
51
|
+
┌─────────────┐ ┌─────────────┐
|
|
52
|
+
│ Agent Alice │ │ Agent Bob │
|
|
53
|
+
│ (tmux) │ │ (tmux) │
|
|
54
|
+
└──────┬──────┘ └──────┬──────┘
|
|
55
|
+
│ │
|
|
56
|
+
└─────────┬─────────┘
|
|
57
|
+
│
|
|
58
|
+
Unix Domain Socket
|
|
59
|
+
│
|
|
60
|
+
┌────────┴────────┐
|
|
61
|
+
│ relay daemon │
|
|
62
|
+
└─────────────────┘
|
|
453
63
|
```
|
|
454
64
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
For spawn-per-message agent management:
|
|
458
|
-
|
|
459
|
-
```bash
|
|
460
|
-
# Run the supervisor (foreground)
|
|
461
|
-
agent-relay supervisor -d /tmp/relay -v
|
|
65
|
+
## Agent Communication
|
|
462
66
|
|
|
463
|
-
|
|
464
|
-
agent-relay supervisor -d /tmp/relay --detach
|
|
67
|
+
### Send Message
|
|
465
68
|
|
|
466
|
-
# Check supervisor status
|
|
467
|
-
agent-relay supervisor-status
|
|
468
|
-
|
|
469
|
-
# Stop background supervisor
|
|
470
|
-
agent-relay supervisor-stop
|
|
471
|
-
|
|
472
|
-
# Register an agent with supervisor
|
|
473
|
-
agent-relay register -n AgentName -c "claude" -d /tmp/relay
|
|
474
69
|
```
|
|
475
|
-
|
|
476
|
-
### Dashboard
|
|
477
|
-
|
|
478
|
-
Web-based dashboard for monitoring agent communication:
|
|
479
|
-
|
|
480
|
-
```bash
|
|
481
|
-
# Start dashboard on default port (3888)
|
|
482
|
-
agent-relay dashboard -d /tmp/my-team
|
|
483
|
-
|
|
484
|
-
# Start on custom port
|
|
485
|
-
agent-relay dashboard -p 8080 -d /tmp/my-team
|
|
70
|
+
@relay:AgentName Your message here
|
|
486
71
|
```
|
|
487
72
|
|
|
488
|
-
###
|
|
73
|
+
### Broadcast
|
|
489
74
|
|
|
490
|
-
```bash
|
|
491
|
-
# Set up tic-tac-toe for two agents
|
|
492
|
-
agent-relay tictactoe-setup -d /tmp/ttt --player-x AgentX --player-o AgentO
|
|
493
75
|
```
|
|
494
|
-
|
|
495
|
-
## Playing Hearts
|
|
496
|
-
|
|
497
|
-
> **Note:** The Hearts game engine (`src/games/hearts.ts`) is implemented but not yet wired to the CLI. The code below shows the intended usage pattern once CLI integration is complete.
|
|
498
|
-
|
|
499
|
-
```bash
|
|
500
|
-
# Terminal 1: Start daemon
|
|
501
|
-
npx agent-relay start -f
|
|
502
|
-
|
|
503
|
-
# Terminal 2-5: Start four agent players (names auto-generated)
|
|
504
|
-
npx agent-relay wrap "claude" # -> GoldenEagle
|
|
505
|
-
npx agent-relay wrap "codex" # -> SilverWolf
|
|
506
|
-
npx agent-relay wrap "gemini-cli" # -> CrystalLake
|
|
507
|
-
npx agent-relay wrap "claude" # -> BronzeBear
|
|
508
|
-
|
|
509
|
-
# Game coordinator integration coming soon
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
Each agent receives game state and prompts:
|
|
513
|
-
```json
|
|
514
|
-
{
|
|
515
|
-
"kind": "your_turn",
|
|
516
|
-
"hand": ["2♣", "7♥", "K♠", ...],
|
|
517
|
-
"valid_plays": ["2♣"],
|
|
518
|
-
"current_trick": [],
|
|
519
|
-
"hearts_broken": false
|
|
520
|
-
}
|
|
76
|
+
@relay:* Message to all agents
|
|
521
77
|
```
|
|
522
78
|
|
|
523
|
-
|
|
524
|
-
```
|
|
525
|
-
[[RELAY]]
|
|
526
|
-
{"to": "hearts-coordinator", "type": "action", "data": {"action": "play_card", "card": {"suit": "clubs", "rank": "2"}}}
|
|
527
|
-
[[/RELAY]]
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
|
-
<details>
|
|
533
|
-
<summary><h2>For Agents (Click to expand)</h2></summary>
|
|
534
|
-
|
|
535
|
-
> **This section is specifically for AI agents setting up agent-relay autonomously.**
|
|
536
|
-
|
|
537
|
-
## Autonomous Setup Instructions
|
|
538
|
-
|
|
539
|
-
If you are an AI agent and need to set up agent-relay for inter-agent communication, follow these steps:
|
|
540
|
-
|
|
541
|
-
### Quick Setup (One Command)
|
|
79
|
+
### Receive
|
|
542
80
|
|
|
543
|
-
|
|
544
|
-
# Install and start daemon in one command
|
|
545
|
-
AGENT_RELAY_START=true AGENT_RELAY_QUIET=true \
|
|
546
|
-
curl -fsSL https://raw.githubusercontent.com/khaliqgant/agent-relay/main/install.sh | bash
|
|
547
|
-
```
|
|
81
|
+
Messages appear as:
|
|
548
82
|
|
|
549
|
-
The installer outputs machine-readable variables:
|
|
550
83
|
```
|
|
551
|
-
|
|
552
|
-
AGENT_RELAY_INSTALL_DIR=/home/user/.agent-relay
|
|
553
|
-
AGENT_RELAY_BIN_PATH=/home/user/.local/bin/agent-relay
|
|
554
|
-
AGENT_RELAY_DAEMON_PID=12345
|
|
84
|
+
Relay message from Alice [abc123]: Your message here
|
|
555
85
|
```
|
|
556
86
|
|
|
557
|
-
###
|
|
87
|
+
### Truncated Messages
|
|
558
88
|
|
|
559
|
-
|
|
89
|
+
Long messages are truncated. Use the ID to read full content:
|
|
560
90
|
|
|
561
91
|
```bash
|
|
562
|
-
|
|
563
|
-
node --version
|
|
564
|
-
|
|
565
|
-
# Verify npm
|
|
566
|
-
npm --version
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
#### 2. Clone and Install
|
|
570
|
-
|
|
571
|
-
```bash
|
|
572
|
-
# If not already in the project directory
|
|
573
|
-
cd /path/to/agent-to-agent-communication
|
|
574
|
-
|
|
575
|
-
# Install dependencies
|
|
576
|
-
npm install
|
|
577
|
-
|
|
578
|
-
# Build the project
|
|
579
|
-
npm run build
|
|
92
|
+
relay read abc123
|
|
580
93
|
```
|
|
581
94
|
|
|
582
|
-
|
|
95
|
+
## Dashboard
|
|
583
96
|
|
|
584
|
-
|
|
585
|
-
# Start in background (recommended for automation)
|
|
586
|
-
nohup npx agent-relay start -f > /tmp/agent-relay.log 2>&1 &
|
|
587
|
-
|
|
588
|
-
# Or start in foreground if you want to monitor
|
|
589
|
-
npx agent-relay start -f
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
#### 4. Verify Daemon is Running
|
|
593
|
-
|
|
594
|
-
```bash
|
|
595
|
-
# Check status
|
|
596
|
-
npx agent-relay status
|
|
597
|
-
|
|
598
|
-
# Should output: Status: RUNNING
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
### 5. Connect as an Agent
|
|
602
|
-
|
|
603
|
-
If you're wrapping another agent (name auto-generated):
|
|
604
|
-
```bash
|
|
605
|
-
npx agent-relay wrap "claude"
|
|
606
|
-
# Your agent name will be displayed, e.g., "Agent name: SwiftFalcon"
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
Or specify your own name:
|
|
610
|
-
```bash
|
|
611
|
-
npx agent-relay wrap -n MyAgent "claude"
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
If you're connecting programmatically:
|
|
615
|
-
```typescript
|
|
616
|
-
import { RelayClient, generateAgentName } from 'agent-relay';
|
|
617
|
-
|
|
618
|
-
// Auto-generate a name
|
|
619
|
-
const agentName = generateAgentName(); // e.g., "BraveOtter"
|
|
620
|
-
|
|
621
|
-
const client = new RelayClient({
|
|
622
|
-
agentName,
|
|
623
|
-
socketPath: '/tmp/agent-relay.sock',
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
await client.connect();
|
|
627
|
-
|
|
628
|
-
// Send messages
|
|
629
|
-
client.sendMessage('other-agent', 'Hello!', 'message');
|
|
630
|
-
|
|
631
|
-
// Listen for messages
|
|
632
|
-
client.onMessage = (from, payload) => {
|
|
633
|
-
console.log(`Message from ${from}: ${payload.body}`);
|
|
634
|
-
};
|
|
635
|
-
```
|
|
636
|
-
|
|
637
|
-
## Communication Protocol for Agents
|
|
638
|
-
|
|
639
|
-
### Sending Messages
|
|
640
|
-
|
|
641
|
-
Use these patterns in your terminal output:
|
|
642
|
-
|
|
643
|
-
**Direct message to another agent:**
|
|
644
|
-
```
|
|
645
|
-
@relay:SwiftFalcon Your message here
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
**Broadcast to all agents:**
|
|
649
|
-
```
|
|
650
|
-
@relay:* Message for everyone
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
**Structured action (for games/coordination):**
|
|
654
|
-
```
|
|
655
|
-
[[RELAY]]
|
|
656
|
-
{"to": "*", "type": "action", "body": "description", "data": {"key": "value"}}
|
|
657
|
-
[[/RELAY]]
|
|
658
|
-
```
|
|
659
|
-
|
|
660
|
-
### Message Types
|
|
661
|
-
|
|
662
|
-
| Type | Use Case |
|
|
663
|
-
|------|----------|
|
|
664
|
-
| `message` | General communication |
|
|
665
|
-
| `action` | Game moves, commands |
|
|
666
|
-
| `state` | State updates, game state |
|
|
667
|
-
| `thinking` | Share reasoning (optional) |
|
|
668
|
-
|
|
669
|
-
### Receiving Messages
|
|
670
|
-
|
|
671
|
-
Messages from other agents appear in your terminal as:
|
|
672
|
-
```
|
|
673
|
-
[MSG] from SwiftFalcon: Their message
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
Or for thinking:
|
|
677
|
-
```
|
|
678
|
-
[THINKING] from SwiftFalcon: Their reasoning
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
## Coordination Patterns
|
|
682
|
-
|
|
683
|
-
### Turn-Based Games
|
|
684
|
-
|
|
685
|
-
1. Subscribe to game topic: `client.subscribe('hearts')`
|
|
686
|
-
2. Wait for `your_turn` state message
|
|
687
|
-
3. Respond with action: `@relay:coordinator {"action": "play_card", ...}`
|
|
688
|
-
4. Wait for next state update
|
|
689
|
-
|
|
690
|
-
### Collaborative Tasks
|
|
691
|
-
|
|
692
|
-
1. Broadcast availability: `@relay:* Ready to collaborate`
|
|
693
|
-
2. Direct message coordinator: `@relay:coordinator Taking task X`
|
|
694
|
-
3. Share progress: `@relay:* Completed task X`
|
|
695
|
-
|
|
696
|
-
### Error Handling
|
|
697
|
-
|
|
698
|
-
If connection fails:
|
|
699
|
-
1. Check daemon is running: `npx agent-relay status`
|
|
700
|
-
2. Check socket exists: `ls -la /tmp/agent-relay.sock`
|
|
701
|
-
3. Restart daemon if needed: `npx agent-relay stop && npx agent-relay start -f`
|
|
702
|
-
|
|
703
|
-
## Example: Agent Self-Registration
|
|
704
|
-
|
|
705
|
-
```typescript
|
|
706
|
-
import { RelayClient, generateAgentName } from 'agent-relay';
|
|
707
|
-
|
|
708
|
-
async function setupAgent() {
|
|
709
|
-
const name = generateAgentName();
|
|
710
|
-
const client = new RelayClient({ agentName: name });
|
|
711
|
-
|
|
712
|
-
try {
|
|
713
|
-
await client.connect();
|
|
714
|
-
console.log(`Connected as ${name}`);
|
|
715
|
-
|
|
716
|
-
// Announce presence
|
|
717
|
-
client.broadcast(`${name} is online`, 'message');
|
|
718
|
-
|
|
719
|
-
// Handle incoming messages
|
|
720
|
-
client.onMessage = (from, payload) => {
|
|
721
|
-
if (payload.body.includes('ping')) {
|
|
722
|
-
client.sendMessage(from, 'pong', 'message');
|
|
723
|
-
}
|
|
724
|
-
};
|
|
725
|
-
|
|
726
|
-
return client;
|
|
727
|
-
} catch (err) {
|
|
728
|
-
console.error('Failed to connect:', err);
|
|
729
|
-
throw err;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
```
|
|
97
|
+
`relay up` starts a web dashboard at http://localhost:3888
|
|
733
98
|
|
|
734
99
|
## Troubleshooting
|
|
735
100
|
|
|
736
101
|
| Issue | Solution |
|
|
737
102
|
|-------|----------|
|
|
738
|
-
|
|
|
739
|
-
|
|
|
740
|
-
|
|
|
741
|
-
| High latency | Check system load, restart daemon |
|
|
742
|
-
|
|
743
|
-
## Socket Path
|
|
744
|
-
|
|
745
|
-
Default: `/tmp/agent-relay.sock`
|
|
746
|
-
|
|
747
|
-
Custom: Use `-s` flag or `socketPath` config option.
|
|
748
|
-
|
|
749
|
-
</details>
|
|
750
|
-
|
|
751
|
-
---
|
|
752
|
-
|
|
753
|
-
## Protocol Specification
|
|
754
|
-
|
|
755
|
-
See [PROTOCOL.md](./PROTOCOL.md) for the complete wire protocol specification including:
|
|
756
|
-
- Frame format (4-byte length prefix + JSON)
|
|
757
|
-
- Message types (HELLO, SEND, DELIVER, ACK, etc.)
|
|
758
|
-
- Handshake flow
|
|
759
|
-
- Reconnection and state sync (spec defined, implementation pending)
|
|
760
|
-
- Backpressure handling (spec defined, implementation pending)
|
|
761
|
-
|
|
762
|
-
**Current implementation status:** The daemon provides best-effort message delivery with per-stream ordering. The protocol supports ACKs, retries, and RESUME/SYNC for reconnection, but these reliability features are optional and not yet fully wired in the current implementation.
|
|
763
|
-
|
|
764
|
-
## Acknowledgments
|
|
765
|
-
|
|
766
|
-
This project stands on the shoulders of giants:
|
|
767
|
-
|
|
768
|
-
- **[mcp_agent_mail](https://github.com/Dicklesworthstone/mcp_agent_mail)** by Jeff Emanuel - Pioneered many patterns we adopted, including auto-generated AdjectiveNoun names, and demonstrated the power of persistent agent communication.
|
|
769
|
-
- **[swarm-tools](https://github.com/joelhooks/swarm-tools)** by Joel Hooks - Showed how swarm coordination patterns can enable powerful multi-agent workflows.
|
|
770
|
-
|
|
771
|
-
If MCP integration or file-based persistence fits your use case better, we highly recommend checking out these projects.
|
|
103
|
+
| Messages not sending | `relay status` to check daemon |
|
|
104
|
+
| Socket not found | `relay up` to start daemon |
|
|
105
|
+
| Truncated message | `relay read <id>` |
|
|
772
106
|
|
|
773
107
|
## Development
|
|
774
108
|
|
|
775
109
|
```bash
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
# Watch mode
|
|
780
|
-
npm run dev
|
|
781
|
-
|
|
782
|
-
# Run tests
|
|
783
|
-
npm test
|
|
784
|
-
|
|
785
|
-
# Lint
|
|
786
|
-
npm run lint
|
|
110
|
+
git clone https://github.com/khaliqgant/agent-relay.git
|
|
111
|
+
cd agent-relay
|
|
112
|
+
npm install && npm run build
|
|
787
113
|
```
|
|
788
114
|
|
|
789
115
|
## License
|