@wings006/agent-link 0.1.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 +298 -0
- package/dist/a2a-client.d.ts +12 -0
- package/dist/a2a-client.js +94 -0
- package/dist/a2a-client.js.map +1 -0
- package/dist/a2a-server.d.ts +20 -0
- package/dist/a2a-server.js +168 -0
- package/dist/a2a-server.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon-api.d.ts +23 -0
- package/dist/daemon-api.js +272 -0
- package/dist/daemon-api.js.map +1 -0
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.js +141 -0
- package/dist/daemon.js.map +1 -0
- package/dist/discovery.d.ts +18 -0
- package/dist/discovery.js +104 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +13 -0
- package/dist/mcp-server.js +354 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/notify.d.ts +1 -0
- package/dist/notify.js +9 -0
- package/dist/notify.js.map +1 -0
- package/dist/relay-client.d.ts +29 -0
- package/dist/relay-client.js +199 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-server.d.ts +8 -0
- package/dist/relay-server.js +108 -0
- package/dist/relay-server.js.map +1 -0
- package/dist/task-store.d.ts +36 -0
- package/dist/task-store.js +167 -0
- package/dist/task-store.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Discovery } from "./discovery.js";
|
|
2
|
+
import type { TaskStore } from "./task-store.js";
|
|
3
|
+
import type { A2AClient } from "./a2a-client.js";
|
|
4
|
+
import type { RelayClient } from "./relay-client.js";
|
|
5
|
+
import type { AgentLinkConfig, TaskEvent } from "./types.js";
|
|
6
|
+
export declare class DaemonApi {
|
|
7
|
+
private server;
|
|
8
|
+
private config;
|
|
9
|
+
private discovery;
|
|
10
|
+
private taskStore;
|
|
11
|
+
private a2aClient;
|
|
12
|
+
private relayClient;
|
|
13
|
+
private startTime;
|
|
14
|
+
private sseClients;
|
|
15
|
+
constructor(config: AgentLinkConfig, discovery: Discovery, taskStore: TaskStore, a2aClient: A2AClient);
|
|
16
|
+
setRelayClient(client: RelayClient): void;
|
|
17
|
+
start(): Promise<number>;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
broadcastEvent(event: TaskEvent): void;
|
|
20
|
+
private handleRequest;
|
|
21
|
+
private getLocalAddress;
|
|
22
|
+
private readBody;
|
|
23
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
export class DaemonApi {
|
|
4
|
+
server;
|
|
5
|
+
config;
|
|
6
|
+
discovery;
|
|
7
|
+
taskStore;
|
|
8
|
+
a2aClient;
|
|
9
|
+
relayClient = null;
|
|
10
|
+
startTime = Date.now();
|
|
11
|
+
sseClients = new Set();
|
|
12
|
+
constructor(config, discovery, taskStore, a2aClient) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.discovery = discovery;
|
|
15
|
+
this.taskStore = taskStore;
|
|
16
|
+
this.a2aClient = a2aClient;
|
|
17
|
+
this.server = http.createServer(this.handleRequest.bind(this));
|
|
18
|
+
}
|
|
19
|
+
setRelayClient(client) {
|
|
20
|
+
this.relayClient = client;
|
|
21
|
+
}
|
|
22
|
+
start() {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const tryListen = (port) => {
|
|
25
|
+
const onError = (err) => {
|
|
26
|
+
if (err.code === "EADDRINUSE") {
|
|
27
|
+
this.server.removeListener("error", onError);
|
|
28
|
+
tryListen(0);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
reject(err);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
this.server.once("error", onError);
|
|
35
|
+
// 仅绑定 127.0.0.1,不暴露到局域网
|
|
36
|
+
this.server.listen(port, "127.0.0.1", () => {
|
|
37
|
+
this.server.removeListener("error", onError);
|
|
38
|
+
const addr = this.server.address();
|
|
39
|
+
this.config.apiPort = addr.port;
|
|
40
|
+
resolve(addr.port);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
tryListen(this.config.apiPort);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
stop() {
|
|
47
|
+
// 关闭所有 SSE 连接
|
|
48
|
+
for (const client of this.sseClients) {
|
|
49
|
+
client.end();
|
|
50
|
+
}
|
|
51
|
+
this.sseClients.clear();
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
this.server.close((err) => err ? reject(err) : resolve());
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
broadcastEvent(event) {
|
|
57
|
+
const data = `data: ${JSON.stringify(event)}\n\n`;
|
|
58
|
+
for (const client of this.sseClients) {
|
|
59
|
+
client.write(data);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async handleRequest(req, res) {
|
|
63
|
+
try {
|
|
64
|
+
// GET /api/health
|
|
65
|
+
if (req.method === "GET" && req.url === "/api/health") {
|
|
66
|
+
res.setHeader("Content-Type", "application/json");
|
|
67
|
+
const health = {
|
|
68
|
+
name: this.config.name,
|
|
69
|
+
port: this.config.port,
|
|
70
|
+
apiPort: this.config.apiPort,
|
|
71
|
+
uptime: Date.now() - this.startTime,
|
|
72
|
+
agentCount: this.discovery.getAgents().length,
|
|
73
|
+
};
|
|
74
|
+
res.writeHead(200);
|
|
75
|
+
res.end(JSON.stringify(health));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// GET /api/events (SSE)
|
|
79
|
+
if (req.method === "GET" && req.url === "/api/events") {
|
|
80
|
+
res.writeHead(200, {
|
|
81
|
+
"Content-Type": "text/event-stream",
|
|
82
|
+
"Cache-Control": "no-cache",
|
|
83
|
+
Connection: "keep-alive",
|
|
84
|
+
});
|
|
85
|
+
res.write(":ok\n\n");
|
|
86
|
+
this.sseClients.add(res);
|
|
87
|
+
req.on("close", () => {
|
|
88
|
+
this.sseClients.delete(res);
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
res.setHeader("Content-Type", "application/json");
|
|
93
|
+
// GET /api/agents
|
|
94
|
+
if (req.method === "GET" && req.url === "/api/agents") {
|
|
95
|
+
res.writeHead(200);
|
|
96
|
+
res.end(JSON.stringify(this.discovery.getAgents()));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// GET /api/tasks/inbox?unread_only=true
|
|
100
|
+
if (req.method === "GET" && req.url?.startsWith("/api/tasks/inbox")) {
|
|
101
|
+
const url = new URL(req.url, `http://127.0.0.1`);
|
|
102
|
+
const unreadOnly = url.searchParams.get("unread_only") === "true";
|
|
103
|
+
const tasks = unreadOnly
|
|
104
|
+
? this.taskStore.getPending(this.config.name)
|
|
105
|
+
: this.taskStore.getInbox(this.config.name);
|
|
106
|
+
res.writeHead(200);
|
|
107
|
+
res.end(JSON.stringify(tasks));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// POST /api/tasks/send body: { to, message }
|
|
111
|
+
if (req.method === "POST" && req.url === "/api/tasks/send") {
|
|
112
|
+
const body = await this.readBody(req);
|
|
113
|
+
const { to, message } = JSON.parse(body);
|
|
114
|
+
const target = this.discovery.getAgent(to);
|
|
115
|
+
if (!target) {
|
|
116
|
+
res.writeHead(404);
|
|
117
|
+
res.end(JSON.stringify({ error: `Agent "${to}" 不在线` }));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
let result;
|
|
121
|
+
if (this.discovery.isRelayAgent(to) && this.relayClient) {
|
|
122
|
+
// 中继 Agent,通过 WebSocket 转发
|
|
123
|
+
const rpcReq = {
|
|
124
|
+
jsonrpc: "2.0",
|
|
125
|
+
id: Date.now(),
|
|
126
|
+
method: "message/send",
|
|
127
|
+
params: { from: this.config.name, message },
|
|
128
|
+
};
|
|
129
|
+
const rpcRes = await this.relayClient.sendRequest(to, rpcReq);
|
|
130
|
+
if (rpcRes.error) {
|
|
131
|
+
throw new Error(rpcRes.error.message);
|
|
132
|
+
}
|
|
133
|
+
result = rpcRes.result;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// 局域网 Agent,直接 HTTP
|
|
137
|
+
const callbackUrl = `http://${this.getLocalAddress()}:${this.config.port}/a2a`;
|
|
138
|
+
result = await this.a2aClient.sendTask(target, this.config.name, message, callbackUrl);
|
|
139
|
+
}
|
|
140
|
+
// 记录发出任务对应的目标 agent(持久化)
|
|
141
|
+
this.taskStore.trackOutbound(result.taskId, to);
|
|
142
|
+
res.writeHead(200);
|
|
143
|
+
res.end(JSON.stringify(result));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// POST /api/tasks/clear body: { read_only, oldest }
|
|
147
|
+
if (req.method === "POST" && req.url === "/api/tasks/clear") {
|
|
148
|
+
const body = await this.readBody(req);
|
|
149
|
+
const params = JSON.parse(body);
|
|
150
|
+
let count;
|
|
151
|
+
if (params.oldest != null) {
|
|
152
|
+
count = this.taskStore.clearOldest(this.config.name, params.oldest);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
count = this.taskStore.clearInbox(this.config.name, params.read_only !== false);
|
|
156
|
+
}
|
|
157
|
+
res.writeHead(200);
|
|
158
|
+
res.end(JSON.stringify({ cleared: count }));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// POST /api/tasks/read body: { task_id } 或 { all: true }
|
|
162
|
+
if (req.method === "POST" && req.url === "/api/tasks/read") {
|
|
163
|
+
const body = await this.readBody(req);
|
|
164
|
+
const params = JSON.parse(body);
|
|
165
|
+
if (params.all) {
|
|
166
|
+
const count = this.taskStore.markAllRead(this.config.name);
|
|
167
|
+
res.writeHead(200);
|
|
168
|
+
res.end(JSON.stringify({ marked: count }));
|
|
169
|
+
}
|
|
170
|
+
else if (params.task_id) {
|
|
171
|
+
const ok = this.taskStore.markRead(params.task_id);
|
|
172
|
+
res.writeHead(ok ? 200 : 404);
|
|
173
|
+
res.end(JSON.stringify({ ok }));
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
res.writeHead(400);
|
|
177
|
+
res.end(JSON.stringify({ error: "需要 task_id 或 all 参数" }));
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// POST /api/tasks/:id/reply body: { message, status }
|
|
182
|
+
const replyMatch = req.url?.match(/^\/api\/tasks\/([^/]+)\/reply$/);
|
|
183
|
+
if (req.method === "POST" && replyMatch) {
|
|
184
|
+
const taskId = replyMatch[1];
|
|
185
|
+
const body = await this.readBody(req);
|
|
186
|
+
const { message, status } = JSON.parse(body);
|
|
187
|
+
const task = this.taskStore.updateTask(taskId, {
|
|
188
|
+
status,
|
|
189
|
+
result: message,
|
|
190
|
+
});
|
|
191
|
+
if (task) {
|
|
192
|
+
this.taskStore.markRead(taskId);
|
|
193
|
+
}
|
|
194
|
+
if (!task) {
|
|
195
|
+
res.writeHead(404);
|
|
196
|
+
res.end(JSON.stringify({ error: `任务 ${taskId} 不存在` }));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// 回调通知发送方
|
|
200
|
+
if (task.callbackUrl && (status === "completed" || status === "rejected")) {
|
|
201
|
+
this.a2aClient.sendTaskNotification(task.callbackUrl, task).catch(() => { });
|
|
202
|
+
}
|
|
203
|
+
res.writeHead(200);
|
|
204
|
+
res.end(JSON.stringify(task));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// GET /api/tasks/:id/poll?target=xxx — 轮询任务状态(本地或远端)
|
|
208
|
+
const pollMatch = req.url?.match(/^\/api\/tasks\/([^/]+)\/poll/);
|
|
209
|
+
if (req.method === "GET" && pollMatch) {
|
|
210
|
+
const taskId = pollMatch[1];
|
|
211
|
+
const url = new URL(req.url, `http://127.0.0.1`);
|
|
212
|
+
const queryTarget = url.searchParams.get("target");
|
|
213
|
+
// 先查本地
|
|
214
|
+
const localTask = this.taskStore.getTask(taskId);
|
|
215
|
+
if (localTask) {
|
|
216
|
+
res.writeHead(200);
|
|
217
|
+
res.end(JSON.stringify(localTask));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// 查远端发出的任务(优先用查询参数,其次用持久化记录)
|
|
221
|
+
const targetName = queryTarget || this.taskStore.getOutboundTarget(taskId);
|
|
222
|
+
if (targetName) {
|
|
223
|
+
const target = this.discovery.getAgent(targetName);
|
|
224
|
+
if (target) {
|
|
225
|
+
try {
|
|
226
|
+
const task = await this.a2aClient.getTask(target, taskId);
|
|
227
|
+
res.writeHead(200);
|
|
228
|
+
res.end(JSON.stringify(task));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
res.writeHead(502);
|
|
233
|
+
res.end(JSON.stringify({ error: `查询远端任务失败: ${err instanceof Error ? err.message : String(err)}` }));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
res.writeHead(404);
|
|
239
|
+
res.end(JSON.stringify({ error: `任务 ${taskId} 不存在` }));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
res.writeHead(404);
|
|
243
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
res.writeHead(500);
|
|
247
|
+
res.end(JSON.stringify({
|
|
248
|
+
error: err instanceof Error ? err.message : String(err),
|
|
249
|
+
}));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
getLocalAddress() {
|
|
253
|
+
const interfaces = os.networkInterfaces();
|
|
254
|
+
for (const name of Object.keys(interfaces)) {
|
|
255
|
+
for (const iface of interfaces[name] || []) {
|
|
256
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
257
|
+
return iface.address;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return "127.0.0.1";
|
|
262
|
+
}
|
|
263
|
+
readBody(req) {
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const chunks = [];
|
|
266
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
267
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString()));
|
|
268
|
+
req.on("error", reject);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=daemon-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-api.js","sourceRoot":"","sources":["../src/daemon-api.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 局域网通信不走代理
|
|
3
|
+
const noProxy = process.env.no_proxy || process.env.NO_PROXY || "";
|
|
4
|
+
if (!noProxy.includes(".local")) {
|
|
5
|
+
const updated = noProxy ? `${noProxy},.local` : ".local";
|
|
6
|
+
process.env.no_proxy = updated;
|
|
7
|
+
process.env.NO_PROXY = updated;
|
|
8
|
+
}
|
|
9
|
+
import { parseArgs } from "./config.js";
|
|
10
|
+
import { Discovery } from "./discovery.js";
|
|
11
|
+
import { A2AServer } from "./a2a-server.js";
|
|
12
|
+
import { A2AClient } from "./a2a-client.js";
|
|
13
|
+
import { TaskStore } from "./task-store.js";
|
|
14
|
+
import { DaemonApi } from "./daemon-api.js";
|
|
15
|
+
import { RelayClient } from "./relay-client.js";
|
|
16
|
+
const config = parseArgs(process.argv.slice(2));
|
|
17
|
+
const taskStore = new TaskStore();
|
|
18
|
+
const discovery = new Discovery(config.name);
|
|
19
|
+
const a2aClient = new A2AClient();
|
|
20
|
+
const a2aServer = new A2AServer(config, taskStore);
|
|
21
|
+
const daemonApi = new DaemonApi(config, discovery, taskStore, a2aClient);
|
|
22
|
+
let relayClient = null;
|
|
23
|
+
// 收到远端任务时通知
|
|
24
|
+
a2aServer.setOnTaskReceived((task) => {
|
|
25
|
+
console.error(`[agent-link daemon] 收到来自 ${task.from} 的任务: ${task.message} (ID: ${task.id})`);
|
|
26
|
+
daemonApi.broadcastEvent({ type: "task:created", task });
|
|
27
|
+
});
|
|
28
|
+
// 远端回调通知(对方回复了我们发出的任务)
|
|
29
|
+
a2aServer.setOnTaskNotified((partialTask) => {
|
|
30
|
+
console.error(`[agent-link daemon] 收到任务回复通知: ${partialTask.id} (状态: ${partialTask.status})`);
|
|
31
|
+
daemonApi.broadcastEvent({
|
|
32
|
+
type: "task:updated",
|
|
33
|
+
task: partialTask,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
// 本地任务状态变更时广播 SSE
|
|
37
|
+
taskStore.on("task:updated", (task) => {
|
|
38
|
+
daemonApi.broadcastEvent({ type: "task:updated", task });
|
|
39
|
+
});
|
|
40
|
+
// 处理通过中继收到的 A2A 请求
|
|
41
|
+
function handleRelayRequest(from, req) {
|
|
42
|
+
switch (req.method) {
|
|
43
|
+
case "message/send": {
|
|
44
|
+
const params = req.params;
|
|
45
|
+
const task = taskStore.createTask(params.from, config.name, params.message);
|
|
46
|
+
console.error(`[agent-link daemon] 收到中继消息来自 ${params.from}: ${params.message} (ID: ${task.id})`);
|
|
47
|
+
daemonApi.broadcastEvent({ type: "task:created", task });
|
|
48
|
+
return { jsonrpc: "2.0", id: req.id, result: { taskId: task.id, status: task.status } };
|
|
49
|
+
}
|
|
50
|
+
case "tasks/get": {
|
|
51
|
+
const params = req.params;
|
|
52
|
+
const task = taskStore.getTask(params.taskId);
|
|
53
|
+
if (!task) {
|
|
54
|
+
return { jsonrpc: "2.0", id: req.id, error: { code: -32001, message: "Task not found" } };
|
|
55
|
+
}
|
|
56
|
+
return { jsonrpc: "2.0", id: req.id, result: task };
|
|
57
|
+
}
|
|
58
|
+
case "tasks/notify": {
|
|
59
|
+
const params = req.params;
|
|
60
|
+
console.error(`[agent-link daemon] 收到中继回复通知: ${params.taskId} (状态: ${params.status})`);
|
|
61
|
+
daemonApi.broadcastEvent({
|
|
62
|
+
type: "task:updated",
|
|
63
|
+
task: { id: params.taskId, status: params.status, result: params.result, from: params.from, to: params.to },
|
|
64
|
+
});
|
|
65
|
+
return { jsonrpc: "2.0", id: req.id, result: { ok: true } };
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
return { jsonrpc: "2.0", id: req.id, error: { code: -32601, message: `Method not found: ${req.method}` } };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function main() {
|
|
72
|
+
// 启动 A2A HTTP Server
|
|
73
|
+
const a2aPort = await a2aServer.start();
|
|
74
|
+
if (a2aPort !== config.port) {
|
|
75
|
+
console.error(`[agent-link daemon] A2A 端口 ${config.port} 已被占用,自动使用 ${a2aPort}`);
|
|
76
|
+
}
|
|
77
|
+
config.port = a2aPort;
|
|
78
|
+
console.error(`[agent-link daemon] A2A Server 启动在端口 ${a2aPort}`);
|
|
79
|
+
// 启动内部 API
|
|
80
|
+
const apiPort = await daemonApi.start();
|
|
81
|
+
if (apiPort !== config.apiPort) {
|
|
82
|
+
console.error(`[agent-link daemon] API 端口 ${config.apiPort} 已被占用,自动使用 ${apiPort}`);
|
|
83
|
+
}
|
|
84
|
+
config.apiPort = apiPort;
|
|
85
|
+
console.error(`[agent-link daemon] 内部 API 启动在 127.0.0.1:${apiPort}`);
|
|
86
|
+
// 广播自己并发现其他 Agent
|
|
87
|
+
discovery.publish(a2aPort, config.skills.map((s) => s.id));
|
|
88
|
+
discovery.browse((agent) => {
|
|
89
|
+
console.error(`[agent-link daemon] 发现 Agent: ${agent.name} (${agent.host}:${agent.port})`);
|
|
90
|
+
}, (name) => {
|
|
91
|
+
console.error(`[agent-link daemon] Agent 离线: ${name}`);
|
|
92
|
+
});
|
|
93
|
+
// 连接中继服务器
|
|
94
|
+
if (config.relayUrl) {
|
|
95
|
+
relayClient = new RelayClient(config.relayUrl, config.name, config.skills.map((s) => s.id));
|
|
96
|
+
relayClient.setOnAgentFound((agent) => {
|
|
97
|
+
console.error(`[agent-link daemon] 中继发现 Agent: ${agent.name}`);
|
|
98
|
+
discovery.addRelayAgent(agent);
|
|
99
|
+
});
|
|
100
|
+
relayClient.setOnAgentLost((name) => {
|
|
101
|
+
console.error(`[agent-link daemon] 中继 Agent 离线: ${name}`);
|
|
102
|
+
discovery.removeRelayAgent(name);
|
|
103
|
+
});
|
|
104
|
+
relayClient.setOnMessageReceived(async (from, payload) => {
|
|
105
|
+
return handleRelayRequest(from, payload);
|
|
106
|
+
});
|
|
107
|
+
relayClient.connect();
|
|
108
|
+
daemonApi.setRelayClient(relayClient);
|
|
109
|
+
console.error(`[agent-link daemon] 正在连接中继服务器 ${config.relayUrl}`);
|
|
110
|
+
}
|
|
111
|
+
// 等待 mDNS 发现完成
|
|
112
|
+
console.error("[agent-link daemon] 等待 mDNS 发现...");
|
|
113
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
114
|
+
const agentCount = discovery.getAgents().length;
|
|
115
|
+
console.error(`[agent-link daemon] Agent "${config.name}" 已就绪 (A2A: ${a2aPort}, API: ${apiPort}, 发现 ${agentCount} 个 Agent)`);
|
|
116
|
+
// daemon 保持运行,输出 ready 信号供 MCP Client 检测
|
|
117
|
+
process.stdout.write(JSON.stringify({ ready: true, apiPort, a2aPort, name: config.name }) + "\n");
|
|
118
|
+
}
|
|
119
|
+
// 优雅退出
|
|
120
|
+
process.on("SIGINT", () => {
|
|
121
|
+
console.error("[agent-link daemon] 正在关闭...");
|
|
122
|
+
discovery.destroy();
|
|
123
|
+
taskStore.close();
|
|
124
|
+
relayClient?.destroy();
|
|
125
|
+
Promise.all([a2aServer.stop(), daemonApi.stop()]).then(() => {
|
|
126
|
+
process.exit(0);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
process.on("SIGTERM", () => {
|
|
130
|
+
discovery.destroy();
|
|
131
|
+
taskStore.close();
|
|
132
|
+
relayClient?.destroy();
|
|
133
|
+
Promise.all([a2aServer.stop(), daemonApi.stop()]).then(() => {
|
|
134
|
+
process.exit(0);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
main().catch((err) => {
|
|
138
|
+
console.error("[agent-link daemon] 启动失败:", err);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentInfo } from "./types.js";
|
|
2
|
+
export declare class Discovery {
|
|
3
|
+
private bonjour;
|
|
4
|
+
private lanAgents;
|
|
5
|
+
private relayAgents;
|
|
6
|
+
private localName;
|
|
7
|
+
private onAgentFound?;
|
|
8
|
+
private onAgentLost?;
|
|
9
|
+
constructor(localName: string);
|
|
10
|
+
publish(port: number, skills: string[]): void;
|
|
11
|
+
browse(onFound?: (agent: AgentInfo) => void, onLost?: (name: string) => void): void;
|
|
12
|
+
addRelayAgent(agent: AgentInfo): void;
|
|
13
|
+
removeRelayAgent(name: string): void;
|
|
14
|
+
getAgents(): AgentInfo[];
|
|
15
|
+
getAgent(name: string): AgentInfo | undefined;
|
|
16
|
+
isRelayAgent(name: string): boolean;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Bonjour } from "bonjour-service";
|
|
2
|
+
const SERVICE_TYPE = "agent-link";
|
|
3
|
+
export class Discovery {
|
|
4
|
+
bonjour;
|
|
5
|
+
lanAgents = new Map();
|
|
6
|
+
relayAgents = new Map();
|
|
7
|
+
localName;
|
|
8
|
+
onAgentFound;
|
|
9
|
+
onAgentLost;
|
|
10
|
+
constructor(localName) {
|
|
11
|
+
this.bonjour = new Bonjour();
|
|
12
|
+
this.localName = localName;
|
|
13
|
+
}
|
|
14
|
+
// 广播自己
|
|
15
|
+
publish(port, skills) {
|
|
16
|
+
this.bonjour.publish({
|
|
17
|
+
name: this.localName,
|
|
18
|
+
type: SERVICE_TYPE,
|
|
19
|
+
port,
|
|
20
|
+
txt: {
|
|
21
|
+
version: "1.0",
|
|
22
|
+
skills: skills.join(","),
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
// 发现其他 Agent
|
|
27
|
+
browse(onFound, onLost) {
|
|
28
|
+
this.onAgentFound = onFound;
|
|
29
|
+
this.onAgentLost = onLost;
|
|
30
|
+
const browser = this.bonjour.find({ type: SERVICE_TYPE });
|
|
31
|
+
browser.on("up", (service) => {
|
|
32
|
+
if (service.name === this.localName)
|
|
33
|
+
return; // 跳过自己
|
|
34
|
+
// 优先使用 IP 地址,避免 mDNS hostname 冲突导致无法解析
|
|
35
|
+
const addresses = (service.addresses || []).filter((a) => !a.includes(":"));
|
|
36
|
+
const host = addresses[0] || service.host;
|
|
37
|
+
const agent = {
|
|
38
|
+
name: service.name,
|
|
39
|
+
host,
|
|
40
|
+
port: service.port,
|
|
41
|
+
skills: (service.txt?.skills || "")
|
|
42
|
+
.split(",")
|
|
43
|
+
.filter(Boolean),
|
|
44
|
+
version: service.txt?.version || "1.0",
|
|
45
|
+
status: "online",
|
|
46
|
+
};
|
|
47
|
+
this.lanAgents.set(agent.name, agent);
|
|
48
|
+
this.onAgentFound?.(agent);
|
|
49
|
+
});
|
|
50
|
+
browser.on("down", (service) => {
|
|
51
|
+
this.lanAgents.delete(service.name);
|
|
52
|
+
// 如果中继也没有这个 Agent,才通知离线
|
|
53
|
+
if (!this.relayAgents.has(service.name)) {
|
|
54
|
+
this.onAgentLost?.(service.name);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// 添加中继发现的 Agent
|
|
59
|
+
addRelayAgent(agent) {
|
|
60
|
+
// 局域网已有的不覆盖
|
|
61
|
+
if (this.lanAgents.has(agent.name))
|
|
62
|
+
return;
|
|
63
|
+
const isNew = !this.relayAgents.has(agent.name);
|
|
64
|
+
this.relayAgents.set(agent.name, agent);
|
|
65
|
+
if (isNew) {
|
|
66
|
+
this.onAgentFound?.(agent);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 移除中继 Agent
|
|
70
|
+
removeRelayAgent(name) {
|
|
71
|
+
if (!this.relayAgents.has(name))
|
|
72
|
+
return;
|
|
73
|
+
this.relayAgents.delete(name);
|
|
74
|
+
// 局域网也没有才通知离线
|
|
75
|
+
if (!this.lanAgents.has(name)) {
|
|
76
|
+
this.onAgentLost?.(name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 获取所有 Agent(局域网优先)
|
|
80
|
+
getAgents() {
|
|
81
|
+
const merged = new Map();
|
|
82
|
+
// 先放中继的
|
|
83
|
+
for (const [name, agent] of this.relayAgents) {
|
|
84
|
+
merged.set(name, agent);
|
|
85
|
+
}
|
|
86
|
+
// 局域网的覆盖中继的(优先直连)
|
|
87
|
+
for (const [name, agent] of this.lanAgents) {
|
|
88
|
+
merged.set(name, agent);
|
|
89
|
+
}
|
|
90
|
+
return [...merged.values()];
|
|
91
|
+
}
|
|
92
|
+
getAgent(name) {
|
|
93
|
+
// 局域网优先
|
|
94
|
+
return this.lanAgents.get(name) || this.relayAgents.get(name);
|
|
95
|
+
}
|
|
96
|
+
// 判断是否是中继 Agent(非局域网直连)
|
|
97
|
+
isRelayAgent(name) {
|
|
98
|
+
return !this.lanAgents.has(name) && this.relayAgents.has(name);
|
|
99
|
+
}
|
|
100
|
+
destroy() {
|
|
101
|
+
this.bonjour.destroy();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED