@bolloon/bolloon-agent 0.6.4 → 0.6.6

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 (173) hide show
  1. package/dist/agents/chain/chain-settlement.js +0 -1
  2. package/dist/agents/chat-segmenter.js +4 -16
  3. package/dist/agents/contacts/human-directory.js +155 -0
  4. package/dist/agents/contacts/tools.js +79 -0
  5. package/dist/agents/experience-review.js +0 -3
  6. package/dist/agents/goal-flywheel/goal-change.js +3 -4
  7. package/dist/agents/goal-resume.js +0 -4
  8. package/dist/agents/intent-classifier.js +1 -1
  9. package/dist/agents/iteration-budget.js +12 -0
  10. package/dist/agents/knowledge-organizer.js +0 -2
  11. package/dist/agents/lesson-to-skill.js +0 -1
  12. package/dist/agents/loop-review.js +2 -2
  13. package/dist/agents/memory-store.js +359 -0
  14. package/dist/agents/opportunity-inbox.js +147 -0
  15. package/dist/agents/opportunity-match.js +48 -7
  16. package/dist/agents/opportunity-web-search.js +222 -0
  17. package/dist/agents/p2p-chat-tools.js +1 -2
  18. package/dist/agents/parse-tool-call.js +9 -22
  19. package/dist/agents/pi-harness.js +1 -2
  20. package/dist/agents/pi-sdk-tools.js +180 -5
  21. package/dist/agents/pi-sdk.js +143 -9
  22. package/dist/agents/process-runner.js +28 -9
  23. package/dist/agents/react-loop.js +9 -17
  24. package/dist/agents/runner-resolver.js +4 -3
  25. package/dist/agents/skill-loader.js +22 -15
  26. package/dist/agents/skills-manager.js +1 -25
  27. package/dist/agents/workflow-pivot-loop.js +152 -61
  28. package/dist/agents/world-watcher.js +30 -1
  29. package/dist/bootstrap/context-collector.js +2 -4
  30. package/dist/bootstrap/context-hierarchy.js +13 -1
  31. package/dist/cli/ink-app.js +44 -17
  32. package/dist/cli/intent-command.js +22 -12
  33. package/dist/cli/loading-tui.js +8 -2
  34. package/dist/cli/log-gate.js +40 -8
  35. package/dist/cli/mention-data.js +1 -0
  36. package/dist/cli/reply-hygiene.js +22 -0
  37. package/dist/cli/trace-line.js +61 -2
  38. package/dist/electron-build/agents/agent-gateway.js.map +1 -1
  39. package/dist/electron-build/agents/chain/chain-indexer.js.map +1 -1
  40. package/dist/electron-build/agents/chain/chain-settlement.js +0 -1
  41. package/dist/electron-build/agents/chain/chain-settlement.js.map +1 -1
  42. package/dist/electron-build/agents/contacts/chain.js.map +1 -1
  43. package/dist/electron-build/agents/contacts/human-directory.js +204 -0
  44. package/dist/electron-build/agents/contacts/human-directory.js.map +1 -0
  45. package/dist/electron-build/agents/contacts/policy.js.map +1 -1
  46. package/dist/electron-build/agents/contacts/tools.js +112 -0
  47. package/dist/electron-build/agents/contacts/tools.js.map +1 -1
  48. package/dist/electron-build/agents/experience-review.js +0 -3
  49. package/dist/electron-build/agents/experience-review.js.map +1 -1
  50. package/dist/electron-build/agents/external-events.js.map +1 -1
  51. package/dist/electron-build/agents/goal-flywheel/goal-change.js +3 -4
  52. package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -1
  53. package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -1
  54. package/dist/electron-build/agents/goal-resume.js +0 -4
  55. package/dist/electron-build/agents/goal-resume.js.map +1 -1
  56. package/dist/electron-build/agents/intent-classifier.js +1 -1
  57. package/dist/electron-build/agents/lesson-to-skill.js +0 -1
  58. package/dist/electron-build/agents/lesson-to-skill.js.map +1 -1
  59. package/dist/electron-build/agents/loop-review.js +2 -2
  60. package/dist/electron-build/agents/loop-review.js.map +1 -1
  61. package/dist/electron-build/agents/memory-recall.js.map +1 -1
  62. package/dist/electron-build/agents/memory-store.js +404 -0
  63. package/dist/electron-build/agents/memory-store.js.map +1 -0
  64. package/dist/electron-build/agents/parse-tool-call.js +9 -22
  65. package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
  66. package/dist/electron-build/agents/pi-harness.js +1 -2
  67. package/dist/electron-build/agents/pi-harness.js.map +1 -1
  68. package/dist/electron-build/agents/pi-sdk-tools.js +180 -5
  69. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  70. package/dist/electron-build/agents/pi-sdk.js +143 -9
  71. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  72. package/dist/electron-build/agents/pre-tool-validator.js.map +1 -1
  73. package/dist/electron-build/agents/process-runner.js +28 -9
  74. package/dist/electron-build/agents/process-runner.js.map +1 -1
  75. package/dist/electron-build/agents/runner-resolver.js +4 -3
  76. package/dist/electron-build/agents/runner-resolver.js.map +1 -1
  77. package/dist/electron-build/agents/skill-loader.js +22 -16
  78. package/dist/electron-build/agents/skill-loader.js.map +1 -1
  79. package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -1
  80. package/dist/electron-build/agents/skills-manager.js +0 -24
  81. package/dist/electron-build/agents/skills-manager.js.map +1 -1
  82. package/dist/electron-build/agents/task/task-runner.js.map +1 -1
  83. package/dist/electron-build/agents/workflow-engine.js.map +1 -1
  84. package/dist/electron-build/agents/workflow-pivot-loop.js +155 -62
  85. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
  86. package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -1
  87. package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -1
  88. package/dist/electron-build/bootstrap/context-collector.js +2 -4
  89. package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
  90. package/dist/electron-build/bootstrap/context-hierarchy.js +13 -1
  91. package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -1
  92. package/dist/electron-build/electron-preload.js.map +1 -1
  93. package/dist/electron-build/external-engines/delegate.js.map +1 -1
  94. package/dist/electron-build/kernel/channel-actor.js +31 -2
  95. package/dist/electron-build/kernel/channel-actor.js.map +1 -1
  96. package/dist/electron-build/kernel/model-runtime.js +8 -1
  97. package/dist/electron-build/kernel/model-runtime.js.map +1 -1
  98. package/dist/electron-build/llm/config-store.js +20 -0
  99. package/dist/electron-build/llm/config-store.js.map +1 -1
  100. package/dist/electron-build/llm/embedding-adapter.js +75 -0
  101. package/dist/electron-build/llm/embedding-adapter.js.map +1 -0
  102. package/dist/electron-build/llm/pi-ai.js +96 -35
  103. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  104. package/dist/electron-build/network/agent-network.js.map +1 -1
  105. package/dist/electron-build/orbitdb/memory-sync.js +76 -0
  106. package/dist/electron-build/orbitdb/memory-sync.js.map +1 -0
  107. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -1
  108. package/dist/electron-build/security/tool-gate.js +2 -0
  109. package/dist/electron-build/security/tool-gate.js.map +1 -1
  110. package/dist/electron-build/setup/setup-store.js +34 -6
  111. package/dist/electron-build/setup/setup-store.js.map +1 -1
  112. package/dist/electron-build/social/heartbeat.js +18 -5
  113. package/dist/electron-build/social/heartbeat.js.map +1 -1
  114. package/dist/electron-build/utils/update-manager.js.map +1 -1
  115. package/dist/index.js +250 -12
  116. package/dist/ios/bolloon-web.json +3 -3
  117. package/dist/ios/client.js +150 -113
  118. package/dist/ios/icons/icon-1400x1400.png +0 -0
  119. package/dist/ios/icons/icon-1400x1400.webp +0 -0
  120. package/dist/ios/index.html +106 -107
  121. package/dist/ios/mobile-agent.js +346 -45
  122. package/dist/ios/mobile-core.js +7303 -4590
  123. package/dist/ios/mobile-harness.js +1004 -0
  124. package/dist/ios/mobile-orbitdb.js +194 -0
  125. package/dist/ios/mobile-persona.js +80 -0
  126. package/dist/ios/mobile-privacy.js +2 -3
  127. package/dist/ios/mobile.css +286 -21
  128. package/dist/ios/mobile.html +106 -107
  129. package/dist/ios/mobile.js +300 -132
  130. package/dist/ios/routes-world.js +58 -1
  131. package/dist/ios/server.js +3 -1
  132. package/dist/ios/style.css +49 -2
  133. package/dist/ios/sw.js +1 -1
  134. package/dist/ios/ui/message-renderer.js +4 -18
  135. package/dist/ios/ui/step-timeline.js +14 -1
  136. package/dist/kernel/channel-actor.js +30 -2
  137. package/dist/kernel/gate-scan.js +1 -1
  138. package/dist/kernel/index.js +33 -0
  139. package/dist/kernel/model-runtime.js +8 -1
  140. package/dist/kernel/plan.js +3 -3
  141. package/dist/kernel/roster.js +3 -3
  142. package/dist/llm/config-store.js +20 -0
  143. package/dist/llm/embedding-adapter.js +69 -0
  144. package/dist/llm/pi-ai.js +94 -34
  145. package/dist/orbitdb/memory-sync.js +70 -0
  146. package/dist/pi-ecosystem-judgment/adaptive-scan.js +1 -1
  147. package/dist/security/tool-gate.js +2 -0
  148. package/dist/setup/setup-store.js +34 -6
  149. package/dist/social/heartbeat.js +18 -5
  150. package/dist/web/bolloon-web.json +3 -3
  151. package/dist/web/client.js +150 -113
  152. package/dist/web/icons/icon-1400x1400.png +0 -0
  153. package/dist/web/icons/icon-1400x1400.webp +0 -0
  154. package/dist/web/index.html +52 -59
  155. package/dist/web/mobile-agent.js +351 -45
  156. package/dist/web/mobile-contacts.js +0 -4
  157. package/dist/web/mobile-core.js +7430 -4590
  158. package/dist/web/mobile-harness.js +1004 -0
  159. package/dist/web/mobile-orbitdb.js +194 -0
  160. package/dist/web/mobile-persona.js +80 -0
  161. package/dist/web/mobile-privacy.js +2 -3
  162. package/dist/web/mobile.css +286 -21
  163. package/dist/web/mobile.html +121 -107
  164. package/dist/web/mobile.js +409 -136
  165. package/dist/web/routes-contacts.js +94 -1
  166. package/dist/web/routes-world.js +58 -1
  167. package/dist/web/server.js +4 -2
  168. package/dist/web/style.css +49 -2
  169. package/dist/web/sw.js +1 -1
  170. package/dist/web/ui/message-renderer.js +4 -18
  171. package/dist/web/ui/step-timeline.js +14 -1
  172. package/package.json +3 -2
  173. package/scripts/build-web.ts +16 -1
@@ -101,6 +101,7 @@ const p2p_document_tools_js_1 = require("./p2p-document-tools.js");
101
101
  const run_store_js_1 = require("./run-store.js");
102
102
  const goal_store_js_1 = require("./goal-store.js");
103
103
  const model_selection_js_1 = require("../llm/model-selection.js");
104
+ // 2026-09-26: 工具名出网净化 (pi-ai.ts 唯一边界) + 回程派发还原 (原名 ↔ API 名)
104
105
  // 2026-09-28 (前缀 KV 可命中): CURRENT TURN 注入标记 —— "当前轮是否已注入"的唯一判据
105
106
  const pi_ai_js_1 = require("../llm/pi-ai.js");
106
107
  const pi_harness_js_1 = require("./pi-harness.js");
@@ -247,6 +248,10 @@ class PiAgentSession {
247
248
  identity;
248
249
  persona = null;
249
250
  minimaxAvailable = false;
251
+ /** 2026-10-13: pivot 路径会话累计真实消耗 (每轮 loop 的 totalTokens 累加, 刻度随会话单调增长) */
252
+ pivotCumulativeTokens = 0;
253
+ /** 2026-10-13: 上下文管理周期压缩在飞标志 (防一轮里重复触发) */
254
+ _ctxCycleCompacting = false;
250
255
  workflows = new Map();
251
256
  constraintLayer;
252
257
  workflowEngine;
@@ -341,6 +346,8 @@ class PiAgentSession {
341
346
  /** 2026-06-30: tool registry 模块 — 独立 alias resolve, 测试可消融. */
342
347
  _toolRegistry = new tool_registry_js_1.ToolRegistry();
343
348
  skillRegistry = new constraint_runtime_2.SkillRegistry();
349
+ /** 2026-10-13: 技能扫描 promise (loadSkills 保存, buildSkillsIndex await) — 确保首次对话前技能已就绪 */
350
+ _skillsReady = Promise.resolve();
344
351
  /** M2.4: 缓存 tool 列表, registerTools() 之后不变, runReActLoop 多次循环复用 */
345
352
  cachedToolDefinitions = '';
346
353
  /** M2.4: 缓存 persona section */
@@ -374,6 +381,41 @@ class PiAgentSession {
374
381
  return bg ? `${bg}\n${plans}` : plans;
375
382
  }
376
383
  cachedPersonaSection = '';
384
+ /**
385
+ * 2026-10-13 (leo: 「重新阅读理解,整体开发整个技能的实现方式… 成整个加载循环」):
386
+ * 技能库索引摘要 —— 注入 systemPrompt, 让模型**知道技能存在**(名字+一句话描述),
387
+ * 需要时用 `list_skills`(按关键词找) → `read_skill`(读全文, 结果进上下文) 按需加载。
388
+ * 为什么必须有: 技能描述**从不进提示** ⇒ 模型不知道 `read_skill` 该读什么 ⇒ 技能加载循环
389
+ * 断在起点 (此前 `describeSkill` 只 import 从不调用, 见 pi-sdk-tools.ts:915 注释)。
390
+ * 预算控制: 只列前 40 个 + 总数, 完整清单由 `list_skills` 按需取 —— 不撑爆 systemPrompt。
391
+ * 失败静默(返回 ''): 技能库读不到时循环退化成 "无技能", 不阻塞主流程。
392
+ */
393
+ async buildSkillsIndex() {
394
+ // 2026-10-13 (leo: 「成整个加载循环」): 先等技能扫描 promise 落地再读 registry ——
395
+ // loadSkills 是构造期 fire-and-forget, 不 await 的话首次对话时 registry 还是空的。
396
+ try {
397
+ await this._skillsReady;
398
+ }
399
+ catch { /* 扫描失败不影响 (registry 为空时返回 '') */ }
400
+ try {
401
+ const all = this.skillRegistry.list();
402
+ if (!all.length)
403
+ return '';
404
+ const budget = 40;
405
+ const lines = all.slice(0, budget).map((sk) => {
406
+ const name = String(sk?.name ?? '').trim();
407
+ const desc = String(sk?.description ?? '').trim().replace(/\s+/g, ' ').slice(0, 100);
408
+ return name ? `- ${name}: ${desc}` : null;
409
+ }).filter(Boolean);
410
+ if (!lines.length)
411
+ return '';
412
+ const more = all.length > budget ? `\n…还有 ${all.length - budget} 个 (用 list_skills 按关键词找)` : '';
413
+ return `## 技能库 (${all.length} 个技能 — 需要时用 list_skills 找, read_skill 读全文执行; 内容进上下文, 按需加载不占首屏)\n${lines.join('\n')}${more}`;
414
+ }
415
+ catch {
416
+ return '';
417
+ }
418
+ }
377
419
  /** 本轮迭代预算 (每轮重置; 批处理工具会退还 —— 见 iteration-budget.ts) */
378
420
  /** 上一个工具调用的参数指纹 (遥测判"是否重复调用") */
379
421
  lastToolSig = null;
@@ -855,14 +897,16 @@ class PiAgentSession {
855
897
  * 2026-07-04: 移除 18 个 bollharness builtin skill (findBolloonBuiltinSkillsPath).
856
898
  * 历史遗留: 写 pi-sdk 时为方便演示, 把 bolloon 项目里的 19 个 skill 强制注入到 system prompt.
857
899
  * 问题: system prompt 涨到 22K chars, LLM (minimax M3) 在 pivot loop 里反复 think 不输出
858
- * `<final gen>`, session 落盘拿不到最终回答.
900
+ * 最终回答, session 落盘拿不到最终回答.
859
901
  * 现在: 只让用户放 .bolloon/skills/SKILL.md 才生效, 干净且 project-owned.
860
902
  *
861
903
  * 静默忽略不存在的目录.
862
904
  */
863
905
  loadSkills(paths) {
864
906
  const resolved = (paths && paths.length > 0) ? paths : (0, skill_loader_js_1.defaultSkillPaths)(os.homedir(), this.cwd);
865
- (0, skill_loader_js_1.loadSkillsFromPaths)(resolved)
907
+ // 2026-10-13 (leo: 「成整个加载循环」): 保存 promise 供 buildSkillsIndex await ——
908
+ // 原来 fire-and-forget, 构造后立即读 registry = 0 ⇒ 技能索引空 ⇒ 模型不知道技能 ⇒ 循环断在起点。
909
+ this._skillsReady = (0, skill_loader_js_1.loadSkillsFromPaths)(resolved)
866
910
  .then((skills) => {
867
911
  for (const s of skills) {
868
912
  if (this.skillRegistry.has(s.name)) {
@@ -959,7 +1003,7 @@ class PiAgentSession {
959
1003
  _inboxMessages: this._inboxMessages,
960
1004
  getChannelWallet: async () => {
961
1005
  try {
962
- const { CHANNELS_PATH } = await Promise.resolve().then(() => __importStar(require('../web/server-types.js')));
1006
+ const {} = await Promise.resolve().then(() => __importStar(require('../web/server-types.js')));
963
1007
  const { loadChannels } = await Promise.resolve().then(() => __importStar(require('../web/server-storage.js')));
964
1008
  const channels = await loadChannels();
965
1009
  const ch = channels.find((c) => c.id === this.actor.state.channelId);
@@ -1082,10 +1126,50 @@ class PiAgentSession {
1082
1126
  * 之前只有 runReActLoop 迭代内上报, chitchat/fallback/pivot 路径状态栏恒 0 */
1083
1127
  reportUsageToContextManager() {
1084
1128
  try {
1085
- (0, context_manager_js_1.getContextManager)().updateUsage(this.estimateHistoryTokens());
1129
+ const cm = (0, context_manager_js_1.getContextManager)();
1130
+ const estimated = this.estimateHistoryTokens();
1131
+ // 2026-10-13 (leo: 刻度被覆盖回 0): pivot 路径在本轮内已上报真实消耗
1132
+ // (promptWithPivotLoop 内 updateUsage(pivotCumulative)); 这里若再用 actor 历史估算**覆盖**,
1133
+ // 刻度会被拉回 ~0 (pivot 路径 actor 历史每轮只有 1-2 条)。⇒ 取 max, 只升不降。
1134
+ cm.updateUsage(Math.max(estimated, cm.getUsage().usedTokens));
1086
1135
  }
1087
1136
  catch { /* 非致命 */ }
1088
1137
  }
1138
+ /**
1139
+ * 2026-10-13: 上下文管理周期 — 阈值触发压缩 (pivot 路径)。
1140
+ * ContextManager 的 markCompressStart/Complete + snapshot 原先只在 promptStream 的
1141
+ * maybeAutoCompact 里被调用; CLI 主路径 (prompt → promptWithPivotLoop) 从没触发过 ⇒
1142
+ * 刻度显示到 'compressing' 但永远不会真压缩。这里补上最小周期:
1143
+ * 累计上报 → stage 达压缩阈值 → 同步前 3 层压缩 (compressHistorySync, 零 LLM 成本) → snapshot。
1144
+ * 失败静默, 不阻塞主流程。
1145
+ */
1146
+ async runContextCycle(usage) {
1147
+ try {
1148
+ const cm = (0, context_manager_js_1.getContextManager)();
1149
+ const history = this.actor.state.messageHistory;
1150
+ if (history.length < 10) {
1151
+ console.log(`[PiAgent] 上下文管理周期: 刻度达压缩阈值 (${Math.round(usage.pct * 100)}%), 历史仅 ${history.length} 条, 跳过压缩 (stage=compressing 留作警示)`);
1152
+ return;
1153
+ }
1154
+ const beforeTokens = this.estimateHistoryTokens();
1155
+ cm.markCompressStart(beforeTokens);
1156
+ const compacted = this.compressHistorySync(history);
1157
+ this.replaceHistory(compacted);
1158
+ const afterTokens = this.estimateHistoryTokens();
1159
+ const snap = cm.makeSnapshot({
1160
+ beforeTokens,
1161
+ afterTokens,
1162
+ summary: `pivot 阈值压缩 (同步前3层): ${beforeTokens.toLocaleString()} → ${afterTokens.toLocaleString()} tokens`,
1163
+ agentId: this.actor.state.agentId,
1164
+ channelId: this.actor.state.channelId,
1165
+ });
1166
+ cm.markCompressComplete(snap);
1167
+ console.log(`[PiAgent] 上下文管理周期: 压缩完成 ${beforeTokens.toLocaleString()}→${afterTokens.toLocaleString()} tokens, stage=${cm.getUsage().stage}, saved=${cm.getUsage().lastSavedTokens.toLocaleString()}`);
1168
+ }
1169
+ catch (err) {
1170
+ console.warn('[PiAgent] 上下文管理周期: 压缩失败 (不阻塞主流程):', String(err?.message ?? err).slice(0, 160));
1171
+ }
1172
+ }
1089
1173
  // ============================================================
1090
1174
  // 2026-08-08: 运行轨迹采集 (trajectory) — 每轮运行 → 落盘 + OrbitDB, 失败静默
1091
1175
  // ============================================================
@@ -1166,6 +1250,32 @@ class PiAgentSession {
1166
1250
  role: 'user',
1167
1251
  content: input
1168
1252
  });
1253
+ // 2026-10-13 (leo: 「记忆加载和管理要变成一种执行的规范, 我刚开始就被复利性质地使用过, 所以这个没有实现」):
1254
+ // 记忆加载原来只在 promptStream 调用 (1514), CLI 主路径 prompt() 从不召回 ⇒ 命令行 Agent 根本没有"记忆"
1255
+ // (用户贴屏: 「没有在工具的调用初始化过程当中看到记忆加载和记忆管理」)。这里与 promptStream 同款召回,
1256
+ // 注入 systemPrompt 的 contextHintAddition —— 每轮执行都过这道闸, 就是"执行的规范"。
1257
+ try {
1258
+ const { recallMemory } = await Promise.resolve().then(() => __importStar(require('./memory-recall.js')));
1259
+ const recalled = await recallMemory({ query: input, agentId: this.actor.state.agentId || this.peerId || '' });
1260
+ if (recalled) {
1261
+ this.contextHintAddition = [this.contextHintAddition, recalled].filter(Boolean).join('\n\n');
1262
+ }
1263
+ }
1264
+ catch { /* 记忆召回失败静默 (增强层) */ }
1265
+ // 2026-10-14 (P0, decentralized-memory-design §2.7): 结构化记忆 (MemoryEntry) 每轮同步召回 —
1266
+ // 与上面会话摘要召回互补: 摘要是「整段会话的压缩」, 这里是「单条结构化记忆」 (带 kind/importance)。
1267
+ // 借鉴 Hermes 冻结快照: 写入落盘不改 prompt, 召回走每轮注入 (progressive disclosure: 只带摘要+权重)。
1268
+ try {
1269
+ const { getMemoryStore, formatRecallBlock } = await Promise.resolve().then(() => __importStar(require('./memory-store.js')));
1270
+ const store = getMemoryStore(this.actor.state.agentId || this.peerId || '');
1271
+ await store.load();
1272
+ const hits = await store.recall({ query: input, limit: 3 });
1273
+ const block = formatRecallBlock(hits);
1274
+ if (block) {
1275
+ this.contextHintAddition = [this.contextHintAddition, block].filter(Boolean).join('\n\n');
1276
+ }
1277
+ }
1278
+ catch { /* 结构化记忆召回失败静默 (增强层, 不阻塞对话) */ }
1169
1279
  // K9 (2026-10-02): 同 `promptWithPivotLoop` —— **回合入口的可用性判据必须问当前适配器**。
1170
1280
  // 这类 `!minimaxAvailable` 闸一共 6 处: 1223(prompt)/1466(promptStream)/1714(pivot, 已修)
1171
1281
  // 是**回合入口** ⇒ 全部改用 `inferenceAvailable()`; 其余三处是 Pi 自己的文档类功能
@@ -1573,7 +1683,11 @@ class PiAgentSession {
1573
1683
  if (attempt > MAX_LOOP_RETRIES) {
1574
1684
  console.warn(`[PiAgent] loop 自动重试 ${MAX_LOOP_RETRIES} 次后仍失败, 终止`);
1575
1685
  if (onStream) {
1576
- onStream({ type: 'status', content: `⛔ loop 自动重试 ${MAX_LOOP_RETRIES} 次后仍失败: ${lastAiFailureReason}`, tool: 'system' });
1686
+ // 2026-10-14 (leo: 「loop 自动重试提示漏进内容栏」): 老代码这条**漏标 internal** ——
1687
+ // `onStream({type:'status'})` 事件在 CLI 渲染层 (index.ts) 只认发送点的显式 internal 声明,
1688
+ // 没标 → 走 appendLine 上内容栏。与下面 1717 行的「重试中」事件对齐, 补标 internal:true
1689
+ // ⇒ 同一判据 (appendInternalRunLog: 落盘 + --verbose 上屏), 不进对话流。
1690
+ onStream({ type: 'status', internal: true, content: `⛔ loop 自动重试 ${MAX_LOOP_RETRIES} 次后仍失败: ${lastAiFailureReason}`, tool: 'system' });
1577
1691
  }
1578
1692
  result = lastAiFailureReason || 'AI 服务调用失败, 自动重试后仍不可用';
1579
1693
  break;
@@ -1897,6 +2011,8 @@ ${exports.PROACTIVE_WORK_DISCIPLINE}
1897
2011
 
1898
2012
  ${await this.renderActivePlansSection()}
1899
2013
 
2014
+ ${await this.buildSkillsIndex()}
2015
+
1900
2016
  工作模式:
1901
2017
  1. 理解用户自然语言请求
1902
2018
  2. 分析需要哪些工具来完成
@@ -1907,7 +2023,7 @@ ${await this.renderActivePlansSection()}
1907
2023
  重要 (一次命中要求):
1908
2024
  - 每次只调用一个工具
1909
2025
  - 仔细分析工具返回结果
1910
- - 当任务完成时,必须在回答末尾添加 <final gen> 标记表示结束
2026
+ - 任务未完成就继续调用工具推进, 直到全部完成
1911
2027
  - 如果需要更多信息,继续调用工具
1912
2028
 
1913
2029
  【工具调用格式 (严格遵守, 否则系统无法解析)】
@@ -1915,8 +2031,7 @@ ${await this.renderActivePlansSection()}
1915
2031
  - 工具调用格式: {"name":"<tool_name>","input":{"arg1":"value1"}}
1916
2032
  - 用 markdown json code block 包裹: \`\`\`json\n{"name":"X","input":{...}}\n\`\`\`
1917
2033
  - 工具调用前可以简短思考 (1-2 句话), 但**不要写长篇 thinking** (会撞 max_tokens)
1918
- - 工具调用后必须等结果, 不要在同一个回复里继续输出
1919
- - <final gen> 只在**真完成所有任务**时输出, 不要在工具调用前/中输出${this.judgmentGateAddition}${this.contextHintAddition}`;
2034
+ - 工具调用后必须等结果, 不要在同一个回复里继续输出${this.judgmentGateAddition}${this.contextHintAddition}`;
1920
2035
  // 2026-06-15: 把 runCtx.eventSink 传给 loop, 让 step-timeline 在 pivot 循环里也能 emit step_start/done
1921
2036
  // 之前 loop.execute() 不接 streamCallback, 导致 step-timeline 只能看到老 runReActLoop 路径
1922
2037
  // promptWithPivotLoop 路径 0 step events — UI 显示 timeline 但永远是空
@@ -1950,6 +2065,25 @@ ${await this.renderActivePlansSection()}
1950
2065
  let result;
1951
2066
  try {
1952
2067
  result = await loop.execute(input, llmWithHarness, systemPrompt + historyBlock, this.runCtx.eventSink ?? undefined, this.runCtx.abortSignal ?? undefined, onCompact);
2068
+ // 2026-10-12 (leo: 「没有根据上下文加载刻度」): pivot 的 messageHistory 是 process-local,
2069
+ // `estimateHistoryTokens()` 读 actor 的旧历史 ⇒ 状态栏上下文刻度恒 0.00% 的根因。
2070
+ // pivot 自己累计的 `state.totalTokens` 才是这一轮**真实**消耗 —— 直接用它上报 ContextManager,
2071
+ // 刻度立刻有数 (旧: 只在上面的 reportUsageToContextManager 里用 actor 历史估, 恒 0)。
2072
+ try {
2073
+ const pivotTokens = Number(result?.state?.totalTokens);
2074
+ if (Number.isFinite(pivotTokens) && pivotTokens > 0) {
2075
+ // 2026-10-13: 会话累计 (多轮对话刻度单调增长; 单轮 totalTokens 只是本轮)
2076
+ this.pivotCumulativeTokens += pivotTokens;
2077
+ const cm = (0, context_manager_js_1.getContextManager)();
2078
+ const usage = cm.updateUsage(this.pivotCumulativeTokens);
2079
+ // 上下文管理周期: 上报 → 阈值判断 → 触发压缩 (刻度有数之外, 到阈值真的会动)
2080
+ if (usage.stage === 'compressing' && !this._ctxCycleCompacting) {
2081
+ this._ctxCycleCompacting = true;
2082
+ void this.runContextCycle(usage).finally(() => { this._ctxCycleCompacting = false; });
2083
+ }
2084
+ }
2085
+ }
2086
+ catch { /* 上报失败不阻塞主流程 */ }
1953
2087
  }
1954
2088
  finally {
1955
2089
  try {
@@ -1970,7 +2104,7 @@ ${await this.renderActivePlansSection()}
1970
2104
  runId: this.actor.state.activeRun || undefined,
1971
2105
  goalId: this.actor.state.goalBinding || undefined,
1972
2106
  });
1973
- console.log(`[PiAgent] reviewFinal (K4-B 恢复调用, 判定不参与流程): ${JSON.stringify(reviewDecision).slice(0, 160)}`);
2107
+ console.log(`[PiAgent] reviewFinal (K4-B 恢复调用, 判定不参与流程): kind=${reviewDecision?.kind} reason=${String(reviewDecision?.reason ?? '').slice(0, 60)}`);
1974
2108
  }
1975
2109
  catch { /* 审查异常不改变本次结论 (门面内部对"审查失效"自有留痕策略) */ }
1976
2110
  if (result.response) {