@perkos/perkos-a2a 0.3.5 → 0.4.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 +76 -574
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +71 -7
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +12 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +85 -20
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/openclaw.plugin.json +17 -30
- package/package.json +1 -1
- package/skills/perkos-a2a/SKILL.md +68 -0
package/README.md
CHANGED
|
@@ -1,620 +1,122 @@
|
|
|
1
|
-
# @perkos/a2a
|
|
2
|
-
|
|
3
|
-
Agent-to-Agent (A2A) protocol communication plugin for [OpenClaw](https://github.com/openclaw/openclaw).
|
|
4
|
-
|
|
5
|
-
Implements Google's [A2A Protocol](https://github.com/a2aproject/A2A) (v0.3.0) to enable OpenClaw agents to discover each other, send tasks, and collaborate autonomously.
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **Agent Card Discovery** — Each agent publishes identity and skills at `/.well-known/agent-card.json`
|
|
10
|
-
- **JSON-RPC 2.0** — Standard A2A protocol methods: `message/send`, `tasks/get`, `tasks/list`, `tasks/cancel`
|
|
11
|
-
- **OpenClaw Tools** — `a2a_discover`, `a2a_send_task`, `a2a_task_status` available to the LLM
|
|
12
|
-
- **CLI Commands** — `openclaw a2a status`, `openclaw a2a discover`, `openclaw a2a send`
|
|
13
|
-
- **Peer Discovery** — Automatic discovery of online agents in the network
|
|
14
|
-
- **Background Service** — A2A HTTP server runs alongside the OpenClaw gateway
|
|
15
|
-
|
|
16
|
-
## Architecture
|
|
17
|
-
|
|
18
|
-
### System Overview
|
|
19
|
-
|
|
20
|
-
```mermaid
|
|
21
|
-
graph TB
|
|
22
|
-
subgraph Internet
|
|
23
|
-
TG[Telegram]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
subgraph Docker Network - council
|
|
27
|
-
subgraph Mimir Container
|
|
28
|
-
M_OC[OpenClaw Gateway :3000]
|
|
29
|
-
M_A2A["@perkos/a2a Plugin :5000"]
|
|
30
|
-
M_OC --- M_A2A
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
subgraph Tyr Container
|
|
34
|
-
T_OC[OpenClaw Gateway :3000]
|
|
35
|
-
T_A2A["@perkos/a2a Plugin :5000"]
|
|
36
|
-
T_OC --- T_A2A
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
subgraph Bragi Container
|
|
40
|
-
B_OC[OpenClaw Gateway :3000]
|
|
41
|
-
B_A2A["@perkos/a2a Plugin :5000"]
|
|
42
|
-
B_OC --- B_A2A
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
subgraph Idunn Container
|
|
46
|
-
I_OC[OpenClaw Gateway :3000]
|
|
47
|
-
I_A2A["@perkos/a2a Plugin :5000"]
|
|
48
|
-
I_OC --- I_A2A
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
TG <--> M_OC
|
|
53
|
-
TG <--> T_OC
|
|
54
|
-
TG <--> B_OC
|
|
55
|
-
TG <--> I_OC
|
|
56
|
-
|
|
57
|
-
M_A2A <-->|A2A JSON-RPC| T_A2A
|
|
58
|
-
M_A2A <-->|A2A JSON-RPC| B_A2A
|
|
59
|
-
M_A2A <-->|A2A JSON-RPC| I_A2A
|
|
60
|
-
T_A2A <-->|A2A JSON-RPC| B_A2A
|
|
61
|
-
T_A2A <-->|A2A JSON-RPC| I_A2A
|
|
62
|
-
B_A2A <-->|A2A JSON-RPC| I_A2A
|
|
63
|
-
|
|
64
|
-
style M_OC fill:#eb1b69,color:#fff
|
|
65
|
-
style T_OC fill:#eb1b69,color:#fff
|
|
66
|
-
style B_OC fill:#eb1b69,color:#fff
|
|
67
|
-
style I_OC fill:#eb1b69,color:#fff
|
|
68
|
-
style M_A2A fill:#8e2051,color:#fff
|
|
69
|
-
style T_A2A fill:#8e2051,color:#fff
|
|
70
|
-
style B_A2A fill:#8e2051,color:#fff
|
|
71
|
-
style I_A2A fill:#8e2051,color:#fff
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Plugin Architecture
|
|
75
|
-
|
|
76
|
-
```mermaid
|
|
77
|
-
graph LR
|
|
78
|
-
subgraph OpenClaw Gateway
|
|
79
|
-
LLM[LLM Agent]
|
|
80
|
-
Tools[Tool Registry]
|
|
81
|
-
Session[Session Manager]
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
subgraph "@perkos/a2a Plugin"
|
|
85
|
-
Service[Background Service]
|
|
86
|
-
Express[Express HTTP Server]
|
|
87
|
-
AgentCard[Agent Card Provider]
|
|
88
|
-
TaskStore[In-Memory Task Store]
|
|
89
|
-
Client[A2A Client]
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
subgraph Endpoints
|
|
93
|
-
WK["/.well-known/agent-card.json"]
|
|
94
|
-
RPC["/a2a/jsonrpc"]
|
|
95
|
-
Health["/health"]
|
|
96
|
-
Peers["/a2a/peers"]
|
|
97
|
-
Send["/a2a/send"]
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
LLM --> Tools
|
|
101
|
-
Tools -->|a2a_discover| Client
|
|
102
|
-
Tools -->|a2a_send_task| Client
|
|
103
|
-
Tools -->|a2a_task_status| Client
|
|
104
|
-
|
|
105
|
-
Service --> Express
|
|
106
|
-
Express --> WK
|
|
107
|
-
Express --> RPC
|
|
108
|
-
Express --> Health
|
|
109
|
-
Express --> Peers
|
|
110
|
-
Express --> Send
|
|
111
|
-
|
|
112
|
-
RPC --> TaskStore
|
|
113
|
-
WK --> AgentCard
|
|
114
|
-
Client -->|HTTP POST| RPC
|
|
115
|
-
|
|
116
|
-
style LLM fill:#eb1b69,color:#fff
|
|
117
|
-
style Service fill:#8e2051,color:#fff
|
|
118
|
-
style Express fill:#76437b,color:#fff
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Protocol Specification
|
|
122
|
-
|
|
123
|
-
### A2A Protocol Layers
|
|
124
|
-
|
|
125
|
-
This plugin implements the three layers of the A2A Protocol Specification:
|
|
126
|
-
|
|
127
|
-
```mermaid
|
|
128
|
-
graph TB
|
|
129
|
-
subgraph "Layer 1: Data Model"
|
|
130
|
-
Task[Task]
|
|
131
|
-
Message[Message]
|
|
132
|
-
AgentCard[AgentCard]
|
|
133
|
-
Part[Part]
|
|
134
|
-
Artifact[Artifact]
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
subgraph "Layer 2: Operations"
|
|
138
|
-
SendMsg["message/send"]
|
|
139
|
-
GetTask["tasks/get"]
|
|
140
|
-
ListTasks["tasks/list"]
|
|
141
|
-
CancelTask["tasks/cancel"]
|
|
142
|
-
GetCard["agent/card"]
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
subgraph "Layer 3: Protocol Binding"
|
|
146
|
-
JSONRPC["JSON-RPC 2.0 over HTTP"]
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
Task --> SendMsg
|
|
150
|
-
Message --> SendMsg
|
|
151
|
-
AgentCard --> GetCard
|
|
152
|
-
Part --> Message
|
|
153
|
-
Artifact --> Task
|
|
154
|
-
|
|
155
|
-
SendMsg --> JSONRPC
|
|
156
|
-
GetTask --> JSONRPC
|
|
157
|
-
ListTasks --> JSONRPC
|
|
158
|
-
CancelTask --> JSONRPC
|
|
159
|
-
GetCard --> JSONRPC
|
|
160
|
-
|
|
161
|
-
style Task fill:#e1f5fe,color:#000
|
|
162
|
-
style Message fill:#e1f5fe,color:#000
|
|
163
|
-
style AgentCard fill:#e1f5fe,color:#000
|
|
164
|
-
style Part fill:#e1f5fe,color:#000
|
|
165
|
-
style Artifact fill:#e1f5fe,color:#000
|
|
166
|
-
style SendMsg fill:#f3e5f5,color:#000
|
|
167
|
-
style GetTask fill:#f3e5f5,color:#000
|
|
168
|
-
style ListTasks fill:#f3e5f5,color:#000
|
|
169
|
-
style CancelTask fill:#f3e5f5,color:#000
|
|
170
|
-
style GetCard fill:#f3e5f5,color:#000
|
|
171
|
-
style JSONRPC fill:#e8f5e8,color:#000
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Task Lifecycle
|
|
175
|
-
|
|
176
|
-
```mermaid
|
|
177
|
-
stateDiagram-v2
|
|
178
|
-
[*] --> submitted: message/send received
|
|
179
|
-
submitted --> working: Processing begins
|
|
180
|
-
working --> completed: Task finished successfully
|
|
181
|
-
working --> failed: Error during processing
|
|
182
|
-
working --> canceled: tasks/cancel received
|
|
183
|
-
completed --> [*]
|
|
184
|
-
failed --> [*]
|
|
185
|
-
canceled --> [*]
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Agent Discovery Sequence
|
|
189
|
-
|
|
190
|
-
```mermaid
|
|
191
|
-
sequenceDiagram
|
|
192
|
-
participant User
|
|
193
|
-
participant Mimir as Mimir (Orchestrator)
|
|
194
|
-
participant TyrCard as Tyr /.well-known/agent-card.json
|
|
195
|
-
participant BragiCard as Bragi /.well-known/agent-card.json
|
|
196
|
-
participant IdunnCard as Idunn /.well-known/agent-card.json
|
|
197
|
-
|
|
198
|
-
User->>Mimir: "Discover all agents"
|
|
199
|
-
activate Mimir
|
|
200
|
-
Mimir->>Mimir: a2a_discover tool invoked
|
|
201
|
-
|
|
202
|
-
par Parallel Discovery
|
|
203
|
-
Mimir->>TyrCard: GET /.well-known/agent-card.json
|
|
204
|
-
TyrCard-->>Mimir: AgentCard {name, skills, url}
|
|
205
|
-
and
|
|
206
|
-
Mimir->>BragiCard: GET /.well-known/agent-card.json
|
|
207
|
-
BragiCard-->>Mimir: AgentCard {name, skills, url}
|
|
208
|
-
and
|
|
209
|
-
Mimir->>IdunnCard: GET /.well-known/agent-card.json
|
|
210
|
-
IdunnCard-->>Mimir: AgentCard {name, skills, url}
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
Mimir-->>User: "3 agents online: Tyr (engineering), Bragi (comms), Idunn (product)"
|
|
214
|
-
deactivate Mimir
|
|
215
|
-
```
|
|
1
|
+
# @perkos/perkos-a2a
|
|
216
2
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
```mermaid
|
|
220
|
-
sequenceDiagram
|
|
221
|
-
participant User
|
|
222
|
-
participant Mimir as Mimir (Orchestrator)
|
|
223
|
-
participant TyrA2A as Tyr A2A Server
|
|
224
|
-
participant TyrOC as Tyr OpenClaw Agent
|
|
225
|
-
participant TyrFS as Tyr Workspace
|
|
226
|
-
|
|
227
|
-
User->>Mimir: "Ask Tyr to implement rate limiting"
|
|
228
|
-
activate Mimir
|
|
229
|
-
Mimir->>Mimir: a2a_send_task(target="tyr", message="...")
|
|
230
|
-
|
|
231
|
-
Mimir->>TyrA2A: POST /a2a/jsonrpc {method: "message/send"}
|
|
232
|
-
activate TyrA2A
|
|
233
|
-
|
|
234
|
-
TyrA2A->>TyrA2A: Create Task (state: submitted)
|
|
235
|
-
TyrA2A-->>Mimir: Task {id, status: "submitted"}
|
|
236
|
-
Mimir-->>User: "Task sent to Tyr. ID: abc-123"
|
|
237
|
-
deactivate Mimir
|
|
238
|
-
|
|
239
|
-
TyrA2A->>TyrA2A: Process Task (state: working)
|
|
240
|
-
TyrA2A->>TyrFS: Write task to memory/a2a-task-{id}.md
|
|
241
|
-
TyrA2A->>TyrA2A: Complete Task (state: completed)
|
|
242
|
-
deactivate TyrA2A
|
|
243
|
-
|
|
244
|
-
Note over TyrOC: Agent picks up task<br/>from workspace on<br/>next heartbeat/session
|
|
245
|
-
|
|
246
|
-
User->>Mimir: "Check status of task abc-123 on Tyr"
|
|
247
|
-
activate Mimir
|
|
248
|
-
Mimir->>TyrA2A: POST /a2a/jsonrpc {method: "tasks/get", id: "abc-123"}
|
|
249
|
-
TyrA2A-->>Mimir: Task {status: "completed", artifacts: [...]}
|
|
250
|
-
Mimir-->>User: "Task completed"
|
|
251
|
-
deactivate Mimir
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Multi-Agent Collaboration Sequence
|
|
255
|
-
|
|
256
|
-
```mermaid
|
|
257
|
-
sequenceDiagram
|
|
258
|
-
participant J as Julio (Founder)
|
|
259
|
-
participant M as Mimir (Strategy)
|
|
260
|
-
participant T as Tyr (Engineering)
|
|
261
|
-
participant B as Bragi (Comms)
|
|
262
|
-
participant I as Idunn (Product)
|
|
263
|
-
|
|
264
|
-
J->>M: "Build a landing page for PerkOS"
|
|
265
|
-
activate M
|
|
266
|
-
|
|
267
|
-
M->>M: Strategic analysis
|
|
268
|
-
Note over M: Break into subtasks:<br/>1. UX spec (Idunn)<br/>2. Implementation (Tyr)<br/>3. Copy (Bragi)
|
|
269
|
-
|
|
270
|
-
M->>I: a2a_send_task("Design the landing page UX")
|
|
271
|
-
activate I
|
|
272
|
-
I-->>M: Task accepted (UX spec)
|
|
273
|
-
I->>I: Creates wireframes + spec
|
|
274
|
-
deactivate I
|
|
275
|
-
|
|
276
|
-
M->>T: a2a_send_task("Implement landing page per Idunn's spec")
|
|
277
|
-
activate T
|
|
278
|
-
T-->>M: Task accepted (implementation)
|
|
279
|
-
T->>T: Writes Next.js + Tailwind code
|
|
280
|
-
deactivate T
|
|
281
|
-
|
|
282
|
-
M->>B: a2a_send_task("Write landing page copy for PerkOS")
|
|
283
|
-
activate B
|
|
284
|
-
B-->>M: Task accepted (copywriting)
|
|
285
|
-
B->>B: Writes headlines, CTAs, descriptions
|
|
286
|
-
deactivate B
|
|
287
|
-
|
|
288
|
-
M-->>J: "Landing page tasks delegated to Idunn (UX), Tyr (code), Bragi (copy)"
|
|
289
|
-
deactivate M
|
|
290
|
-
```
|
|
3
|
+
Agent-to-Agent (A2A) protocol plugin for [OpenClaw](https://openclaw.ai). Enables multi-agent communication using Google's A2A protocol specification.
|
|
291
4
|
|
|
292
|
-
##
|
|
5
|
+
## Quick Start
|
|
293
6
|
|
|
294
|
-
|
|
7
|
+
```bash
|
|
8
|
+
# Install the plugin
|
|
9
|
+
openclaw plugin install @perkos/perkos-a2a
|
|
295
10
|
|
|
296
|
-
|
|
11
|
+
# Run the setup wizard to detect your environment
|
|
12
|
+
openclaw perkos-a2a setup
|
|
297
13
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"name": "Tyr",
|
|
301
|
-
"description": "Engineering and execution agent",
|
|
302
|
-
"protocolVersion": "0.3.0",
|
|
303
|
-
"version": "1.0.0",
|
|
304
|
-
"url": "http://perkos-tyr:5000/a2a/jsonrpc",
|
|
305
|
-
"skills": [
|
|
306
|
-
{
|
|
307
|
-
"id": "code",
|
|
308
|
-
"name": "Code Implementation",
|
|
309
|
-
"description": "Write production-quality TypeScript, Solidity, Next.js code",
|
|
310
|
-
"tags": ["coding", "typescript", "solidity"]
|
|
311
|
-
}
|
|
312
|
-
],
|
|
313
|
-
"capabilities": { "pushNotifications": false },
|
|
314
|
-
"defaultInputModes": ["text"],
|
|
315
|
-
"defaultOutputModes": ["text"]
|
|
316
|
-
}
|
|
14
|
+
# Check status
|
|
15
|
+
openclaw perkos-a2a status
|
|
317
16
|
```
|
|
318
17
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
Tasks track the lifecycle of delegated work:
|
|
18
|
+
Add to your `openclaw.json`:
|
|
322
19
|
|
|
323
20
|
```json
|
|
324
21
|
{
|
|
325
|
-
"
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
"parts": [{ "kind": "text", "text": "Implement rate limiting on the API" }],
|
|
338
|
-
"metadata": { "fromAgent": "mimir" }
|
|
339
|
-
}
|
|
340
|
-
],
|
|
341
|
-
"artifacts": [
|
|
342
|
-
{
|
|
343
|
-
"kind": "artifact",
|
|
344
|
-
"artifactId": "b2c3d4e5-...",
|
|
345
|
-
"parts": [{ "kind": "text", "text": "Task queued for processing" }]
|
|
22
|
+
"plugins": {
|
|
23
|
+
"entries": {
|
|
24
|
+
"perkos-a2a": {
|
|
25
|
+
"config": {
|
|
26
|
+
"agentName": "my-agent",
|
|
27
|
+
"port": 5050,
|
|
28
|
+
"mode": "auto",
|
|
29
|
+
"peers": {
|
|
30
|
+
"other-agent": "http://10.0.0.2:5050"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
346
34
|
}
|
|
347
|
-
]
|
|
348
|
-
}
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### Message
|
|
352
|
-
|
|
353
|
-
Messages are communication turns between agents:
|
|
354
|
-
|
|
355
|
-
```json
|
|
356
|
-
{
|
|
357
|
-
"kind": "message",
|
|
358
|
-
"messageId": "unique-id",
|
|
359
|
-
"role": "user",
|
|
360
|
-
"parts": [
|
|
361
|
-
{ "kind": "text", "text": "Your task description here" }
|
|
362
|
-
],
|
|
363
|
-
"metadata": {
|
|
364
|
-
"fromAgent": "mimir"
|
|
365
35
|
}
|
|
366
36
|
}
|
|
367
37
|
```
|
|
368
38
|
|
|
369
|
-
##
|
|
39
|
+
## Networking Guide
|
|
370
40
|
|
|
371
|
-
|
|
372
|
-
|--------|------------|----------------|----------|
|
|
373
|
-
| `message/send` | Send a task to the agent | `{message: Message}` | `Task` |
|
|
374
|
-
| `tasks/get` | Get task by ID | `{id: string}` | `Task` |
|
|
375
|
-
| `tasks/list` | List all tasks | `{}` | `{tasks: Task[]}` |
|
|
376
|
-
| `tasks/cancel` | Cancel a running task | `{id: string}` | `Task` |
|
|
377
|
-
| `agent/card` | Get the agent's card | `{}` | `AgentCard` |
|
|
41
|
+
### VPS / Public IP
|
|
378
42
|
|
|
379
|
-
|
|
43
|
+
If your agent runs on a VPS with a public IP, you're ready to go. Configure peers with your public IP:
|
|
380
44
|
|
|
381
45
|
```json
|
|
382
|
-
{
|
|
383
|
-
"
|
|
384
|
-
"method": "message/send",
|
|
385
|
-
"id": "req-1",
|
|
386
|
-
"params": {
|
|
387
|
-
"message": {
|
|
388
|
-
"kind": "message",
|
|
389
|
-
"messageId": "msg-1",
|
|
390
|
-
"role": "user",
|
|
391
|
-
"parts": [{"kind": "text", "text": "Review the API security"}],
|
|
392
|
-
"metadata": {"fromAgent": "mimir"}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
46
|
+
"peers": {
|
|
47
|
+
"agent-b": "http://203.0.113.10:5050"
|
|
395
48
|
}
|
|
396
49
|
```
|
|
397
50
|
|
|
398
|
-
###
|
|
51
|
+
### Behind NAT (macOS / Laptop)
|
|
399
52
|
|
|
400
|
-
|
|
401
|
-
{
|
|
402
|
-
"jsonrpc": "2.0",
|
|
403
|
-
"id": "req-1",
|
|
404
|
-
"result": {
|
|
405
|
-
"kind": "task",
|
|
406
|
-
"id": "task-uuid",
|
|
407
|
-
"contextId": "ctx-uuid",
|
|
408
|
-
"status": {"state": "submitted", "timestamp": "2026-03-12T16:00:00Z"},
|
|
409
|
-
"messages": [...],
|
|
410
|
-
"artifacts": []
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
## HTTP Endpoints
|
|
416
|
-
|
|
417
|
-
| Endpoint | Method | Description |
|
|
418
|
-
|----------|--------|-------------|
|
|
419
|
-
| `/.well-known/agent-card.json` | GET | A2A Agent Card (discovery) |
|
|
420
|
-
| `/a2a/jsonrpc` | POST | JSON-RPC 2.0 endpoint |
|
|
421
|
-
| `/a2a/peers` | GET | Discover all peer agents |
|
|
422
|
-
| `/a2a/send` | POST | REST convenience for sending tasks |
|
|
423
|
-
| `/health` | GET | Health check with agent info |
|
|
53
|
+
Most development machines are behind NAT. The plugin auto-detects this and offers options:
|
|
424
54
|
|
|
425
|
-
|
|
55
|
+
**Tailscale (recommended):**
|
|
56
|
+
1. Install Tailscale: https://tailscale.com
|
|
57
|
+
2. Both agents join the same tailnet
|
|
58
|
+
3. Use Tailscale IPs for peers:
|
|
59
|
+
```json
|
|
60
|
+
"peers": { "agent-b": "http://100.64.0.2:5050" }
|
|
61
|
+
```
|
|
426
62
|
|
|
427
|
-
|
|
63
|
+
**Cloudflare Tunnel:**
|
|
64
|
+
1. Set up `cloudflared` to expose port 5050
|
|
65
|
+
2. Use the tunnel URL for peers
|
|
428
66
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
| `a2a_discover` | Discover peer agents and capabilities | none |
|
|
432
|
-
| `a2a_send_task` | Send a task to a peer agent | `target`, `message` |
|
|
433
|
-
| `a2a_task_status` | Check status of a sent task | `target`, `taskId` |
|
|
67
|
+
**Client-only mode:**
|
|
68
|
+
If you only need to send tasks (not receive), set `"mode": "client-only"`. No server is started.
|
|
434
69
|
|
|
435
|
-
|
|
70
|
+
## CLI Commands
|
|
436
71
|
|
|
437
72
|
```bash
|
|
438
|
-
openclaw a2a
|
|
439
|
-
openclaw a2a
|
|
440
|
-
openclaw a2a
|
|
73
|
+
openclaw perkos-a2a setup # Detect environment and show recommendations
|
|
74
|
+
openclaw perkos-a2a status # Show agent status and config
|
|
75
|
+
openclaw perkos-a2a discover # Discover peer agents
|
|
76
|
+
openclaw perkos-a2a send <target> <message> # Send a task to a peer
|
|
441
77
|
```
|
|
442
78
|
|
|
443
|
-
|
|
79
|
+
## Configuration
|
|
444
80
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
81
|
+
| Option | Type | Default | Description |
|
|
82
|
+
|-------------|----------|----------|------------------------------------------------|
|
|
83
|
+
| `agentName` | string | "agent" | This agent's name in the council |
|
|
84
|
+
| `port` | number | 5050 | HTTP server port (avoid 5000 on macOS/AirPlay) |
|
|
85
|
+
| `mode` | string | "auto" | `full`, `client-only`, or `auto` (detect) |
|
|
86
|
+
| `skills` | array | [] | Skills this agent exposes via A2A |
|
|
87
|
+
| `peers` | object | {} | Map of peer names to A2A base URLs |
|
|
448
88
|
|
|
449
|
-
|
|
89
|
+
### Mode Details
|
|
450
90
|
|
|
451
|
-
|
|
91
|
+
- **auto** (default): Detects NAT/Tailscale. Falls back to client-only if behind NAT with no tunnel. Also falls back if port is unavailable.
|
|
92
|
+
- **full**: Always starts the HTTP server. Fails loudly if port is in use.
|
|
93
|
+
- **client-only**: No HTTP server. Can send tasks and discover peers but cannot receive inbound tasks.
|
|
452
94
|
|
|
453
|
-
##
|
|
95
|
+
## Agent Tools
|
|
454
96
|
|
|
455
|
-
|
|
97
|
+
When the plugin is active, three tools are available to the agent:
|
|
456
98
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
99
|
+
- `a2a_discover` -- Discover all configured peer agents and their capabilities
|
|
100
|
+
- `a2a_send_task` -- Send a task to a named peer agent
|
|
101
|
+
- `a2a_task_status` -- Check the status of a previously sent task
|
|
460
102
|
|
|
461
|
-
|
|
103
|
+
## Troubleshooting
|
|
462
104
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
cd PerkOS-A2A
|
|
466
|
-
npm install
|
|
467
|
-
npm run build
|
|
468
|
-
openclaw plugins install -l .
|
|
469
|
-
```
|
|
105
|
+
**Port 5050 in use:**
|
|
106
|
+
Change the port in config, or run `lsof -i :5050` to find the conflicting process.
|
|
470
107
|
|
|
471
|
-
|
|
108
|
+
**Port 5000 on macOS:**
|
|
109
|
+
macOS Monterey+ uses port 5000 for AirPlay Receiver. Use 5050 (the default) instead.
|
|
472
110
|
|
|
473
|
-
|
|
111
|
+
**Peers show offline:**
|
|
112
|
+
- Verify the peer URL is correct and reachable
|
|
113
|
+
- Check firewalls/security groups
|
|
114
|
+
- If behind NAT, ensure both agents are on the same tailnet or have tunnel access
|
|
474
115
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
entries: {
|
|
479
|
-
"perkos-a2a": {
|
|
480
|
-
enabled: true,
|
|
481
|
-
config: {
|
|
482
|
-
// This agent's name in the network
|
|
483
|
-
agentName: "mimir",
|
|
484
|
-
// Port for the A2A HTTP server (default 5050; use 5000 on Linux/Docker)
|
|
485
|
-
port: 5050,
|
|
486
|
-
// Skills this agent exposes
|
|
487
|
-
skills: [
|
|
488
|
-
{
|
|
489
|
-
id: "strategy",
|
|
490
|
-
name: "Strategic Planning",
|
|
491
|
-
description: "Break down goals into actionable tasks",
|
|
492
|
-
tags: ["planning", "strategy"]
|
|
493
|
-
}
|
|
494
|
-
],
|
|
495
|
-
// Peer agents (name -> A2A URL)
|
|
496
|
-
peers: {
|
|
497
|
-
tyr: "http://perkos-tyr:5000",
|
|
498
|
-
bragi: "http://perkos-bragi:5000",
|
|
499
|
-
idunn: "http://perkos-idunn:5000"
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
### Configuration Options
|
|
509
|
-
|
|
510
|
-
| Option | Type | Default | Description |
|
|
511
|
-
|--------|------|---------|-------------|
|
|
512
|
-
| `agentName` | string | `"agent"` | This agent's name in the network |
|
|
513
|
-
| `port` | number | `5050` | Port for the A2A HTTP server (macOS avoids 5000/AirPlay) |
|
|
514
|
-
| `skills` | array | `[]` | Skills to advertise in the Agent Card |
|
|
515
|
-
| `peers` | object | `{}` | Map of peer agent names to A2A URLs |
|
|
516
|
-
|
|
517
|
-
## Docker Deployment
|
|
518
|
-
|
|
519
|
-
For multi-agent setups, use Docker Compose with a shared network:
|
|
520
|
-
|
|
521
|
-
```yaml
|
|
522
|
-
services:
|
|
523
|
-
mimir:
|
|
524
|
-
build: .
|
|
525
|
-
container_name: perkos-mimir
|
|
526
|
-
ports:
|
|
527
|
-
- "3001:3000" # OpenClaw
|
|
528
|
-
- "5001:5000" # A2A
|
|
529
|
-
environment:
|
|
530
|
-
- AGENT_NAME=mimir
|
|
531
|
-
networks:
|
|
532
|
-
- council
|
|
533
|
-
|
|
534
|
-
tyr:
|
|
535
|
-
build: .
|
|
536
|
-
container_name: perkos-tyr
|
|
537
|
-
ports:
|
|
538
|
-
- "3002:3000"
|
|
539
|
-
- "5002:5000"
|
|
540
|
-
environment:
|
|
541
|
-
- AGENT_NAME=tyr
|
|
542
|
-
networks:
|
|
543
|
-
- council
|
|
544
|
-
|
|
545
|
-
networks:
|
|
546
|
-
council:
|
|
547
|
-
driver: bridge
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
Agents can discover each other via Docker DNS: `http://perkos-tyr:5000`.
|
|
551
|
-
|
|
552
|
-
## A2A Protocol Compliance
|
|
553
|
-
|
|
554
|
-
This plugin implements the [A2A Protocol Specification RC v1.0](https://a2a-protocol.org/latest/specification/):
|
|
555
|
-
|
|
556
|
-
| Feature | Status |
|
|
557
|
-
|---------|--------|
|
|
558
|
-
| Agent Card at `/.well-known/agent-card.json` | ✅ |
|
|
559
|
-
| JSON-RPC 2.0 binding | ✅ |
|
|
560
|
-
| `message/send` | ✅ |
|
|
561
|
-
| `tasks/get` | ✅ |
|
|
562
|
-
| `tasks/list` | ✅ |
|
|
563
|
-
| `tasks/cancel` | ✅ |
|
|
564
|
-
| Task lifecycle states | ✅ |
|
|
565
|
-
| Text parts | ✅ |
|
|
566
|
-
| Artifact generation | ✅ |
|
|
567
|
-
| Streaming (SSE) | 🔜 Planned |
|
|
568
|
-
| Push notifications | 🔜 Planned |
|
|
569
|
-
| File parts | 🔜 Planned |
|
|
570
|
-
| gRPC binding | 🔜 Planned |
|
|
571
|
-
|
|
572
|
-
## TypeScript Types
|
|
573
|
-
|
|
574
|
-
The plugin exports full TypeScript types for the A2A protocol:
|
|
575
|
-
|
|
576
|
-
```typescript
|
|
577
|
-
import type {
|
|
578
|
-
AgentCard,
|
|
579
|
-
AgentSkill,
|
|
580
|
-
Task,
|
|
581
|
-
TaskStatus,
|
|
582
|
-
Message,
|
|
583
|
-
Part,
|
|
584
|
-
Artifact,
|
|
585
|
-
JsonRpcRequest,
|
|
586
|
-
JsonRpcResponse,
|
|
587
|
-
A2APluginConfig,
|
|
588
|
-
} from "@perkos/a2a";
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
## Standalone Server
|
|
592
|
-
|
|
593
|
-
You can also use the A2A server independently of OpenClaw:
|
|
594
|
-
|
|
595
|
-
```typescript
|
|
596
|
-
import { A2AServer } from "@perkos/a2a";
|
|
597
|
-
|
|
598
|
-
const server = new A2AServer({
|
|
599
|
-
agentName: "my-agent",
|
|
600
|
-
port: 5050,
|
|
601
|
-
skills: [{ id: "chat", name: "Chat", description: "General chat", tags: [] }],
|
|
602
|
-
peers: {
|
|
603
|
-
other: "http://other-agent:5050",
|
|
604
|
-
},
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
server.start();
|
|
608
|
-
```
|
|
116
|
+
**Auto mode starts client-only unexpectedly:**
|
|
117
|
+
- Run `openclaw perkos-a2a setup` to diagnose
|
|
118
|
+
- Force `"mode": "full"` if you know the port is accessible
|
|
609
119
|
|
|
610
120
|
## License
|
|
611
121
|
|
|
612
122
|
MIT
|
|
613
|
-
|
|
614
|
-
## Links
|
|
615
|
-
|
|
616
|
-
- [A2A Protocol Specification](https://a2a-protocol.org/latest/specification/)
|
|
617
|
-
- [A2A GitHub](https://github.com/a2aproject/A2A)
|
|
618
|
-
- [A2A JS SDK](https://github.com/a2aproject/a2a-js)
|
|
619
|
-
- [OpenClaw](https://github.com/openclaw/openclaw)
|
|
620
|
-
- [PerkOS](https://perkos.xyz)
|