@twinsearth/agent-universe 2.3.5 → 2.5.6

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.
@@ -0,0 +1,224 @@
1
+ // test/test.js
2
+ // Agent Universe JS SDK 测试(8 项)
3
+
4
+ const assert = require('node:assert');
5
+ const {
6
+ version,
7
+ AgentUniverse,
8
+ Keypair,
9
+ AgentCard,
10
+ Task,
11
+ TaskStatus,
12
+ MemoryDHT,
13
+ ShardedIndex,
14
+ shardOf,
15
+ AgentMarket,
16
+ MIN_STAKE,
17
+ AipIdentity,
18
+ buildManifest,
19
+ buildEnvelope,
20
+ proposalMessage,
21
+ buildReceipt,
22
+ verifyManifest,
23
+ verifyMessage,
24
+ verifyReceipt,
25
+ verifyReceiptResult,
26
+ } = require('../index');
27
+
28
+ let passed = 0;
29
+ function test(name, fn) {
30
+ try {
31
+ fn();
32
+ passed++;
33
+ console.log(` ✓ ${name}`);
34
+ } catch (e) {
35
+ console.error(` ✗ ${name}`);
36
+ console.error(` ${e.message}`);
37
+ process.exitCode = 1;
38
+ }
39
+ }
40
+
41
+ console.log('Agent Universe JS SDK 测试\n');
42
+
43
+ // 1. 版本号
44
+ test('版本号为 2.5.6', () => {
45
+ assert.strictEqual(version, '2.5.6');
46
+ });
47
+
48
+ // 2. 密钥对 + DID + 签名验证
49
+ test('Keypair 生成 DID 且签名可验证', () => {
50
+ const kp = Keypair.generate();
51
+ assert.ok(kp.did.startsWith('did:au:'), 'DID 前缀');
52
+ assert.strictEqual(kp.did.length, 'did:au:'.length + 32);
53
+ const msg = 'hello agent universe';
54
+ const sig = kp.sign(msg);
55
+ assert.ok(kp.verify(msg, sig), '签名验证通过');
56
+ assert.ok(!kp.verify('tampered', sig), '篡改消息验证失败');
57
+ });
58
+
59
+ // 3. AgentCard
60
+ test('AgentCard 能力与技能', () => {
61
+ const card = AgentCard.new({ did: 'did:au:abc', name: 'writer' })
62
+ .withCapability('writing')
63
+ .withSkill('translation');
64
+ assert.ok(card.hasCapability('writing'));
65
+ assert.deepStrictEqual(card.toJSON().skills, ['translation']);
66
+ });
67
+
68
+ // 4. Task 状态机
69
+ test('Task 状态机合法流转且拒绝非法转移', () => {
70
+ const t = new Task('t1', 'write doc');
71
+ t.transition(TaskStatus.OPEN);
72
+ t.assign('did:au:worker');
73
+ t.start();
74
+ t.complete();
75
+ t.verify(true);
76
+ t.settle();
77
+ assert.strictEqual(t.status, TaskStatus.SETTLED);
78
+ assert.ok(t.isTerminal);
79
+
80
+ const t2 = new Task('t2', 'bad');
81
+ assert.throws(() => t2.start(), /非法状态转移/);
82
+ });
83
+
84
+ // 5. MemoryDHT
85
+ test('MemoryDHT 存取与前缀查找', () => {
86
+ const dht = new MemoryDHT();
87
+ dht.put('/aip/agent/1', { name: 'a' });
88
+ dht.put('/aip/agent/2', { name: 'b' });
89
+ assert.strictEqual(dht.size, 2);
90
+ assert.strictEqual(dht.get('/aip/agent/1').name, 'a');
91
+ assert.strictEqual(dht.findByPrefix('/aip/agent').length, 2);
92
+ });
93
+
94
+ // 6. ShardedIndex 分片
95
+ test('ShardedIndex 分片落盘且分片号合法', () => {
96
+ const idx = new ShardedIndex(16);
97
+ for (let i = 0; i < 100; i++) {
98
+ const s = idx.put(`key-${i}`, i);
99
+ assert.ok(s >= 0 && s < 16);
100
+ }
101
+ assert.strictEqual(idx.size, 100);
102
+ assert.strictEqual(shardOf('key-0', 16), shardOf('key-0', 16));
103
+ // 分布:100 key 到 16 片,不应有大片为空(概率性,至少覆盖 8 片)
104
+ const nonEmpty = idx.distribution().filter((n) => n > 0).length;
105
+ assert.ok(nonEmpty >= 8, `非空分片 ${nonEmpty} >= 8`);
106
+ });
107
+
108
+ // 7. AgentMarket 端到端 + 守恒
109
+ test('AgentMarket 端到端:注册→发布→投标→匹配→完成→结算→守恒', () => {
110
+ const market = new AgentMarket();
111
+ const owner = 'did:au:owner';
112
+ const requester = 'did:au:requester';
113
+
114
+ // 充值(owner 质押 100,requester 预算 50)
115
+ market.deposit(owner, 100);
116
+ market.deposit(requester, 50);
117
+ const totalDeposits = 150;
118
+
119
+ const card = AgentCard.new({ did: owner, name: 'worker' })
120
+ .withSkill('writing');
121
+ market.registerAgent(card, MIN_STAKE);
122
+
123
+ market.publishTask('task-1', 'write an article', 50, requester);
124
+ market.submitBid('task-1', owner, 40);
125
+ const winner = market.matchTask('task-1');
126
+ assert.strictEqual(winner.agentId, owner);
127
+
128
+ market.completeTask('task-1', true);
129
+ const result = market.settle('task-1');
130
+ assert.strictEqual(result.paid, 40);
131
+
132
+ // 重复结算短路
133
+ const again = market.settle('task-1');
134
+ assert.strictEqual(again.reason, 'already_paid');
135
+
136
+ // 守恒:无罚没,总余额 = 总充值
137
+ const check = market.conservationCheck(totalDeposits);
138
+ assert.ok(check.conserved, `守恒: ${JSON.stringify(check)}`);
139
+ });
140
+
141
+ // 8. 罚没守恒
142
+ test('罚没后守恒:总余额 = 总充值 − 罚没', () => {
143
+ const market = new AgentMarket();
144
+ const owner = 'did:au:bad';
145
+ market.deposit(owner, 200);
146
+ const card = AgentCard.new({ did: owner, name: 'bad' });
147
+ market.registerAgent(card, MIN_STAKE); // 质押 100
148
+
149
+ const slashResult = market.slash(owner, 60, 'fraud');
150
+ assert.strictEqual(slashResult.slashed, 60);
151
+
152
+ const check = market.conservationCheck(200);
153
+ assert.ok(check.conserved, `罚没守恒: ${JSON.stringify(check)}`);
154
+ assert.strictEqual(check.balanceSum, 140);
155
+ });
156
+
157
+ // 9. AipIdentity DID 与签名往返
158
+ test('AipIdentity 生成 did:aip 且签名可验证', () => {
159
+ const id = AipIdentity.generate();
160
+ assert.ok(id.did.startsWith('did:aip:'), 'DID 前缀');
161
+ assert.strictEqual(id.publicKey.length, 32, '原始公钥 32 字节');
162
+ const obj = { did: id.did, name: 't' };
163
+ id.signInto(obj);
164
+ assert.ok(AipIdentity.verifyObject(obj, id.publicKey), '验签通过');
165
+ const tampered = { ...obj, name: 'x' };
166
+ assert.ok(!AipIdentity.verifyObject(tampered, id.publicKey), '篡改拒绝');
167
+ });
168
+
169
+ // 10. 跨语言基准(与 Rust/Python 固定种子一致)
170
+ test('AipIdentity.fromSeed 复算 Rust/Python 基准', () => {
171
+ const id = AipIdentity.fromSeed(Buffer.alloc(32, 1));
172
+ assert.strictEqual(
173
+ id.publicKey.toString('hex'),
174
+ '8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c'
175
+ );
176
+ assert.strictEqual(id.did, 'did:aip:34750f98bd59fcfc');
177
+ const obj = {
178
+ did: id.did,
179
+ name: 'CrossLang',
180
+ capabilities: ['text-generation', 'mcp'],
181
+ stake: 100,
182
+ };
183
+ const sig = id.signObject(obj);
184
+ assert.strictEqual(
185
+ sig,
186
+ 'e14d3f9e8204ea185ea4ba32a8117f262095ab9dac1352e1a7964ce36d3355c288dd6804ffa7daeb5f6eba9f30428f52702a75fd3efbb6a62555a7f24665da0e'
187
+ );
188
+ });
189
+
190
+ // 11. ACA manifest/message 构造与验签
191
+ test('ACA manifest 与 proposal message 可验签、篡改拒绝', () => {
192
+ const owner = AipIdentity.generate();
193
+ const peer = AipIdentity.generate();
194
+ const manifest = buildManifest(owner, 'Agent1', ['text-generation'], {
195
+ stake: 100,
196
+ mcpToolCount: 3,
197
+ });
198
+ assert.ok(verifyManifest(manifest, owner.publicKey));
199
+ assert.ok(!verifyManifest({ ...manifest, name: 'Fake' }, owner.publicKey));
200
+
201
+ const envelope = buildEnvelope(owner.did, 'text-generation', 'out', {
202
+ budget: 10,
203
+ });
204
+ const message = proposalMessage(owner, peer.did, envelope);
205
+ assert.ok(verifyMessage(message, owner.publicKey));
206
+ assert.ok(!verifyMessage(message, peer.publicKey), '他人公钥拒绝');
207
+ });
208
+
209
+ // 12. Receipt 签名与结果哈希
210
+ test('ACA receipt 签名、结果哈希正反例', () => {
211
+ const owner = AipIdentity.generate();
212
+ const result = Buffer.from('hello result');
213
+ const receipt = buildReceipt(owner, 'task-1', result);
214
+ assert.ok(verifyReceipt(receipt, owner.publicKey));
215
+ assert.ok(verifyReceiptResult(receipt, result));
216
+ assert.ok(!verifyReceiptResult(receipt, Buffer.from('other')));
217
+ });
218
+
219
+ console.log(`\n${passed} 项测试通过`);
220
+ if (process.exitCode === 1) {
221
+ console.error('存在失败测试');
222
+ } else {
223
+ console.log('全部通过');
224
+ }
package/package.json CHANGED
@@ -1,18 +1,25 @@
1
1
  {
2
2
  "name": "@twinsearth/agent-universe",
3
- "version": "2.3.5",
3
+ "version": "2.5.6",
4
4
  "description": "Agent Universe - 群众化的 AGI 路线,去中心化的智能体共享 & 开源网络。使命:让科技造福全人类!",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
7
  "scripts": {
8
- "test": "node test/test.js"
8
+ "start": "node index.js",
9
+ "test": "node js/test/test.js"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/TwinsEarth/agent-universe.git"
9
14
  },
10
15
  "keywords": [
11
16
  "agi",
12
- "agent",
13
17
  "p2p",
18
+ "agent",
14
19
  "decentralized",
20
+ "gsn",
15
21
  "swarm",
22
+ "libp2p",
16
23
  "dht",
17
24
  "mcp",
18
25
  "a2a",
@@ -20,17 +27,13 @@
20
27
  ],
21
28
  "author": "TwinsEarth",
22
29
  "license": "MIT",
23
- "repository": {
24
- "type": "git",
25
- "url": "git+https://github.com/TwinsEarth/agent-universe.git",
26
- "directory": "js"
27
- },
28
- "homepage": "https://github.com/TwinsEarth/agent-universe#readme",
29
30
  "bugs": {
30
31
  "url": "https://github.com/TwinsEarth/agent-universe/issues"
31
32
  },
33
+ "homepage": "https://github.com/TwinsEarth/agent-universe#readme",
32
34
  "publishConfig": {
33
- "registry": "https://registry.npmjs.org/"
35
+ "registry": "https://registry.npmjs.org",
36
+ "access": "public"
34
37
  },
35
38
  "engines": {
36
39
  "node": ">=18"
@@ -38,6 +41,6 @@
38
41
  "files": [
39
42
  "index.js",
40
43
  "index.d.ts",
41
- "lib"
44
+ "js"
42
45
  ]
43
46
  }
File without changes
File without changes
File without changes
File without changes