remote-pi 0.4.1 → 0.4.3

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.
@@ -1,239 +0,0 @@
1
- ---
2
- name: agent-network
3
- description: Use when the remote-pi mesh tools (`list_peers`, `agent_send`, `get_messages`) are available — you are a Claude agent connected to the remote-pi agent mesh over a local broker. This skill teaches how to discover who's online (`list_peers`), how to send messages with delivery status (`agent_send` + ACK), how incoming messages arrive (`get_messages` at the start of each turn, plus channel push), how to reply (echo `re`), and how cross-PC addressing works (`<pc_label>:<peer>`).
4
- ---
5
-
6
- # Agent Network (Claude ↔ remote-pi mesh)
7
-
8
- You are connected to the **remote-pi agent mesh** through an MCP server.
9
- Other agents — other Claude sessions, Pi coding agents on this machine, and
10
- agents on the Owner's other PCs (via the relay) — can send you messages, and
11
- you can send messages to them.
12
-
13
- Read this to the end before acting. The protocol is **event-driven**, not
14
- request/reply. Getting the receive model wrong leaves coordination broken.
15
-
16
- You have exactly three tools: `list_peers`, `agent_send`, `get_messages`.
17
-
18
- ---
19
-
20
- ## The most important rule: check your inbox every turn
21
-
22
- Incoming messages are buffered for you. **At the start of every turn, call
23
- `get_messages`** to drain and read anything other agents sent you:
24
-
25
- ```
26
- get_messages()
27
- → "[2026-05-30T12:00:01Z] from=backend re=<your-id>
28
- id=<msg-id>
29
- { "shape": { "sub": "string", "exp": "number" } }"
30
- ```
31
-
32
- - Returns all pending messages and clears the buffer (call once per turn).
33
- - Returns `(no messages)` when nothing is waiting — that's normal, keep working.
34
- - A channel push may also surface a message mid-session (a `📨 Message from …`
35
- notification). When it does, still call `get_messages` to get the full,
36
- structured payload (`from`, `id`, `re`, `body`) — the push is just a nudge.
37
-
38
- **If a message arrived, someone wanted your attention. Don't ignore it.**
39
- You only ever receive messages addressed to you — the broker filters before
40
- delivery.
41
-
42
- ---
43
-
44
- ## First thing in a new session: `list_peers`
45
-
46
- Before sending anything, find out who's actually online:
47
-
48
- ```
49
- list_peers()
50
- → backend
51
- frontend
52
- casa:agent-1
53
- trab:worker
54
- ```
55
-
56
- Synchronous (resolves in milliseconds — not another agent's turn). Use it:
57
-
58
- - At the start of a session, to see what mesh you're in
59
- - Before any `agent_send` whose target name is uncertain
60
- - After a while, to refresh (peers join/leave over time)
61
-
62
- **Entry shape:**
63
- - `backend` → local peer (this machine, same broker)
64
- - `casa:agent-1` → cross-PC peer on the PC labeled `casa` (the Owner's other
65
- machine, reached through the relay)
66
-
67
- You are excluded from the result — no need to filter yourself out.
68
-
69
- ---
70
-
71
- ## Anatomy of a message (envelope)
72
-
73
- `get_messages` shows you, per message: `from`, `id`, `re`, and `body`.
74
-
75
- | Field | Meaning |
76
- |---|---|
77
- | `from` | Who sent it. Use this verbatim as your `to` when replying. |
78
- | `id` | Unique id of this message. Echo it as `re` when you reply. |
79
- | `re` | If set, this message is itself a REPLY to an earlier `id` of yours. |
80
- | `body` | Free-form content — string or JSON, sender's choice. |
81
-
82
- ---
83
-
84
- ## Sending: `agent_send` returns an ACK status
85
-
86
- `agent_send({ to, body, re? })` is how you talk to peers. Every **unicast**
87
- call returns a status telling you what happened at the recipient. **Always
88
- inspect the status — it dictates what to do next.**
89
-
90
- | Status | Means | What you do |
91
- |---|---|---|
92
- | `received` | Peer was idle; broker delivered the envelope; peer will process it on its next turn. | Move on. Any reply arrives later — check `get_messages` on future turns. |
93
- | `busy` | Peer is mid-turn — envelope **dropped**. | Retry 2× with backoff (~2s, ~5s). Still busy → abandon or escalate. You own the retry. |
94
- | `denied` | Peer explicitly refused. | Do NOT retry. Report to the user. |
95
- | `timeout` | No ACK (~5s). Transport error — broker down, or peer vanished. | Treat as transient. Retry once after ~10s, then escalate. |
96
-
97
- For `to: "broadcast"`, there's no single ACK — it's fire-and-forget
98
- ("Broadcast sent").
99
-
100
- **Replies bypass the busy gate.** A message with `re=<some-id>` (an answer to
101
- something the recipient asked) is always delivered — it resolves their pending
102
- state instead of starting a new turn. So if you fan out questions to several
103
- peers, every reply reaches you even while they're busy.
104
-
105
- ---
106
-
107
- ## Receiving: replies arrive on a later turn
108
-
109
- You **do not block** waiting for a reply. The model is event-driven:
110
-
111
- 1. You call `agent_send` → status `received`.
112
- 2. Your turn continues / ends.
113
- 3. **Later** the peer finishes its own work and sends a reply.
114
- 4. The reply lands in your inbox. You see it the next time you call
115
- `get_messages`, with `re` set to the `id` you originally sent.
116
-
117
- No wait/sleep/poll-loop. Just call `get_messages` at the start of your turns.
118
-
119
- ### Walk-through
120
-
121
- ```
122
- agent_send({ to: "backend", body: { q: "what's the JWT shape?" } })
123
- → Delivered to backend # status received; remember the message id
124
- ```
125
-
126
- Your turn continues. A turn or two later:
127
-
128
- ```
129
- get_messages()
130
- → "[…] from=backend re=<your-id>
131
- id=<new-id>
132
- { "shape": { "sub": "string", "exp": "number", "roles": ["string"] } }"
133
- ```
134
-
135
- You correlate by `re` — it matches the send you made. Now you have your answer.
136
-
137
- ---
138
-
139
- ## Replying to a message
140
-
141
- When you receive (via `get_messages`):
142
-
143
- ```
144
- from=orchestrator id=abc-uuid re=(none)
145
- { "task": "Implement POST /auth/login" }
146
- ```
147
-
148
- Reply with `re` set to that `id`, and `to` set to the sender's `from`:
149
-
150
- ```
151
- agent_send({
152
- to: "orchestrator",
153
- body: { status: "done", files_changed: [...] },
154
- re: "abc-uuid"
155
- })
156
- ```
157
-
158
- Without `re`, the sender gets your message but can't match it to the
159
- question — coordination drifts. **Always echo `re` on a reply.**
160
-
161
- ---
162
-
163
- ## Asking multiple peers at once
164
-
165
- Fire multiple `agent_send` in one turn — each returns its own ACK. Replies
166
- arrive on future turns as peers finish.
167
-
168
- ```
169
- agent_send({ to: "backend", body: { q: "JWT shape?" } }) // received
170
- agent_send({ to: "frontend", body: { q: "theme tokens?" } }) // received
171
- agent_send({ to: "infra", body: { q: "ETA for Y?" } }) // busy — retry
172
- ```
173
-
174
- Track which `id` maps to which question. Don't assume replies arrive in send
175
- order — use `re` to identify what each reply answers.
176
-
177
- ---
178
-
179
- ## Cross-PC addressing (`<pc_label>:<peer>`)
180
-
181
- When the Owner has paired multiple PCs, remote peers appear with a prefix:
182
-
183
- ```
184
- list_peers() → backend frontend casa:agent-1 trab:worker
185
- ```
186
-
187
- Send to a remote peer with the prefixed name verbatim:
188
-
189
- ```
190
- agent_send({ to: "casa:agent-1", body: { ... } })
191
- ```
192
-
193
- The relay routes it across the mesh; `received | busy | denied | timeout`
194
- semantics are identical to local. When you **reply** to a cross-PC message,
195
- use the sender's `from` verbatim (it already carries the prefix) as your `to`.
196
- You never prefix your own name — the broker handles that.
197
-
198
- Cross-PC failure notes:
199
- - `denied` → the remote broker has no peer by that name (left, or stale cache
200
- → call `list_peers` again).
201
- - `timeout` → the other PC is offline or the relay is unreachable.
202
-
203
- ---
204
-
205
- ## Broadcast and multicast
206
-
207
- - `to: "broadcast"` → every other peer. Use for announcements
208
- ("wave 2 started"), never for questions (replies would be uncorrelated).
209
- - Broadcast skips ACK — you don't know who received it. For delivery
210
- confirmation, use individual unicast sends.
211
-
212
- ---
213
-
214
- ## When in doubt
215
-
216
- - **Received a task you don't understand** → reply with `body.status:"error"`,
217
- echoing the original `id` in `re`. Don't go silent.
218
- - **Received a `re` you never sent** → late reply to something already wrapped
219
- up. Ignore. Don't reply to a reply.
220
- - **No messages ever arrive** → normal. You only receive when addressed. Keep
221
- working; just keep calling `get_messages` each turn.
222
- - **`timeout` on send** → broker restarting (failover) or peer vanished. Retry
223
- once after ~10s, then escalate.
224
-
225
- ---
226
-
227
- ## Single-page summary
228
-
229
- 1. **Every turn**: `get_messages()` first — drain your inbox.
230
- 2. **Discover**: `list_peers()` → locals + `<pc>:<peer>` cross-PC. Synchronous.
231
- 3. **Send**: `agent_send({to, body, re?})` → inspect the status.
232
- 4. **Unicast status**: `received | busy | denied | timeout`. Retry on `busy`
233
- (backoff); abandon on `denied`; investigate on `timeout`.
234
- 5. **Broadcast**: fire-and-forget, no ACK.
235
- 6. **Reply**: set `re` to their `id`, `to` to their `from` (prefix and all).
236
- 7. You never receive your own messages. The broker does not queue — if a peer
237
- is busy, your message is dropped; you own the retry.
238
-
239
- Re-read when in doubt.