1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# A2A Protocol Specification v0.2
## Overview
Agent-to-Agent (A2A) is a decentralized message protocol for agent negotiation within newOS4. Agents discover each other via VFS registrations and communicate through a VFS mailbox system. No central broker.
## Message Format
All messages are JSON with this envelope:
```json
{
"a2a_version": "0.1",
"msg_id": "<uuid>",
"type": "request" | "response" | "broadcast" | "lease" | "heartbeat",
"from": "<agent_id>",
"to": "<agent_id>" | "*",
"timestamp": "<ISO 8601>",
"ttl_seconds": 30,
"contract": {
"capabilities": ["list_files", "read_file", "web_search"],
"constraints": {
"max_tool_turns": 8,
"max_duration_seconds": 60
}
},
"payload": { }
}
```
## Transport Layer (VFS Mailbox)
Each agent has a VFS mailbox:
- **Inbox** — `/agents/<agent_id>/inbox.json` — receives incoming A2A messages
- **Outbox** — `/agents/<agent_id>/outbox.json` — agent writes results here after execution
The orchestrator polls all agent inboxes every **500ms** via `_pollAgentMailboxes()`. When a new A2A message appears, it:
1. Reads the message envelope
2. Routes by type:
- `request` — task delegation, checks outbox for completion
- `response` — task result from agent
- `broadcast` — capability advertisement
- `heartbeat` — updates agent's lastHeartbeat timestamp
3. Marks messages as `_processed` to avoid re-routing
## Message Types
- **request**: Point-to-point task delegation. From=orchestrator, To=worker.
- **response**: Task result. From=worker, To=orchestrator.
- **broadcast**: Discovery / capability advertisement. To="*".
- **lease**: Time-bound contract granting a worker exclusive task rights.
- **heartbeat**: Alive signal. Every 5 seconds. Missing 3 consecutive = presumed dead.
## Commands
- `a2a-send <agent-id> <json-message>` — Send an A2A message to an agent's inbox
- `a2a-list` — Show all A2A messages across agents with status
## Lifecycle
1. Orchestrator sends `request` to agent's inbox via `a2a-send`
2. AI module receives delegated task, executes it
3. Result written to agent's outbox
4. Polling loop detects outbox completion, sends `response` message
5. Orchestrator marks lease as complete, agent returns to idle pool
## Implementation Status
- ✅ Message format (v0.1 envelope)
- ✅ VFS mailbox transport (inbox.json / outbox.json)
- ✅ 500ms polling loop in orchestrator
- ✅ Type routing (request, response, broadcast, heartbeat)
- ✅ a2a-send / a2a-list CLI commands
- ⬜ Heartbeat sending from worker agents
- ⬜ Full broadcast discovery flow
- ⬜ Lease revocation via A2A message (currently uses separate LeaseModule)
|