macro-agent 0.0.14 → 0.0.16
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/settings.local.json +59 -0
- package/dist/acp/index.d.ts +1 -1
- package/dist/acp/index.d.ts.map +1 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/macro-agent.d.ts +21 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +182 -0
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/types.d.ts +31 -2
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +10 -4
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/cli/acp.d.ts +6 -0
- package/dist/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +16 -2
- package/dist/cli/acp.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts +5 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +47 -4
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/utils/address-translation.d.ts +99 -0
- package/dist/map/utils/address-translation.d.ts.map +1 -0
- package/dist/map/utils/address-translation.js +285 -0
- package/dist/map/utils/address-translation.js.map +1 -0
- package/dist/map/utils/index.d.ts +7 -0
- package/dist/map/utils/index.d.ts.map +1 -0
- package/dist/map/utils/index.js +7 -0
- package/dist/map/utils/index.js.map +1 -0
- package/dist/store/event-store.js +9 -2
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +2 -0
- package/dist/store/types/agents.d.ts.map +1 -1
- package/package.json +4 -4
- package/references/acp-factory-ref/CHANGELOG.md +33 -0
- package/references/acp-factory-ref/LICENSE +21 -0
- package/references/acp-factory-ref/README.md +341 -0
- package/references/acp-factory-ref/package-lock.json +3102 -0
- package/references/acp-factory-ref/package.json +96 -0
- package/references/acp-factory-ref/python/CHANGELOG.md +33 -0
- package/references/acp-factory-ref/python/LICENSE +21 -0
- package/references/acp-factory-ref/python/Makefile +57 -0
- package/references/acp-factory-ref/python/README.md +253 -0
- package/references/acp-factory-ref/python/pyproject.toml +73 -0
- package/references/acp-factory-ref/python/tests/__init__.py +0 -0
- package/references/acp-factory-ref/python/tests/e2e/__init__.py +1 -0
- package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +349 -0
- package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +165 -0
- package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +296 -0
- package/references/acp-factory-ref/python/tests/test_client_handler.py +543 -0
- package/references/acp-factory-ref/python/tests/test_pushable.py +199 -0
- package/references/claude-code-acp/.github/workflows/ci.yml +45 -0
- package/references/claude-code-acp/.github/workflows/publish.yml +34 -0
- package/references/claude-code-acp/.prettierrc.json +4 -0
- package/references/claude-code-acp/CHANGELOG.md +249 -0
- package/references/claude-code-acp/LICENSE +222 -0
- package/references/claude-code-acp/README.md +53 -0
- package/references/claude-code-acp/docs/RELEASES.md +24 -0
- package/references/claude-code-acp/eslint.config.js +48 -0
- package/references/claude-code-acp/package-lock.json +4570 -0
- package/references/claude-code-acp/package.json +88 -0
- package/references/claude-code-acp/scripts/release.sh +119 -0
- package/references/claude-code-acp/src/acp-agent.ts +2079 -0
- package/references/claude-code-acp/src/index.ts +26 -0
- package/references/claude-code-acp/src/lib.ts +38 -0
- package/references/claude-code-acp/src/mcp-server.ts +911 -0
- package/references/claude-code-acp/src/settings.ts +522 -0
- package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +5 -0
- package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +6 -0
- package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +479 -0
- package/references/claude-code-acp/src/tests/acp-agent.test.ts +1502 -0
- package/references/claude-code-acp/src/tests/extract-lines.test.ts +103 -0
- package/references/claude-code-acp/src/tests/fork-session.test.ts +335 -0
- package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +334 -0
- package/references/claude-code-acp/src/tests/settings.test.ts +617 -0
- package/references/claude-code-acp/src/tests/skills-options.test.ts +187 -0
- package/references/claude-code-acp/src/tests/tools.test.ts +318 -0
- package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +558 -0
- package/references/claude-code-acp/src/tools.ts +819 -0
- package/references/claude-code-acp/src/utils.ts +171 -0
- package/references/claude-code-acp/tsconfig.json +18 -0
- package/references/claude-code-acp/vitest.config.ts +19 -0
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +111 -0
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +13 -0
- package/references/multi-agent-protocol/LICENSE +21 -0
- package/references/multi-agent-protocol/README.md +113 -0
- package/references/multi-agent-protocol/docs/00-design-specification.md +496 -0
- package/references/multi-agent-protocol/docs/01-open-questions.md +1050 -0
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +296 -0
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +252 -0
- package/references/multi-agent-protocol/docs/04-error-handling.md +231 -0
- package/references/multi-agent-protocol/docs/05-connection-model.md +244 -0
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +243 -0
- package/references/multi-agent-protocol/docs/07-federation.md +259 -0
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +253 -0
- package/references/multi-agent-protocol/docs/09-authentication.md +680 -0
- package/references/multi-agent-protocol/docs/10-mail-protocol.md +553 -0
- package/references/multi-agent-protocol/docs/agent-iam-integration.md +877 -0
- package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +459 -0
- package/references/multi-agent-protocol/docs/git-transport-draft.md +251 -0
- package/references/multi-agent-protocol/docs-site/Gemfile +22 -0
- package/references/multi-agent-protocol/docs-site/README.md +82 -0
- package/references/multi-agent-protocol/docs-site/_config.yml +91 -0
- package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +20 -0
- package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +42 -0
- package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +34 -0
- package/references/multi-agent-protocol/docs-site/examples/full-integration.md +510 -0
- package/references/multi-agent-protocol/docs-site/examples/index.md +138 -0
- package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +282 -0
- package/references/multi-agent-protocol/docs-site/examples/task-queue.md +399 -0
- package/references/multi-agent-protocol/docs-site/getting-started/index.md +98 -0
- package/references/multi-agent-protocol/docs-site/getting-started/installation.md +219 -0
- package/references/multi-agent-protocol/docs-site/getting-started/overview.md +172 -0
- package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +237 -0
- package/references/multi-agent-protocol/docs-site/index.md +136 -0
- package/references/multi-agent-protocol/docs-site/protocol/authentication.md +391 -0
- package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +376 -0
- package/references/multi-agent-protocol/docs-site/protocol/design.md +284 -0
- package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +312 -0
- package/references/multi-agent-protocol/docs-site/protocol/federation.md +449 -0
- package/references/multi-agent-protocol/docs-site/protocol/index.md +129 -0
- package/references/multi-agent-protocol/docs-site/protocol/permissions.md +398 -0
- package/references/multi-agent-protocol/docs-site/protocol/streaming.md +353 -0
- package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +369 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +357 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/client.md +380 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/index.md +62 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/server.md +453 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/types.md +468 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +375 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +405 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +352 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +89 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +360 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +446 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +363 -0
- package/references/multi-agent-protocol/docs-site/sdk/index.md +206 -0
- package/references/multi-agent-protocol/package-lock.json +3886 -0
- package/references/multi-agent-protocol/package.json +56 -0
- package/references/multi-agent-protocol/schema/meta.json +467 -0
- package/references/multi-agent-protocol/schema/schema.json +2558 -0
- package/src/acp/__tests__/history.test.ts +526 -0
- package/src/acp/__tests__/integration.test.ts +2 -1
- package/src/acp/index.ts +4 -0
- package/src/acp/macro-agent.ts +329 -85
- package/src/acp/types.ts +39 -2
- package/src/agent/__tests__/agent-manager.test.ts +67 -1
- package/src/agent/agent-manager.ts +10 -4
- package/src/cli/__tests__/stable-instance-id.test.ts +57 -0
- package/src/cli/acp.ts +17 -2
- package/src/map/adapter/acp-over-map.ts +57 -2
- package/src/store/event-store.ts +10 -3
- package/src/store/types/agents.ts +2 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# MAP Wire Protocol & ACP Compatibility Layer
|
|
2
|
+
|
|
3
|
+
This spec details the wire protocol format for MAP and how it maintains compatibility with ACP.
|
|
4
|
+
|
|
5
|
+
## Design Goals
|
|
6
|
+
|
|
7
|
+
1. **JSON-RPC 2.0 base** - Same foundation as ACP for tooling compatibility
|
|
8
|
+
2. **Bidirectional streaming** - Native support, not bolted on
|
|
9
|
+
3. **ACP downgrade path** - Graceful degradation to ACP-only clients
|
|
10
|
+
4. **Transport agnostic** - WebSocket, stdio, HTTP/SSE all viable
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Wire Protocol Format
|
|
15
|
+
|
|
16
|
+
### Message Types
|
|
17
|
+
|
|
18
|
+
MAP uses four message types over JSON-RPC:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// 1. Request (expects response)
|
|
22
|
+
interface MAPRequest {
|
|
23
|
+
jsonrpc: "2.0";
|
|
24
|
+
id: string | number;
|
|
25
|
+
method: string;
|
|
26
|
+
params?: unknown;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 2. Response (to a request)
|
|
30
|
+
interface MAPResponse {
|
|
31
|
+
jsonrpc: "2.0";
|
|
32
|
+
id: string | number;
|
|
33
|
+
result?: unknown;
|
|
34
|
+
error?: MAPError;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 3. Notification (no response expected)
|
|
38
|
+
interface MAPNotification {
|
|
39
|
+
jsonrpc: "2.0";
|
|
40
|
+
method: string;
|
|
41
|
+
params?: unknown;
|
|
42
|
+
// Note: no 'id' field
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 4. Batch (multiple messages)
|
|
46
|
+
type MAPBatch = Array<MAPRequest | MAPNotification>;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Method Namespacing
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
map/ # Full MAP mode methods
|
|
53
|
+
├── initialize
|
|
54
|
+
├── agent.*
|
|
55
|
+
├── hierarchy.*
|
|
56
|
+
├── scope.*
|
|
57
|
+
├── send
|
|
58
|
+
├── request
|
|
59
|
+
├── broadcast
|
|
60
|
+
├── inject
|
|
61
|
+
├── subscribe
|
|
62
|
+
├── task.*
|
|
63
|
+
├── role.*
|
|
64
|
+
├── env.*
|
|
65
|
+
└── user.*
|
|
66
|
+
|
|
67
|
+
_map/ # ACP-compat mode (via extMethod)
|
|
68
|
+
├── agent.list
|
|
69
|
+
├── hierarchy.get
|
|
70
|
+
├── scope.list
|
|
71
|
+
├── send
|
|
72
|
+
├── broadcast
|
|
73
|
+
├── task.list
|
|
74
|
+
└── subscribe
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Protocol Phases
|
|
80
|
+
|
|
81
|
+
### Phase 1: Connection Establishment
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Client Server
|
|
85
|
+
│ │
|
|
86
|
+
│─────── Transport Connect ──────────────►│
|
|
87
|
+
│ │
|
|
88
|
+
│◄────── Transport Accept ───────────────│
|
|
89
|
+
│ │
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Phase 2: Protocol Negotiation
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Client sends initialize request
|
|
96
|
+
{
|
|
97
|
+
"jsonrpc": "2.0",
|
|
98
|
+
"id": "req_001",
|
|
99
|
+
"method": "map/initialize",
|
|
100
|
+
"params": {
|
|
101
|
+
"protocolVersion": "2025-01-01",
|
|
102
|
+
"mode": "full", // or "acp-compat"
|
|
103
|
+
"clientInfo": {
|
|
104
|
+
"name": "macro-agent",
|
|
105
|
+
"version": "1.0.0"
|
|
106
|
+
},
|
|
107
|
+
"capabilities": {
|
|
108
|
+
"streaming": true,
|
|
109
|
+
"scopes": true,
|
|
110
|
+
"tasks": true,
|
|
111
|
+
"roles": true,
|
|
112
|
+
"environments": true,
|
|
113
|
+
"federation": false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Server responds with negotiated capabilities
|
|
119
|
+
{
|
|
120
|
+
"jsonrpc": "2.0",
|
|
121
|
+
"id": "req_001",
|
|
122
|
+
"result": {
|
|
123
|
+
"protocolVersion": "2025-01-01",
|
|
124
|
+
"mode": "full",
|
|
125
|
+
"serverInfo": {
|
|
126
|
+
"name": "map-server",
|
|
127
|
+
"version": "1.0.0"
|
|
128
|
+
},
|
|
129
|
+
"capabilities": {
|
|
130
|
+
"streaming": true,
|
|
131
|
+
"scopes": true,
|
|
132
|
+
"tasks": true,
|
|
133
|
+
"roles": true,
|
|
134
|
+
"environments": true,
|
|
135
|
+
"federation": true,
|
|
136
|
+
"replay": true,
|
|
137
|
+
"deliverySemantics": ["inject", "interrupt", "queue", "best-effort"],
|
|
138
|
+
"maxSubscriptions": 100,
|
|
139
|
+
"maxMessageSize": 1048576
|
|
140
|
+
},
|
|
141
|
+
"agentId": "agent_root_001"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Phase 3: Graceful Shutdown
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Client initiates shutdown
|
|
150
|
+
{
|
|
151
|
+
"jsonrpc": "2.0",
|
|
152
|
+
"id": "req_final",
|
|
153
|
+
"method": "map/shutdown",
|
|
154
|
+
"params": {
|
|
155
|
+
"reason": "user_requested",
|
|
156
|
+
"timeout": 5000,
|
|
157
|
+
"cascade": true
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Messaging Wire Format
|
|
165
|
+
|
|
166
|
+
### Send Message
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// Request
|
|
170
|
+
{
|
|
171
|
+
"jsonrpc": "2.0",
|
|
172
|
+
"id": "msg_001",
|
|
173
|
+
"method": "map/send",
|
|
174
|
+
"params": {
|
|
175
|
+
"to": { "type": "agent", "id": "agent_worker_001" },
|
|
176
|
+
"payload": {
|
|
177
|
+
"type": "task_assignment",
|
|
178
|
+
"task": {
|
|
179
|
+
"id": "task_001",
|
|
180
|
+
"description": "Review PR #123"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"meta": {
|
|
184
|
+
"priority": "high",
|
|
185
|
+
"delivery": "inject",
|
|
186
|
+
"ttl": 60000,
|
|
187
|
+
"requireAck": true
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Response
|
|
193
|
+
{
|
|
194
|
+
"jsonrpc": "2.0",
|
|
195
|
+
"id": "msg_001",
|
|
196
|
+
"result": {
|
|
197
|
+
"messageId": "envelope_a1b2c3",
|
|
198
|
+
"delivered": 1,
|
|
199
|
+
"receipts": [
|
|
200
|
+
{
|
|
201
|
+
"agentId": "agent_worker_001",
|
|
202
|
+
"status": "delivered",
|
|
203
|
+
"semantic": "inject",
|
|
204
|
+
"timestamp": 1706123456789
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## ACP Compatibility Layer
|
|
214
|
+
|
|
215
|
+
### Mode Detection
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
function detectMode(request: MAPInitializeRequest): "full" | "acp-compat" {
|
|
219
|
+
if (request.mode === "acp-compat") return "acp-compat";
|
|
220
|
+
if (!request.capabilities?.streaming) return "acp-compat";
|
|
221
|
+
if (!request.mode && request.clientCapabilities) return "acp-compat";
|
|
222
|
+
return "full";
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Feature Degradation Table
|
|
227
|
+
|
|
228
|
+
| Feature | Full MAP | ACP-compat |
|
|
229
|
+
|---------|----------|------------|
|
|
230
|
+
| Multi-agent context | Native | Session-per-agent |
|
|
231
|
+
| Streaming | Native bidirectional | Via sessionUpdate |
|
|
232
|
+
| Hierarchy queries | Full tree ops | Flat list only |
|
|
233
|
+
| Scopes | Full CRUD | Read-only listing |
|
|
234
|
+
| Delivery semantics | All 4 modes | Best-effort only |
|
|
235
|
+
| Federation | Supported | Not available |
|
|
236
|
+
| Subscriptions | Multiple concurrent | Single per session |
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Transport Bindings
|
|
241
|
+
|
|
242
|
+
### WebSocket
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Primary transport for bidirectional streaming
|
|
246
|
+
// WebSocket frame format: NDJSON (newline-delimited JSON)
|
|
247
|
+
// Each message is a single line of JSON followed by \n
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Stdio (for subprocess agents)
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// Same NDJSON format over stdin/stdout
|
|
254
|
+
interface StdioTransport {
|
|
255
|
+
stdin: WritableStream<MAPMessage>;
|
|
256
|
+
stdout: ReadableStream<MAPMessage>;
|
|
257
|
+
stderr: ReadableStream<string>;
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### HTTP/SSE (for stateless clients)
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// Endpoints:
|
|
265
|
+
// POST /map/rpc - Single RPC call
|
|
266
|
+
// GET /map/events - SSE event stream
|
|
267
|
+
// POST /map/batch - Batch RPC calls
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Protocol Extensions
|
|
273
|
+
|
|
274
|
+
### Custom Methods
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
// Vendor-specific extension
|
|
278
|
+
{
|
|
279
|
+
"jsonrpc": "2.0",
|
|
280
|
+
"id": "ext_001",
|
|
281
|
+
"method": "macro/workspace.sync",
|
|
282
|
+
"params": {
|
|
283
|
+
"worktree": "/path/to/worktree",
|
|
284
|
+
"remote": "origin/main"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Open Questions
|
|
292
|
+
|
|
293
|
+
1. **Compression**: Should we support message compression (gzip, brotli)?
|
|
294
|
+
2. **Batching**: Should batch responses preserve order or allow reordering?
|
|
295
|
+
3. **Heartbeat**: Explicit ping/pong or rely on transport-level?
|
|
296
|
+
4. **Message size limits**: Hard protocol limit or capability-negotiated?
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# MAP Streaming Semantics
|
|
2
|
+
|
|
3
|
+
This spec details how MAP handles system-wide event streaming, subscriptions, filtering, and replay.
|
|
4
|
+
|
|
5
|
+
## Design Goals
|
|
6
|
+
|
|
7
|
+
1. **System-wide visibility** - See all agent activity, not just one session
|
|
8
|
+
2. **Efficient filtering** - Subscribe only to relevant events
|
|
9
|
+
3. **Replay capability** - Catch up on missed events
|
|
10
|
+
4. **Backpressure handling** - Don't overwhelm slow consumers
|
|
11
|
+
5. **Ordered delivery** - Causal ordering where it matters
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Subscription Model
|
|
16
|
+
|
|
17
|
+
### Creating Subscriptions
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// Subscribe to multiple stream types with filtering
|
|
21
|
+
{
|
|
22
|
+
"jsonrpc": "2.0",
|
|
23
|
+
"id": "sub_001",
|
|
24
|
+
"method": "map/subscribe",
|
|
25
|
+
"params": {
|
|
26
|
+
"streams": ["messages", "state", "tasks"],
|
|
27
|
+
"filter": {
|
|
28
|
+
"agents": ["agent_worker_*"], // Glob pattern
|
|
29
|
+
"roles": ["worker", "integrator"],
|
|
30
|
+
"priorities": ["urgent", "high"],
|
|
31
|
+
"scopes": ["scope_active"]
|
|
32
|
+
},
|
|
33
|
+
"options": {
|
|
34
|
+
"includeHistory": false,
|
|
35
|
+
"bufferSize": 1000,
|
|
36
|
+
"deliveryMode": "at-least-once"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Subscription Lifecycle
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
┌──────────┐ subscribe ┌──────────┐
|
|
46
|
+
│ inactive │ ──────────────► │ active │
|
|
47
|
+
└──────────┘ └────┬─────┘
|
|
48
|
+
▲ │
|
|
49
|
+
│ │ pause
|
|
50
|
+
│ ▼
|
|
51
|
+
│ ┌──────────┐
|
|
52
|
+
│ resume │ paused │
|
|
53
|
+
│ ◄──────────────────── └────┬─────┘
|
|
54
|
+
│ │
|
|
55
|
+
│ unsubscribe │ unsubscribe
|
|
56
|
+
│ ▼
|
|
57
|
+
└─────────────────────► ┌──────────┐
|
|
58
|
+
│ closed │
|
|
59
|
+
└──────────┘
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Event Delivery
|
|
65
|
+
|
|
66
|
+
### Event Envelope
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface MAPStreamEventEnvelope {
|
|
70
|
+
subscriptionId: string;
|
|
71
|
+
sequence: number; // Monotonic within subscription
|
|
72
|
+
timestamp: number; // Server timestamp
|
|
73
|
+
event: MAPStreamEvent;
|
|
74
|
+
|
|
75
|
+
// For ordering/dedup
|
|
76
|
+
eventId: string; // Globally unique
|
|
77
|
+
causedBy?: string[]; // Causal predecessors
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Event Types
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
type MAPStreamEvent =
|
|
85
|
+
// Messaging events
|
|
86
|
+
| { type: "message"; envelope: MAPEnvelope; receipts: MAPDeliveryReceipt[] }
|
|
87
|
+
| { type: "message.ack"; messageId: string; agentId: string }
|
|
88
|
+
| { type: "message.failed"; messageId: string; error: MAPError }
|
|
89
|
+
|
|
90
|
+
// Agent state events
|
|
91
|
+
| { type: "agent.registered"; agent: MAPAgent }
|
|
92
|
+
| { type: "agent.unregistered"; agentId: string; reason: string }
|
|
93
|
+
| { type: "agent.state"; agentId: string; previous: string; current: string }
|
|
94
|
+
| { type: "agent.updated"; agentId: string; changes: Partial<MAPAgent> }
|
|
95
|
+
|
|
96
|
+
// Task events
|
|
97
|
+
| { type: "task.created"; task: MAPTask }
|
|
98
|
+
| { type: "task.assigned"; taskId: string; agentId: string }
|
|
99
|
+
| { type: "task.status"; taskId: string; previous: string; current: string }
|
|
100
|
+
| { type: "task.completed"; taskId: string; result?: unknown }
|
|
101
|
+
|
|
102
|
+
// Scope events
|
|
103
|
+
| { type: "scope.created"; scope: MAPScope }
|
|
104
|
+
| { type: "scope.deleted"; scopeId: string }
|
|
105
|
+
| { type: "scope.member.added"; scopeId: string; agentId: string }
|
|
106
|
+
| { type: "scope.member.removed"; scopeId: string; agentId: string }
|
|
107
|
+
|
|
108
|
+
// System events
|
|
109
|
+
| { type: "system.heartbeat"; timestamp: number }
|
|
110
|
+
| { type: "system.capacity"; agents: number; maxAgents: number };
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Filtering
|
|
116
|
+
|
|
117
|
+
### Filter Syntax
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
interface MAPStreamFilter {
|
|
121
|
+
// Agent filtering (OR within, AND across fields)
|
|
122
|
+
agents?: string[]; // Glob patterns
|
|
123
|
+
roles?: string[]; // Role names
|
|
124
|
+
scopes?: string[]; // Scope IDs
|
|
125
|
+
environments?: string[]; // Environment IDs
|
|
126
|
+
|
|
127
|
+
// Event filtering
|
|
128
|
+
eventTypes?: string[]; // e.g., ["message", "task.*"]
|
|
129
|
+
priorities?: MAPPriority[]; // For message events
|
|
130
|
+
|
|
131
|
+
// Hierarchy filtering
|
|
132
|
+
descendants?: string; // All descendants of agent
|
|
133
|
+
ancestors?: string; // All ancestors of agent
|
|
134
|
+
subtree?: string; // Agent and all descendants
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Replay
|
|
141
|
+
|
|
142
|
+
### Replay Request
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
{
|
|
146
|
+
"jsonrpc": "2.0",
|
|
147
|
+
"id": "replay_001",
|
|
148
|
+
"method": "map/replay",
|
|
149
|
+
"params": {
|
|
150
|
+
// Time-based replay
|
|
151
|
+
"from": 1706120000000,
|
|
152
|
+
"to": 1706123456789,
|
|
153
|
+
|
|
154
|
+
// OR event-based replay
|
|
155
|
+
"afterEventId": "evt_x1y2z3",
|
|
156
|
+
|
|
157
|
+
// Filter
|
|
158
|
+
"filter": {
|
|
159
|
+
"agents": ["agent_worker_*"],
|
|
160
|
+
"eventTypes": ["task.*"]
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Options
|
|
164
|
+
"options": {
|
|
165
|
+
"limit": 1000,
|
|
166
|
+
"order": "chronological",
|
|
167
|
+
"includeSnapshots": true
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Ordering Guarantees
|
|
176
|
+
|
|
177
|
+
### Within-Agent Ordering
|
|
178
|
+
|
|
179
|
+
Events for a single agent are always delivered in causal order:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
Agent A: state=idle → state=busy → state=idle
|
|
183
|
+
(seq 1) (seq 2) (seq 3)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Cross-Agent Ordering
|
|
187
|
+
|
|
188
|
+
Events across agents may be reordered unless causally related:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
Agent A: message sent ────────────────┐
|
|
192
|
+
▼
|
|
193
|
+
Agent B: message received → state=busy
|
|
194
|
+
|
|
195
|
+
// The "message received" always comes after "message sent"
|
|
196
|
+
// But unrelated events may interleave
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Ordering Modes
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
interface SubscriptionOptions {
|
|
203
|
+
ordering:
|
|
204
|
+
| "none" // No ordering guarantee (fastest)
|
|
205
|
+
| "per-agent" // Ordered within each agent
|
|
206
|
+
| "causal" // Full causal ordering (may have latency)
|
|
207
|
+
| "total"; // Total ordering (highest latency)
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Backpressure
|
|
214
|
+
|
|
215
|
+
### Client Flow Control
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// Client acknowledges events (enables flow control)
|
|
219
|
+
{
|
|
220
|
+
"jsonrpc": "2.0",
|
|
221
|
+
"method": "map/subscribe.ack",
|
|
222
|
+
"params": {
|
|
223
|
+
"subscriptionId": "sub_a1b2c3",
|
|
224
|
+
"upToSequence": 100
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Overflow Handling
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// Server notifies client of overflow
|
|
233
|
+
{
|
|
234
|
+
"event": {
|
|
235
|
+
"type": "subscription.overflow",
|
|
236
|
+
"eventsDropped": 150,
|
|
237
|
+
"oldestDropped": "evt_x1y2z3",
|
|
238
|
+
"newestDropped": "evt_a4b5c6",
|
|
239
|
+
"recommendation": "reduce_filter_scope"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Open Questions
|
|
247
|
+
|
|
248
|
+
1. **Event retention**: How long should servers retain events for replay?
|
|
249
|
+
2. **Compression**: Should event streams be compressible?
|
|
250
|
+
3. **Fan-out limits**: Max subscribers per event type?
|
|
251
|
+
4. **Cross-federation streaming**: How do events propagate across federated systems?
|
|
252
|
+
5. **Snapshot frequency**: How often should state snapshots be created?
|