@f2a/network 0.1.2 → 0.1.3

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.
Files changed (136) hide show
  1. package/package.json +8 -1
  2. package/.github/workflows/ci.yml +0 -113
  3. package/.github/workflows/publish.yml +0 -60
  4. package/MONOREPO.md +0 -58
  5. package/SKILL.md +0 -137
  6. package/dist/adapters/openclaw.d.ts +0 -103
  7. package/dist/adapters/openclaw.d.ts.map +0 -1
  8. package/dist/adapters/openclaw.js +0 -297
  9. package/dist/adapters/openclaw.js.map +0 -1
  10. package/dist/core/connection-manager.d.ts +0 -80
  11. package/dist/core/connection-manager.d.ts.map +0 -1
  12. package/dist/core/connection-manager.js +0 -235
  13. package/dist/core/connection-manager.js.map +0 -1
  14. package/dist/core/connection-manager.test.d.ts +0 -2
  15. package/dist/core/connection-manager.test.d.ts.map +0 -1
  16. package/dist/core/connection-manager.test.js +0 -52
  17. package/dist/core/connection-manager.test.js.map +0 -1
  18. package/dist/core/identity.d.ts +0 -47
  19. package/dist/core/identity.d.ts.map +0 -1
  20. package/dist/core/identity.js +0 -130
  21. package/dist/core/identity.js.map +0 -1
  22. package/dist/core/identity.test.d.ts +0 -2
  23. package/dist/core/identity.test.d.ts.map +0 -1
  24. package/dist/core/identity.test.js +0 -43
  25. package/dist/core/identity.test.js.map +0 -1
  26. package/dist/core/serverless.d.ts +0 -155
  27. package/dist/core/serverless.d.ts.map +0 -1
  28. package/dist/core/serverless.js +0 -615
  29. package/dist/core/serverless.js.map +0 -1
  30. package/dist/daemon/webhook.test.d.ts +0 -2
  31. package/dist/daemon/webhook.test.d.ts.map +0 -1
  32. package/dist/daemon/webhook.test.js +0 -24
  33. package/dist/daemon/webhook.test.js.map +0 -1
  34. package/dist/protocol/messages.d.ts +0 -739
  35. package/dist/protocol/messages.d.ts.map +0 -1
  36. package/dist/protocol/messages.js +0 -188
  37. package/dist/protocol/messages.js.map +0 -1
  38. package/dist/protocol/messages.test.d.ts +0 -2
  39. package/dist/protocol/messages.test.d.ts.map +0 -1
  40. package/dist/protocol/messages.test.js +0 -55
  41. package/dist/protocol/messages.test.js.map +0 -1
  42. package/docs/F2A-PROTOCOL.md +0 -61
  43. package/docs/MOBILE_BOOTSTRAP_DESIGN.md +0 -126
  44. package/docs/a2a-lessons.md +0 -316
  45. package/docs/middleware-guide.md +0 -448
  46. package/docs/readme-update-checklist.md +0 -90
  47. package/docs/reputation-guide.md +0 -396
  48. package/docs/rfcs/001-reputation-system.md +0 -712
  49. package/docs/security-design.md +0 -247
  50. package/install.sh +0 -231
  51. package/packages/openclaw-adapter/README.md +0 -510
  52. package/packages/openclaw-adapter/openclaw.plugin.json +0 -106
  53. package/packages/openclaw-adapter/package.json +0 -40
  54. package/packages/openclaw-adapter/src/announcement-queue.test.ts +0 -449
  55. package/packages/openclaw-adapter/src/announcement-queue.ts +0 -403
  56. package/packages/openclaw-adapter/src/capability-detector.test.ts +0 -99
  57. package/packages/openclaw-adapter/src/capability-detector.ts +0 -183
  58. package/packages/openclaw-adapter/src/claim-handlers.test.ts +0 -974
  59. package/packages/openclaw-adapter/src/claim-handlers.ts +0 -482
  60. package/packages/openclaw-adapter/src/connector.business.test.ts +0 -583
  61. package/packages/openclaw-adapter/src/connector.ts +0 -795
  62. package/packages/openclaw-adapter/src/index.test.ts +0 -82
  63. package/packages/openclaw-adapter/src/index.ts +0 -18
  64. package/packages/openclaw-adapter/src/integration.e2e.test.ts +0 -829
  65. package/packages/openclaw-adapter/src/logger.ts +0 -51
  66. package/packages/openclaw-adapter/src/network-client.test.ts +0 -266
  67. package/packages/openclaw-adapter/src/network-client.ts +0 -251
  68. package/packages/openclaw-adapter/src/network-recovery.test.ts +0 -465
  69. package/packages/openclaw-adapter/src/node-manager.test.ts +0 -136
  70. package/packages/openclaw-adapter/src/node-manager.ts +0 -429
  71. package/packages/openclaw-adapter/src/plugin.test.ts +0 -439
  72. package/packages/openclaw-adapter/src/plugin.ts +0 -104
  73. package/packages/openclaw-adapter/src/reputation.test.ts +0 -221
  74. package/packages/openclaw-adapter/src/reputation.ts +0 -368
  75. package/packages/openclaw-adapter/src/task-guard.test.ts +0 -502
  76. package/packages/openclaw-adapter/src/task-guard.ts +0 -860
  77. package/packages/openclaw-adapter/src/task-queue.concurrency.test.ts +0 -462
  78. package/packages/openclaw-adapter/src/task-queue.edge-cases.test.ts +0 -284
  79. package/packages/openclaw-adapter/src/task-queue.persistence.test.ts +0 -408
  80. package/packages/openclaw-adapter/src/task-queue.ts +0 -668
  81. package/packages/openclaw-adapter/src/tool-handlers.test.ts +0 -906
  82. package/packages/openclaw-adapter/src/tool-handlers.ts +0 -574
  83. package/packages/openclaw-adapter/src/types.ts +0 -361
  84. package/packages/openclaw-adapter/src/webhook-pusher.test.ts +0 -188
  85. package/packages/openclaw-adapter/src/webhook-pusher.ts +0 -220
  86. package/packages/openclaw-adapter/src/webhook-server.test.ts +0 -580
  87. package/packages/openclaw-adapter/src/webhook-server.ts +0 -202
  88. package/packages/openclaw-adapter/tsconfig.json +0 -20
  89. package/src/cli/commands.test.ts +0 -157
  90. package/src/cli/commands.ts +0 -129
  91. package/src/cli/index.test.ts +0 -77
  92. package/src/cli/index.ts +0 -234
  93. package/src/core/autonomous-economy.test.ts +0 -291
  94. package/src/core/autonomous-economy.ts +0 -428
  95. package/src/core/e2ee-crypto.test.ts +0 -125
  96. package/src/core/e2ee-crypto.ts +0 -246
  97. package/src/core/f2a.test.ts +0 -269
  98. package/src/core/f2a.ts +0 -618
  99. package/src/core/p2p-network.test.ts +0 -199
  100. package/src/core/p2p-network.ts +0 -1432
  101. package/src/core/reputation-security.test.ts +0 -403
  102. package/src/core/reputation-security.ts +0 -562
  103. package/src/core/reputation.test.ts +0 -260
  104. package/src/core/reputation.ts +0 -576
  105. package/src/core/review-committee.test.ts +0 -380
  106. package/src/core/review-committee.ts +0 -401
  107. package/src/core/token-manager.test.ts +0 -133
  108. package/src/core/token-manager.ts +0 -140
  109. package/src/daemon/control-server.test.ts +0 -216
  110. package/src/daemon/control-server.ts +0 -292
  111. package/src/daemon/index.test.ts +0 -85
  112. package/src/daemon/index.ts +0 -89
  113. package/src/daemon/main.ts +0 -44
  114. package/src/daemon/start.ts +0 -29
  115. package/src/daemon/webhook.test.ts +0 -68
  116. package/src/daemon/webhook.ts +0 -105
  117. package/src/index.test.ts +0 -436
  118. package/src/index.ts +0 -72
  119. package/src/types/index.test.ts +0 -87
  120. package/src/types/index.ts +0 -341
  121. package/src/types/result.ts +0 -68
  122. package/src/utils/benchmark.ts +0 -237
  123. package/src/utils/logger.ts +0 -331
  124. package/src/utils/middleware.ts +0 -229
  125. package/src/utils/rate-limiter.ts +0 -207
  126. package/src/utils/signature.ts +0 -136
  127. package/src/utils/validation.ts +0 -186
  128. package/tests/docker/Dockerfile.node +0 -23
  129. package/tests/docker/Dockerfile.runner +0 -18
  130. package/tests/docker/docker-compose.test.yml +0 -73
  131. package/tests/integration/message-passing.test.ts +0 -109
  132. package/tests/integration/multi-node.test.ts +0 -92
  133. package/tests/integration/p2p-connection.test.ts +0 -83
  134. package/tests/integration/test-config.ts +0 -32
  135. package/tsconfig.json +0 -21
  136. package/vitest.config.ts +0 -26
package/src/core/f2a.ts DELETED
@@ -1,618 +0,0 @@
1
- /**
2
- * F2A 主类 - P2P 版本
3
- * 整合 P2P 网络、能力发现与任务委托
4
- */
5
-
6
- import { EventEmitter } from 'eventemitter3';
7
- import { P2PNetwork } from './p2p-network.js';
8
- import { Logger } from '../utils/logger.js';
9
- import { Middleware } from '../utils/middleware.js';
10
- import { validateAgentCapability, validateTaskDelegateOptions } from '../utils/validation.js';
11
- import {
12
- F2AOptions,
13
- F2AEvents,
14
- AgentInfo,
15
- AgentCapability,
16
- Result,
17
- TaskDelegateOptions,
18
- TaskDelegateResult,
19
- TaskRequestEvent,
20
- TaskResponseEvent,
21
- PeerDiscoveredEvent,
22
- PeerConnectedEvent,
23
- PeerDisconnectedEvent,
24
- RegisteredCapability,
25
- NetworkStartedEvent,
26
- success,
27
- failureFromError
28
- } from '../types/index.js';
29
-
30
- // 版本号
31
- const F2A_VERSION = '1.0.0';
32
- const PROTOCOL_VERSION = 'f2a/1.0';
33
-
34
- export interface F2AInstance {
35
- readonly peerId: string;
36
- /** 获取 Agent 信息(延迟获取,确保 peerId 在 start() 后才有效) */
37
- readonly agentInfo: AgentInfo;
38
- start(): Promise<Result<void>>;
39
- stop(): Promise<void>;
40
-
41
- // 能力管理
42
- registerCapability(capability: AgentCapability, handler: (params: Record<string, unknown>) => Promise<unknown>): void;
43
- getCapabilities(): AgentCapability[];
44
-
45
- // 发现
46
- discoverAgents(capability?: string): Promise<AgentInfo[]>;
47
- getConnectedPeers(): AgentInfo[];
48
- getAllPeers(): AgentInfo[];
49
-
50
- // 任务委托
51
- delegateTask(options: TaskDelegateOptions): Promise<Result<TaskDelegateResult>>;
52
-
53
- // 直接通信
54
- sendTaskTo(peerId: string, taskType: string, description: string, parameters?: Record<string, unknown>): Promise<Result<unknown>>;
55
-
56
- // 中间件
57
- useMiddleware(middleware: Middleware): void;
58
- removeMiddleware(name: string): boolean;
59
- listMiddlewares(): string[];
60
-
61
- // DHT
62
- findPeerViaDHT(peerId: string): Promise<Result<string[]>>;
63
- getDHTPeerCount(): number;
64
- isDHTEnabled(): boolean;
65
- }
66
-
67
- export class F2A extends EventEmitter<F2AEvents> implements F2AInstance {
68
- private _agentInfo: AgentInfo;
69
- private p2pNetwork: P2PNetwork;
70
- private options: Required<F2AOptions>;
71
- private running: boolean = false;
72
- private registeredCapabilities: Map<string, RegisteredCapability> = new Map();
73
- private logger: Logger;
74
-
75
- private constructor(
76
- agentInfo: AgentInfo,
77
- p2pNetwork: P2PNetwork,
78
- options: Required<F2AOptions>
79
- ) {
80
- super();
81
- this._agentInfo = agentInfo;
82
- this.p2pNetwork = p2pNetwork;
83
- this.options = options;
84
- this.logger = new Logger({ level: options.logLevel, component: 'F2A' });
85
-
86
- this.bindEvents();
87
- }
88
-
89
- /**
90
- * 获取 Agent 信息
91
- * 使用 getter 延迟获取 peerId,避免在 start() 前读到空值
92
- */
93
- get agentInfo(): AgentInfo {
94
- // 返回一个代理对象,确保 peerId 始终从 p2pNetwork 获取最新值
95
- return {
96
- ...this._agentInfo,
97
- peerId: this.running ? this._agentInfo.peerId : ''
98
- };
99
- }
100
-
101
- /**
102
- * 工厂方法:创建 F2A 实例
103
- */
104
- static async create(options: F2AOptions = {}): Promise<F2A> {
105
- // 默认配置
106
- const mergedOptions: Required<F2AOptions> = {
107
- displayName: options.displayName || 'F2A Agent',
108
- agentType: options.agentType || 'openclaw',
109
- network: {
110
- listenPort: 0,
111
- enableMDNS: true,
112
- enableDHT: false,
113
- ...options.network
114
- },
115
- security: {
116
- level: 'medium',
117
- requireConfirmation: true,
118
- verifySignatures: true,
119
- ...options.security
120
- },
121
- logLevel: options.logLevel || 'INFO',
122
- dataDir: options.dataDir || './f2a-data'
123
- };
124
-
125
- // 创建 AgentInfo
126
- const agentInfo: AgentInfo = {
127
- peerId: '', // 启动后由 P2P 网络填充
128
- displayName: mergedOptions.displayName,
129
- agentType: mergedOptions.agentType as AgentInfo['agentType'],
130
- version: F2A_VERSION,
131
- capabilities: [],
132
- protocolVersion: PROTOCOL_VERSION,
133
- lastSeen: Date.now(),
134
- multiaddrs: []
135
- };
136
-
137
- // 创建 P2P 网络
138
- const p2pNetwork = new P2PNetwork(agentInfo, mergedOptions.network);
139
-
140
- // 创建实例
141
- const f2a = new F2A(agentInfo, p2pNetwork, mergedOptions);
142
-
143
- return f2a;
144
- }
145
-
146
- /**
147
- * 启动 F2A
148
- */
149
- async start(): Promise<Result<void>> {
150
- if (this.running) {
151
- return failureFromError('NETWORK_ALREADY_RUNNING', 'F2A already running');
152
- }
153
-
154
- this.logger.info('Starting agent', { displayName: this.agentInfo.displayName });
155
-
156
- // 启动 P2P 网络
157
- const result = await this.p2pNetwork.start();
158
- if (!result.success) {
159
- return result;
160
- }
161
-
162
- // 更新 agentInfo
163
- this._agentInfo.peerId = result.data.peerId;
164
- this._agentInfo.multiaddrs = result.data.addresses;
165
-
166
- this.running = true;
167
-
168
- this.emit('network:started', {
169
- peerId: result.data.peerId,
170
- listenAddresses: result.data.addresses
171
- });
172
-
173
- this.logger.info('Started', { peerId: result.data.peerId.slice(0, 16) });
174
-
175
- return { success: true, data: undefined };
176
- }
177
-
178
- /**
179
- * 停止 F2A
180
- */
181
- async stop(): Promise<void> {
182
- if (!this.running) return;
183
-
184
- this.logger.info('Stopping');
185
-
186
- await this.p2pNetwork.stop();
187
-
188
- this.running = false;
189
- this.emit('network:stopped');
190
-
191
- this.logger.info('Stopped');
192
- }
193
-
194
- /**
195
- * 注册能力
196
- */
197
- registerCapability(
198
- capability: AgentCapability,
199
- handler: (params: Record<string, unknown>) => Promise<unknown>
200
- ): void {
201
- // 验证能力定义
202
- const validation = validateAgentCapability(capability);
203
- if (!validation.success) {
204
- this.logger.error('Invalid capability definition', {
205
- errors: validation.error.errors
206
- });
207
- throw new Error(`Invalid capability: ${validation.error.errors.map(e => e.message).join(', ')}`);
208
- }
209
-
210
- this.registeredCapabilities.set(capability.name, {
211
- ...capability,
212
- handler
213
- });
214
-
215
- // 更新 agentInfo
216
- this.updateAgentCapabilities();
217
-
218
- this.logger.info('Registered capability', { name: capability.name });
219
- }
220
-
221
- /**
222
- * 获取已注册的能力
223
- */
224
- getCapabilities(): AgentCapability[] {
225
- return Array.from(this.registeredCapabilities.values()).map(c => ({
226
- name: c.name,
227
- description: c.description,
228
- tools: c.tools,
229
- parameters: c.parameters
230
- }));
231
- }
232
-
233
- /**
234
- * 发现网络中的 Agents
235
- */
236
- async discoverAgents(capability?: string): Promise<AgentInfo[]> {
237
- return this.p2pNetwork.discoverAgents(capability);
238
- }
239
-
240
- /**
241
- * 获取已连接的 Peers
242
- */
243
- getConnectedPeers(): AgentInfo[] {
244
- return this.p2pNetwork.getConnectedPeers()
245
- .filter(p => p.agentInfo)
246
- .map(p => p.agentInfo!);
247
- }
248
-
249
- /**
250
- * 获取所有已知的 Peers(包括已断开但已发现的)
251
- */
252
- getAllPeers(): AgentInfo[] {
253
- // 返回所有已知节点,包括还没有交换 agentInfo 的
254
- // 如果 agentInfo 不存在,创建一个基本的 AgentInfo
255
- return this.p2pNetwork.getAllPeers()
256
- .map(p => {
257
- if (p.agentInfo) {
258
- return p.agentInfo;
259
- }
260
- // 创建基本的 AgentInfo
261
- return {
262
- peerId: p.peerId,
263
- capabilities: [],
264
- multiaddrs: p.multiaddrs.map(m => m.toString()),
265
- lastSeen: p.lastSeen,
266
- agentType: 'custom' as const,
267
- version: '0.0.0',
268
- protocolVersion: '1.0.0'
269
- };
270
- });
271
- }
272
-
273
- /**
274
- * 委托任务给网络
275
- */
276
- async delegateTask(options: TaskDelegateOptions): Promise<Result<TaskDelegateResult>> {
277
- // 验证任务委托选项
278
- const validation = validateTaskDelegateOptions(options);
279
- if (!validation.success) {
280
- this.logger.error('Invalid task delegate options', {
281
- errors: validation.error.errors
282
- });
283
- return failureFromError(
284
- 'INVALID_OPTIONS',
285
- `Invalid options: ${validation.error.errors.map(e => e.message).join(', ')}`
286
- );
287
- }
288
-
289
- const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
290
-
291
- this.logger.info('Delegating task', {
292
- taskId,
293
- capability: options.capability,
294
- description: options.description.slice(0, 50)
295
- });
296
-
297
- // 可配置的重试选项
298
- const retryOptions = {
299
- maxRetries: options.retryOptions?.maxRetries ?? 3,
300
- retryDelayMs: options.retryOptions?.retryDelayMs ?? 1000,
301
- discoverTimeoutMs: options.retryOptions?.discoverTimeoutMs ?? 5000
302
- };
303
-
304
- // 1. 发现有能力执行任务的 Agents(带重试)
305
- let agents: AgentInfo[] = [];
306
- let lastError: string | undefined;
307
-
308
- for (let attempt = 0; attempt <= retryOptions.maxRetries; attempt++) {
309
- agents = await this.discoverAgents(options.capability);
310
-
311
- if (agents.length > 0) {
312
- break;
313
- }
314
-
315
- if (attempt < retryOptions.maxRetries) {
316
- this.logger.warn(`No agents found, retrying (${attempt + 1}/${retryOptions.maxRetries})`, {
317
- capability: options.capability
318
- });
319
- await new Promise(resolve => setTimeout(resolve, retryOptions.retryDelayMs));
320
- }
321
- }
322
-
323
- if (agents.length === 0) {
324
- this.logger.warn('No agents found with capability after retries', {
325
- capability: options.capability,
326
- retries: retryOptions.maxRetries
327
- });
328
- return failureFromError(
329
- 'CAPABILITY_NOT_SUPPORTED',
330
- `No agent found with capability: ${options.capability} (after ${retryOptions.maxRetries} retries)`
331
- );
332
- }
333
-
334
- this.logger.info('Found agents with capability', {
335
- count: agents.length,
336
- capability: options.capability
337
- });
338
-
339
- // 2. 发送任务请求
340
- const timeout = options.timeout || 30000;
341
- const results: TaskDelegateResult['results'] = [];
342
-
343
- if (options.parallel) {
344
- // 并行发送给多个 Agents
345
- const minResponses = options.minResponses || 1;
346
-
347
- const promises = agents.map(async (agent) => {
348
- const startTime = Date.now();
349
- const result = await this.p2pNetwork.sendTaskRequest(
350
- agent.peerId,
351
- options.capability,
352
- options.description,
353
- options.parameters,
354
- timeout
355
- );
356
- const latency = Date.now() - startTime;
357
-
358
- return {
359
- peerId: agent.peerId,
360
- status: result.success ? 'success' as const : 'error' as const,
361
- result: result.success ? result.data : undefined,
362
- error: result.success ? undefined : (result.error?.message || String(result.error)),
363
- latency
364
- };
365
- });
366
-
367
- // 等待至少 minResponses 个响应
368
- const settled = await Promise.allSettled(promises);
369
-
370
- for (const outcome of settled) {
371
- if (outcome.status === 'fulfilled') {
372
- results.push(outcome.value);
373
- }
374
- }
375
-
376
- // 检查是否达到最小响应数
377
- const successCount = results.filter(r => r.status === 'success').length;
378
- if (successCount < minResponses) {
379
- return failureFromError(
380
- 'TASK_FAILED',
381
- `Only ${successCount} successful responses, required ${minResponses}`
382
- );
383
- }
384
- } else {
385
- // 串行发送,取第一个成功的
386
- for (const agent of agents) {
387
- const startTime = Date.now();
388
- const result = await this.p2pNetwork.sendTaskRequest(
389
- agent.peerId,
390
- options.capability,
391
- options.description,
392
- options.parameters,
393
- timeout
394
- );
395
- const latency = Date.now() - startTime;
396
-
397
- results.push({
398
- peerId: agent.peerId,
399
- status: result.success ? 'success' : 'error',
400
- result: result.success ? result.data : undefined,
401
- error: result.success ? undefined : (result.error?.message || String(result.error)),
402
- latency
403
- });
404
-
405
- if (result.success) {
406
- break; // 第一个成功就停止
407
- }
408
- }
409
-
410
- // 检查是否有成功结果
411
- if (!results.some(r => r.status === 'success')) {
412
- return failureFromError('TASK_FAILED', 'All agents failed to execute the task');
413
- }
414
- }
415
-
416
- return success({ taskId, results });
417
- }
418
-
419
- /**
420
- * 直接发送任务给特定 Peer
421
- */
422
- async sendTaskTo(
423
- peerId: string,
424
- taskType: string,
425
- description: string,
426
- parameters?: Record<string, unknown>
427
- ): Promise<Result<unknown>> {
428
- return this.p2pNetwork.sendTaskRequest(
429
- peerId,
430
- taskType,
431
- description,
432
- parameters,
433
- 30000
434
- );
435
- }
436
-
437
- /**
438
- * 注册中间件
439
- */
440
- useMiddleware(middleware: Middleware): void {
441
- this.p2pNetwork.useMiddleware(middleware);
442
- }
443
-
444
- /**
445
- * 移除中间件
446
- */
447
- removeMiddleware(name: string): boolean {
448
- return this.p2pNetwork.removeMiddleware(name);
449
- }
450
-
451
- /**
452
- * 获取已注册中间件列表
453
- */
454
- listMiddlewares(): string[] {
455
- return this.p2pNetwork.listMiddlewares();
456
- }
457
-
458
- /**
459
- * 通过 DHT 查找节点
460
- */
461
- async findPeerViaDHT(peerId: string): Promise<Result<string[]>> {
462
- return this.p2pNetwork.findPeerViaDHT(peerId);
463
- }
464
-
465
- /**
466
- * 获取 DHT 路由表大小
467
- */
468
- getDHTPeerCount(): number {
469
- return this.p2pNetwork.getDHTPeerCount();
470
- }
471
-
472
- /**
473
- * 检查 DHT 是否启用
474
- */
475
- isDHTEnabled(): boolean {
476
- return this.p2pNetwork.isDHTEnabled();
477
- }
478
-
479
- /**
480
- * 获取 PeerID
481
- */
482
- get peerId(): string {
483
- return this.agentInfo.peerId;
484
- }
485
-
486
- /**
487
- * 绑定内部事件
488
- */
489
- private bindEvents(): void {
490
- // 转发 P2P 网络事件
491
- this.p2pNetwork.on('peer:discovered', (event) => {
492
- this.emit('peer:discovered', event);
493
- });
494
-
495
- this.p2pNetwork.on('peer:connected', (event) => {
496
- this.emit('peer:connected', event);
497
- });
498
-
499
- this.p2pNetwork.on('peer:disconnected', (event) => {
500
- this.emit('peer:disconnected', event);
501
- });
502
-
503
- // 处理收到的任务请求
504
- this.p2pNetwork.on('message:received', async (message, peerId) => {
505
- if (message.type === 'TASK_REQUEST') {
506
- await this.handleTaskRequest(message.payload as TaskRequestEvent, peerId);
507
- }
508
- });
509
-
510
- this.p2pNetwork.on('error', (error) => {
511
- this.emit('error', error);
512
- });
513
- }
514
-
515
- /**
516
- * 处理收到的任务请求
517
- */
518
- private async handleTaskRequest(
519
- request: TaskRequestEvent,
520
- fromPeerId: string
521
- ): Promise<void> {
522
- this.logger.info('Received task request', {
523
- fromPeerId: fromPeerId.slice(0, 16),
524
- taskType: request.taskType,
525
- taskId: request.taskId
526
- });
527
-
528
- // 查找对应的能力处理器
529
- const capability = this.registeredCapabilities.get(request.taskType);
530
-
531
- if (!capability) {
532
- this.logger.warn('Capability not supported, rejecting task', {
533
- taskType: request.taskType,
534
- fromPeerId: fromPeerId.slice(0, 16)
535
- });
536
- // 拒绝任务
537
- await this.p2pNetwork.sendTaskResponse(
538
- fromPeerId,
539
- request.taskId,
540
- 'rejected',
541
- undefined,
542
- `Capability not supported: ${request.taskType}`
543
- );
544
- return;
545
- }
546
-
547
- // 触发事件,让上层(OpenClaw)可以拦截或监控
548
- this.emit('task:request', request);
549
-
550
- // 如果有注册 handler,自动执行任务并发送响应
551
- if (capability.handler) {
552
- try {
553
- const result = await capability.handler(request.parameters || {});
554
- await this.p2pNetwork.sendTaskResponse(
555
- fromPeerId,
556
- request.taskId,
557
- 'success',
558
- result
559
- );
560
- this.logger.info('Task executed successfully', {
561
- taskId: request.taskId,
562
- fromPeerId: fromPeerId.slice(0, 16)
563
- });
564
- } catch (error) {
565
- this.logger.error('Task execution failed', {
566
- taskId: request.taskId,
567
- error: error instanceof Error ? error.message : String(error)
568
- });
569
- await this.p2pNetwork.sendTaskResponse(
570
- fromPeerId,
571
- request.taskId,
572
- 'error',
573
- undefined,
574
- error instanceof Error ? error.message : String(error)
575
- );
576
- }
577
- }
578
- // 如果没有 handler,依赖上层通过 respondToTask 手动响应
579
- }
580
-
581
- /**
582
- * 发送任务响应(供 OpenClaw 调用)
583
- */
584
- async respondToTask(
585
- peerId: string,
586
- taskId: string,
587
- status: 'success' | 'error' | 'rejected',
588
- result?: unknown,
589
- error?: string
590
- ): Promise<Result<void>> {
591
- const responseResult = await this.p2pNetwork.sendTaskResponse(
592
- peerId,
593
- taskId,
594
- status,
595
- result,
596
- error
597
- );
598
-
599
- if (responseResult.success) {
600
- this.emit('task:response', {
601
- taskId,
602
- from: this.peerId,
603
- status,
604
- result,
605
- error
606
- });
607
- }
608
-
609
- return responseResult;
610
- }
611
-
612
- /**
613
- * 更新 AgentInfo 中的能力列表
614
- */
615
- private updateAgentCapabilities(): void {
616
- this._agentInfo.capabilities = this.getCapabilities();
617
- }
618
- }