agent-comms 1.4.1 → 1.4.2
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/.claude-plugin/plugin.json +1 -1
- package/README.md +71 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Comms
|
|
2
2
|
|
|
3
|
-
Cross-harness communication
|
|
3
|
+
Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.
|
|
4
4
|
|
|
5
5
|
## Why
|
|
6
6
|
|
|
@@ -14,24 +14,48 @@ The project began as a filesystem-based bus (`~/.agents/bus/`), where agents rea
|
|
|
14
14
|
|
|
15
15
|
Each bridge instance is a peer in a TCP mesh on localhost. The first instance to start becomes the **coordinator** (port 19876). Subsequent instances connect to the coordinator, receive the peer list, and establish direct data connections with every other peer.
|
|
16
16
|
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
```mermaid
|
|
18
|
+
graph LR
|
|
19
|
+
subgraph Agent A ["Agent A (pi)"]
|
|
20
|
+
A_LLM["LLM"]
|
|
21
|
+
A_Bridge["pi bridge"]
|
|
22
|
+
end
|
|
23
|
+
subgraph Agent B ["Agent B (Claude Code)"]
|
|
24
|
+
B_Bridge["Claude bridge"]
|
|
25
|
+
B_LLM["LLM"]
|
|
26
|
+
end
|
|
27
|
+
A_LLM -- "agent_comms(send, ...)" --> A_Bridge
|
|
28
|
+
A_Bridge -- "TCP localhost" --> B_Bridge
|
|
29
|
+
B_Bridge -- "channel notification" --> B_LLM
|
|
28
30
|
```
|
|
29
31
|
|
|
30
32
|
All state is held in memory and synchronised between peers. Delivery events are pushed directly over TCP: no polling, no filesystem, no daemon process.
|
|
31
33
|
|
|
32
34
|
### Coordinator pattern
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
```mermaid
|
|
37
|
+
sequenceDiagram
|
|
38
|
+
participant P1 as Peer 1 (first to start)
|
|
39
|
+
participant P2 as Peer 2
|
|
40
|
+
participant P3 as Peer 3
|
|
41
|
+
P1->>P1: binds port 19876 → becomes coordinator
|
|
42
|
+
P2->>P1: connect to 19876
|
|
43
|
+
P1-->>P2: peer list [P1]
|
|
44
|
+
P2->>P1: establish data connection
|
|
45
|
+
P3->>P1: connect to 19876
|
|
46
|
+
P1-->>P3: peer list [P1, P2]
|
|
47
|
+
P3->>P1: establish data connection
|
|
48
|
+
P3->>P2: establish data connection
|
|
49
|
+
Note over P1,P3: All peers now connected directly
|
|
50
|
+
rect rgb(255, 230, 230)
|
|
51
|
+
Note over P1: Coordinator crashes
|
|
52
|
+
P2->>P2: race to bind 19876
|
|
53
|
+
P3->>P3: race to bind 19876
|
|
54
|
+
Note over P2,P3: ~100ms recovery, longest-running wins
|
|
55
|
+
end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- **Well-known port** 19876 on localhost — the only agreed-upon constant
|
|
35
59
|
- The first instance to bind it becomes coordinator
|
|
36
60
|
- Coordinator handles introductions only; it is not a router
|
|
37
61
|
- On graceful shutdown, coordinator hands over to the longest-running peer
|
|
@@ -188,6 +212,22 @@ agent_comms({ action: "update", visibility: "hidden" })
|
|
|
188
212
|
|
|
189
213
|
When an agent joins a room, it receives a `room_members` delivery event listing all current members with their status. Existing members receive `member_joined` / `member_left` notifications (excluding the joining/leaving agent).
|
|
190
214
|
|
|
215
|
+
```mermaid
|
|
216
|
+
sequenceDiagram
|
|
217
|
+
participant A as Agent A (in room)
|
|
218
|
+
participant Mesh
|
|
219
|
+
participant B as Agent B (joining)
|
|
220
|
+
B->>Mesh: joinRoom("code-review")
|
|
221
|
+
Mesh-->>B: room_members { [{ id: A, status: active }] }
|
|
222
|
+
Mesh-->>A: member_joined { agent: B }
|
|
223
|
+
Note over A: A knows B arrived, B knows who is already there
|
|
224
|
+
rect rgb(255, 245, 230)
|
|
225
|
+
Note over B: B goes idle
|
|
226
|
+
B->>Mesh: update(status: idle)
|
|
227
|
+
Mesh-->>A: member_status { agent: B, status: idle }
|
|
228
|
+
end
|
|
229
|
+
```
|
|
230
|
+
|
|
191
231
|
When an agent's status changes (active / idle / busy / offline), all rooms it belongs to receive a `member_status` notification. This covers:
|
|
192
232
|
|
|
193
233
|
- Explicit `update` action
|
|
@@ -199,6 +239,24 @@ When an agent's status changes (active / idle / busy / offline), all rooms it be
|
|
|
199
239
|
|
|
200
240
|
Messages carry a `readBy` field tracking which agents have consumed them. Status events are emitted to the sender automatically — no explicit action needed.
|
|
201
241
|
|
|
242
|
+
```mermaid
|
|
243
|
+
sequenceDiagram
|
|
244
|
+
participant A as Agent A (sender)
|
|
245
|
+
participant Mesh
|
|
246
|
+
participant B as Agent B (recipient)
|
|
247
|
+
A->>Mesh: send("Hello")
|
|
248
|
+
Mesh->>B: queue room_message
|
|
249
|
+
Mesh-->>A: delivery_status { delivered }
|
|
250
|
+
alt Push bridge (pi, Claude Code)
|
|
251
|
+
Mesh->>B: onDelivery fires
|
|
252
|
+
else Drain bridge (MCP, Codex, OpenCode)
|
|
253
|
+
B->>Mesh: drainDelivery()
|
|
254
|
+
end
|
|
255
|
+
Mesh->>Mesh: markRead(msgId, B)
|
|
256
|
+
Mesh-->>A: delivery_status { read }
|
|
257
|
+
Mesh->>Mesh: broadcast message_read patch
|
|
258
|
+
```
|
|
259
|
+
|
|
202
260
|
| Moment | Sender receives |
|
|
203
261
|
|--------|-----------------|
|
|
204
262
|
| Message queued for recipient | `delivery_status { status: "delivered" }` |
|
package/package.json
CHANGED