@bolloon/bolloon-agent 0.5.2 → 0.5.4
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/README.md +4 -4
- package/dist/agents/chain/transfer-classify.js +99 -0
- package/dist/agents/chain/transfer-index.js +354 -0
- package/dist/agents/identity/address-binding.js +613 -0
- package/dist/agents/network-pulse.js +706 -27
- package/dist/agents/pi-sdk-tools.js +67 -15
- package/dist/agents/pi-sdk.js +7 -1
- package/dist/agents/session-store.js +144 -3
- package/dist/agents/wallet-tools.js +63 -0
- package/dist/agents/x402/direct-payment.js +689 -0
- package/dist/agents/x402/order-identity.js +408 -0
- package/dist/agents/x402/paid-info-store.js +17 -0
- package/dist/agents/x402/seller-signing.js +614 -0
- package/dist/agents/x402/seller-summary.js +398 -0
- package/dist/cli/identity-command.js +327 -2
- package/dist/cli/ink-app.js +79 -27
- package/dist/cli/input-history.js +119 -0
- package/dist/cli/loading-tui.js +66 -6
- package/dist/cli/log-gate.js +39 -1
- package/dist/cli/protocol-envelope.js +4 -0
- package/dist/cli/session-summary.js +129 -0
- package/dist/cli/session-tree.js +141 -0
- package/dist/cli/status-segments.js +70 -0
- package/dist/cli/stores.js +16 -0
- package/dist/cli/update-commands.js +41 -25
- package/dist/cli/wallet-store.js +159 -0
- package/dist/cli/wallet-table.js +46 -0
- package/dist/cli/x402-buyer-command.js +463 -0
- package/dist/cli/x402-seller-command.js +289 -0
- package/dist/cli-entry.js +43 -5
- package/dist/electron-build/agents/chain/transfer-classify.js +106 -0
- package/dist/electron-build/agents/chain/transfer-classify.js.map +1 -0
- package/dist/electron-build/agents/chain/transfer-index.js +400 -0
- package/dist/electron-build/agents/chain/transfer-index.js.map +1 -0
- package/dist/electron-build/agents/identity/address-binding.js +672 -0
- package/dist/electron-build/agents/identity/address-binding.js.map +1 -0
- package/dist/electron-build/agents/network-pulse.js +714 -28
- package/dist/electron-build/agents/network-pulse.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-tools.js +68 -15
- package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +7 -1
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/session-store.js +144 -3
- package/dist/electron-build/agents/session-store.js.map +1 -1
- package/dist/electron-build/agents/wallet-tools.js +102 -0
- package/dist/electron-build/agents/wallet-tools.js.map +1 -0
- package/dist/electron-build/agents/x402/direct-payment.js +744 -0
- package/dist/electron-build/agents/x402/direct-payment.js.map +1 -0
- package/dist/electron-build/agents/x402/order-identity.js +458 -0
- package/dist/electron-build/agents/x402/order-identity.js.map +1 -0
- package/dist/electron-build/agents/x402/paid-info-protocol.js.map +1 -1
- package/dist/electron-build/agents/x402/paid-info-store.js +18 -0
- package/dist/electron-build/agents/x402/paid-info-store.js.map +1 -1
- package/dist/electron-build/agents/x402/seller-signing.js +682 -0
- package/dist/electron-build/agents/x402/seller-signing.js.map +1 -0
- package/dist/electron-build/cli/wallet-store.js +200 -0
- package/dist/electron-build/cli/wallet-store.js.map +1 -0
- package/dist/electron-build/llm/pi-ai.js +25 -0
- package/dist/electron-build/llm/pi-ai.js.map +1 -1
- package/dist/electron-build/utils/auto-update.js +2 -2
- package/dist/electron-build/utils/auto-update.js.map +1 -1
- package/dist/electron-build/utils/runtime-bootstrap.js +1 -1
- package/dist/electron-build/utils/runtime-bootstrap.js.map +1 -1
- package/dist/electron-build/utils/update-manager.js +3 -3
- package/dist/electron-build/utils/update-manager.js.map +1 -1
- package/dist/electron-build/utils/version-identity.js +1 -1
- package/dist/electron-build/utils/version-identity.js.map +1 -1
- package/dist/electron-build/web/routes-x402-info.js +28 -1
- package/dist/electron-build/web/routes-x402-info.js.map +1 -1
- package/dist/index.js +829 -104
- package/dist/llm/pi-ai.js +23 -0
- package/dist/utils/auto-update.js +2 -2
- package/dist/utils/runtime-bootstrap.js +1 -1
- package/dist/utils/update-health.js +2 -2
- package/dist/utils/update-manager.js +3 -3
- package/dist/utils/version-identity.js +1 -1
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/routes-x402-info.js +28 -1
- package/dist/web/sw.js +1 -1
- package/package.json +2 -1
package/dist/llm/pi-ai.js
CHANGED
|
@@ -920,6 +920,8 @@ export class PiAIModel {
|
|
|
920
920
|
const _tAfter = Date.now();
|
|
921
921
|
const promptBytes = JSON.stringify(messages).length;
|
|
922
922
|
console.log(`[pi-ai timing] total=${_tAfter - _t0}ms attempt=${attempt + 1} fetch=${_tResp - _tFetch}ms parse=${_tParse - _tResp}ms reply=${content.length}B toolCalls=${toolCalls?.length ?? 0} model=${this.mapModel()} prompt=${promptBytes}B`);
|
|
923
|
+
lastAiTiming = { bytes: content.length, ms: Math.max(1, _tAfter - _t0), at: _tAfter }; // 状态栏 ↑ t/s 的真数
|
|
924
|
+
lastAiUsage = { cached: usage?.cachedTokens || 0, prompt: usage?.promptTokens || 0, at: _tAfter }; // 状态栏 ◎ 缓存命中率
|
|
923
925
|
retryAgent?.destroy().catch(() => { });
|
|
924
926
|
return { reply: content, toolCalls: toolCalls && toolCalls.length > 0 ? toolCalls : undefined, reasoningContent, usage };
|
|
925
927
|
}
|
|
@@ -994,6 +996,8 @@ export class PiAIModel {
|
|
|
994
996
|
console.log(formatKvServerLine(purpose, usage, { stream: true }));
|
|
995
997
|
const toolCalls = acc.filter(Boolean);
|
|
996
998
|
console.log(`[pi-ai timing] total=${Date.now() - t0}ms stream reply=${reply.length}B toolCalls=${toolCalls.length}`);
|
|
999
|
+
lastAiTiming = { bytes: reply.length, ms: Math.max(1, Date.now() - t0), at: Date.now() }; // 状态栏 ↑ t/s 的真数
|
|
1000
|
+
lastAiUsage = { cached: usage?.cachedTokens || 0, prompt: usage?.promptTokens || 0, at: Date.now() }; // 状态栏 ◎ 缓存命中率
|
|
997
1001
|
return {
|
|
998
1002
|
reply,
|
|
999
1003
|
reasoningContent: reasoning || undefined,
|
|
@@ -1448,6 +1452,25 @@ export function getModel() {
|
|
|
1448
1452
|
export function isModelAvailable() {
|
|
1449
1453
|
return modelInstance !== null;
|
|
1450
1454
|
}
|
|
1455
|
+
/**
|
|
1456
|
+
* 最近一次模型调用的**真实吞吐** (2026-09-30, 状态栏 `↑ ≈N t/s` 用)。
|
|
1457
|
+
*
|
|
1458
|
+
* 为什么不用"猜": 这里就是 pi-ai 自己打 timing 日志的地方 —— `total=<ms>` 与 `reply=<bytes>`
|
|
1459
|
+
* 都是**实测**, 状态栏直接读它 = 真数字 (字节折 token 才标 ≈)。
|
|
1460
|
+
* 注意: 只在**成功的模型调用**后更新; 没有记录时状态栏就不显示 ↑ (不编)。
|
|
1461
|
+
*/
|
|
1462
|
+
let lastAiTiming = null;
|
|
1463
|
+
/** 读最近一次模型调用的吞吐记录 (null = 本进程还没成功调过) */
|
|
1464
|
+
export function getLastAiTiming() { return lastAiTiming; }
|
|
1465
|
+
/**
|
|
1466
|
+
* 最近一次模型调用的**用量** (2026-09-30, 状态栏 `◎ 缓存命中率` 用)。
|
|
1467
|
+
* cachedTokens / promptTokens 都来自 provider 的 usage 字段 (OpenAI/DeepSeek:
|
|
1468
|
+
* prompt_tokens_details.cached_tokens; llama.cpp: timings.cache_n) —— 见 extractUsage。
|
|
1469
|
+
* 命中率 = cached / prompt。**只报实测**, 没记录就不显示 (不编)。
|
|
1470
|
+
*/
|
|
1471
|
+
let lastAiUsage = null;
|
|
1472
|
+
/** 读最近一次模型调用的用量记录 (null = 本进程还没有带 usage 的成功调用) */
|
|
1473
|
+
export function getLastAiUsage() { return lastAiUsage; }
|
|
1451
1474
|
export function getMinimax() {
|
|
1452
1475
|
return getModel();
|
|
1453
1476
|
}
|
|
@@ -94,10 +94,10 @@ export async function checkAndUpdate(opts = {}) {
|
|
|
94
94
|
case 'update_available': {
|
|
95
95
|
notify(`⚠ 发现新版本: ${r.currentVersion} → ${r.latestVersion}`, YELLOW);
|
|
96
96
|
if (!prefs.autoInstall) {
|
|
97
|
-
notify(' 当前设置为**只通知不自动安装** (autoInstall=false)。更新: bolloon update
|
|
97
|
+
notify(' 当前设置为**只通知不自动安装** (autoInstall=false)。更新: bolloon update (直接执行; 只看计划用 --dry-run)', CYAN);
|
|
98
98
|
return {
|
|
99
99
|
hasUpdate: true, info, updated: false,
|
|
100
|
-
message: `发现新版 ${r.latestVersion}(未自动安装;运行 bolloon update
|
|
100
|
+
message: `发现新版 ${r.latestVersion}(未自动安装;运行 bolloon update 更新)`,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
notify(' 自动安装已开启 (autoInstall=true),执行更新...', CYAN);
|
|
@@ -25,7 +25,7 @@ import { execFileSync, spawnSync } from 'child_process';
|
|
|
25
25
|
import { resolveBolloonHome, CANONICAL_CONFIG_FILE } from '../setup/setup-store.js';
|
|
26
26
|
export const RUNTIME_MIN = {
|
|
27
27
|
node: { min: '18.0.0', why: 'Bolloon CLI 与依赖 (ESM / 全局 fetch / node: 前缀) 的运行时' },
|
|
28
|
-
npm: { min: '9.0.0', why: '随 Node 18+ 发布; 全局安装与 `update
|
|
28
|
+
npm: { min: '9.0.0', why: '随 Node 18+ 发布; 全局安装与 `bolloon update` 的安装通道' },
|
|
29
29
|
git: { min: '2.20.0', why: '`git -C` / `--porcelain` / worktree —— 源码更新与协作通道' },
|
|
30
30
|
python: { min: '3.8.0', why: 'scripts/** (wiki 门禁/消融夹具) 与 Python Skill 执行' },
|
|
31
31
|
};
|
|
@@ -345,13 +345,13 @@ export async function runDoctor(opts) {
|
|
|
345
345
|
detail: `dev 快照: GitHub master ${st.devRef || 'refs/heads/master'} @ commit ${devSha} (比较语义 ${channelKindOf('dev')}, 非 semver)`
|
|
346
346
|
+ `${st.switchableTo ? ` · 可切回 stable (${st.switchableTo.source}${st.switchableTo.target ? ` @ ${st.switchableTo.target}` : ''})` : ''}`
|
|
347
347
|
+ ` · ${DEV_CHANNEL_WARNING}`,
|
|
348
|
-
action: 'bolloon update
|
|
348
|
+
action: 'bolloon update --channel stable',
|
|
349
349
|
}
|
|
350
350
|
: {
|
|
351
351
|
id: 'update_source', label: '安装来源 (双源)', grade: 'ok',
|
|
352
352
|
detail: `stable: npm registry 权威 (比较语义 ${channelKindOf('stable')})`
|
|
353
353
|
+ `${st.devSha ? ` · 上次用过 dev 快照 commit ${st.devSha}${st.devCheckedAt ? ` (${st.devCheckedAt})` : ''}, 已切回` : ''}`
|
|
354
|
-
+ ` · 默认通道 ${prefsChannel} · 切 dev 用: bolloon update
|
|
354
|
+
+ ` · 默认通道 ${prefsChannel} · 切 dev 用: bolloon update --channel dev`,
|
|
355
355
|
});
|
|
356
356
|
}
|
|
357
357
|
const inFlight = st.lastUpdate && IN_FLIGHT_RUN_STATUSES.includes(st.lastUpdate.status);
|
|
@@ -589,12 +589,12 @@ export function renderUpdatePlan(plan) {
|
|
|
589
589
|
L.push('提醒 (不阻塞, 但建议先处理):');
|
|
590
590
|
for (const a of plan.advisories)
|
|
591
591
|
L.push(` - ${a}`);
|
|
592
|
-
L.push(` 建议策略: 等当前 Run 结束后更新 (bolloon update
|
|
592
|
+
L.push(` 建议策略: 等当前 Run 结束后更新 (bolloon update wait)`);
|
|
593
593
|
}
|
|
594
594
|
L.push('');
|
|
595
|
-
L.push(`可选: 立即更新 (bolloon update --
|
|
595
|
+
L.push(`可选: 立即更新 (bolloon update --channel ${plan.channel}) / 等当前 Run 结束 (bolloon update wait --channel ${plan.channel}) / 取消`);
|
|
596
596
|
if (plan.channelKind === 'git-ref')
|
|
597
|
-
L.push(`一键回稳定版: bolloon update
|
|
597
|
+
L.push(`一键回稳定版: bolloon update --channel stable`);
|
|
598
598
|
L.push(`默认: ${plan.defaultStrategy === 'wait' ? '等待当前 Run 结束后更新' : '立即更新'}`);
|
|
599
599
|
return L.join('\n');
|
|
600
600
|
}
|
|
@@ -101,7 +101,7 @@ export function devShaFromIdentity(v) {
|
|
|
101
101
|
*/
|
|
102
102
|
export const DEV_CHANNEL_WARNING = '⚠️ dev 通道 = GitHub master HEAD 的即时快照 (未走发布门): 可能中断正在跑的 Goal/Run, 且不保证可回滚到上一个 dev 版。';
|
|
103
103
|
/** 一键回 stable 的提示语 (同一份措辞)。 */
|
|
104
|
-
export const DEV_BACK_TO_STABLE_HINT = '一键回稳定版: bolloon update
|
|
104
|
+
export const DEV_BACK_TO_STABLE_HINT = '一键回稳定版: bolloon update --channel stable';
|
|
105
105
|
/** 手机端同一件事的说法 (原生层规则不同: 手机走 web 层 OTA, 不是 npm 全局安装)。 */
|
|
106
106
|
export const DEV_BACK_TO_STABLE_HINT_MOBILE = '一键回稳定版: 手机端「更新」页 → 切回 stable';
|
|
107
107
|
// ── 版本比较 (唯一一份) ─────────────────────────────────────────────────────
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "bolloon-mobile-web/1",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"channel": "stable",
|
|
5
5
|
"build": "stable",
|
|
6
|
-
"commit": "
|
|
7
|
-
"builtAt": "2026-09-
|
|
6
|
+
"commit": "4ac5fe0393fe1b00b21d7d23dade62e4e7854a52",
|
|
7
|
+
"builtAt": "2026-09-30T10:52:06.970Z",
|
|
8
8
|
"layer": "web",
|
|
9
9
|
"note": "web 资源层构建戳 (手机端 OTA 的身份第 ③ 级回退; 装机后以 OTA state.json 为准)"
|
|
10
10
|
}
|
|
@@ -20,6 +20,7 @@ import * as os from 'os';
|
|
|
20
20
|
import { listInfo, getStoredInfo, publishInfo, removeInfo, buildPaymentRequired, checkAndSettlePayment, buyInfo, } from '../agents/x402/paid-info-store.js';
|
|
21
21
|
import { buildSignedEnvelope, verifyEnvelope, summarizeVerify } from '../agents/x402/paid-info-protocol.js';
|
|
22
22
|
import { makeDidResolver } from '../agents/x402/paid-info-tools.js';
|
|
23
|
+
import { handleDirectPayment, directHealth, directPaymentPath, directPaymentEnabled } from '../agents/x402/direct-payment.js';
|
|
23
24
|
/** 本机 DIAP 身份 (签发信封用) — 缺失时明确报错, 不静默造一个 */
|
|
24
25
|
async function loadProviderKeypair() {
|
|
25
26
|
try {
|
|
@@ -122,7 +123,7 @@ export function registerX402InfoRoutes(app) {
|
|
|
122
123
|
content: stored.content,
|
|
123
124
|
keypair: kp,
|
|
124
125
|
payment: {
|
|
125
|
-
mode: pay.mode === 'facilitator' ? 'facilitator' : 'local-dev',
|
|
126
|
+
mode: pay.mode === 'facilitator' ? 'facilitator' : pay.mode === 'direct' ? 'direct' : 'local-dev',
|
|
126
127
|
receipt: String(pay.receipt || ''),
|
|
127
128
|
txHash: pay.txHash,
|
|
128
129
|
network: pay.network || stored.item.price.network,
|
|
@@ -139,6 +140,32 @@ export function registerX402InfoRoutes(app) {
|
|
|
139
140
|
res.status(500).json({ error: e?.message });
|
|
140
141
|
}
|
|
141
142
|
});
|
|
143
|
+
// ---- 去中心化直付 (mode = 'direct'): 买方自己发 USDC, 把 txHash 交回来 ----
|
|
144
|
+
// POST /api/x402/info/:id/payment body: { "txHash": "0x…" }
|
|
145
|
+
// 服务器**只读链**: receipt.status=1 + USDC Transfer → payTo + value >= accepts.amount
|
|
146
|
+
// + 两条不同 RPC 交叉一致 + 确认数够 → 落待办 + 给取件 token (202); 未过 → 402 (accepts 逐字)
|
|
147
|
+
app.post('/api/x402/info/:id/payment', async (req, res) => {
|
|
148
|
+
try {
|
|
149
|
+
const id = String(req.params.id);
|
|
150
|
+
const stored = await getStoredInfo(id);
|
|
151
|
+
if (!stored)
|
|
152
|
+
return res.status(404).json({ error: '信息不存在' });
|
|
153
|
+
const baseUrl = `${req.protocol || 'http'}://${req.headers?.host || `127.0.0.1:${process.env.PORT || 54188}`}`;
|
|
154
|
+
const out = await handleDirectPayment({
|
|
155
|
+
item: stored.item,
|
|
156
|
+
bodyText: typeof req.body === 'string' ? req.body : JSON.stringify(req.body ?? {}),
|
|
157
|
+
resourceUrl: `${baseUrl}${directPaymentPath(stored.item.id)}`,
|
|
158
|
+
});
|
|
159
|
+
return res.status(out.status).set(out.headers).send(out.body);
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
res.status(500).json({ error: e?.message });
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// ---- 直付模式自述 (health 用: 开关与口径必须能从机器读到) ----
|
|
166
|
+
app.get('/api/x402/direct', async (_req, res) => {
|
|
167
|
+
res.json({ enabled: directPaymentEnabled(), paymentPath: directPaymentPath(':id'), ...directHealth() });
|
|
168
|
+
});
|
|
142
169
|
// ---- 买方辅助: 代付 + 验真 ----
|
|
143
170
|
app.post('/api/x402/info/buy', async (req, res) => {
|
|
144
171
|
try {
|
package/dist/web/sw.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 现在: 代码类资源 (html/js/css/json) 一律 **network-first** (拿不到网才回退缓存),
|
|
7
7
|
* 缓存名带版本号, activate 时清掉所有旧缓存; 图标等静态资源仍 cache-first。
|
|
8
8
|
*/
|
|
9
|
-
const CACHE = 'bolloon-mobile-v0.5.
|
|
9
|
+
const CACHE = 'bolloon-mobile-v0.5.4';
|
|
10
10
|
const SHELL = [
|
|
11
11
|
'./mobile.html',
|
|
12
12
|
'./mobile.css',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bolloon/bolloon-agent",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
|
|
6
6
|
"main": "dist/cli-entry.js",
|
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
"qrcode": "^1.5.4",
|
|
109
109
|
"react": "^19.2.8",
|
|
110
110
|
"react-dom": "^19.2.8",
|
|
111
|
+
"undici": "^7.30.0",
|
|
111
112
|
"viem": "^2.56.3"
|
|
112
113
|
},
|
|
113
114
|
"devDependencies": {
|