@bolloon/bolloon-agent 0.3.34 → 0.3.36

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.
@@ -287,10 +287,11 @@ export function renderMessageBox(opts) {
287
287
  const inner = Math.max(20, dispWidth(title) + 4, maxLine);
288
288
  const width = Math.min(termWidth() - 2, opts.width ?? inner + 4);
289
289
  const lines = [];
290
- lines.push(boxTop(`${color}${title}${RESET}`, width, RD));
290
+ // 2026-08-06: 边框改 bolloon 色系 (C_BORDER #3a3a36 暗色描边, 标题色不变)
291
+ lines.push(`${C_BORDER}${boxTop(`${color}${title}${RESET}`, width, RD)}${RESET}`);
291
292
  for (const l of wrapText(opts.body, width - 4))
292
- lines.push(boxRow(l, width, 'left', RD));
293
- lines.push(boxBottom(width, RD));
293
+ lines.push(`${C_BORDER}${boxRow(l, width, 'left', RD)}${RESET}`);
294
+ lines.push(`${C_BORDER}${boxBottom(width, RD)}${RESET}`);
294
295
  return lines.join('\n');
295
296
  }
296
297
  /** 取首条非空行作为预览 (按可见宽度截断, 加省略号) */
@@ -21,6 +21,29 @@ const CLI_COMMANDS = [
21
21
  { kind: 'command', label: 'peers', hint: '查看 P2P 节点', insert: 'peers' },
22
22
  { kind: 'command', label: 'iroh', hint: '查看 iroh 状态', insert: 'iroh' },
23
23
  { kind: 'command', label: 'add_friend', hint: '添加好友 <64位hex公钥>', insert: 'add_friend' },
24
+ // 2026-08-06: 系统命令组
25
+ { kind: 'command', label: 'model', hint: '模型供应商选择器 (↑↓ 选择)', insert: 'model' },
26
+ { kind: 'command', label: 'login', hint: '登录模型供应商 (选择器)', insert: 'login' },
27
+ { kind: 'command', label: 'logout', hint: '查看当前供应商', insert: 'logout' },
28
+ { kind: 'command', label: 'now', hint: '当前状态总览', insert: 'now' },
29
+ { kind: 'command', label: 'session', hint: '当前会话信息', insert: 'session' },
30
+ { kind: 'command', label: 'loop', hint: '循环状态 (消息/token)', insert: 'loop' },
31
+ { kind: 'command', label: 'memory', hint: '记忆摘要', insert: 'memory' },
32
+ { kind: 'command', label: 'resume', hint: '恢复上下文', insert: 'resume' },
33
+ { kind: 'command', label: 'goal', hint: '进行中目标', insert: 'goal' },
34
+ { kind: 'command', label: 'tools', hint: '可用工具列表', insert: 'tools' },
35
+ { kind: 'command', label: 'skill', hint: '技能候选', insert: 'skill' },
36
+ { kind: 'command', label: 'mcp', hint: 'MCP 服务器列表', insert: 'mcp' },
37
+ { kind: 'command', label: 'agent', hint: '当前智能体', insert: 'agent' },
38
+ { kind: 'command', label: 'did', hint: 'DID 身份', insert: 'did' },
39
+ { kind: 'command', label: 'ipfs', hint: 'Kubo 状态', insert: 'ipfs' },
40
+ { kind: 'command', label: 'ipns', hint: 'IPNS keys', insert: 'ipns' },
41
+ { kind: 'command', label: 'wallet', hint: '钱包状态', insert: 'wallet' },
42
+ { kind: 'command', label: 'email', hint: '邮件配置', insert: 'email' },
43
+ { kind: 'command', label: 'judgement', hint: '判断力列表', insert: 'judgement' },
44
+ { kind: 'command', label: 'insight', hint: '洞察 (08-Insights)', insert: 'insight' },
45
+ { kind: 'command', label: 'wiki', hint: 'wiki 状态', insert: 'wiki' },
46
+ { kind: 'command', label: 'dream', hint: '随机灵感', insert: 'dream' },
24
47
  ];
25
48
  /** Web 端斜杠命令 (server /message 路由 → LLM 工具) */
26
49
  const WEB_COMMANDS = [
package/dist/cli-entry.js CHANGED
@@ -62,17 +62,24 @@ ${BOLD}选项:${RESET}
62
62
  --help, -h 显示帮助信息
63
63
 
64
64
  ${BOLD}命令:${RESET}
65
- bolloon --read <file> 读取文档
66
- bolloon --summarize <file> 总结文档
67
- bolloon --improve <file> <req> 改进文档
68
- bolloon x402 fetch <url> x402 自动支付 HTTP 请求
69
- bolloon x402 balance <address> 查询 x402 钱包余额
65
+ bolloon update [--now] 检查更新 / 立即更新 (bolloon update --now)
66
+ bolloon model [name] [model] 列出 / 切换模型供应商 (如: bolloon model deepseek deepseek-v4-flash)
67
+ bolloon read <file> 读取文档
68
+ bolloon summarize <file> 总结文档
69
+ bolloon improve <file> <req> 改进文档
70
+ bolloon engine list 列出外部编码智能体
71
+ bolloon engine run <prompt> 委派任务给智能体
72
+ bolloon x402 fetch <url> x402 自动支付 HTTP 请求
73
+ bolloon x402 balance <address> 查询 x402 钱包余额
70
74
 
71
75
  ${BOLD}示例:${RESET}
72
76
  bolloon # 启动图形界面
73
77
  bolloon --web # 启动 Web UI
74
- bolloon --read 想法.md # 读取文档
75
78
  bolloon --cli # 命令行模式
79
+ bolloon model # 查看当前模型供应商
80
+ bolloon model minimax # 切换到 MiniMax
81
+ bolloon update # 检查更新
82
+ bolloon update --now # 立即更新
76
83
 
77
84
  ${BOLD}环境变量:${RESET}
78
85
  MINIMAX_API_KEY MiniMax API 密钥
@@ -139,6 +146,16 @@ function parseArgs() {
139
146
  return { mode: 'engine', args: args.slice(1) };
140
147
  case 'x402':
141
148
  return { mode: 'x402', args: args.slice(1) };
149
+ // 2026-08-06: 子命令形式 (去掉 -- 前缀)
150
+ case 'update':
151
+ return { mode: 'update', args: args.slice(1) };
152
+ case 'model':
153
+ return { mode: 'model', args: args.slice(1) };
154
+ case 'read':
155
+ case 'summarize':
156
+ case 'improve':
157
+ // 映射回旧 --flag 格式传给主程序 (保留 index.ts 现有实现)
158
+ return { mode: 'passthrough', args: [`--${mode}`, ...args.slice(1)] };
142
159
  default:
143
160
  // 传递所有参数给主程序
144
161
  return { mode: 'passthrough', args };
@@ -259,6 +276,89 @@ async function handleX402Command(x402Args) {
259
276
  console.error(`未知 x402 子命令: ${sub}`);
260
277
  process.exit(1);
261
278
  }
279
+ /** update 子命令: 检查 / 执行更新 (bolloon update [--now|now] [packages]) */
280
+ async function handleUpdateCommand(updateArgs) {
281
+ const { checkForUpdates, performUpdate } = await import('./utils/auto-update.js');
282
+ // bolloon update --now / bolloon update now [packages] — 立即更新
283
+ if (updateArgs[0] === '--now' || updateArgs[0] === 'now') {
284
+ const packages = updateArgs.slice(1).filter(a => !a.startsWith('-'));
285
+ console.log('🔄 正在检查并更新...');
286
+ const result = await performUpdate(packages.length > 0 ? packages : undefined);
287
+ if (result.success) {
288
+ console.log(`${GREEN}✅ 更新成功${result.updatedPackages ? `: ${result.updatedPackages.join(', ')}` : ''}${RESET}`);
289
+ if (result.updated)
290
+ console.log(`${YELLOW} 请重新启动应用以使用新版本${RESET}`);
291
+ }
292
+ else {
293
+ console.error(`${MAGENTA}❌ 更新失败: ${result.error}${RESET}`);
294
+ process.exit(1);
295
+ }
296
+ return;
297
+ }
298
+ // 默认: 检查更新
299
+ console.log('🔄 正在检查更新...');
300
+ const info = await checkForUpdates();
301
+ if (info && info.outdated) {
302
+ console.log(`${CYAN}📦 发现更新可用:${RESET}\n`);
303
+ console.log(` 当前版本: ${info.version}`);
304
+ console.log(` 最新版本: ${info.latest}\n`);
305
+ console.log(` 待更新包:`);
306
+ for (const p of info.packages)
307
+ console.log(` - ${p.name}: ${p.current} → ${p.latest}`);
308
+ console.log(`\n 运行 ${GREEN}bolloon update --now${RESET} 执行更新`);
309
+ }
310
+ else {
311
+ console.log(`${GREEN}✅ 已是最新版本${RESET} (${info?.version || 'unknown'})`);
312
+ }
313
+ }
314
+ /** model 子命令: 列出 / 切换模型供应商 (bolloon model [name] [model]) */
315
+ async function handleModelCommand(modelArgs) {
316
+ const { llmConfigStore, PROVIDER_INFO } = await import('./llm/config-store.js');
317
+ await llmConfigStore.initialize();
318
+ // 无参: 列出所有供应商 + 当前 active
319
+ if (modelArgs.length === 0) {
320
+ const config = await llmConfigStore.getConfig();
321
+ console.log(`\n${BOLD}模型供应商${RESET} (当前: ${config.activeProvider})\n`);
322
+ console.log('─'.repeat(58));
323
+ for (const [name, p] of Object.entries(config.providers)) {
324
+ const info = PROVIDER_INFO[name] || {};
325
+ const active = name === config.activeProvider ? '●' : '○';
326
+ const keyState = p.apiKey ? '🔑' : p.requiresApiKey ? '⚠ 无 key' : '';
327
+ const model = p.model || (info.models && info.models[0]) || '';
328
+ console.log(` ${active} ${name.padEnd(10)} ${String(info.name || '').padEnd(16)} ${keyState.padEnd(8)} model: ${model}`);
329
+ }
330
+ console.log(`\n${BOLD}用法:${RESET}`);
331
+ console.log(` bolloon model <name> # 切换到该供应商`);
332
+ console.log(` bolloon model <name> <model> # 切换并指定模型`);
333
+ console.log(` 示例: bolloon model deepseek deepseek-v4-flash`);
334
+ return;
335
+ }
336
+ // 切换供应商
337
+ const name = modelArgs[0].toLowerCase();
338
+ const config = await llmConfigStore.getConfig();
339
+ const providers = config.providers;
340
+ if (!providers[name]) {
341
+ console.error(`${MAGENTA}❌ 未知供应商: ${name}${RESET}`);
342
+ console.error(` 可用: ${Object.keys(providers).join(', ')}`);
343
+ process.exit(1);
344
+ }
345
+ const provider = providers[name];
346
+ if (provider.requiresApiKey && !provider.apiKey) {
347
+ console.error(`${MAGENTA}❌ ${name} 需要 API key (当前未配置)${RESET}`);
348
+ console.error(` 配置方式: ① Web UI API 配置页 ② 环境变量 (如 DEEPSEEK_API_KEY)`);
349
+ process.exit(1);
350
+ }
351
+ await llmConfigStore.setActiveProvider(name);
352
+ let modelNote = '';
353
+ if (modelArgs[1]) {
354
+ await llmConfigStore.updateProvider(name, { model: modelArgs[1] });
355
+ modelNote = `, model=${modelArgs[1]}`;
356
+ }
357
+ const info = PROVIDER_INFO[name] || {};
358
+ console.log(`${GREEN}✅ 已切换到 ${name}${RESET} (${info.name || ''})${modelNote}`);
359
+ console.log(` 当前模型: ${modelArgs[1] || provider.model || (info.models && info.models[0]) || '默认'}`);
360
+ console.log(` 配置已持久化: ~/.bolloon/llm-config.json`);
361
+ }
262
362
  /** 引擎子命令: list / run */
263
363
  async function handleEngineCommand(engineArgs) {
264
364
  if (engineArgs.length === 0) {
@@ -462,6 +562,13 @@ async function main() {
462
562
  case 'x402':
463
563
  await handleX402Command(args);
464
564
  break;
565
+ // 2026-08-06: 子命令 (bolloon update / bolloon model)
566
+ case 'update':
567
+ await handleUpdateCommand(args);
568
+ break;
569
+ case 'model':
570
+ await handleModelCommand(args);
571
+ break;
465
572
  case 'passthrough':
466
573
  // 传递所有参数给主程序
467
574
  try {