macro-agent 0.0.13 → 0.0.15
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/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/index.d.ts +1 -1
- package/dist/map/adapter/index.d.ts.map +1 -1
- package/dist/map/adapter/index.js +1 -1
- package/dist/map/adapter/index.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/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +8 -1
- package/dist/server/combined-server.js.map +1 -1
- 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/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/index.ts +3 -0
- package/src/server/combined-server.ts +10 -0
- package/src/store/event-store.ts +10 -3
- package/src/store/types/agents.ts +2 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# MAP Federation & System-to-System Communication
|
|
2
|
+
|
|
3
|
+
This spec details how multiple MAP systems can communicate with each other, enabling distributed multi-agent architectures while maintaining internal transparency.
|
|
4
|
+
|
|
5
|
+
## Design Principles
|
|
6
|
+
|
|
7
|
+
1. **Internal transparency, external opacity**: Each system is transparent internally but appears as a single entity externally
|
|
8
|
+
2. **MAP-native federation**: Systems communicate via MAP protocol, not A2A
|
|
9
|
+
3. **Gateway pattern**: Dedicated agents handle inter-system routing
|
|
10
|
+
4. **Selective exposure**: Each system controls what's visible to peers
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Federation Model
|
|
15
|
+
|
|
16
|
+
### Conceptual View
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌──────────────────────────────────────────────────────────────────────────┐
|
|
20
|
+
│ Federation │
|
|
21
|
+
├──────────────────────────────────────────────────────────────────────────┤
|
|
22
|
+
│ │
|
|
23
|
+
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
|
24
|
+
│ │ MAP System "Alpha" │ │ MAP System "Beta" │ │
|
|
25
|
+
│ │ │ │ │ │
|
|
26
|
+
│ │ Internal agents: │ │ Internal agents: │ │
|
|
27
|
+
│ │ ┌───┐ ┌───┐ ┌───┐ │ MAP │ ┌───┐ ┌───┐ ┌───┐ │ │
|
|
28
|
+
│ │ │ A │ │ B │ │ C │ │ ◄─────► │ │ X │ │ Y │ │ Z │ │ │
|
|
29
|
+
│ │ └─┬─┘ └─┬─┘ └─┬─┘ │ │ └─┬─┘ └─┬─┘ └─┬─┘ │ │
|
|
30
|
+
│ │ └─────┼─────┘ │ │ └─────┼─────┘ │ │
|
|
31
|
+
│ │ │ │ │ │ │ │
|
|
32
|
+
│ │ ┌─────▼─────┐ │ │ ┌─────▼─────┐ │ │
|
|
33
|
+
│ │ │ Gateway │───────┼─────────┼────│ Gateway │ │ │
|
|
34
|
+
│ │ └───────────┘ │ │ └───────────┘ │ │
|
|
35
|
+
│ │ │ │ │ │
|
|
36
|
+
│ └─────────────────────────┘ └─────────────────────────┘ │
|
|
37
|
+
│ │
|
|
38
|
+
└──────────────────────────────────────────────────────────────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Why MAP for Federation (not A2A)?
|
|
42
|
+
|
|
43
|
+
| Aspect | A2A | MAP Federation |
|
|
44
|
+
|--------|-----|----------------|
|
|
45
|
+
| Visibility | Opaque peers | Configurable exposure |
|
|
46
|
+
| Streaming | Task-focused | Full event streams |
|
|
47
|
+
| Structure | Flat | Can expose partial hierarchy |
|
|
48
|
+
| Discovery | Agent Cards | Direct connection |
|
|
49
|
+
| Use case | Cross-org | Same-org distributed |
|
|
50
|
+
|
|
51
|
+
MAP federation is for **systems that trust each other** and want shared visibility.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Federation Configuration
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
interface MAPFederationConfig {
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
systemId: string;
|
|
61
|
+
systemInfo: {
|
|
62
|
+
name: string;
|
|
63
|
+
version: string;
|
|
64
|
+
endpoint: string;
|
|
65
|
+
};
|
|
66
|
+
peers: MAPPeerConfig[];
|
|
67
|
+
exposure: MAPFederationExposure;
|
|
68
|
+
security: MAPFederationSecurity;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface MAPPeerConfig {
|
|
72
|
+
systemId: string;
|
|
73
|
+
endpoint: string;
|
|
74
|
+
connection: {
|
|
75
|
+
autoConnect: boolean;
|
|
76
|
+
reconnect: boolean;
|
|
77
|
+
healthCheckInterval: number;
|
|
78
|
+
};
|
|
79
|
+
accepts: {
|
|
80
|
+
messageTypes: string[];
|
|
81
|
+
maxMessagesPerMinute: number;
|
|
82
|
+
};
|
|
83
|
+
auth: {
|
|
84
|
+
method: "mutual-tls" | "bearer" | "api-key";
|
|
85
|
+
credentials: unknown;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface MAPFederationExposure {
|
|
90
|
+
agents: {
|
|
91
|
+
expose: "none" | "gateway" | "tagged" | "all";
|
|
92
|
+
tags?: string[];
|
|
93
|
+
};
|
|
94
|
+
scopes: {
|
|
95
|
+
expose: "none" | "tagged" | "all";
|
|
96
|
+
tags?: string[];
|
|
97
|
+
};
|
|
98
|
+
events: {
|
|
99
|
+
expose: string[];
|
|
100
|
+
};
|
|
101
|
+
structure: boolean;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Gateway Agent Pattern
|
|
108
|
+
|
|
109
|
+
Each system has a gateway agent that:
|
|
110
|
+
1. Handles connections from peer systems
|
|
111
|
+
2. Routes messages between internal agents and peers
|
|
112
|
+
3. Enforces exposure policies
|
|
113
|
+
4. Translates addresses
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Federation Protocol
|
|
118
|
+
|
|
119
|
+
### Connection Establishment
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
{
|
|
123
|
+
"method": "map/federation/connect",
|
|
124
|
+
"params": {
|
|
125
|
+
"systemId": "alpha",
|
|
126
|
+
"systemInfo": {
|
|
127
|
+
"name": "Alpha System",
|
|
128
|
+
"version": "1.0.0",
|
|
129
|
+
"endpoint": "wss://alpha.example.com/map"
|
|
130
|
+
},
|
|
131
|
+
"protocolVersion": "2025-01-01",
|
|
132
|
+
"auth": {
|
|
133
|
+
"method": "mutual-tls",
|
|
134
|
+
"certificate": "..."
|
|
135
|
+
},
|
|
136
|
+
"exposure": {
|
|
137
|
+
"agents": { "expose": "tagged", "tags": ["public"] },
|
|
138
|
+
"scopes": { "expose": "tagged", "tags": ["federation"] },
|
|
139
|
+
"events": { "expose": ["message.sent", "agent.state"] }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Cross-System Messaging
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
{
|
|
149
|
+
"method": "map/federation/send",
|
|
150
|
+
"params": {
|
|
151
|
+
"peerId": "beta",
|
|
152
|
+
"message": {
|
|
153
|
+
"from": "agent_a",
|
|
154
|
+
"to": { "agent": "agent_x" },
|
|
155
|
+
"payload": {
|
|
156
|
+
"type": "task_request",
|
|
157
|
+
"data": { ... }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Addressing in Federation
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
type MAPFederatedAddress =
|
|
170
|
+
| { system: string; agent: string }
|
|
171
|
+
| { system: string; scope: string }
|
|
172
|
+
| { system: string; role: string }
|
|
173
|
+
| { federation: true }
|
|
174
|
+
| { federation: true; systems: string[] }
|
|
175
|
+
| { gateway: string; target: MAPAddress };
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Use Cases
|
|
181
|
+
|
|
182
|
+
### Use Case 1: Distributed Workload
|
|
183
|
+
|
|
184
|
+
Alpha handles task coordination, Beta handles execution.
|
|
185
|
+
|
|
186
|
+
### Use Case 2: Regional Distribution
|
|
187
|
+
|
|
188
|
+
Each region has its own MAP system, federated for global coordination.
|
|
189
|
+
|
|
190
|
+
### Use Case 3: Secure Computation
|
|
191
|
+
|
|
192
|
+
Sensitive computation isolated in secure system, federated for I/O.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Federation vs A2A: When to Use Which
|
|
197
|
+
|
|
198
|
+
| Scenario | Use | Reason |
|
|
199
|
+
|----------|-----|--------|
|
|
200
|
+
| Internal distributed system | MAP Federation | Need visibility, trust exists |
|
|
201
|
+
| External partner integration | A2A | Opaque peers, no visibility needed |
|
|
202
|
+
| Multi-cloud same org | MAP Federation | Control over both systems |
|
|
203
|
+
| Third-party service | A2A | Don't control peer system |
|
|
204
|
+
| Hierarchical multi-region | MAP Federation | Want structure visibility |
|
|
205
|
+
| Ad-hoc collaboration | A2A | Dynamic peer discovery |
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Security Considerations
|
|
210
|
+
|
|
211
|
+
### Authentication
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
type MAPFederationAuth =
|
|
215
|
+
| { method: "mutual-tls"; certificate: string }
|
|
216
|
+
| { method: "bearer"; token: string }
|
|
217
|
+
| { method: "api-key"; key: string }
|
|
218
|
+
| { method: "oauth2"; config: OAuth2Config };
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Message Signing
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
interface MAPFederationEnvelope {
|
|
225
|
+
message: MAPMessage;
|
|
226
|
+
federation: {
|
|
227
|
+
sourceSystem: string;
|
|
228
|
+
targetSystem: string;
|
|
229
|
+
hopCount: number;
|
|
230
|
+
timestamp: number;
|
|
231
|
+
signature?: string;
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Failure Handling
|
|
239
|
+
|
|
240
|
+
### Message Queue During Outage
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
interface MAPFederationQueueConfig {
|
|
244
|
+
queueOnDisconnect: boolean;
|
|
245
|
+
maxQueueDuration: number;
|
|
246
|
+
maxQueueSize: number;
|
|
247
|
+
overflowPolicy: "drop-oldest" | "drop-newest" | "reject-new";
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Open Questions
|
|
254
|
+
|
|
255
|
+
1. **Transitive federation**: If A↔B and B↔C, can A route to C via B?
|
|
256
|
+
2. **Federation discovery**: Should there be a discovery mechanism for finding peers?
|
|
257
|
+
3. **Consistency**: How to handle concurrent updates across federated systems?
|
|
258
|
+
4. **Schema versioning**: What if peers have different protocol versions?
|
|
259
|
+
5. **Audit requirements**: What federation activity must be logged?
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# macro-agent Migration to MAP
|
|
2
|
+
|
|
3
|
+
This spec provides a concrete example of how the existing macro-agent implementation would migrate to use MAP, demonstrating the protocol's practical application.
|
|
4
|
+
|
|
5
|
+
## Current Architecture Recap
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ macro-agent Today │
|
|
10
|
+
├─────────────────────────────────────────────────────────────┤
|
|
11
|
+
│ │
|
|
12
|
+
│ External Layer │
|
|
13
|
+
│ • ACP (via MacroAgent class) │
|
|
14
|
+
│ • REST API (Express server) │
|
|
15
|
+
│ • WebSocket server │
|
|
16
|
+
│ │
|
|
17
|
+
│ Communication Layers (3 separate systems) │
|
|
18
|
+
│ 1. ACP Extensions (_macro/*) │
|
|
19
|
+
│ 2. MessageRouter (6 channel types) │
|
|
20
|
+
│ 3. PeerManager (cross-instance) │
|
|
21
|
+
│ │
|
|
22
|
+
│ Core Components │
|
|
23
|
+
│ • AgentManager (lifecycle) │
|
|
24
|
+
│ • EventStore (persistence) │
|
|
25
|
+
│ • TaskManager / TaskBackend │
|
|
26
|
+
│ • WorkspaceManager (git worktrees) │
|
|
27
|
+
│ • MergeQueue │
|
|
28
|
+
│ • RoleRegistry │
|
|
29
|
+
│ │
|
|
30
|
+
└─────────────────────────────────────────────────────────────┘
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Migration Strategy
|
|
36
|
+
|
|
37
|
+
### Phase 1: Protocol Adapter Layer
|
|
38
|
+
|
|
39
|
+
Add MAP as an alternative protocol layer without changing internals.
|
|
40
|
+
|
|
41
|
+
### Phase 2: Unified Communication
|
|
42
|
+
|
|
43
|
+
Replace MessageRouter + PeerManager with MAP-native implementation.
|
|
44
|
+
|
|
45
|
+
### Phase 3: Full MAP Native
|
|
46
|
+
|
|
47
|
+
All components use MAP primitives.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Component Mapping
|
|
52
|
+
|
|
53
|
+
| macro-agent Component | MAP Equivalent |
|
|
54
|
+
|----------------------|----------------|
|
|
55
|
+
| `AgentManager.spawn()` | `map/agent.register` |
|
|
56
|
+
| `AgentManager.getHierarchy()` | `map/hierarchy.get` |
|
|
57
|
+
| `MessageRouter.send()` | `map/send` |
|
|
58
|
+
| `MessageRouter.subscribe()` | `map/subscribe` |
|
|
59
|
+
| `Broadcast channels` | `map/broadcast` + Scopes |
|
|
60
|
+
| `Role channels` | Role-based addressing |
|
|
61
|
+
| `PeerManager.sendMessage()` | `map/send` to federated address |
|
|
62
|
+
| `injectContext()` | `map/inject` |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Code Examples
|
|
67
|
+
|
|
68
|
+
### Before: Spawning an Agent (ACP Extension)
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Current: src/acp/macro-agent.ts
|
|
72
|
+
async handleSpawnAgent(params, sessionId) {
|
|
73
|
+
const mapping = this.sessionMapper.getMapping(sessionId);
|
|
74
|
+
const parentId = params.parentId ?? mapping?.agentId;
|
|
75
|
+
|
|
76
|
+
// Check role capability
|
|
77
|
+
if (params.role) {
|
|
78
|
+
const capability = `agent.spawn.${params.role}`;
|
|
79
|
+
if (!this.roleRegistry.hasCapability(parentAgent.role, capability)) {
|
|
80
|
+
throw new ACPError("Cannot spawn this role", "CAPABILITY_DENIED");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const result = await this.agentManager.spawn({ ... });
|
|
85
|
+
return { agentId: result.agentId, taskId: result.taskId };
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### After: Spawning an Agent (MAP)
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// New: src/map/handlers/agent.ts
|
|
93
|
+
async handleAgentRegister(params, context) {
|
|
94
|
+
// Role capability check is now protocol-level
|
|
95
|
+
|
|
96
|
+
const agent = await this.registry.registerAgent({
|
|
97
|
+
id: generateAgentId(),
|
|
98
|
+
name: params.name,
|
|
99
|
+
role: params.role,
|
|
100
|
+
parent: params.parent ?? context.agentId,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const process = await this.processManager.spawn({
|
|
104
|
+
agentId: agent.id,
|
|
105
|
+
role: params.role,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await this.events.emit({ type: "agent.registered", agent });
|
|
109
|
+
|
|
110
|
+
return { agentId: agent.id, registered: true };
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Before: Sending a Message
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Current: MessageRouter
|
|
118
|
+
async send(from, channel, message) {
|
|
119
|
+
const recipients = await this.resolveChannel(channel, from);
|
|
120
|
+
const wakeAction = this.determineWakeAction(message.priority);
|
|
121
|
+
|
|
122
|
+
for (const recipientId of recipients) {
|
|
123
|
+
// Complex wake/inject/queue logic
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
await this.eventStore.emit({ type: "message_sent", ... });
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### After: Sending a Message (MAP)
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// New: Using MAP SDK
|
|
134
|
+
await this.map.send({
|
|
135
|
+
to: { role: "worker", within: "scope_active" },
|
|
136
|
+
payload: { type: "task_assignment", task: { id: "task_001" } },
|
|
137
|
+
meta: { priority: "high", delivery: "inject" }
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Before: Context Injection
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// Current: src/steering/inject.ts
|
|
145
|
+
export async function injectContext(agentId, content, deps) {
|
|
146
|
+
const session = await deps.agentManager.getSession(agentId);
|
|
147
|
+
|
|
148
|
+
// Try inject → interrupt → message fallback
|
|
149
|
+
if (session.inject) { ... }
|
|
150
|
+
if (session.interruptWith) { ... }
|
|
151
|
+
await deps.messageRouter.send(...);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### After: Context Injection (MAP)
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// MAP inject with explicit semantics
|
|
159
|
+
await this.map.inject({
|
|
160
|
+
to: { agent: agentId },
|
|
161
|
+
payload: { content },
|
|
162
|
+
meta: {
|
|
163
|
+
delivery: "best-effort", // Try inject → interrupt → queue
|
|
164
|
+
priority: "high"
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Subscription Migration
|
|
172
|
+
|
|
173
|
+
### Before: Multiple subscription points
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// 1. MessageRouter subscription
|
|
177
|
+
await messageRouter.subscribe(agentId, { type: "subtree", rootId: parentId });
|
|
178
|
+
|
|
179
|
+
// 2. EventStore subscription
|
|
180
|
+
eventStore.on("task_completed", (event) => { ... });
|
|
181
|
+
|
|
182
|
+
// 3. PeerManager inbox polling
|
|
183
|
+
const messages = await peerManager.getInbox(agentId);
|
|
184
|
+
|
|
185
|
+
// 4. Session update callbacks
|
|
186
|
+
session.onUpdate((update) => { ... });
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### After: Unified Subscription (MAP)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const subscription = await this.map.subscribe({
|
|
193
|
+
streams: ["messages", "tasks", "state"],
|
|
194
|
+
filter: {
|
|
195
|
+
subtree: myAgentId,
|
|
196
|
+
eventTypes: ["message", "task.completed", "agent.state"]
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
for await (const event of subscription.events) {
|
|
201
|
+
switch (event.type) {
|
|
202
|
+
case "message": handleMessage(event.envelope); break;
|
|
203
|
+
case "task.completed": handleTaskComplete(event.task); break;
|
|
204
|
+
case "agent.state": handleStateChange(event.agentId, event.current); break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Migration Checklist
|
|
212
|
+
|
|
213
|
+
### Phase 1: Adapter Layer
|
|
214
|
+
- [ ] Add MAP SDK dependency
|
|
215
|
+
- [ ] Create MAPAdapter class wrapping existing components
|
|
216
|
+
- [ ] Implement MAP server alongside existing ACP server
|
|
217
|
+
- [ ] Add feature flag for MAP mode
|
|
218
|
+
- [ ] Write integration tests comparing ACP vs MAP behavior
|
|
219
|
+
|
|
220
|
+
### Phase 2: Unified Communication
|
|
221
|
+
- [ ] Migrate MessageRouter to use MAP addressing
|
|
222
|
+
- [ ] Migrate PeerManager to MAP federation
|
|
223
|
+
- [ ] Consolidate event subscriptions
|
|
224
|
+
- [ ] Remove duplicate event emission
|
|
225
|
+
- [ ] Update agent spawn to use MAP registration
|
|
226
|
+
|
|
227
|
+
### Phase 3: Full Native
|
|
228
|
+
- [ ] Migrate TaskManager to MAP tasks (optional)
|
|
229
|
+
- [ ] Migrate RoleRegistry to MAP roles
|
|
230
|
+
- [ ] Remove legacy communication code
|
|
231
|
+
- [ ] Update all clients to MAP
|
|
232
|
+
- [ ] Deprecate ACP extensions (keep compat layer)
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Risks & Mitigations
|
|
237
|
+
|
|
238
|
+
| Risk | Mitigation |
|
|
239
|
+
|------|------------|
|
|
240
|
+
| Breaking existing ACP clients | ACP-compat mode as fallback |
|
|
241
|
+
| Performance regression | Benchmark at each phase |
|
|
242
|
+
| Feature parity gaps | Feature flag for gradual rollout |
|
|
243
|
+
| State migration | Snapshot + replay for existing sessions |
|
|
244
|
+
| Federation complexity | Phase federation last |
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Open Questions
|
|
249
|
+
|
|
250
|
+
1. **Task backend**: Keep as separate abstraction or fully integrate?
|
|
251
|
+
2. **Workspace/git**: Should environment concept include workspace management?
|
|
252
|
+
3. **MCP tools**: Should MAP define standard tools or leave to implementation?
|
|
253
|
+
4. **Session persistence**: How to migrate existing ACP sessions to MAP?
|