@bolloon/bolloon-agent 0.4.30 → 0.4.32
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/dist/agents/agent-gateway.js +5 -0
- package/dist/agents/agent-manifest-protocol.js +29 -0
- package/dist/agents/chain/chain-config.js +504 -0
- package/dist/agents/chain/chain-index-query.js +135 -0
- package/dist/agents/chain/chain-indexer.js +1045 -0
- package/dist/agents/chain/chain-settlement.js +284 -0
- package/dist/agents/chain/chain-state-store.js +245 -0
- package/dist/agents/chain/chain-wallet.js +198 -0
- package/dist/agents/chain/escrow-client.js +433 -0
- package/dist/agents/chain/index.js +20 -0
- package/dist/agents/chain/onchain-trade.js +691 -0
- package/dist/agents/economic-policy.js +7 -0
- package/dist/agents/gateway-network.js +6 -0
- package/dist/agents/local-signer.js +59 -0
- package/dist/agents/network-pulse.js +912 -0
- package/dist/agents/task/task-onchain-runner.js +284 -0
- package/dist/agents/task-contract.js +322 -0
- package/dist/agents/task-inbox.js +267 -0
- package/dist/agents/task-transport.js +280 -0
- package/dist/agents/x402/paid-info-store.js +75 -6
- package/dist/agents/x402/transaction-store.js +8 -1
- package/dist/cli/commands/agent.js +230 -0
- package/dist/cli/commands/chain.js +926 -0
- package/dist/cli/commands/index.js +69 -0
- package/dist/cli/commands/mcp.js +98 -0
- package/dist/cli/commands/network.js +334 -0
- package/dist/cli/commands/payment.js +125 -0
- package/dist/cli/commands/tasks.js +1236 -0
- package/dist/cli/commands/trade.js +229 -0
- package/dist/cli/commands/wallet.js +450 -0
- package/dist/cli/mcp/bridge.js +105 -0
- package/dist/cli/mcp/server.js +188 -0
- package/dist/cli/mcp/tools.js +955 -0
- package/dist/cli/protocol-envelope.js +358 -0
- package/dist/cli-entry.js +146 -17
- package/dist/electron-build/agents/agent-gateway.js +5 -0
- package/dist/electron-build/agents/agent-gateway.js.map +1 -1
- package/dist/electron-build/agents/agent-manifest-protocol.js +62 -0
- package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -1
- package/dist/electron-build/agents/chain/chain-config.js +556 -0
- package/dist/electron-build/agents/chain/chain-config.js.map +1 -0
- package/dist/electron-build/agents/chain/chain-index-query.js +145 -0
- package/dist/electron-build/agents/chain/chain-index-query.js.map +1 -0
- package/dist/electron-build/agents/chain/chain-indexer.js +1095 -0
- package/dist/electron-build/agents/chain/chain-indexer.js.map +1 -0
- package/dist/electron-build/agents/chain/chain-settlement.js +291 -0
- package/dist/electron-build/agents/chain/chain-settlement.js.map +1 -0
- package/dist/electron-build/agents/chain/escrow-client.js +443 -0
- package/dist/electron-build/agents/chain/escrow-client.js.map +1 -0
- package/dist/electron-build/agents/economic-policy.js +7 -0
- package/dist/electron-build/agents/economic-policy.js.map +1 -1
- package/dist/electron-build/agents/gateway-network.js +6 -0
- package/dist/electron-build/agents/gateway-network.js.map +1 -1
- package/dist/electron-build/agents/network-pulse.js +979 -0
- package/dist/electron-build/agents/network-pulse.js.map +1 -0
- package/dist/electron-build/agents/x402/paid-info-store.js +76 -6
- package/dist/electron-build/agents/x402/paid-info-store.js.map +1 -1
- package/dist/electron-build/agents/x402/transaction-store.js +8 -1
- package/dist/electron-build/agents/x402/transaction-store.js.map +1 -1
- package/dist/web/chain-explorer.js +617 -0
- package/dist/web/explorer.html +163 -0
- package/dist/web/index.html +5 -0
- package/dist/web/routes-chain-index.js +108 -0
- package/dist/web/routes-onchain-trade.js +99 -0
- package/dist/web/server.js +42 -0
- package/dist/web/task-frame-server.js +211 -0
- package/package.json +2 -1
- package/scripts/build-web.ts +20 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent.ts — P3 `bolloon agent register|manifest|discover|inspect`
|
|
3
|
+
*
|
|
4
|
+
* 全部是现有服务的薄包装:
|
|
5
|
+
* register → `agent-gateway.gatewayRegisterAgent()` (warm registry + 写服务声明, 落 ~/.bolloon/agent-registry.json)
|
|
6
|
+
* `--manifest` 时另调 `agent-manifest-protocol.setLocalManifest()` (进程内, 不落盘 —— 如实标注)
|
|
7
|
+
* manifest → `agent-manifest-protocol.getLocalManifest()`
|
|
8
|
+
* discover → `agent-registry.discover(q)` (OrbitDB 优先, 失败回退本地文件)
|
|
9
|
+
* inspect → `agent-registry.list()` 按 agentId 命中 / 远端 manifest 缓存 (`getRemoteManifests`)
|
|
10
|
+
*
|
|
11
|
+
* 找不到能力 → §3 `CAPABILITY_NOT_FOUND` (next_action `redefine_capability`); **绝不**因此发起付款 (§9 第 3 条)。
|
|
12
|
+
*/
|
|
13
|
+
import { okEnvelope, failEnvelope, line, title, hint, plain, opt, has, } from '../protocol-envelope.js';
|
|
14
|
+
export const AGENT_USAGE = `
|
|
15
|
+
${title('bolloon agent')}
|
|
16
|
+
bolloon agent discover <能力> [--json] 按能力发现服务 (registry, OrbitDB 优先/本地回退)
|
|
17
|
+
bolloon agent register --capability <能力> [--name 名] [--price 0.05] [--per query] [--description 说明] [--wallet 0x..]
|
|
18
|
+
bolloon agent manifest [--json] 本进程内的 manifest (agents/capabilities)
|
|
19
|
+
bolloon agent inspect <agentId|能力> [--json] 看某个 agent 的声明 (钱包/服务/能力/信誉)
|
|
20
|
+
|
|
21
|
+
选项: --json · --quiet · --request-id <id> · --timeout <ms>
|
|
22
|
+
`;
|
|
23
|
+
/** registry 预热 (有界): CLI 一次性命令里不许无限等 OrbitDB */
|
|
24
|
+
async function warmBounded(ms) {
|
|
25
|
+
try {
|
|
26
|
+
const { warmAgentRegistry } = await import('../../agents/agent-registry.js');
|
|
27
|
+
return await Promise.race([
|
|
28
|
+
warmAgentRegistry().then((v) => !!v),
|
|
29
|
+
new Promise((resolve) => setTimeout(() => resolve(false), ms)),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function localDid() {
|
|
37
|
+
const { getUserOwnerDid } = await import('../../agents/agent-identity.js');
|
|
38
|
+
const fromUser = getUserOwnerDid();
|
|
39
|
+
if (fromUser)
|
|
40
|
+
return fromUser;
|
|
41
|
+
try {
|
|
42
|
+
const { getGatewayJoinState } = await import('../../agents/gateway-join.js');
|
|
43
|
+
const st = await getGatewayJoinState();
|
|
44
|
+
return String(st?.did || '');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return '';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function agentCommand(flags) {
|
|
51
|
+
const sub = flags.positionals[0];
|
|
52
|
+
switch (sub) {
|
|
53
|
+
case 'register': return agentRegister(flags);
|
|
54
|
+
case 'manifest': return agentManifest(flags);
|
|
55
|
+
case 'discover': return agentDiscover(flags);
|
|
56
|
+
case 'inspect': return agentInspect(flags);
|
|
57
|
+
default:
|
|
58
|
+
return {
|
|
59
|
+
envelope: failEnvelope('INVALID_ARGUMENT', sub ? `未知 agent 子命令: ${sub}` : '缺少 agent 子命令', { usage: plain(AGENT_USAGE.trim()) }, [], 'needs_human'),
|
|
60
|
+
human: AGENT_USAGE,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ── agent discover ──────────────────────────────────────────────────────────
|
|
65
|
+
async function agentDiscover(flags) {
|
|
66
|
+
const q = flags.positionals[1] || opt(flags, '--capability') || '';
|
|
67
|
+
const ready = await warmBounded(flags.timeoutMs ?? 8_000);
|
|
68
|
+
const { getAgentRegistry } = await import('../../agents/agent-registry.js');
|
|
69
|
+
const reg = getAgentRegistry(await localDid() || 'local');
|
|
70
|
+
const hits = await reg.discover(q);
|
|
71
|
+
const data = {
|
|
72
|
+
query: q,
|
|
73
|
+
count: hits.length,
|
|
74
|
+
registryReady: ready,
|
|
75
|
+
services: hits.map((s) => ({
|
|
76
|
+
agentId: s.agentId, name: s.name, wallet: s.wallet,
|
|
77
|
+
capability: s.service?.name, description: s.service?.description,
|
|
78
|
+
price: s.service?.price, capabilities: s.capabilities || [],
|
|
79
|
+
})),
|
|
80
|
+
};
|
|
81
|
+
if (!hits.length) {
|
|
82
|
+
return {
|
|
83
|
+
// §3 CAPABILITY_NOT_FOUND: ✅可重试 (**只重查发现**, 绝不因此重发付款)
|
|
84
|
+
envelope: failEnvelope('CAPABILITY_NOT_FOUND', q ? `registry 里找不到能力/关键字 '${q}'` : 'registry 里没有任何服务声明', data, [], 'redefine_capability'),
|
|
85
|
+
human: `${title('bolloon agent discover')}\n${line('查询', q || '(全部)')}\n 没找到 (registry ready=${ready})\n\n${hint('下一步: 换关键词重查 (发现是只读的, 重试安全); 或让对方先声明能力 —— 查不到 ≠ 网络上没有, 更不要因此付款')}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
envelope: okEnvelope('OK', `找到 ${hits.length} 个匹配 '${q || '全部'}' 的服务`, data, hits.map((s) => s.agentId), null),
|
|
90
|
+
human: [
|
|
91
|
+
title(`bolloon agent discover ${q || '(全部)'}`),
|
|
92
|
+
line('命中', `${hits.length} 个 (registry ready=${ready})`),
|
|
93
|
+
...hits.slice(0, 20).map((s) => `\n ${s.name} [${s.service?.name}] ${s.service?.price?.amount || '?'} ${s.service?.price?.currency || ''}/${s.service?.price?.per || ''}\n agentId: ${s.agentId}\n wallet: ${s.wallet || '(无)'}`),
|
|
94
|
+
].join('\n'),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// ── agent register ──────────────────────────────────────────────────────────
|
|
98
|
+
async function agentRegister(flags) {
|
|
99
|
+
const capability = opt(flags, '--capability') || flags.positionals[1];
|
|
100
|
+
if (!capability) {
|
|
101
|
+
return {
|
|
102
|
+
envelope: failEnvelope('INVALID_ARGUMENT', '缺少 --capability (要声明什么能力)', { usage: plain(AGENT_USAGE.trim()) }, [], 'needs_human'),
|
|
103
|
+
human: `${AGENT_USAGE}\n${hint('示例: bolloon agent register --capability research --price 0.05 --per query --name 我的研究体')}`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const did = await localDid();
|
|
107
|
+
if (!did) {
|
|
108
|
+
return {
|
|
109
|
+
envelope: failEnvelope('INVALID_ARGUMENT', '本机还没有 DID 身份, 无法声明能力', { did: '' }, [], 'needs_human'),
|
|
110
|
+
human: `${title('bolloon agent register')}\n 本机还没有 DID 身份\n\n${hint('下一步: bolloon setup (生成 ~/.bolloon/identity/user.json) 或 bolloon network join 入网')}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const name = opt(flags, '--name') || 'bolloon-agent';
|
|
114
|
+
const wallet = opt(flags, '--wallet') || '';
|
|
115
|
+
const { gatewayRegisterAgent } = await import('../../agents/agent-gateway.js');
|
|
116
|
+
const r = await gatewayRegisterAgent({
|
|
117
|
+
capability,
|
|
118
|
+
price: opt(flags, '--price') || '0',
|
|
119
|
+
currency: opt(flags, '--currency') || 'USDC',
|
|
120
|
+
per: opt(flags, '--per') || 'query',
|
|
121
|
+
description: opt(flags, '--description'),
|
|
122
|
+
wallet,
|
|
123
|
+
endpoint: opt(flags, '--endpoint'),
|
|
124
|
+
}, { did, name, wallet });
|
|
125
|
+
// `--manifest`: 额外登记进程内 manifest (agent-manifest-protocol **不落盘**, 如实标注)
|
|
126
|
+
let manifest = null;
|
|
127
|
+
if (has(flags, '--manifest')) {
|
|
128
|
+
const { setLocalManifest, getLocalManifest } = await import('../../agents/agent-manifest-protocol.js');
|
|
129
|
+
setLocalManifest({ ownerName: name, ownerPublicKey: did, agents: [{ id: `${name}-main`, name, capabilities: [capability], status: 'active' }] });
|
|
130
|
+
const m = getLocalManifest();
|
|
131
|
+
manifest = { registered: (m.agents || []).length > 0, persisted: false, agents: (m.agents || []).map((a) => a.id) };
|
|
132
|
+
}
|
|
133
|
+
const data = { agentId: did, name, capability, wallet: wallet || null, registryPath: '~/.bolloon/agent-registry.json', manifest };
|
|
134
|
+
if (!r.ok) {
|
|
135
|
+
return {
|
|
136
|
+
envelope: failEnvelope('INTERNAL_ERROR', `服务声明没写成功: ${r.error || '未知原因'}`, data, [did], 'needs_human'),
|
|
137
|
+
human: `${title('bolloon agent register')}\n ✗ 没写成功: ${r.error || '未知原因'}`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
envelope: okEnvelope('AGENT_REGISTERED', `已声明能力 '${capability}' (agentId=${did})`, data, [did], null),
|
|
142
|
+
human: `${title('bolloon agent register')}\n${line('agentId', did)}\n${line('名称', name)}\n${line('能力', capability)}\n${line('价格', `${opt(flags, '--price') || '0'} ${opt(flags, '--currency') || 'USDC'}/${opt(flags, '--per') || 'query'}`)}\n${line('账号钱包', wallet || '(未给)')}${manifest ? `\n${line('manifest', manifest.registered ? '本进程已登记 (不落盘)' : '登记后读回为空')}` : ''}\n\n${hint('下一步: bolloon agent discover ' + capability + ' 自查能不能被发现')}`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// ── agent manifest ──────────────────────────────────────────────────────────
|
|
146
|
+
async function agentManifest(flags) {
|
|
147
|
+
const { getLocalManifest, getRemoteManifests } = await import('../../agents/agent-manifest-protocol.js');
|
|
148
|
+
const m = getLocalManifest();
|
|
149
|
+
const remote = getRemoteManifests();
|
|
150
|
+
const data = {
|
|
151
|
+
scope: 'in-process',
|
|
152
|
+
persisted: false,
|
|
153
|
+
ownerName: m.ownerName || '',
|
|
154
|
+
ownerPublicKey: m.ownerPublicKey || '',
|
|
155
|
+
publishedAt: m.publishedAt || 0,
|
|
156
|
+
agents: (m.agents || []).map((a) => ({ id: a.id, name: a.name, capabilities: a.capabilities, status: a.status })),
|
|
157
|
+
remoteManifests: remote.map((r) => ({ ownerPublicKey: r.ownerPublicKey, ownerName: r.ownerName, agents: (r.agents || []).length })),
|
|
158
|
+
note: 'local manifest 是**进程内**结构 (agent-manifest-protocol 不落盘): 一次性 CLI 命令里读不到 = 这个进程还没登记过, 不等于本机没注册过 (注册发生在运行中的 Runtime 进程内)',
|
|
159
|
+
};
|
|
160
|
+
return {
|
|
161
|
+
envelope: okEnvelope('OK', `本进程 manifest: agents=${data.agents.length}, 远端缓存=${remote.length} 份`, data, data.ownerPublicKey ? [data.ownerPublicKey] : [], null),
|
|
162
|
+
human: [
|
|
163
|
+
title('bolloon agent manifest (本进程)'),
|
|
164
|
+
line('ownerName', data.ownerName || '(空)'),
|
|
165
|
+
line('ownerDid', data.ownerPublicKey || '(空)'),
|
|
166
|
+
line('agents', data.agents.length),
|
|
167
|
+
...data.agents.map((a) => ` · ${a.id} [${a.capabilities.join(',')}] ${a.status}`),
|
|
168
|
+
line('远端 manifest 缓存', remote.length),
|
|
169
|
+
`\n ${data.note}`,
|
|
170
|
+
].join('\n'),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// ── agent inspect ───────────────────────────────────────────────────────────
|
|
174
|
+
async function agentInspect(flags) {
|
|
175
|
+
const target = flags.positionals[1] || opt(flags, '--capability') || '';
|
|
176
|
+
if (!target) {
|
|
177
|
+
return {
|
|
178
|
+
envelope: failEnvelope('INVALID_ARGUMENT', '缺少要查看的 agentId 或能力名', { usage: plain(AGENT_USAGE.trim()) }, [], 'needs_human'),
|
|
179
|
+
human: AGENT_USAGE,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const ready = await warmBounded(flags.timeoutMs ?? 8_000);
|
|
183
|
+
const { getAgentRegistry } = await import('../../agents/agent-registry.js');
|
|
184
|
+
const reg = getAgentRegistry((await localDid()) || 'local');
|
|
185
|
+
const all = await reg.list();
|
|
186
|
+
const byId = all.find((s) => s.agentId === target);
|
|
187
|
+
const byCap = byId ? undefined : all.find((s) => (s.capabilities || []).includes(target) || s.service?.name === target);
|
|
188
|
+
const hit = byId || byCap;
|
|
189
|
+
if (hit) {
|
|
190
|
+
return {
|
|
191
|
+
envelope: okEnvelope('OK', `找到 ${hit.agentId}`, {
|
|
192
|
+
registryReady: ready, matchedBy: byId ? 'agentId' : 'capability',
|
|
193
|
+
agent: {
|
|
194
|
+
agentId: hit.agentId, name: hit.name, wallet: hit.wallet,
|
|
195
|
+
service: hit.service, capabilities: hit.capabilities || [],
|
|
196
|
+
endpoint: hit.endpoint || null, reputation: hit.reputation || null,
|
|
197
|
+
registeredAt: hit.registeredAt || null, updatedAt: hit.updatedAt || null,
|
|
198
|
+
},
|
|
199
|
+
}, [hit.agentId], null),
|
|
200
|
+
human: [
|
|
201
|
+
title(`bolloon agent inspect ${target}`),
|
|
202
|
+
line('agentId', hit.agentId),
|
|
203
|
+
line('名称', hit.name),
|
|
204
|
+
line('能力', (hit.capabilities || []).join(', ')),
|
|
205
|
+
line('服务', `${hit.service?.name} — ${hit.service?.description || ''}`),
|
|
206
|
+
line('价格', `${hit.service?.price?.amount} ${hit.service?.price?.currency}/${hit.service?.price?.per}`),
|
|
207
|
+
line('收款钱包', hit.wallet || '(未声明)'),
|
|
208
|
+
line('信誉', hit.reputation ? `${hit.reputation.score} (${hit.reputation.tasks} 次)` : '(无记录)'),
|
|
209
|
+
line('更新时间', hit.updatedAt || '(无)'),
|
|
210
|
+
].join('\n'),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// 远端 manifest 缓存兜底 (对方节点握手时换来的人)
|
|
214
|
+
const { getRemoteManifests } = await import('../../agents/agent-manifest-protocol.js');
|
|
215
|
+
const remoteHit = getRemoteManifests().find((r) => r.ownerPublicKey === target || (r.agents || []).some((a) => a.id === target || (a.capabilities || []).includes(target)));
|
|
216
|
+
if (remoteHit) {
|
|
217
|
+
return {
|
|
218
|
+
envelope: okEnvelope('OK', `在远端 manifest 缓存里找到 ${target}`, {
|
|
219
|
+
registryReady: ready, matchedBy: 'remote-manifest',
|
|
220
|
+
owner: { ownerPublicKey: remoteHit.ownerPublicKey, ownerName: remoteHit.ownerName },
|
|
221
|
+
agents: (remoteHit.agents || []).map((a) => ({ id: a.id, name: a.name, capabilities: a.capabilities, status: a.status })),
|
|
222
|
+
}, [remoteHit.ownerPublicKey], null),
|
|
223
|
+
human: `${title(`bolloon agent inspect ${target}`)}\n${line('来源', '远端 manifest 缓存 (P2P 握手换来)')}\n${line('owner', `${remoteHit.ownerName} ${remoteHit.ownerPublicKey}`)}\n${(remoteHit.agents || []).map((a) => ` · ${a.id} [${(a.capabilities || []).join(',')}]`).join('\n')}`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
envelope: failEnvelope('CAPABILITY_NOT_FOUND', `registry 与远端缓存里都没有 '${target}'`, { registryReady: ready, query: target, knownAgents: all.map((s) => s.agentId) }, [], 'redefine_capability'),
|
|
228
|
+
human: `${title(`bolloon agent inspect ${target}`)}\n 没找到 (registry ready=${ready}, 本机已知 ${all.length} 个服务)\n\n${hint('下一步: bolloon agent discover <关键字> 换词重查 (只读, 重试安全)')}`,
|
|
229
|
+
};
|
|
230
|
+
}
|