@bolloon/bolloon-agent 0.6.6 → 0.6.7

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 (52) hide show
  1. package/dist/agents/ha-daemon.js +85 -0
  2. package/dist/agents/ha-supervisor.js +146 -0
  3. package/dist/agents/memory-store.js +25 -0
  4. package/dist/agents/opportunity-match.js +15 -3
  5. package/dist/agents/pi-sdk-session-manager.js +8 -0
  6. package/dist/agents/pi-sdk.js +67 -494
  7. package/dist/bootstrap/context-collector.js +65 -3
  8. package/dist/bootstrap/persona-loader.js +26 -0
  9. package/dist/electron-build/agents/memory-store.js +26 -0
  10. package/dist/electron-build/agents/memory-store.js.map +1 -1
  11. package/dist/electron-build/agents/pi-sdk-session-manager.js +8 -0
  12. package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
  13. package/dist/electron-build/agents/pi-sdk.js +65 -492
  14. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  15. package/dist/electron-build/bootstrap/context-collector.js +66 -3
  16. package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
  17. package/dist/electron-build/bootstrap/persona-loader.js +27 -0
  18. package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
  19. package/dist/electron-build/llm/pi-ai.js +16 -3
  20. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  21. package/dist/electron-build/llm/system-prompt/registry.js +8 -6
  22. package/dist/electron-build/llm/system-prompt/registry.js.map +1 -1
  23. package/dist/ios/bolloon-web.json +3 -3
  24. package/dist/ios/index.html +19 -4
  25. package/dist/ios/mobile-agent.js +267 -41
  26. package/dist/ios/mobile-contacts.js +0 -4
  27. package/dist/ios/mobile-core.js +806 -30
  28. package/dist/ios/mobile-memory.js +317 -0
  29. package/dist/ios/mobile.html +19 -4
  30. package/dist/ios/mobile.js +144 -30
  31. package/dist/ios/routes-contacts.js +94 -1
  32. package/dist/ios/routes-world.js +9 -1
  33. package/dist/ios/server.js +51 -40
  34. package/dist/ios/sw.js +1 -1
  35. package/dist/kernel/gate-scan.js +1 -1
  36. package/dist/kernel/ha/ha-arbiter.js +177 -0
  37. package/dist/kernel/ha/ha-guard.js +151 -0
  38. package/dist/kernel/index.js +3 -0
  39. package/dist/kernel/plan.js +5 -5
  40. package/dist/kernel/roster.js +3 -3
  41. package/dist/llm/pi-ai.js +16 -3
  42. package/dist/llm/system-prompt/registry.js +8 -6
  43. package/dist/web/bolloon-web.json +3 -3
  44. package/dist/web/mobile-agent.js +265 -44
  45. package/dist/web/mobile-core.js +681 -32
  46. package/dist/web/mobile-memory.js +317 -0
  47. package/dist/web/mobile.html +4 -4
  48. package/dist/web/mobile.js +36 -27
  49. package/dist/web/routes-world.js +9 -1
  50. package/dist/web/server.js +50 -39
  51. package/dist/web/sw.js +1 -1
  52. package/package.json +1 -1
@@ -1669,6 +1669,30 @@ export async function createWebServer(port = 3000, options = {}) {
1669
1669
  catch (err) {
1670
1670
  console.warn('[runs] 对账失败 (非致命):', err?.message);
1671
1671
  }
1672
+ // 2026-10-16 (leo: 双内核冗余 — 独立 kernel 守护进程): HA 双活 — 主进程以 primary 写心跳,
1673
+ // spawn 独立 kernel 守护进程 (standby), 主死 → daemon 接管; daemon 死 → 自动重启。
1674
+ // 环境变量门控: BOLLOON_HA=1 启用 (默认关 — 单节点常规运行不启动额外进程)。
1675
+ if (process.env.BOLLOON_HA === '1') {
1676
+ try {
1677
+ const { createHaSupervisor } = await import('../agents/ha-supervisor.js');
1678
+ const haSup = createHaSupervisor({
1679
+ log: (level, message) => {
1680
+ if (level === 'error')
1681
+ console.warn(message);
1682
+ else if (level === 'warn')
1683
+ console.warn(message);
1684
+ else if (process.env.BOLLOON_VERBOSE === '1')
1685
+ console.log(message);
1686
+ },
1687
+ });
1688
+ await haSup.start();
1689
+ globalThis.__bolloonHaSupervisor = haSup;
1690
+ console.log('[ha] 双活守护已启动 (primary 心跳 + standby kernel 守护进程)');
1691
+ }
1692
+ catch (err) {
1693
+ console.warn('[ha] 双活守护启动失败 (非致命):', err?.message);
1694
+ }
1695
+ }
1672
1696
  // 2026-09-16 (M2-B): ExecutionSupervisor —— 长期执行层。
1673
1697
  // 页面关掉、进程重启后由它把 Goal 继续下去; 跨进程排他靠 Goal lease (不是内存状态)。
1674
1698
  // Harness 管"这一段能不能安全执行", Supervisor 管"这个目标还要不要继续执行"。
@@ -5167,56 +5191,38 @@ fetchState();
5167
5191
  const judgmentHint = await buildJudgmentHint(channelForJudgment, channelId);
5168
5192
  if (judgmentHint)
5169
5193
  contextHint += judgmentHint;
5170
- // 2026-06-10: 注入 skills 列表 (本机 ~/.bolloon/skills/ 下所有 skills)
5171
- // 让 LLM 知道有哪些 skill 可用, 在回复中提示用户
5194
+ // 2026-06-10: 注入 skills 存在性提示 (2026-10-16 按需化: 删逐条列表 —
5195
+ // pi-sdk buildSkillsIndex 已注入前 40 技能名+描述, 这里只保留存在提示与触发语法)
5172
5196
  try {
5173
5197
  const { loadSkillsFromPaths, defaultSkillPaths } = await import('../agents/skill-loader.js');
5174
5198
  const paths = defaultSkillPaths();
5175
5199
  const skills = await loadSkillsFromPaths(paths);
5176
5200
  if (skills.length > 0) {
5177
- contextHint += `[系统上下文] 本机已加载的 skills (${skills.length} 个, 你可以提示用户主动调用):\n`;
5178
- for (const s of skills.slice(0, 20)) { // 上限 20 避免 prompt 过长
5179
- const desc = (s.description || '').slice(0, 80);
5180
- contextHint += ` - /${s.name}${desc ? ' — ' + desc : ''}\n`;
5181
- }
5182
- contextHint += '调用语法: 用户说 "/技能名 ..." 或 你回复时建议 "/技能名 ..." 让用户主动触发.\n\n';
5201
+ contextHint += `[系统上下文] 本机已加载 ${skills.length} 个 skills (技能名+描述见上方技能库索引; 需要详情时用 list_skills / read_skill 按需读取). 调用语法: 用户说 "/技能名 ..." 或 你回复时建议 "/技能名 ..." 让用户主动触发.\n\n`;
5183
5202
  }
5184
5203
  }
5185
5204
  catch (err) {
5186
5205
  // 静默失败 — skills 不是核心, 加载失败不阻塞
5187
5206
  }
5188
- // 2026-06-10: 注入 human values 摘要 (最常用的 judgment / 价值偏好)
5189
- // 与 judgment 不同: values 是更宏观的"用户偏好", judgment 是针对具体决策的约束
5207
+ // 2026-06-10: human values 存在性提示 (2026-10-16 按需化: 删 8 条摘要列表 —
5208
+ // buildJudgmentHint 已注入绑定判断力 + 候选, 这里只保留"库里有多少"的指针)
5190
5209
  try {
5191
5210
  const { loadAllJudgments } = await import('../pi-ecosystem-judgment/human-value-store.js');
5192
5211
  const allJudgments = await loadAllJudgments().catch(() => []);
5193
- // 把所有 judgment 视作软参考 (跟 buildJudgmentHint 的 candidates 同理)
5194
5212
  if (Array.isArray(allJudgments) && allJudgments.length > 0) {
5195
- contextHint += `[系统上下文] 用户的核心价值倾向 (来自 ${allJudgments.length} 条历史 judgment, 软参考, 体现而非复述):\n`;
5196
- for (const j of allJudgments.slice(0, 8)) {
5197
- const decision = (j.decision || '').slice(0, 80);
5198
- contextHint += ` - ${decision}\n`;
5199
- }
5200
- contextHint += '\n';
5213
+ contextHint += `[系统上下文] 判断力库存 ${allJudgments.length} 条历史 judgment (绑定判断力见上方; 需要更多时用读取判断力的工具按需取, 软参考体现而非复述).\n\n`;
5201
5214
  }
5202
5215
  }
5203
5216
  catch (err) {
5204
5217
  // 静默失败
5205
5218
  }
5206
- // 2026-06-10: 注入 documents 列表 (本机 documents/ 目录的文档元数据)
5207
- // 让 LLM 知道有文档存在, 用户可主动要求读
5219
+ // 2026-06-10: documents 存在性提示 (2026-10-16 按需化: 删逐条元数据 —
5220
+ // 只留计数, 用户提到某文档时用读文档工具按需读取)
5208
5221
  try {
5209
5222
  const { documentStore } = await import('../documents/store.js');
5210
5223
  const docs = await documentStore.getReceivedDocuments(50).catch(() => []);
5211
5224
  if (Array.isArray(docs) && docs.length > 0) {
5212
- contextHint += `[系统上下文] 本机 documents (${docs.length} 篇, 用户可让你读):\n`;
5213
- for (const d of docs.slice(0, 10)) {
5214
- const name = d.fileName || d.id || '(未命名)';
5215
- const size = d.fileSize ? ` (${Math.round(d.fileSize / 1024)}KB)` : '';
5216
- const sender = d.fromNodeId ? ` [来自 ${d.fromNodeIdShort || d.fromNodeId.substring(0, 8)}…]` : '';
5217
- contextHint += ` - ${name}${size}${sender}\n`;
5218
- }
5219
- contextHint += '用户提到某文档时, 你可以调用读文档工具读取并总结.\n\n';
5225
+ contextHint += `[系统上下文] 本机 documents ${docs.length} 篇 (用户提到某文档时, 用读文档工具按需读取并总结).\n\n`;
5220
5226
  }
5221
5227
  }
5222
5228
  catch (err) {
@@ -5282,8 +5288,10 @@ fetchState();
5282
5288
  catch { /* 无 sessions 目录 */ }
5283
5289
  }
5284
5290
  if (summariesToRead.length > 0) {
5285
- const memBlock = summariesToRead.map(s => s.trim().slice(-1500)).join('\n\n---\n\n');
5286
- contextHint += `[系统上下文] 动态状态层 · chat-worksite (上次做到哪 — 本 channel 历史记忆, 来自 memory-compressor 摘要, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
5291
+ // 2026-10-16 按需化: 历史记忆只注尾部 800 chars 作为"上次做到哪"的锚,
5292
+ // 完整摘要按需用 read 工具取 (记忆是引用而非复述, 全量 2500 常驻浪费)
5293
+ const memBlock = summariesToRead.map(s => s.trim().slice(-800)).join('\n\n---\n\n');
5294
+ contextHint += `[系统上下文] 动态状态层 · chat-worksite (上次做到哪 — 本 channel 历史记忆尾部摘录, 来自 memory-compressor 摘要, 引用而非复述):\n${memBlock.slice(-800)}\n\n`;
5287
5295
  }
5288
5296
  else {
5289
5297
  // 2026-08-08 (DID 目录读侧): 磁盘无摘要时, 回退读 DID 目录 memory 表 (跨设备同步来的记忆)
@@ -5294,11 +5302,11 @@ fetchState();
5294
5302
  const rows = catalogMemoryRows(cat, agentId);
5295
5303
  if (rows.length > 0) {
5296
5304
  const memBlock = rows.slice(0, 2)
5297
- .map(({ row }) => String(row.data.summary || '').slice(-1500))
5305
+ .map(({ row }) => String(row.data.summary || '').slice(-800))
5298
5306
  .filter(Boolean)
5299
5307
  .join('\n\n---\n\n');
5300
5308
  if (memBlock) {
5301
- contextHint += `[系统上下文] 动态状态层 · chat-worksite (DID 目录同步记忆, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
5309
+ contextHint += `[系统上下文] 动态状态层 · chat-worksite (DID 目录同步记忆尾部摘录, 引用而非复述):\n${memBlock.slice(-800)}\n\n`;
5302
5310
  }
5303
5311
  }
5304
5312
  }
@@ -5339,24 +5347,27 @@ fetchState();
5339
5347
  }
5340
5348
  const linkedIds = channelForJudgment?.linkedDocumentIds;
5341
5349
  if (Array.isArray(linkedIds) && linkedIds.length > 0) {
5350
+ // 2026-10-16 按需化: 关联文档不再每轮全文注入 (10篇×1.5KB=15KB 常驻 prompt),
5351
+ // 只列文件名指针, 用户提到某文档时用读文档工具按需读取。
5352
+ // 关联文档本身不常在单轮对话中被用到, 全量注入是浪费。
5342
5353
  try {
5343
5354
  const { documentStore } = await import('../documents/store.js');
5344
- contextHint += `[系统上下文] 此 channel 关联了 ${linkedIds.length} 篇文档 (已自动加载内容, 你应基于它们回答):\n`;
5345
- let loaded = 0;
5355
+ const names = [];
5346
5356
  for (const docId of linkedIds.slice(0, 10)) {
5347
5357
  const doc = await documentStore.readDocument(docId).catch(() => null);
5348
5358
  if (!doc)
5349
5359
  continue;
5350
5360
  const name = doc.metadata?.fileName || docId;
5351
- const content = (doc.content || '').slice(0, 1500); // 单篇 1.5KB 上限, 总 prompt 防爆
5352
- contextHint += `\n--- 文档: ${name} ---\n${content}\n--- 文档结束 ---\n`;
5353
- loaded++;
5361
+ names.push(name);
5362
+ if (names.length >= 5)
5363
+ break; // 指针只列前 5, 其余计数
5354
5364
  }
5355
- if (loaded === 0) {
5356
- contextHint += `(但加载失败, 文档可能已被删除)\n\n`;
5365
+ if (names.length > 0) {
5366
+ const more = linkedIds.length > names.length ? ` (共 ${linkedIds.length} 篇)` : '';
5367
+ contextHint += `[系统上下文] 此 channel 关联了 ${linkedIds.length} 篇文档 — ${names.join('、')}${more}. 用户提到某篇时, 用读文档工具按需读取全文再回答.\n\n`;
5357
5368
  }
5358
5369
  else {
5359
- contextHint += '\n';
5370
+ contextHint += `[系统上下文] 此 channel 关联了 ${linkedIds.length} 篇文档 (内容读取失败, 用读文档工具按需读取).\n\n`;
5360
5371
  }
5361
5372
  }
5362
5373
  catch (err) {
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.6.6';
9
+ const CACHE = 'bolloon-mobile-v0.6.7';
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.6.6",
3
+ "version": "0.6.7",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",