@bolloon/bolloon-agent 0.3.4 → 0.3.5

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.
@@ -8,11 +8,14 @@ export class CLIInterface {
8
8
  agent = null;
9
9
  localNode = null;
10
10
  rl;
11
- constructor() {
11
+ // 2026-07-20 Bug 3: quiet 模式压制 console.error
12
+ _quiet;
13
+ constructor(quiet = false) {
12
14
  this.rl = readline.createInterface({
13
15
  input: process.stdin,
14
16
  output: process.stdout
15
17
  });
18
+ this._quiet = quiet;
16
19
  }
17
20
  async start() {
18
21
  console.log('\n🤖 AI文档智能体 P2P 网络');
@@ -105,7 +108,8 @@ export class CLIInterface {
105
108
  }
106
109
  }
107
110
  catch (e) {
108
- console.error('错误:', e);
111
+ if (!this._quiet)
112
+ console.error('错误:', e);
109
113
  }
110
114
  }
111
115
  }
@@ -190,12 +194,13 @@ export class CLIInterface {
190
194
  stdio: 'inherit',
191
195
  });
192
196
  child.on('close', (code) => {
193
- if (code !== 0)
194
- console.error(`chat 子进程退出码 ${code}`);
197
+ if (code !== 0 && !this._quiet)
198
+ console.warn(`chat 子进程退出码 ${code}`);
195
199
  resolve();
196
200
  });
197
201
  child.on('error', (err) => {
198
- console.error('chat 子进程启动失败:', err.message);
202
+ if (!this._quiet)
203
+ console.warn('chat 子进程启动失败:', err.message);
199
204
  resolve();
200
205
  });
201
206
  });
package/dist/cli-entry.js CHANGED
@@ -22,8 +22,18 @@ const CYAN = '\x1b[36m';
22
22
  const YELLOW = '\x1b[33m';
23
23
  const GREEN = '\x1b[32m';
24
24
  const MAGENTA = '\x1b[35m';
25
- // 版本信息 — package.json:version 同步, 否则 banner 会显示过时版本误导用户
26
- const VERSION = '0.2.15';
25
+ // 版本信息 — 2026-07-20 Bug 3: 从 package.json 读取, 不再硬编码
26
+ const VERSION = (() => {
27
+ try {
28
+ const entryDir = path.dirname(fileURLToPath(import.meta.url));
29
+ const pkgPath = path.resolve(entryDir, '..', 'package.json');
30
+ const raw = fs.readFileSync(pkgPath, 'utf-8');
31
+ return JSON.parse(raw).version || '0.0.0';
32
+ }
33
+ catch {
34
+ return '0.0.0';
35
+ }
36
+ })();
27
37
  function log(msg, color = RESET) {
28
38
  console.log(`${color}${msg}${RESET}`);
29
39
  }
package/dist/index.js CHANGED
@@ -14,6 +14,16 @@ import { createBollharnessIntegration } from './bollharness-integration/index.js
14
14
  import * as readline from 'readline';
15
15
  import { LoadingTUI } from './cli/loading-tui.js';
16
16
  // 启动时自动检查更新已禁用 (改用 --update-check / --update-now 显式触发)
17
+ import { createRequire } from 'module';
18
+ const _require = createRequire(import.meta.url);
19
+ const _BOLLOON_VERSION = (() => {
20
+ try {
21
+ return _require('../package.json').version || '0.0.0';
22
+ }
23
+ catch {
24
+ return '0.0.0';
25
+ }
26
+ })();
17
27
  const RESET = '\x1b[0m';
18
28
  const BOLD = '\x1b[1m';
19
29
  const DIM = '\x1b[2m';
@@ -32,11 +42,16 @@ const CLEAR_LINE = '\x1b[2K';
32
42
  const HIDE_CURSOR = '\x1b[?25l';
33
43
  const SHOW_CURSOR = '\x1b[?25h';
34
44
  const s = {
35
- banner: () => console.log(`\n${CYAN}${BOLD}
45
+ banner: () => {
46
+ const verStr = ` v${_BOLLOON_VERSION}`;
47
+ const pad = Math.max(0, 39 - 17 - verStr.length);
48
+ const spaces = ' '.repeat(pad);
49
+ console.log(`\n${CYAN}${BOLD}
36
50
  ╔═══════════════════════════════════════════╗
37
- ║ ${WHITE}🤖 Bolloon ${CYAN}
51
+ ║ ${WHITE}🤖 Bolloon ${CYAN}${verStr}${spaces}
38
52
  ║ ${WHITE}P2P AI Document Processor${CYAN} ║
39
- ╚═══════════════════════════════════════════╝${RESET}\n`),
53
+ ╚═══════════════════════════════════════════╝${RESET}\n`);
54
+ },
40
55
  step: (num, total, text, status) => {
41
56
  const check = status === 'ok' ? `${GREEN}✓` :
42
57
  status === 'loading' ? `${YELLOW}⟳` :
@@ -782,6 +782,7 @@
782
782
  addMessage: () => addMessage,
783
783
  escapeHtml: () => escapeHtml,
784
784
  finalizeTimelineAsMessage: () => finalizeTimelineAsMessage,
785
+ flushStepEventBuffer: () => flushStepEventBuffer,
785
786
  getMessagesContainerForCurrent: () => getMessagesContainerForCurrent,
786
787
  handleStepEvent: () => handleStepEvent,
787
788
  handleStreamTokenEvent: () => handleStreamTokenEvent,
@@ -939,6 +940,7 @@
939
940
  }
940
941
  if (type === "ai" && msgContainer) {
941
942
  mountStepTimeline(div, currentChannelId2);
943
+ flushStepEventBuffer(currentChannelId2, ctx);
942
944
  }
943
945
  div.appendChild(time);
944
946
  if (msgContainer) {
@@ -1143,7 +1145,14 @@
1143
1145
  let target = streamingMessageEl && streamingMessageEl.isConnected ? streamingMessageEl : null;
1144
1146
  if (!target) {
1145
1147
  const aiMsgs = container.querySelectorAll(".message-ai");
1146
- if (aiMsgs.length === 0) return;
1148
+ if (aiMsgs.length === 0) {
1149
+ if (currentChannelId2) {
1150
+ const buf = stepEventBuffer.get(currentChannelId2) || [];
1151
+ buf.push(data);
1152
+ stepEventBuffer.set(currentChannelId2, buf);
1153
+ }
1154
+ return;
1155
+ }
1147
1156
  target = aiMsgs[aiMsgs.length - 1];
1148
1157
  }
1149
1158
  if (!target) return;
@@ -1157,6 +1166,15 @@
1157
1166
  error: data.error
1158
1167
  });
1159
1168
  }
1169
+ function flushStepEventBuffer(channelId, ctx) {
1170
+ if (!channelId) return;
1171
+ const buf = stepEventBuffer.get(channelId);
1172
+ if (!buf || buf.length === 0) return;
1173
+ stepEventBuffer.delete(channelId);
1174
+ for (const evt of buf) {
1175
+ handleStepEvent(evt, ctx);
1176
+ }
1177
+ }
1160
1178
  function resetRendererState() {
1161
1179
  streamingMessageEl = null;
1162
1180
  streamingTextNode = null;
@@ -1168,7 +1186,7 @@
1168
1186
  scrollToBottomTimer = null;
1169
1187
  }
1170
1188
  }
1171
- var streamingMessageEl, streamingTextNode, streamingText, lastUserCommand, lastAiContent, scrollToBottomTimer, MessageRenderer;
1189
+ var streamingMessageEl, streamingTextNode, streamingText, lastUserCommand, lastAiContent, stepEventBuffer, scrollToBottomTimer, MessageRenderer;
1172
1190
  var init_message_renderer = __esm({
1173
1191
  "src/web/ui/message-renderer.ts"() {
1174
1192
  "use strict";
@@ -1179,12 +1197,14 @@
1179
1197
  streamingText = "";
1180
1198
  lastUserCommand = "";
1181
1199
  lastAiContent = "";
1200
+ stepEventBuffer = /* @__PURE__ */ new Map();
1182
1201
  scrollToBottomTimer = null;
1183
1202
  MessageRenderer = {
1184
1203
  addMessage,
1185
1204
  handleStreamTokenEvent,
1186
1205
  finalizeTimelineAsMessage,
1187
1206
  handleStepEvent,
1207
+ flushStepEventBuffer,
1188
1208
  escapeHtml,
1189
1209
  getMessagesContainerForCurrent,
1190
1210
  resetRendererState
@@ -57,6 +57,8 @@ export function sanitizeChannelForPeer(ch, peerPublicKey) {
57
57
  updatedAt: ch.updatedAt,
58
58
  hasWallet: !!ch.walletAddress,
59
59
  share_id: ch.share_id,
60
+ // 2026-07-20 Bug 2: 保留 ownerPublicKey, 前端用 peerId 区分多节点
61
+ _ownerPublicKey: ch.publicKey,
60
62
  };
61
63
  }
62
64
  /** v3 新增: 判断 channel 是否分享给 peerPublicKey */
@@ -10,6 +10,7 @@ let streamingTextNode = null;
10
10
  let streamingText = "";
11
11
  let lastUserCommand = "";
12
12
  let lastAiContent = "";
13
+ const stepEventBuffer = /* @__PURE__ */ new Map();
13
14
  function hasStreamingText() {
14
15
  return streamingText.length > 0;
15
16
  }
@@ -160,6 +161,7 @@ function addMessage(content, type, save = true, container, usedJudgmentIds = [],
160
161
  }
161
162
  if (type === "ai" && msgContainer) {
162
163
  mountStepTimeline(div, currentChannelId);
164
+ flushStepEventBuffer(currentChannelId, ctx);
163
165
  }
164
166
  div.appendChild(time);
165
167
  if (msgContainer) {
@@ -364,7 +366,14 @@ function handleStepEvent(data, ctx = { messagesEl: null, messagesContainers: /*
364
366
  let target = streamingMessageEl && streamingMessageEl.isConnected ? streamingMessageEl : null;
365
367
  if (!target) {
366
368
  const aiMsgs = container.querySelectorAll(".message-ai");
367
- if (aiMsgs.length === 0) return;
369
+ if (aiMsgs.length === 0) {
370
+ if (currentChannelId) {
371
+ const buf = stepEventBuffer.get(currentChannelId) || [];
372
+ buf.push(data);
373
+ stepEventBuffer.set(currentChannelId, buf);
374
+ }
375
+ return;
376
+ }
368
377
  target = aiMsgs[aiMsgs.length - 1];
369
378
  }
370
379
  if (!target) return;
@@ -378,6 +387,15 @@ function handleStepEvent(data, ctx = { messagesEl: null, messagesContainers: /*
378
387
  error: data.error
379
388
  });
380
389
  }
390
+ function flushStepEventBuffer(channelId, ctx) {
391
+ if (!channelId) return;
392
+ const buf = stepEventBuffer.get(channelId);
393
+ if (!buf || buf.length === 0) return;
394
+ stepEventBuffer.delete(channelId);
395
+ for (const evt of buf) {
396
+ handleStepEvent(evt, ctx);
397
+ }
398
+ }
381
399
  function resetRendererState() {
382
400
  streamingMessageEl = null;
383
401
  streamingTextNode = null;
@@ -394,6 +412,7 @@ const MessageRenderer = {
394
412
  handleStreamTokenEvent,
395
413
  finalizeTimelineAsMessage,
396
414
  handleStepEvent,
415
+ flushStepEventBuffer,
397
416
  escapeHtml,
398
417
  getMessagesContainerForCurrent,
399
418
  resetRendererState
@@ -406,6 +425,7 @@ export {
406
425
  addMessage,
407
426
  escapeHtml,
408
427
  finalizeTimelineAsMessage,
428
+ flushStepEventBuffer,
409
429
  getMessagesContainerForCurrent,
410
430
  handleStepEvent,
411
431
  handleStreamTokenEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",