@f2a/network 0.1.2

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 (234) hide show
  1. package/.github/workflows/ci.yml +113 -0
  2. package/.github/workflows/publish.yml +60 -0
  3. package/LICENSE +21 -0
  4. package/MONOREPO.md +58 -0
  5. package/README.md +280 -0
  6. package/SKILL.md +137 -0
  7. package/dist/adapters/openclaw.d.ts +103 -0
  8. package/dist/adapters/openclaw.d.ts.map +1 -0
  9. package/dist/adapters/openclaw.js +297 -0
  10. package/dist/adapters/openclaw.js.map +1 -0
  11. package/dist/cli/commands.d.ts +17 -0
  12. package/dist/cli/commands.d.ts.map +1 -0
  13. package/dist/cli/commands.js +107 -0
  14. package/dist/cli/commands.js.map +1 -0
  15. package/dist/cli/index.d.ts +6 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +203 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/core/autonomous-economy.d.ts +136 -0
  20. package/dist/core/autonomous-economy.d.ts.map +1 -0
  21. package/dist/core/autonomous-economy.js +255 -0
  22. package/dist/core/autonomous-economy.js.map +1 -0
  23. package/dist/core/connection-manager.d.ts +80 -0
  24. package/dist/core/connection-manager.d.ts.map +1 -0
  25. package/dist/core/connection-manager.js +235 -0
  26. package/dist/core/connection-manager.js.map +1 -0
  27. package/dist/core/connection-manager.test.d.ts +2 -0
  28. package/dist/core/connection-manager.test.d.ts.map +1 -0
  29. package/dist/core/connection-manager.test.js +52 -0
  30. package/dist/core/connection-manager.test.js.map +1 -0
  31. package/dist/core/e2ee-crypto.d.ts +90 -0
  32. package/dist/core/e2ee-crypto.d.ts.map +1 -0
  33. package/dist/core/e2ee-crypto.js +190 -0
  34. package/dist/core/e2ee-crypto.js.map +1 -0
  35. package/dist/core/f2a.d.ts +126 -0
  36. package/dist/core/f2a.d.ts.map +1 -0
  37. package/dist/core/f2a.js +425 -0
  38. package/dist/core/f2a.js.map +1 -0
  39. package/dist/core/identity.d.ts +47 -0
  40. package/dist/core/identity.d.ts.map +1 -0
  41. package/dist/core/identity.js +130 -0
  42. package/dist/core/identity.js.map +1 -0
  43. package/dist/core/identity.test.d.ts +2 -0
  44. package/dist/core/identity.test.d.ts.map +1 -0
  45. package/dist/core/identity.test.js +43 -0
  46. package/dist/core/identity.test.js.map +1 -0
  47. package/dist/core/p2p-network.d.ts +242 -0
  48. package/dist/core/p2p-network.d.ts.map +1 -0
  49. package/dist/core/p2p-network.js +1182 -0
  50. package/dist/core/p2p-network.js.map +1 -0
  51. package/dist/core/reputation-security.d.ts +168 -0
  52. package/dist/core/reputation-security.d.ts.map +1 -0
  53. package/dist/core/reputation-security.js +369 -0
  54. package/dist/core/reputation-security.js.map +1 -0
  55. package/dist/core/reputation.d.ts +179 -0
  56. package/dist/core/reputation.d.ts.map +1 -0
  57. package/dist/core/reputation.js +472 -0
  58. package/dist/core/reputation.js.map +1 -0
  59. package/dist/core/review-committee.d.ts +130 -0
  60. package/dist/core/review-committee.d.ts.map +1 -0
  61. package/dist/core/review-committee.js +251 -0
  62. package/dist/core/review-committee.js.map +1 -0
  63. package/dist/core/serverless.d.ts +155 -0
  64. package/dist/core/serverless.d.ts.map +1 -0
  65. package/dist/core/serverless.js +615 -0
  66. package/dist/core/serverless.js.map +1 -0
  67. package/dist/core/token-manager.d.ts +42 -0
  68. package/dist/core/token-manager.d.ts.map +1 -0
  69. package/dist/core/token-manager.js +122 -0
  70. package/dist/core/token-manager.js.map +1 -0
  71. package/dist/daemon/control-server.d.ts +55 -0
  72. package/dist/daemon/control-server.d.ts.map +1 -0
  73. package/dist/daemon/control-server.js +262 -0
  74. package/dist/daemon/control-server.js.map +1 -0
  75. package/dist/daemon/index.d.ts +35 -0
  76. package/dist/daemon/index.d.ts.map +1 -0
  77. package/dist/daemon/index.js +69 -0
  78. package/dist/daemon/index.js.map +1 -0
  79. package/dist/daemon/main.d.ts +6 -0
  80. package/dist/daemon/main.d.ts.map +1 -0
  81. package/dist/daemon/main.js +38 -0
  82. package/dist/daemon/main.js.map +1 -0
  83. package/dist/daemon/start.d.ts +6 -0
  84. package/dist/daemon/start.d.ts.map +1 -0
  85. package/dist/daemon/start.js +25 -0
  86. package/dist/daemon/start.js.map +1 -0
  87. package/dist/daemon/webhook.d.ts +30 -0
  88. package/dist/daemon/webhook.d.ts.map +1 -0
  89. package/dist/daemon/webhook.js +86 -0
  90. package/dist/daemon/webhook.js.map +1 -0
  91. package/dist/daemon/webhook.test.d.ts +2 -0
  92. package/dist/daemon/webhook.test.d.ts.map +1 -0
  93. package/dist/daemon/webhook.test.js +24 -0
  94. package/dist/daemon/webhook.test.js.map +1 -0
  95. package/dist/index.d.ts +24 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +25 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/protocol/messages.d.ts +739 -0
  100. package/dist/protocol/messages.d.ts.map +1 -0
  101. package/dist/protocol/messages.js +188 -0
  102. package/dist/protocol/messages.js.map +1 -0
  103. package/dist/protocol/messages.test.d.ts +2 -0
  104. package/dist/protocol/messages.test.d.ts.map +1 -0
  105. package/dist/protocol/messages.test.js +55 -0
  106. package/dist/protocol/messages.test.js.map +1 -0
  107. package/dist/types/index.d.ts +247 -0
  108. package/dist/types/index.d.ts.map +1 -0
  109. package/dist/types/index.js +10 -0
  110. package/dist/types/index.js.map +1 -0
  111. package/dist/types/result.d.ts +28 -0
  112. package/dist/types/result.d.ts.map +1 -0
  113. package/dist/types/result.js +16 -0
  114. package/dist/types/result.js.map +1 -0
  115. package/dist/utils/benchmark.d.ts +67 -0
  116. package/dist/utils/benchmark.d.ts.map +1 -0
  117. package/dist/utils/benchmark.js +179 -0
  118. package/dist/utils/benchmark.js.map +1 -0
  119. package/dist/utils/logger.d.ts +105 -0
  120. package/dist/utils/logger.d.ts.map +1 -0
  121. package/dist/utils/logger.js +275 -0
  122. package/dist/utils/logger.js.map +1 -0
  123. package/dist/utils/middleware.d.ts +85 -0
  124. package/dist/utils/middleware.d.ts.map +1 -0
  125. package/dist/utils/middleware.js +173 -0
  126. package/dist/utils/middleware.js.map +1 -0
  127. package/dist/utils/rate-limiter.d.ts +71 -0
  128. package/dist/utils/rate-limiter.d.ts.map +1 -0
  129. package/dist/utils/rate-limiter.js +160 -0
  130. package/dist/utils/rate-limiter.js.map +1 -0
  131. package/dist/utils/signature.d.ts +57 -0
  132. package/dist/utils/signature.d.ts.map +1 -0
  133. package/dist/utils/signature.js +102 -0
  134. package/dist/utils/signature.js.map +1 -0
  135. package/dist/utils/validation.d.ts +504 -0
  136. package/dist/utils/validation.d.ts.map +1 -0
  137. package/dist/utils/validation.js +159 -0
  138. package/dist/utils/validation.js.map +1 -0
  139. package/docs/F2A-PROTOCOL.md +61 -0
  140. package/docs/MOBILE_BOOTSTRAP_DESIGN.md +126 -0
  141. package/docs/a2a-lessons.md +316 -0
  142. package/docs/middleware-guide.md +448 -0
  143. package/docs/readme-update-checklist.md +90 -0
  144. package/docs/reputation-guide.md +396 -0
  145. package/docs/rfcs/001-reputation-system.md +712 -0
  146. package/docs/security-design.md +247 -0
  147. package/install.sh +231 -0
  148. package/package.json +64 -0
  149. package/packages/openclaw-adapter/README.md +510 -0
  150. package/packages/openclaw-adapter/openclaw.plugin.json +106 -0
  151. package/packages/openclaw-adapter/package.json +40 -0
  152. package/packages/openclaw-adapter/src/announcement-queue.test.ts +449 -0
  153. package/packages/openclaw-adapter/src/announcement-queue.ts +403 -0
  154. package/packages/openclaw-adapter/src/capability-detector.test.ts +99 -0
  155. package/packages/openclaw-adapter/src/capability-detector.ts +183 -0
  156. package/packages/openclaw-adapter/src/claim-handlers.test.ts +974 -0
  157. package/packages/openclaw-adapter/src/claim-handlers.ts +482 -0
  158. package/packages/openclaw-adapter/src/connector.business.test.ts +583 -0
  159. package/packages/openclaw-adapter/src/connector.ts +795 -0
  160. package/packages/openclaw-adapter/src/index.test.ts +82 -0
  161. package/packages/openclaw-adapter/src/index.ts +18 -0
  162. package/packages/openclaw-adapter/src/integration.e2e.test.ts +829 -0
  163. package/packages/openclaw-adapter/src/logger.ts +51 -0
  164. package/packages/openclaw-adapter/src/network-client.test.ts +266 -0
  165. package/packages/openclaw-adapter/src/network-client.ts +251 -0
  166. package/packages/openclaw-adapter/src/network-recovery.test.ts +465 -0
  167. package/packages/openclaw-adapter/src/node-manager.test.ts +136 -0
  168. package/packages/openclaw-adapter/src/node-manager.ts +429 -0
  169. package/packages/openclaw-adapter/src/plugin.test.ts +439 -0
  170. package/packages/openclaw-adapter/src/plugin.ts +104 -0
  171. package/packages/openclaw-adapter/src/reputation.test.ts +221 -0
  172. package/packages/openclaw-adapter/src/reputation.ts +368 -0
  173. package/packages/openclaw-adapter/src/task-guard.test.ts +502 -0
  174. package/packages/openclaw-adapter/src/task-guard.ts +860 -0
  175. package/packages/openclaw-adapter/src/task-queue.concurrency.test.ts +462 -0
  176. package/packages/openclaw-adapter/src/task-queue.edge-cases.test.ts +284 -0
  177. package/packages/openclaw-adapter/src/task-queue.persistence.test.ts +408 -0
  178. package/packages/openclaw-adapter/src/task-queue.ts +668 -0
  179. package/packages/openclaw-adapter/src/tool-handlers.test.ts +906 -0
  180. package/packages/openclaw-adapter/src/tool-handlers.ts +574 -0
  181. package/packages/openclaw-adapter/src/types.ts +361 -0
  182. package/packages/openclaw-adapter/src/webhook-pusher.test.ts +188 -0
  183. package/packages/openclaw-adapter/src/webhook-pusher.ts +220 -0
  184. package/packages/openclaw-adapter/src/webhook-server.test.ts +580 -0
  185. package/packages/openclaw-adapter/src/webhook-server.ts +202 -0
  186. package/packages/openclaw-adapter/tsconfig.json +20 -0
  187. package/src/cli/commands.test.ts +157 -0
  188. package/src/cli/commands.ts +129 -0
  189. package/src/cli/index.test.ts +77 -0
  190. package/src/cli/index.ts +234 -0
  191. package/src/core/autonomous-economy.test.ts +291 -0
  192. package/src/core/autonomous-economy.ts +428 -0
  193. package/src/core/e2ee-crypto.test.ts +125 -0
  194. package/src/core/e2ee-crypto.ts +246 -0
  195. package/src/core/f2a.test.ts +269 -0
  196. package/src/core/f2a.ts +618 -0
  197. package/src/core/p2p-network.test.ts +199 -0
  198. package/src/core/p2p-network.ts +1432 -0
  199. package/src/core/reputation-security.test.ts +403 -0
  200. package/src/core/reputation-security.ts +562 -0
  201. package/src/core/reputation.test.ts +260 -0
  202. package/src/core/reputation.ts +576 -0
  203. package/src/core/review-committee.test.ts +380 -0
  204. package/src/core/review-committee.ts +401 -0
  205. package/src/core/token-manager.test.ts +133 -0
  206. package/src/core/token-manager.ts +140 -0
  207. package/src/daemon/control-server.test.ts +216 -0
  208. package/src/daemon/control-server.ts +292 -0
  209. package/src/daemon/index.test.ts +85 -0
  210. package/src/daemon/index.ts +89 -0
  211. package/src/daemon/main.ts +44 -0
  212. package/src/daemon/start.ts +29 -0
  213. package/src/daemon/webhook.test.ts +68 -0
  214. package/src/daemon/webhook.ts +105 -0
  215. package/src/index.test.ts +436 -0
  216. package/src/index.ts +72 -0
  217. package/src/types/index.test.ts +87 -0
  218. package/src/types/index.ts +341 -0
  219. package/src/types/result.ts +68 -0
  220. package/src/utils/benchmark.ts +237 -0
  221. package/src/utils/logger.ts +331 -0
  222. package/src/utils/middleware.ts +229 -0
  223. package/src/utils/rate-limiter.ts +207 -0
  224. package/src/utils/signature.ts +136 -0
  225. package/src/utils/validation.ts +186 -0
  226. package/tests/docker/Dockerfile.node +23 -0
  227. package/tests/docker/Dockerfile.runner +18 -0
  228. package/tests/docker/docker-compose.test.yml +73 -0
  229. package/tests/integration/message-passing.test.ts +109 -0
  230. package/tests/integration/multi-node.test.ts +92 -0
  231. package/tests/integration/p2p-connection.test.ts +83 -0
  232. package/tests/integration/test-config.ts +32 -0
  233. package/tsconfig.json +21 -0
  234. package/vitest.config.ts +26 -0
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ /**
3
+ * 身份管理器
4
+ * 负责生成、加载和保存 Agent 身份
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.IdentityManager = void 0;
8
+ const crypto_1 = require("crypto");
9
+ const fs_1 = require("fs");
10
+ const path_1 = require("path");
11
+ const os_1 = require("os");
12
+ class IdentityManager {
13
+ configDir;
14
+ identityFile;
15
+ constructor(options = {}) {
16
+ this.configDir = options.configDir ?? (0, path_1.join)((0, os_1.homedir)(), '.f2a');
17
+ this.identityFile = (0, path_1.join)(this.configDir, 'identity.json');
18
+ this.ensureConfigDir();
19
+ }
20
+ /**
21
+ * 获取或创建身份
22
+ */
23
+ getOrCreateIdentity(displayName) {
24
+ const existing = this.loadIdentity();
25
+ if (existing) {
26
+ return { ...existing, isNew: false };
27
+ }
28
+ return this.createIdentity(displayName);
29
+ }
30
+ /**
31
+ * 创建新身份
32
+ */
33
+ createIdentity(displayName) {
34
+ const keyPair = (0, crypto_1.generateKeyPairSync)('ed25519', {
35
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
36
+ privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
37
+ });
38
+ const agentId = this.generateAgentId(keyPair.publicKey);
39
+ const identity = {
40
+ agentId,
41
+ publicKey: keyPair.publicKey,
42
+ privateKey: keyPair.privateKey,
43
+ displayName
44
+ };
45
+ this.saveIdentity(identity);
46
+ return {
47
+ ...identity,
48
+ isNew: true,
49
+ createdAt: Date.now()
50
+ };
51
+ }
52
+ /**
53
+ * 加载已有身份
54
+ */
55
+ loadIdentity() {
56
+ try {
57
+ if (!(0, fs_1.existsSync)(this.identityFile)) {
58
+ return null;
59
+ }
60
+ const data = (0, fs_1.readFileSync)(this.identityFile, 'utf-8');
61
+ const identity = JSON.parse(data);
62
+ // 验证必要字段
63
+ if (!identity.agentId || !identity.publicKey || !identity.privateKey) {
64
+ console.error('[IdentityManager] 身份文件格式错误');
65
+ return null;
66
+ }
67
+ return identity;
68
+ }
69
+ catch (error) {
70
+ console.error('[IdentityManager] 加载身份失败:', error);
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * 保存身份
76
+ */
77
+ saveIdentity(identity) {
78
+ try {
79
+ const data = JSON.stringify(identity, null, 2);
80
+ (0, fs_1.writeFileSync)(this.identityFile, data, { mode: 0o600 }); // 只有所有者可读写
81
+ return { success: true, data: undefined };
82
+ }
83
+ catch (error) {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ return { success: false, error: `保存身份失败: ${message}` };
86
+ }
87
+ }
88
+ /**
89
+ * 获取身份文件路径
90
+ */
91
+ getConfigPath() {
92
+ return this.identityFile;
93
+ }
94
+ /**
95
+ * 获取身份信息(只读)
96
+ */
97
+ getIdentityInfo() {
98
+ const identity = this.loadIdentity();
99
+ if (!identity)
100
+ return null;
101
+ return {
102
+ agentId: identity.agentId,
103
+ displayName: identity.displayName
104
+ };
105
+ }
106
+ /**
107
+ * 生成 Agent ID
108
+ * 基于公钥派生
109
+ */
110
+ generateAgentId(publicKey) {
111
+ // 使用公钥的前 16 位作为基础
112
+ const base = publicKey
113
+ .replace(/-----BEGIN PUBLIC KEY-----/, '')
114
+ .replace(/-----END PUBLIC KEY-----/, '')
115
+ .replace(/\s/g, '')
116
+ .slice(0, 16);
117
+ // 格式: f2a-xxxx-xxxx
118
+ return `f2a-${base.slice(0, 4)}-${base.slice(4, 8)}-${base.slice(8, 12)}`;
119
+ }
120
+ /**
121
+ * 确保配置目录存在
122
+ */
123
+ ensureConfigDir() {
124
+ if (!(0, fs_1.existsSync)(this.configDir)) {
125
+ (0, fs_1.mkdirSync)(this.configDir, { recursive: true, mode: 0o700 });
126
+ }
127
+ }
128
+ }
129
+ exports.IdentityManager = IdentityManager;
130
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/core/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=identity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../../src/core/identity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const identity_1 = require("./identity");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const os_1 = require("os");
8
+ (0, vitest_1.describe)('IdentityManager', () => {
9
+ let testDir;
10
+ let im;
11
+ (0, vitest_1.beforeEach)(() => {
12
+ testDir = (0, path_1.join)((0, os_1.tmpdir)(), `f2a-test-${Date.now()}`);
13
+ im = new identity_1.IdentityManager({ configDir: testDir });
14
+ });
15
+ (0, vitest_1.afterEach)(() => {
16
+ if ((0, fs_1.existsSync)(testDir)) {
17
+ (0, fs_1.rmSync)(testDir, { recursive: true });
18
+ }
19
+ });
20
+ (0, vitest_1.it)('should create new identity', () => {
21
+ const identity = im.getOrCreateIdentity('TestAgent');
22
+ (0, vitest_1.expect)(identity.isNew).toBe(true);
23
+ (0, vitest_1.expect)(identity.agentId).toBeDefined();
24
+ (0, vitest_1.expect)(identity.publicKey).toBeDefined();
25
+ (0, vitest_1.expect)(identity.privateKey).toBeDefined();
26
+ (0, vitest_1.expect)(identity.displayName).toBe('TestAgent');
27
+ });
28
+ (0, vitest_1.it)('should load existing identity', () => {
29
+ const identity1 = im.getOrCreateIdentity();
30
+ const identity2 = im.getOrCreateIdentity();
31
+ (0, vitest_1.expect)(identity1.isNew).toBe(true);
32
+ (0, vitest_1.expect)(identity2.isNew).toBe(false);
33
+ (0, vitest_1.expect)(identity1.agentId).toBe(identity2.agentId);
34
+ });
35
+ (0, vitest_1.it)('should return identity info', () => {
36
+ im.getOrCreateIdentity('TestAgent');
37
+ const info = im.getIdentityInfo();
38
+ (0, vitest_1.expect)(info).toBeDefined();
39
+ (0, vitest_1.expect)(info?.agentId).toBeDefined();
40
+ (0, vitest_1.expect)(info?.displayName).toBe('TestAgent');
41
+ });
42
+ });
43
+ //# sourceMappingURL=identity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.test.js","sourceRoot":"","sources":["../../src/core/identity.test.ts"],"names":[],"mappings":";;AAAA,mCAAqE;AACrE,yCAA6C;AAC7C,2BAAwC;AACxC,+BAA4B;AAC5B,2BAA4B;AAE5B,IAAA,iBAAQ,EAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,OAAe,CAAC;IACpB,IAAI,EAAmB,CAAC;IAExB,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,EAAE,GAAG,IAAI,0BAAe,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAA,kBAAS,EAAC,GAAG,EAAE;QACb,IAAI,IAAA,eAAU,EAAC,OAAO,CAAC,EAAE,CAAC;YACxB,IAAA,WAAM,EAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,QAAQ,GAAG,EAAE,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAErD,IAAA,eAAM,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,IAAA,eAAM,EAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,IAAA,eAAM,EAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QACzC,IAAA,eAAM,EAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAA,eAAM,EAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,SAAS,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC;QAE3C,IAAA,eAAM,EAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAA,eAAM,EAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,IAAA,eAAM,EAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC;QAElC,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,IAAA,eAAM,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,IAAA,eAAM,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * P2P 网络管理器
3
+ * 基于 libp2p 实现 Agent 发现与通信
4
+ */
5
+ import { EventEmitter } from 'eventemitter3';
6
+ import { P2PNetworkConfig, AgentInfo, F2AMessage, PeerInfo, PeerDiscoveredEvent, PeerConnectedEvent, PeerDisconnectedEvent, Result } from '../types/index.js';
7
+ import { Middleware } from '../utils/middleware.js';
8
+ export interface P2PNetworkEvents {
9
+ 'peer:discovered': (event: PeerDiscoveredEvent) => void;
10
+ 'peer:connected': (event: PeerConnectedEvent) => void;
11
+ 'peer:disconnected': (event: PeerDisconnectedEvent) => void;
12
+ 'message:received': (message: F2AMessage, peerId: string) => void;
13
+ 'error': (error: Error) => void;
14
+ }
15
+ /** 发现选项 */
16
+ export interface DiscoverOptions {
17
+ /** 发现超时毫秒(默认 2000) */
18
+ timeoutMs?: number;
19
+ /** 是否等待首个响应即返回(默认 false) */
20
+ waitForFirstResponse?: boolean;
21
+ }
22
+ export declare class P2PNetwork extends EventEmitter<P2PNetworkEvents> {
23
+ private node;
24
+ private config;
25
+ private peerTable;
26
+ /** 用于保护 peerTable 并发访问的锁 */
27
+ private peerTableLock;
28
+ private agentInfo;
29
+ private pendingTasks;
30
+ private cleanupInterval?;
31
+ private discoveryInterval?;
32
+ private e2eeCrypto;
33
+ private enableE2EE;
34
+ private logger;
35
+ private middlewareManager;
36
+ constructor(agentInfo: AgentInfo, config?: P2PNetworkConfig);
37
+ /**
38
+ * 启动 P2P 网络
39
+ */
40
+ start(): Promise<Result<{
41
+ peerId: string;
42
+ addresses: string[];
43
+ }>>;
44
+ /**
45
+ * 停止 P2P 网络
46
+ */
47
+ stop(): Promise<void>;
48
+ /**
49
+ * 发现网络中的 Agent(按能力过滤)
50
+ * @param capability 可选的能力过滤
51
+ * @param options 发现选项
52
+ */
53
+ discoverAgents(capability?: string, options?: DiscoverOptions): Promise<AgentInfo[]>;
54
+ /**
55
+ * 向特定 Peer 发送任务请求
56
+ */
57
+ sendTaskRequest(peerId: string, taskType: string, description: string, parameters?: Record<string, unknown>, timeout?: number): Promise<Result<unknown>>;
58
+ /**
59
+ * 发送任务响应
60
+ */
61
+ sendTaskResponse(peerId: string, taskId: string, status: 'success' | 'error' | 'rejected' | 'delegated', result?: unknown, error?: string): Promise<Result<void>>;
62
+ /**
63
+ * 广播发现消息
64
+ */
65
+ private broadcastDiscovery;
66
+ /**
67
+ * 广播消息到全网
68
+ */
69
+ private broadcast;
70
+ /**
71
+ * 向特定 Peer 发送消息
72
+ * @param peerId 目标 Peer ID
73
+ * @param message 消息内容
74
+ * @param encrypt 是否启用 E2EE 加密(默认 false,发现类消息不需要加密)
75
+ */
76
+ private sendMessage;
77
+ /**
78
+ * 设置 libp2p 事件处理
79
+ */
80
+ private setupEventHandlers;
81
+ /**
82
+ * 处理收到的消息
83
+ */
84
+ private handleMessage;
85
+ /**
86
+ * 处理加密消息
87
+ * @returns 处理结果,包含是否继续处理和解密后的消息
88
+ */
89
+ private handleEncryptedMessage;
90
+ /**
91
+ * 验证发送方身份
92
+ */
93
+ private verifySenderIdentity;
94
+ /**
95
+ * 发送解密失败响应
96
+ */
97
+ private sendDecryptFailureResponse;
98
+ /**
99
+ * 根据消息类型分发处理
100
+ */
101
+ private dispatchMessage;
102
+ /**
103
+ * 处理发现消息
104
+ */
105
+ private handleDiscoverMessage;
106
+ /**
107
+ * 处理能力响应消息
108
+ */
109
+ private handleCapabilityResponseMessage;
110
+ /**
111
+ * 处理能力查询消息
112
+ */
113
+ private handleCapabilityQueryMessage;
114
+ /**
115
+ * 处理任务响应消息
116
+ */
117
+ private handleTaskResponseMessage;
118
+ /**
119
+ * 处理解密失败通知消息
120
+ */
121
+ private handleDecryptFailedMessage;
122
+ /**
123
+ * 处理发现消息
124
+ */
125
+ /**
126
+ * 处理发现消息
127
+ */
128
+ private handleDiscover;
129
+ /**
130
+ * 将发现到的 Agent 信息更新到 Peer 表
131
+ */
132
+ private upsertPeerFromAgentInfo;
133
+ /**
134
+ * 处理能力查询
135
+ */
136
+ private handleCapabilityQuery;
137
+ /**
138
+ * 处理任务响应
139
+ */
140
+ private handleTaskResponse;
141
+ /**
142
+ * 连接引导节点
143
+ */
144
+ private connectToBootstrapPeers;
145
+ /**
146
+ * 启动定期发现广播
147
+ */
148
+ private startDiscoveryBroadcast;
149
+ /**
150
+ * 启动定期清理任务
151
+ */
152
+ private startCleanupTask;
153
+ /**
154
+ * 清理过期的 Peer 记录(带锁保护)
155
+ * @param aggressive 是否使用激进清理策略(清理更多条目)
156
+ */
157
+ private cleanupStalePeers;
158
+ /**
159
+ * 清理过期的 Peer 记录(内部方法,调用前必须持有锁)
160
+ * @param aggressive 是否使用激进清理策略(清理更多条目)
161
+ */
162
+ private cleanupStalePeersLocked;
163
+ /**
164
+ * 原子操作:获取 peer 信息
165
+ */
166
+ private getPeer;
167
+ /**
168
+ * 原子操作:设置 peer 信息
169
+ */
170
+ private setPeer;
171
+ /**
172
+ * 原子操作:更新 peer 信息(线程安全)
173
+ * @param peerId Peer ID
174
+ * @param updater 更新函数,接收当前值,返回新值
175
+ * @returns 更新后的 peer 信息,如果 peer 不存在则返回 undefined
176
+ */
177
+ private updatePeer;
178
+ /**
179
+ * 原子操作:安全地更新或创建 peer
180
+ * @param peerId Peer ID
181
+ * @param creator 创建新 peer 的函数(如果不存在)
182
+ * @param updater 更新函数(如果存在)
183
+ */
184
+ private upsertPeer;
185
+ /**
186
+ * 原子操作:删除 peer
187
+ */
188
+ private deletePeer;
189
+ /**
190
+ * 检查 Agent 是否有特定能力
191
+ */
192
+ private hasCapability;
193
+ /**
194
+ * 获取已连接的 Peers
195
+ */
196
+ getConnectedPeers(): PeerInfo[];
197
+ /**
198
+ * 获取所有已知的 Peers
199
+ */
200
+ getAllPeers(): PeerInfo[];
201
+ /**
202
+ * 获取节点 ID
203
+ */
204
+ getPeerId(): string | null;
205
+ /**
206
+ * 获取 E2EE 加密公钥
207
+ */
208
+ getEncryptionPublicKey(): string | null;
209
+ /**
210
+ * 获取已注册的加密对等方数量
211
+ */
212
+ getEncryptedPeerCount(): number;
213
+ /**
214
+ * 通过 DHT 查找节点 (全局发现)
215
+ */
216
+ findPeerViaDHT(peerId: string): Promise<Result<string[]>>;
217
+ /**
218
+ * 获取 DHT 路由表大小
219
+ */
220
+ getDHTPeerCount(): number;
221
+ /**
222
+ * 检查 DHT 是否启用
223
+ */
224
+ isDHTEnabled(): boolean;
225
+ /**
226
+ * 注册中间件
227
+ * @param middleware 中间件实例
228
+ */
229
+ useMiddleware(middleware: Middleware): void;
230
+ /**
231
+ * 移除中间件
232
+ * @param name 中间件名称
233
+ * @returns 是否成功移除
234
+ */
235
+ removeMiddleware(name: string): boolean;
236
+ /**
237
+ * 获取已注册的中间件列表
238
+ * @returns 中间件名称列表
239
+ */
240
+ listMiddlewares(): string[];
241
+ }
242
+ //# sourceMappingURL=p2p-network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"p2p-network.d.ts","sourceRoot":"","sources":["../../src/core/p2p-network.ts"],"names":[],"mappings":"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"}