@bolloon/bolloon-agent 0.4.29 → 0.4.31

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 (83) hide show
  1. package/dist/agents/agent-gateway.js +5 -0
  2. package/dist/agents/agent-manifest-protocol.js +29 -0
  3. package/dist/agents/contacts/chain.js +579 -0
  4. package/dist/agents/contacts/cli.js +158 -0
  5. package/dist/agents/contacts/consent.js +124 -0
  6. package/dist/agents/contacts/grant-payload.js +45 -0
  7. package/dist/agents/contacts/grants.js +451 -0
  8. package/dist/agents/contacts/policy.js +264 -0
  9. package/dist/agents/contacts/preview-types.js +6 -0
  10. package/dist/agents/contacts/providers.js +341 -0
  11. package/dist/agents/contacts/store.js +326 -0
  12. package/dist/agents/contacts/tools.js +154 -0
  13. package/dist/agents/contacts/types.js +148 -0
  14. package/dist/agents/economic-policy.js +7 -0
  15. package/dist/agents/gateway-network.js +6 -0
  16. package/dist/agents/local-signer.js +59 -0
  17. package/dist/agents/network-pulse.js +450 -0
  18. package/dist/agents/pi-sdk.js +10 -0
  19. package/dist/agents/task-contract.js +322 -0
  20. package/dist/agents/task-inbox.js +267 -0
  21. package/dist/agents/task-transport.js +280 -0
  22. package/dist/agents/x402/transaction-store.js +8 -1
  23. package/dist/cli/commands/agent.js +230 -0
  24. package/dist/cli/commands/index.js +61 -0
  25. package/dist/cli/commands/mcp.js +98 -0
  26. package/dist/cli/commands/network.js +334 -0
  27. package/dist/cli/commands/payment.js +125 -0
  28. package/dist/cli/commands/tasks.js +1236 -0
  29. package/dist/cli/commands/trade.js +229 -0
  30. package/dist/cli/commands/wallet.js +450 -0
  31. package/dist/cli/mcp/bridge.js +105 -0
  32. package/dist/cli/mcp/server.js +185 -0
  33. package/dist/cli/mcp/tools.js +612 -0
  34. package/dist/cli/protocol-envelope.js +346 -0
  35. package/dist/cli-entry.js +141 -17
  36. package/dist/electron-build/agents/agent-gateway.js +5 -0
  37. package/dist/electron-build/agents/agent-gateway.js.map +1 -1
  38. package/dist/electron-build/agents/agent-manifest-protocol.js +62 -0
  39. package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -1
  40. package/dist/electron-build/agents/contacts/chain.js +619 -0
  41. package/dist/electron-build/agents/contacts/chain.js.map +1 -0
  42. package/dist/electron-build/agents/contacts/consent.js +163 -0
  43. package/dist/electron-build/agents/contacts/consent.js.map +1 -0
  44. package/dist/electron-build/agents/contacts/grant-payload.js +52 -0
  45. package/dist/electron-build/agents/contacts/grant-payload.js.map +1 -0
  46. package/dist/electron-build/agents/contacts/grants.js +500 -0
  47. package/dist/electron-build/agents/contacts/grants.js.map +1 -0
  48. package/dist/electron-build/agents/contacts/policy.js +271 -0
  49. package/dist/electron-build/agents/contacts/policy.js.map +1 -0
  50. package/dist/electron-build/agents/contacts/preview-types.js +8 -0
  51. package/dist/electron-build/agents/contacts/preview-types.js.map +1 -0
  52. package/dist/electron-build/agents/contacts/providers.js +384 -0
  53. package/dist/electron-build/agents/contacts/providers.js.map +1 -0
  54. package/dist/electron-build/agents/contacts/store.js +370 -0
  55. package/dist/electron-build/agents/contacts/store.js.map +1 -0
  56. package/dist/electron-build/agents/contacts/tools.js +159 -0
  57. package/dist/electron-build/agents/contacts/tools.js.map +1 -0
  58. package/dist/electron-build/agents/contacts/types.js +166 -0
  59. package/dist/electron-build/agents/contacts/types.js.map +1 -0
  60. package/dist/electron-build/agents/economic-policy.js +7 -0
  61. package/dist/electron-build/agents/economic-policy.js.map +1 -1
  62. package/dist/electron-build/agents/external-events.js.map +1 -1
  63. package/dist/electron-build/agents/gateway-network.js +6 -0
  64. package/dist/electron-build/agents/gateway-network.js.map +1 -1
  65. package/dist/electron-build/agents/goal-store.js.map +1 -1
  66. package/dist/electron-build/agents/network-pulse.js +504 -0
  67. package/dist/electron-build/agents/network-pulse.js.map +1 -0
  68. package/dist/electron-build/agents/pi-sdk.js +10 -0
  69. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  70. package/dist/electron-build/agents/x402/transaction-store.js +8 -1
  71. package/dist/electron-build/agents/x402/transaction-store.js.map +1 -1
  72. package/dist/electron-build/security/tool-gate.js +4 -0
  73. package/dist/electron-build/security/tool-gate.js.map +1 -1
  74. package/dist/index.js +30 -0
  75. package/dist/security/tool-gate.js +4 -0
  76. package/dist/web/mobile-contacts.js +329 -0
  77. package/dist/web/mobile-core.js +481 -15
  78. package/dist/web/mobile.html +32 -0
  79. package/dist/web/mobile.js +139 -0
  80. package/dist/web/routes-contacts.js +420 -0
  81. package/dist/web/server.js +34 -0
  82. package/dist/web/task-frame-server.js +211 -0
  83. package/package.json +1 -1
@@ -0,0 +1,185 @@
1
+ /**
2
+ * server.ts — P4 MCP server (stdio transport, JSON-RPC 2.0)
3
+ *
4
+ * 位置: `bolloon mcp serve`。**只调 P3 命令/服务层** (经 `bridge.callP3`), 不复制业务逻辑。
5
+ *
6
+ * 三条硬规矩 (P4 任务书):
7
+ * ① **stdout 只走 JSON-RPC** —— 永远不往 stdout 打日志/横幅 (`bolloon mcp serve` 时 console 被改道去 stderr)。
8
+ * ② **失败不得变成 MCP 成功** —— tool 返回 P3 信封**原样** (含 `code`/`next_action`), 同时
9
+ * `isError = !ok`。客户端既可以机器分派 (`code`/`next_action`), 也能从 `isError` 看出成败。
10
+ * MCP 协议级错误 (未知 method / 未知 tool 名 / 未知 resource URI) 才用 JSON-RPC error。
11
+ * ③ **调用超时** —— 走 P3 的 `--timeout`; 超时给 `code=TIMEOUT` 的信封 (不是把错误吞掉后回成功)。
12
+ *
13
+ * 支持的方法: initialize · notifications/* · ping · tools/list · tools/call ·
14
+ * resources/list · resources/read。其它 method → JSON-RPC -32601 (不静默)。
15
+ */
16
+ import * as readline from 'readline';
17
+ import { collectVersionInfo } from '../../utils/version-info.js';
18
+ import { callP3 } from './bridge.js';
19
+ import { TOOL_BY_NAME, RESOURCE_BY_URI, listToolsPayload, listResourcesPayload, } from './tools.js';
20
+ export const SERVER_NAME = 'bolloon';
21
+ /** 支持的 MCP 协议版本 (客户端请求哪个就回哪个; 都不认就回最新的) */
22
+ export const SUPPORTED_PROTOCOL_VERSIONS = ['2025-06-18', '2025-03-26', '2024-11-05'];
23
+ export const DEFAULT_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSIONS[0];
24
+ export const JSONRPC = {
25
+ PARSE_ERROR: -32700,
26
+ INVALID_REQUEST: -32600,
27
+ METHOD_NOT_FOUND: -32601,
28
+ INVALID_PARAMS: -32602,
29
+ INTERNAL_ERROR: -32603,
30
+ };
31
+ export function serverVersion() {
32
+ try {
33
+ return collectVersionInfo({ light: true }).packageVersion || '0.0.0';
34
+ }
35
+ catch {
36
+ return '0.0.0';
37
+ }
38
+ }
39
+ function err(id, code, message, data) {
40
+ return { jsonrpc: '2.0', id, result: undefined, error: { code, message, data } };
41
+ }
42
+ function ok(id, result) {
43
+ return { jsonrpc: '2.0', id, result };
44
+ }
45
+ /**
46
+ * 处理一条 JSON-RPC 消息。
47
+ * 返回 `null` = 这是通知 (notification), 按协议不回响应。
48
+ * 这个方法**不写 stdout** —— 由调用方 (serveStdio) 或测试直接拿返回值。
49
+ */
50
+ export async function handleMessage(msg) {
51
+ if (!msg || typeof msg !== 'object' || Array.isArray(msg)) {
52
+ return err(null, JSONRPC.INVALID_REQUEST, 'JSON-RPC 消息必须是对象');
53
+ }
54
+ const req = msg;
55
+ const id = req.id === undefined ? null : req.id;
56
+ const method = String(req.method || '');
57
+ const params = (req.params || {});
58
+ const isNotification = req.id === undefined;
59
+ // 通知: 一律不响应 (protocol spec)
60
+ if (method.startsWith('notifications/'))
61
+ return null;
62
+ switch (method) {
63
+ case 'initialize': {
64
+ const wanted = String(params.protocolVersion || '');
65
+ const protocolVersion = SUPPORTED_PROTOCOL_VERSIONS.includes(wanted) ? wanted : DEFAULT_PROTOCOL_VERSION;
66
+ return ok(id, {
67
+ protocolVersion,
68
+ capabilities: {
69
+ tools: { listChanged: false },
70
+ resources: { subscribe: false, listChanged: false },
71
+ },
72
+ serverInfo: { name: SERVER_NAME, version: serverVersion() },
73
+ instructions: 'Bolloon 本机 Agent Runtime 的 MCP 入口。所有 tool 都是 `bolloon <命令组> <子命令>` 的薄包装, ' +
74
+ '返回统一信封 { ok, code, message, data, evidence, next_action } —— **判据永远是 ok/code, 不是 MCP 的 isError 之外的任何东西**; ' +
75
+ 'ok:false 表示这次调用没有成功 (含"等人工放行"这类正常态, 例如 PAYMENT_REQUIRED + approve_payment)。' +
76
+ '本适配层不发付款、不改交易历史、不伪造 verified、不返回私钥; 付款不确定时先 reconcile (绝不重付)。',
77
+ });
78
+ }
79
+ case 'ping':
80
+ return ok(id, {});
81
+ case 'tools/list':
82
+ return ok(id, { tools: listToolsPayload() });
83
+ case 'tools/call': {
84
+ const name = String(params.name || '');
85
+ const tool = TOOL_BY_NAME.get(name);
86
+ if (!tool) {
87
+ return err(id, JSONRPC.INVALID_PARAMS, `未知 tool: '${name}'`, { knownTools: Array.from(TOOL_BY_NAME.keys()) });
88
+ }
89
+ const rawArgs = params.arguments;
90
+ if (rawArgs !== undefined && (rawArgs === null || typeof rawArgs !== 'object' || Array.isArray(rawArgs))) {
91
+ return ok(id, toolResult({ ok: false, code: 'INVALID_ARGUMENT', message: 'arguments 必须是 JSON 对象', data: { got: typeof rawArgs }, evidence: [], next_action: 'needs_human' }));
92
+ }
93
+ const built = tool.build((rawArgs || {}));
94
+ const envelope = built.ok ? await callP3(built.plan) : built.envelope;
95
+ return ok(id, toolResult(envelope));
96
+ }
97
+ case 'resources/list':
98
+ return ok(id, { resources: listResourcesPayload() });
99
+ case 'resources/read': {
100
+ const uri = String(params.uri || '');
101
+ const res = RESOURCE_BY_URI.get(uri);
102
+ if (!res) {
103
+ return err(id, JSONRPC.INVALID_PARAMS, `未知 resource: '${uri}'`, { knownResources: Array.from(RESOURCE_BY_URI.keys()) });
104
+ }
105
+ let payload;
106
+ try {
107
+ payload = await res.load();
108
+ }
109
+ catch (e) {
110
+ // 读取本身炸了 → 也必须是**结构化**的失败 (绝不假装读到)
111
+ payload = {
112
+ uri,
113
+ mimeType: 'application/json',
114
+ ok: false,
115
+ text: JSON.stringify({ ok: false, code: 'INTERNAL_ERROR', message: `resource 读取失败: ${String(e?.message || e).slice(0, 200)}`, data: { uri }, evidence: [], next_action: 'needs_human' }, null, 2),
116
+ };
117
+ }
118
+ return ok(id, { contents: [{ uri: payload.uri, mimeType: payload.mimeType, text: payload.text }] });
119
+ }
120
+ default: {
121
+ if (isNotification)
122
+ return null;
123
+ return err(id, JSONRPC.METHOD_NOT_FOUND, `不支持的 method: '${method}'`, { supported: ['initialize', 'ping', 'tools/list', 'tools/call', 'resources/list', 'resources/read'] });
124
+ }
125
+ }
126
+ }
127
+ /**
128
+ * `tools/call` 的结果体。
129
+ * ★ `isError` 直接取 P3 信封的 `!ok` —— **失败绝不变成 MCP 成功**。
130
+ * `content[0].text` = 信封原样 JSON (code / message / data / evidence / next_action 一个不改)。
131
+ */
132
+ export function toolResult(env) {
133
+ const text = JSON.stringify(env, null, 2);
134
+ return {
135
+ content: [{ type: 'text', text }],
136
+ structuredContent: env,
137
+ isError: env.ok !== true,
138
+ };
139
+ }
140
+ /**
141
+ * stdio 事件循环: 一行一条 JSON-RPC (MCP stdio transport)。
142
+ * 读到 stdin 结束 → 正常退出 (return 0); 解析失败的**单行**不回崩, 回 -32700 继续跑。
143
+ */
144
+ export async function serveStdio(opts = {}) {
145
+ const input = opts.input ?? process.stdin;
146
+ const output = opts.output ?? process.stdout;
147
+ const write = (resp) => output.write(`${JSON.stringify(resp)}\n`);
148
+ if (opts.announce !== false) {
149
+ process.stderr.write(`${SERVER_NAME} mcp serve — stdio / MCP ${DEFAULT_PROTOCOL_VERSION} · tools=${TOOL_BY_NAME.size} resources=${RESOURCE_BY_URI.size} · stdout 只走 JSON-RPC\n`);
150
+ }
151
+ const rl = readline.createInterface({ input, crlfDelay: Infinity });
152
+ for await (const line of rl) {
153
+ const text = String(line).trim();
154
+ if (!text)
155
+ continue;
156
+ let msg;
157
+ try {
158
+ msg = JSON.parse(text);
159
+ }
160
+ catch (e) {
161
+ write(err(null, JSONRPC.PARSE_ERROR, `JSON 解析失败: ${String(e?.message || e).slice(0, 120)}`));
162
+ continue;
163
+ }
164
+ // 顺序处理: 读一行 → 处理完 → 写一行。响应因此与请求**同序** (客户端按 id 配对也照样行),
165
+ // 也不会出现两个响应交错写半行的可能 (stdout 是协议流)。
166
+ let resp = null;
167
+ try {
168
+ resp = await handleMessage(msg);
169
+ }
170
+ catch (e) {
171
+ resp = err(msg?.id ?? null, JSONRPC.INTERNAL_ERROR, `服务内部异常: ${String(e?.message || e).slice(0, 200)}`);
172
+ }
173
+ if (resp)
174
+ write(resp);
175
+ }
176
+ return 0;
177
+ }
178
+ /** 工具清单 (给 `bolloon mcp tools` 用, 也方便验收) */
179
+ export function inventory() {
180
+ return {
181
+ server: { name: SERVER_NAME, version: serverVersion(), protocolVersions: [...SUPPORTED_PROTOCOL_VERSIONS] },
182
+ tools: listToolsPayload().map((t) => ({ name: t.name, title: (t.description.match(/^\[(.*?)\]/) || [])[1] || '', params: Object.keys((t.inputSchema.properties || {})) })),
183
+ resources: listResourcesPayload(),
184
+ };
185
+ }