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,510 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Full Integration
|
|
3
|
+
parent: Examples
|
|
4
|
+
nav_order: 3
|
|
5
|
+
description: "Complete end-to-end application"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Full Integration
|
|
9
|
+
{: .no_toc }
|
|
10
|
+
|
|
11
|
+
A complete application demonstrating all MAP concepts.
|
|
12
|
+
{: .fs-6 .fw-300 }
|
|
13
|
+
|
|
14
|
+
## Table of contents
|
|
15
|
+
{: .no_toc .text-delta }
|
|
16
|
+
|
|
17
|
+
1. TOC
|
|
18
|
+
{:toc}
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
This example brings together all MAP concepts:
|
|
25
|
+
- Server with authentication
|
|
26
|
+
- Multiple agent types with roles
|
|
27
|
+
- Scopes for collaboration
|
|
28
|
+
- Client dashboard with real-time updates
|
|
29
|
+
- Error handling and reconnection
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
flowchart TB
|
|
37
|
+
subgraph Server["MAP Server"]
|
|
38
|
+
EventBus["EventBus"]
|
|
39
|
+
Agents["Agents"]
|
|
40
|
+
Scopes["Scopes"]
|
|
41
|
+
Subs["Subscriptions"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
Dashboard["Dashboard<br/>(Client)"] --> Server
|
|
45
|
+
Coordinator["Coordinator<br/>(Agent)"] --> Server
|
|
46
|
+
Workers["Workers<br/>(Agents)"] --> Server
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Server with Authentication
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// server.ts
|
|
55
|
+
import { MAPServer } from "@multi-agent-protocol/sdk/server";
|
|
56
|
+
import { WebSocketServer } from "ws";
|
|
57
|
+
import jwt from "jsonwebtoken";
|
|
58
|
+
|
|
59
|
+
const JWT_SECRET = process.env.JWT_SECRET || "development-secret";
|
|
60
|
+
|
|
61
|
+
const server = new MAPServer({
|
|
62
|
+
name: "ProductionServer",
|
|
63
|
+
version: "1.0.0",
|
|
64
|
+
|
|
65
|
+
auth: {
|
|
66
|
+
required: process.env.NODE_ENV === "production",
|
|
67
|
+
methods: ["bearer", "none"],
|
|
68
|
+
|
|
69
|
+
validate: async (credentials) => {
|
|
70
|
+
if (credentials.method === "none") {
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
principal: { id: "anonymous", claims: { role: "guest" } },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (credentials.method === "bearer") {
|
|
78
|
+
try {
|
|
79
|
+
const payload = jwt.verify(credentials.credential!, JWT_SECRET);
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
principal: {
|
|
83
|
+
id: payload.sub as string,
|
|
84
|
+
claims: payload,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
} catch {
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: { code: "invalid_credentials", message: "Invalid token" },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return { success: false, error: { code: "method_not_supported", message: "Unknown method" } };
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
middleware: [
|
|
100
|
+
// Logging
|
|
101
|
+
async (method, params, ctx, next) => {
|
|
102
|
+
const start = Date.now();
|
|
103
|
+
console.log(`[${ctx.session.id}] → ${method}`);
|
|
104
|
+
const result = await next();
|
|
105
|
+
console.log(`[${ctx.session.id}] ← ${method} (${Date.now() - start}ms)`);
|
|
106
|
+
return result;
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
|
|
110
|
+
additionalHandlers: {
|
|
111
|
+
"stats/overview": async () => ({
|
|
112
|
+
agents: server.agents.list().length,
|
|
113
|
+
scopes: server.scopes.list().length,
|
|
114
|
+
connections: server.connections.size,
|
|
115
|
+
uptime: process.uptime(),
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Track statistics
|
|
121
|
+
let messagesProcessed = 0;
|
|
122
|
+
server.on("message.sent", () => messagesProcessed++);
|
|
123
|
+
|
|
124
|
+
const wss = new WebSocketServer({ port: 8080 });
|
|
125
|
+
|
|
126
|
+
wss.on("connection", (ws, req) => {
|
|
127
|
+
console.log(`New connection from ${req.socket.remoteAddress}`);
|
|
128
|
+
server.accept(websocketToStream(ws)).start();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Graceful shutdown
|
|
132
|
+
process.on("SIGTERM", async () => {
|
|
133
|
+
console.log("Shutting down...");
|
|
134
|
+
await server.close({ timeout: 10000 });
|
|
135
|
+
wss.close();
|
|
136
|
+
process.exit(0);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
console.log("Server running on ws://localhost:8080");
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Coordinator Agent
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// coordinator.ts
|
|
148
|
+
import { AgentConnection } from "@multi-agent-protocol/sdk";
|
|
149
|
+
|
|
150
|
+
interface Task {
|
|
151
|
+
id: string;
|
|
152
|
+
type: string;
|
|
153
|
+
data: unknown;
|
|
154
|
+
submitter: string;
|
|
155
|
+
assignedTo?: string;
|
|
156
|
+
status: "pending" | "assigned" | "completed" | "failed";
|
|
157
|
+
createdAt: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function main() {
|
|
161
|
+
const agent = new AgentConnection(await connect(), {
|
|
162
|
+
name: "Coordinator",
|
|
163
|
+
role: "coordinator",
|
|
164
|
+
metadata: {
|
|
165
|
+
version: "1.0.0",
|
|
166
|
+
capabilities: ["task-routing", "load-balancing"],
|
|
167
|
+
},
|
|
168
|
+
reconnect: { enabled: true },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
await agent.connect();
|
|
172
|
+
console.log("Coordinator started");
|
|
173
|
+
|
|
174
|
+
// Create work scope
|
|
175
|
+
const workScope = await agent.createScope({
|
|
176
|
+
name: "work-queue",
|
|
177
|
+
metadata: { maxWorkers: 10 },
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// State
|
|
181
|
+
const workers = new Map<string, { busy: boolean; tasksCompleted: number }>();
|
|
182
|
+
const tasks = new Map<string, Task>();
|
|
183
|
+
const pendingQueue: string[] = [];
|
|
184
|
+
|
|
185
|
+
// Subscribe to events
|
|
186
|
+
const sub = await agent.subscribe({
|
|
187
|
+
eventTypes: ["scope.joined", "scope.left", "agent.unregistered"],
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Event processing
|
|
191
|
+
(async () => {
|
|
192
|
+
for await (const event of sub) {
|
|
193
|
+
handleEvent(event);
|
|
194
|
+
}
|
|
195
|
+
})();
|
|
196
|
+
|
|
197
|
+
function handleEvent(event: any) {
|
|
198
|
+
switch (event.type) {
|
|
199
|
+
case "scope.joined":
|
|
200
|
+
if (event.data.scopeId === workScope.id && event.data.agentId !== agent.id) {
|
|
201
|
+
workers.set(event.data.agentId, { busy: false, tasksCompleted: 0 });
|
|
202
|
+
console.log(`Worker joined: ${event.data.agentId}`);
|
|
203
|
+
processQueue();
|
|
204
|
+
}
|
|
205
|
+
break;
|
|
206
|
+
|
|
207
|
+
case "scope.left":
|
|
208
|
+
case "agent.unregistered":
|
|
209
|
+
if (workers.has(event.data.agentId)) {
|
|
210
|
+
workers.delete(event.data.agentId);
|
|
211
|
+
console.log(`Worker left: ${event.data.agentId}`);
|
|
212
|
+
// Reassign their tasks
|
|
213
|
+
reassignTasks(event.data.agentId);
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Message handling
|
|
220
|
+
agent.onMessage(async (message) => {
|
|
221
|
+
const { type } = message.payload;
|
|
222
|
+
|
|
223
|
+
switch (type) {
|
|
224
|
+
case "submit-task":
|
|
225
|
+
handleSubmitTask(message);
|
|
226
|
+
break;
|
|
227
|
+
|
|
228
|
+
case "task-result":
|
|
229
|
+
handleTaskResult(message);
|
|
230
|
+
break;
|
|
231
|
+
|
|
232
|
+
case "get-status":
|
|
233
|
+
await sendStatus(message.from);
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
function handleSubmitTask(message: any) {
|
|
239
|
+
const task: Task = {
|
|
240
|
+
id: `task-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
241
|
+
type: message.payload.taskType,
|
|
242
|
+
data: message.payload.data,
|
|
243
|
+
submitter: message.from,
|
|
244
|
+
status: "pending",
|
|
245
|
+
createdAt: Date.now(),
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
tasks.set(task.id, task);
|
|
249
|
+
pendingQueue.push(task.id);
|
|
250
|
+
console.log(`Task ${task.id} queued`);
|
|
251
|
+
|
|
252
|
+
processQueue();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function handleTaskResult(message: any) {
|
|
256
|
+
const { taskId, success, result, error } = message.payload;
|
|
257
|
+
const task = tasks.get(taskId);
|
|
258
|
+
|
|
259
|
+
if (task) {
|
|
260
|
+
task.status = success ? "completed" : "failed";
|
|
261
|
+
|
|
262
|
+
const worker = workers.get(message.from);
|
|
263
|
+
if (worker) {
|
|
264
|
+
worker.busy = false;
|
|
265
|
+
if (success) worker.tasksCompleted++;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Notify submitter
|
|
269
|
+
agent.send({
|
|
270
|
+
to: { agentId: task.submitter },
|
|
271
|
+
payload: {
|
|
272
|
+
type: "task-completed",
|
|
273
|
+
taskId,
|
|
274
|
+
success,
|
|
275
|
+
result,
|
|
276
|
+
error,
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
console.log(`Task ${taskId}: ${task.status}`);
|
|
281
|
+
processQueue();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function processQueue() {
|
|
286
|
+
while (pendingQueue.length > 0) {
|
|
287
|
+
const availableWorker = [...workers.entries()].find(([, w]) => !w.busy);
|
|
288
|
+
if (!availableWorker) break;
|
|
289
|
+
|
|
290
|
+
const taskId = pendingQueue.shift()!;
|
|
291
|
+
const task = tasks.get(taskId)!;
|
|
292
|
+
const [workerId, worker] = availableWorker;
|
|
293
|
+
|
|
294
|
+
task.status = "assigned";
|
|
295
|
+
task.assignedTo = workerId;
|
|
296
|
+
worker.busy = true;
|
|
297
|
+
|
|
298
|
+
agent.send({
|
|
299
|
+
to: { agentId: workerId },
|
|
300
|
+
payload: { type: "task", task },
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
console.log(`Task ${taskId} assigned to ${workerId}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function reassignTasks(workerId: string) {
|
|
308
|
+
for (const [taskId, task] of tasks) {
|
|
309
|
+
if (task.assignedTo === workerId && task.status === "assigned") {
|
|
310
|
+
task.status = "pending";
|
|
311
|
+
task.assignedTo = undefined;
|
|
312
|
+
pendingQueue.unshift(taskId);
|
|
313
|
+
console.log(`Task ${taskId} requeued`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
processQueue();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async function sendStatus(to: string) {
|
|
320
|
+
await agent.send({
|
|
321
|
+
to: { agentId: to },
|
|
322
|
+
payload: {
|
|
323
|
+
type: "status",
|
|
324
|
+
workers: workers.size,
|
|
325
|
+
pendingTasks: pendingQueue.length,
|
|
326
|
+
totalTasks: tasks.size,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
console.log(`Work scope created: ${workScope.id}`);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
main().catch(console.error);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Worker Agent
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// worker.ts
|
|
343
|
+
import { AgentConnection } from "@multi-agent-protocol/sdk";
|
|
344
|
+
|
|
345
|
+
async function main() {
|
|
346
|
+
const name = process.argv[2] || `Worker-${Date.now()}`;
|
|
347
|
+
|
|
348
|
+
const agent = new AgentConnection(await connect(), {
|
|
349
|
+
name,
|
|
350
|
+
role: "worker",
|
|
351
|
+
metadata: { capabilities: ["compute"] },
|
|
352
|
+
reconnect: { enabled: true },
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const { agent: registered } = await agent.connect();
|
|
356
|
+
console.log(`Worker ${name} started (${registered.id})`);
|
|
357
|
+
|
|
358
|
+
// Find and join work scope
|
|
359
|
+
const { scopes } = await agent.listScopes();
|
|
360
|
+
const workScope = scopes.find((s) => s.name === "work-queue");
|
|
361
|
+
|
|
362
|
+
if (workScope) {
|
|
363
|
+
await agent.joinScope(workScope.id);
|
|
364
|
+
console.log("Joined work queue");
|
|
365
|
+
} else {
|
|
366
|
+
// Wait for scope to be created
|
|
367
|
+
const sub = await agent.subscribe({ eventTypes: ["scope.created"] });
|
|
368
|
+
for await (const event of sub) {
|
|
369
|
+
if (event.data.scope.name === "work-queue") {
|
|
370
|
+
await agent.joinScope(event.data.scope.id);
|
|
371
|
+
console.log("Joined work queue");
|
|
372
|
+
await sub.unsubscribe();
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Handle tasks
|
|
379
|
+
agent.onMessage(async (message) => {
|
|
380
|
+
if (message.payload.type === "task") {
|
|
381
|
+
const { task } = message.payload;
|
|
382
|
+
console.log(`Processing: ${task.id} (${task.type})`);
|
|
383
|
+
|
|
384
|
+
await agent.update({ state: "busy", metadata: { currentTask: task.id } });
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
// Simulate work
|
|
388
|
+
const result = await processTask(task);
|
|
389
|
+
|
|
390
|
+
await agent.send({
|
|
391
|
+
to: { agentId: message.from },
|
|
392
|
+
payload: { type: "task-result", taskId: task.id, success: true, result },
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
console.log(`Completed: ${task.id}`);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
await agent.send({
|
|
398
|
+
to: { agentId: message.from },
|
|
399
|
+
payload: { type: "task-result", taskId: task.id, success: false, error: error.message },
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
console.log(`Failed: ${task.id} - ${error.message}`);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
await agent.update({ state: "running", metadata: { currentTask: null } });
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
console.log("Ready for work");
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async function processTask(task: any) {
|
|
413
|
+
// Simulate processing time
|
|
414
|
+
await new Promise((r) => setTimeout(r, 1000 + Math.random() * 2000));
|
|
415
|
+
return { processed: true, timestamp: Date.now() };
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
main().catch(console.error);
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Dashboard Client
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
// dashboard.ts
|
|
427
|
+
import { ClientConnection } from "@multi-agent-protocol/sdk";
|
|
428
|
+
|
|
429
|
+
async function main() {
|
|
430
|
+
const client = new ClientConnection(await connect(), {
|
|
431
|
+
name: "Dashboard",
|
|
432
|
+
reconnect: { enabled: true },
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
client.onStateChange((state) => {
|
|
436
|
+
console.log(`Connection: ${state}`);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
const { systemInfo } = await client.connect();
|
|
440
|
+
console.log(`Connected to ${systemInfo?.name}`);
|
|
441
|
+
|
|
442
|
+
// Initial state
|
|
443
|
+
await refreshState();
|
|
444
|
+
|
|
445
|
+
// Subscribe to all events
|
|
446
|
+
const sub = await client.subscribe({ eventTypes: ["*"] });
|
|
447
|
+
|
|
448
|
+
console.log("\nMonitoring events...\n");
|
|
449
|
+
|
|
450
|
+
for await (const event of sub) {
|
|
451
|
+
console.log(`[${new Date().toISOString()}] ${event.type}`);
|
|
452
|
+
|
|
453
|
+
if (event.type.startsWith("agent.")) {
|
|
454
|
+
await refreshState();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
async function refreshState() {
|
|
459
|
+
const { agents } = await client.listAgents();
|
|
460
|
+
const { scopes } = await client.listScopes();
|
|
461
|
+
|
|
462
|
+
console.log("\n--- System State ---");
|
|
463
|
+
console.log(`Agents: ${agents.length}`);
|
|
464
|
+
agents.forEach((a) => {
|
|
465
|
+
console.log(` ${a.name} (${a.role}) - ${a.state}`);
|
|
466
|
+
});
|
|
467
|
+
console.log(`Scopes: ${scopes.length}`);
|
|
468
|
+
scopes.forEach((s) => {
|
|
469
|
+
console.log(` ${s.name}`);
|
|
470
|
+
});
|
|
471
|
+
console.log("-------------------\n");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
main().catch(console.error);
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Running the Full Example
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# Terminal 1: Server
|
|
484
|
+
npx ts-node server.ts
|
|
485
|
+
|
|
486
|
+
# Terminal 2: Coordinator
|
|
487
|
+
npx ts-node coordinator.ts
|
|
488
|
+
|
|
489
|
+
# Terminal 3-5: Workers
|
|
490
|
+
npx ts-node worker.ts Worker1
|
|
491
|
+
npx ts-node worker.ts Worker2
|
|
492
|
+
npx ts-node worker.ts Worker3
|
|
493
|
+
|
|
494
|
+
# Terminal 6: Dashboard
|
|
495
|
+
npx ts-node dashboard.ts
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Concepts Demonstrated
|
|
501
|
+
|
|
502
|
+
- **Authentication** with JWT tokens
|
|
503
|
+
- **Middleware** for logging
|
|
504
|
+
- **Custom handlers** for stats
|
|
505
|
+
- **Scopes** for work distribution
|
|
506
|
+
- **Coordinator pattern** with load balancing
|
|
507
|
+
- **Worker pool** with task reassignment
|
|
508
|
+
- **Real-time dashboard** with event subscription
|
|
509
|
+
- **Reconnection** handling
|
|
510
|
+
- **Graceful shutdown**
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Examples
|
|
3
|
+
nav_order: 5
|
|
4
|
+
has_children: true
|
|
5
|
+
description: "Complete working examples"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Examples
|
|
9
|
+
|
|
10
|
+
Complete working examples demonstrating MAP patterns.
|
|
11
|
+
{: .fs-6 .fw-300 }
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Available Examples
|
|
16
|
+
|
|
17
|
+
| Example | Description | Concepts |
|
|
18
|
+
|:--------|:------------|:---------|
|
|
19
|
+
| [Simple Chat](./simple-chat.html) | Basic agent-to-agent messaging | Agents, messaging |
|
|
20
|
+
| [Task Queue](./task-queue.html) | Work distribution with scopes | Scopes, coordination |
|
|
21
|
+
| [Full Integration](./full-integration.html) | Complete end-to-end application | All concepts |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Running Examples
|
|
26
|
+
|
|
27
|
+
All examples are available in the SDK repository:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git clone https://github.com/multi-agent-protocol/multi-agent-protocol.git
|
|
31
|
+
cd multi-agent-protocol/ts-sdk/examples
|
|
32
|
+
npm install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Each example has its own README with specific instructions.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Example Patterns
|
|
40
|
+
|
|
41
|
+
### Pattern 1: Hub and Spoke
|
|
42
|
+
|
|
43
|
+
One coordinator, multiple workers:
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
flowchart TB
|
|
47
|
+
Client["Client"]
|
|
48
|
+
Coord["Coordinator"]
|
|
49
|
+
W1["Worker 1"]
|
|
50
|
+
W2["Worker 2"]
|
|
51
|
+
W3["Worker 3"]
|
|
52
|
+
|
|
53
|
+
Client --> Coord
|
|
54
|
+
Coord --> W1
|
|
55
|
+
Coord --> W2
|
|
56
|
+
Coord --> W3
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Pattern 2: Peer Collaboration
|
|
60
|
+
|
|
61
|
+
Agents collaborate through shared scopes:
|
|
62
|
+
|
|
63
|
+
```mermaid
|
|
64
|
+
flowchart TB
|
|
65
|
+
subgraph ScopeA["Scope A"]
|
|
66
|
+
A1["Agent 1"]
|
|
67
|
+
A2["Agent 2"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
subgraph ScopeB["Scope B"]
|
|
71
|
+
A2b["Agent 2"]
|
|
72
|
+
A3["Agent 3"]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
A2 -.->|"shared"| A2b
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Pattern 3: Pipeline
|
|
79
|
+
|
|
80
|
+
Sequential processing through agents:
|
|
81
|
+
|
|
82
|
+
```mermaid
|
|
83
|
+
flowchart LR
|
|
84
|
+
Input["Input"] --> Agent1["Agent 1"]
|
|
85
|
+
Agent1 --> Agent2["Agent 2"]
|
|
86
|
+
Agent2 --> Agent3["Agent 3"]
|
|
87
|
+
Agent3 --> Output["Output"]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Quick Start Template
|
|
93
|
+
|
|
94
|
+
Here's a minimal template to start a new MAP application:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// server.ts
|
|
98
|
+
import { MAPServer } from "@multi-agent-protocol/sdk/server";
|
|
99
|
+
import { WebSocketServer } from "ws";
|
|
100
|
+
|
|
101
|
+
const server = new MAPServer({ name: "MyServer" });
|
|
102
|
+
const wss = new WebSocketServer({ port: 8080 });
|
|
103
|
+
|
|
104
|
+
wss.on("connection", (ws) => {
|
|
105
|
+
server.accept(websocketToStream(ws)).start();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
console.log("Server running on ws://localhost:8080");
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// agent.ts
|
|
113
|
+
import { AgentConnection } from "@multi-agent-protocol/sdk";
|
|
114
|
+
|
|
115
|
+
const agent = new AgentConnection(stream, {
|
|
116
|
+
name: "MyAgent",
|
|
117
|
+
role: "worker",
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await agent.connect();
|
|
121
|
+
|
|
122
|
+
agent.onMessage(async (message) => {
|
|
123
|
+
// Handle messages
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// client.ts
|
|
129
|
+
import { ClientConnection } from "@multi-agent-protocol/sdk";
|
|
130
|
+
|
|
131
|
+
const client = new ClientConnection(stream, { name: "MyClient" });
|
|
132
|
+
await client.connect();
|
|
133
|
+
|
|
134
|
+
const subscription = await client.subscribe({ eventTypes: ["*"] });
|
|
135
|
+
for await (const event of subscription) {
|
|
136
|
+
// Handle events
|
|
137
|
+
}
|
|
138
|
+
```
|