@bolloon/bolloon-agent 0.3.52 → 0.4.0

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 (217) hide show
  1. package/README.md +135 -135
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon.cjs +0 -0
  4. package/bin/bolloon.js +157 -0
  5. package/dist/agents/constraint-layer.js +19 -19
  6. package/dist/agents/judgment-protocol.js +14 -14
  7. package/dist/agents/loop-review.js +21 -0
  8. package/dist/agents/pi-sdk-tools.js +86 -2
  9. package/dist/agents/pi-sdk-types.js +12 -12
  10. package/dist/agents/pi-sdk.js +90 -90
  11. package/dist/agents/shell-guard.js +22 -1
  12. package/dist/agents/skill-organizer.js +19 -19
  13. package/dist/agents/verify-recipe.js +84 -0
  14. package/dist/agents/workflow-pivot-loop.js +101 -13
  15. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  16. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  17. package/dist/bollharness-integration/context-router.js +292 -292
  18. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  19. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  20. package/dist/bollharness-integration/skill-adapter.js +21 -21
  21. package/dist/bootstrap/chat-archiver.js +14 -14
  22. package/dist/bootstrap/context-os.js +50 -40
  23. package/dist/bootstrap/memory-compressor.js +13 -13
  24. package/dist/cli-entry.js +36 -36
  25. package/dist/context-compaction/auto-compact.js +7 -7
  26. package/dist/electron/first-run.js +54 -54
  27. package/dist/electron-build/electron/first-run.js +54 -54
  28. package/dist/electron-preload.js.map +1 -1
  29. package/dist/electron.js.map +1 -1
  30. package/dist/external-engines/delegate-handle.js +70 -0
  31. package/dist/external-engines/delegate.js +24 -3
  32. package/dist/index.js +112 -112
  33. package/dist/llm/error-lessons.js +53 -0
  34. package/dist/llm/llm-judgment-client.js +102 -102
  35. package/dist/llm/pi-ai.js +61 -48
  36. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  37. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  38. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  39. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  40. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  41. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  42. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  43. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  44. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  45. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  46. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  47. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  48. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  49. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  50. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  51. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  52. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  53. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  54. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  55. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  56. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  57. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  58. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  59. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  60. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  61. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  62. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  63. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  64. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  65. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  66. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  67. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  68. package/dist/llm/system-prompt/registry.js +9 -1
  69. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  70. package/dist/llm/tool-manifest/bash.js +3 -3
  71. package/dist/llm/tool-manifest/create_file.js +4 -4
  72. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  73. package/dist/llm/tool-manifest/image_search.js +2 -2
  74. package/dist/llm/tool-manifest/index.js +0 -59
  75. package/dist/llm/tool-manifest/mcp.js +2 -2
  76. package/dist/llm/tool-manifest/message_compose.js +3 -3
  77. package/dist/llm/tool-manifest/places.js +2 -2
  78. package/dist/llm/tool-manifest/present_files.js +1 -1
  79. package/dist/llm/tool-manifest/recipe.js +2 -2
  80. package/dist/llm/tool-manifest/str_replace.js +5 -5
  81. package/dist/llm/tool-manifest/view.js +3 -3
  82. package/dist/llm/tool-manifest/weather.js +4 -4
  83. package/dist/llm/tool-manifest/web.js +4 -4
  84. package/dist/locales/en.js +28 -0
  85. package/dist/locales/zh.js +26 -0
  86. package/dist/pi-ecosystem-colony/index.js +365 -0
  87. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  88. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  89. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  90. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  91. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  92. package/dist/security/context-router-tool.js +15 -15
  93. package/dist/social/ant-colony/AdaptiveHeartbeat.js +101 -0
  94. package/dist/social/ant-colony/PheromoneEngine.js +227 -0
  95. package/dist/social/ant-colony/index.js +6 -0
  96. package/dist/social/ant-colony/types.js +24 -0
  97. package/dist/storage/trajectory.js +101 -0
  98. package/dist/test/ai-judgment-test.js +80 -0
  99. package/dist/test/bollharness-integration.test.js +318 -0
  100. package/dist/test/channel-agent-multi-dialogue.js +205 -0
  101. package/dist/test/channel-heartbeat-agent-test.js +201 -0
  102. package/dist/test/constraint-layer.test.js +164 -0
  103. package/dist/test/diap-identity-test.js +172 -0
  104. package/dist/test/diap-quick-test.js +62 -0
  105. package/dist/test/global-shared-context.test.js +315 -0
  106. package/dist/test/harness-judgment-injection.test.js +246 -0
  107. package/dist/test/harness-workflow-integrator-test.js +228 -0
  108. package/dist/test/human-value-store.test.js +243 -0
  109. package/dist/test/hybrid-integration-test.js +118 -0
  110. package/dist/test/hybrid-messenger-verify.js +55 -0
  111. package/dist/test/iroh-bistream-debug.js +38 -0
  112. package/dist/test/iroh-communication.test.js +66 -0
  113. package/dist/test/iroh-debug-test.js +57 -0
  114. package/dist/test/iroh-diap-test.js +71 -0
  115. package/dist/test/iroh-direct-connect.js +55 -0
  116. package/dist/test/iroh-e2e-fixed.js +89 -0
  117. package/dist/test/iroh-e2e-same-process.js +63 -0
  118. package/dist/test/iroh-e2e.js +66 -0
  119. package/dist/test/iroh-final-e2e.js +72 -0
  120. package/dist/test/iroh-relay-test.js +37 -0
  121. package/dist/test/iroh-simple-test.js +41 -0
  122. package/dist/test/iroh-transport-verify.js +54 -0
  123. package/dist/test/iroh-transport.test.js +37 -0
  124. package/dist/test/iroh-two-nodes.js +70 -0
  125. package/dist/test/iroh-verify.js +44 -0
  126. package/dist/test/judgment-decision.test.js +219 -0
  127. package/dist/test/llm-judgment-integration.test.js +220 -0
  128. package/dist/test/p2p-agent-complex-dialogue.js +385 -0
  129. package/dist/test/p2p-agent-dialogue.js +341 -0
  130. package/dist/test/p2p-agent-full-bidirectional.js +510 -0
  131. package/dist/test/p2p-agent-harness-flow.js +437 -0
  132. package/dist/test/p2p-agent-harness-single.js +143 -0
  133. package/dist/test/p2p-ai-dialogue-test.js +318 -0
  134. package/dist/test/p2p-cid-connect-test.js +195 -0
  135. package/dist/test/p2p-connect-receiver.js +69 -0
  136. package/dist/test/p2p-doc-transfer.js +110 -0
  137. package/dist/test/p2p-identity-page-test.js +77 -0
  138. package/dist/test/p2p-iroh-test.js +171 -0
  139. package/dist/test/p2p-minimal-test.js +241 -0
  140. package/dist/test/p2p-node-1.js +148 -0
  141. package/dist/test/p2p-node-2.js +148 -0
  142. package/dist/test/p2p-server.js +281 -0
  143. package/dist/test/p2p-two-nodes-test.js +438 -0
  144. package/dist/test/pi-sdk.test.js +44 -0
  145. package/dist/test/set-persona.js +40 -0
  146. package/dist/test/simple.test.js +9 -0
  147. package/dist/test/storage-integration.test.js +150 -0
  148. package/dist/test/subagent-manager.test.js +276 -0
  149. package/dist/test/test-gate-flow.test.js +81 -0
  150. package/dist/test/workflow-engine.test.js +87 -0
  151. package/dist/test/workflow-pivot-loop.test.js +246 -0
  152. package/dist/web/api-config.html +779 -779
  153. package/dist/web/client-hearth.js +10 -10
  154. package/dist/web/components/wallet-viem.mjs +118 -118
  155. package/dist/web/delivery-ledger.js +103 -0
  156. package/dist/web/i18n.js +104 -0
  157. package/dist/web/index.html +472 -472
  158. package/dist/web/manifest.json +20 -20
  159. package/dist/web/routes-tasks.js +242 -24
  160. package/dist/web/server-storage.js +111 -0
  161. package/dist/web/server.js +55 -26
  162. package/dist/web/style.css +4946 -4946
  163. package/dist/web/task-breaker.js +18 -0
  164. package/dist/web/task-cancel.js +35 -0
  165. package/dist/web/task-deps.js +36 -0
  166. package/dist/web/task-review.js +27 -0
  167. package/dist/web/task-verify.js +60 -0
  168. package/package.json +196 -196
  169. package/scripts/build-cli.js +215 -215
  170. package/scripts/build-web.ts +130 -130
  171. package/scripts/postinstall.js +152 -152
  172. package/bin/bolloon-daemon.sh +0 -207
  173. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +0 -63
  174. package/dist/constraint-runtime/reference_data/commands_snapshot.json +0 -1037
  175. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +0 -8
  176. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +0 -8
  177. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +0 -32
  178. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +0 -13
  179. package/dist/constraint-runtime/reference_data/subsystems/cli.json +0 -26
  180. package/dist/constraint-runtime/reference_data/subsystems/components.json +0 -32
  181. package/dist/constraint-runtime/reference_data/subsystems/constants.json +0 -28
  182. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +0 -8
  183. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +0 -15
  184. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +0 -32
  185. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +0 -21
  186. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +0 -15
  187. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +0 -18
  188. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +0 -8
  189. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +0 -11
  190. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +0 -8
  191. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +0 -9
  192. package/dist/constraint-runtime/reference_data/subsystems/remote.json +0 -11
  193. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +0 -8
  194. package/dist/constraint-runtime/reference_data/subsystems/screens.json +0 -10
  195. package/dist/constraint-runtime/reference_data/subsystems/server.json +0 -10
  196. package/dist/constraint-runtime/reference_data/subsystems/services.json +0 -32
  197. package/dist/constraint-runtime/reference_data/subsystems/skills.json +0 -27
  198. package/dist/constraint-runtime/reference_data/subsystems/state.json +0 -13
  199. package/dist/constraint-runtime/reference_data/subsystems/types.json +0 -18
  200. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +0 -9
  201. package/dist/constraint-runtime/reference_data/subsystems/utils.json +0 -32
  202. package/dist/constraint-runtime/reference_data/subsystems/vim.json +0 -12
  203. package/dist/constraint-runtime/reference_data/subsystems/voice.json +0 -8
  204. package/dist/constraint-runtime/reference_data/tools_snapshot.json +0 -922
  205. package/dist/electron/config.js.map +0 -1
  206. package/dist/electron/dialogs.js.map +0 -1
  207. package/dist/electron/first-run.js.map +0 -1
  208. package/dist/electron/ipc.js.map +0 -1
  209. package/dist/electron/logger.js.map +0 -1
  210. package/dist/electron/main.js.map +0 -1
  211. package/dist/electron/menu.js.map +0 -1
  212. package/dist/electron/paths.js.map +0 -1
  213. package/dist/electron/server.js.map +0 -1
  214. package/dist/electron/tray.js.map +0 -1
  215. package/dist/electron/window.js.map +0 -1
  216. package/dist/utils/auto-update.js.map +0 -1
  217. package/dist/web/client.js.map +0 -7
@@ -0,0 +1,53 @@
1
+ /**
2
+ * error-lessons.ts — LLM API 错误分类 + 会话级教训学习 (借鉴 Hermes agent/error_classifier.py:
3
+ * "record the (provider, model) so we don't waste another call learning the same lesson, retry")
4
+ *
5
+ * Hermes 模式:
6
+ * - 模式库分类错误 (context overflow / multimodal / 400 / 402 / 429 / 5xx)
7
+ * - 同类错误会话内只学一次 (lesson memory), 之后的调用直接走已学恢复动作, 不重复分析
8
+ * - 恢复动作: context overflow → 压缩上下文重试; 429/5xx → 退避重试; auth → 不重试
9
+ *
10
+ * 纯函数 + 有状态 store 分离, 可单测。
11
+ */
12
+ const PATTERNS = [
13
+ { category: 'rate-limit', recovery: 'backoff-retry', re: /(rate.?limit|too many requests|429|quota|限流|频率)/i },
14
+ { category: 'context-overflow', recovery: 'compact-retry', re: /(context|token|prompt).*(length|limit|size|exceed|too (long|large|many|small|big))|maximum context|reduce.*length|(token|上下文).*(上限|超长|过长|超出)|请求过长/i },
15
+ { category: 'auth', recovery: 'no-retry', re: /(401|403|402|unauthori[sz]ed|invalid api key|permission denied|鉴权|api.?key)/i },
16
+ { category: 'network', recovery: 'retry-once', re: /(ECONNRESET|ETIMEDOUT|ENOTFOUND|socket|network|undici|fetch failed|other side closed|timeout)/i },
17
+ { category: 'server', recovery: 'backoff-retry', re: /(50[0-9]|internal server|bad gateway|service unavailable|overloaded|server error)/i },
18
+ ];
19
+ /** 分类错误 (Hermes classify_api_error 的轻量版) */
20
+ export function classifyApiError(err) {
21
+ const msg = String(err?.message || err || '').slice(0, 500);
22
+ for (const p of PATTERNS) {
23
+ if (p.re.test(msg)) {
24
+ return { category: p.category, pattern: p.re.source, recoverable: p.recovery !== 'no-retry', recovery: p.recovery };
25
+ }
26
+ }
27
+ return { category: 'unknown', pattern: '(无匹配)', recoverable: false, recovery: 'no-retry' };
28
+ }
29
+ /** 会话级教训记忆: 同类错误只学一次 (Hermes "don't waste another call learning the same lesson") */
30
+ export class ErrorLessonStore {
31
+ lessons = new Map();
32
+ /** 记录一次错误; 返回 true = 本次是新教训 (同类第一次), false = 已学过 (去重) */
33
+ learn(err) {
34
+ const classified = classifyApiError(err);
35
+ if (this.lessons.has(classified.category)) {
36
+ return { classified, isNewLesson: false };
37
+ }
38
+ this.lessons.set(classified.category, { learnedAt: Date.now(), recovery: classified.recovery });
39
+ return { classified, isNewLesson: true };
40
+ }
41
+ /** 查询已学恢复动作 (未学过返回 undefined) */
42
+ recoveryFor(category) {
43
+ return this.lessons.get(category)?.recovery;
44
+ }
45
+ /** 已学教训数 */
46
+ get size() {
47
+ return this.lessons.size;
48
+ }
49
+ /** 清空 (新会话/新 provider 时) */
50
+ reset() {
51
+ this.lessons.clear();
52
+ }
53
+ }
@@ -31,55 +31,55 @@ export const JUDGMENT_PROMPTS = {
31
31
  default: {
32
32
  systemPrompt: '',
33
33
  systemPromptResolver: () => loadRoleLayer('role.expert', '你是一个专业的 AI 任务分析专家. '),
34
- userPromptTemplate: `【当前输入】
35
- {user_input}
36
-
37
- 【对话历史】
38
- {history}
39
-
40
- 【发送者】
41
- {sender_name}
42
-
43
- 请分析以上输入,判断:
44
-
45
- ## 理解
46
- 1. 问题本质是什么?(how-to / why / what / should / feasibility)
47
- 2. 核心需求是什么?
48
- 3. 有哪些隐含信息需要注意?
49
-
50
- ## 评估
51
- 1. 复杂性等级(simple / moderate / complex / profound)
52
- 2. 为什么是这个等级?
53
- 3. 需要多深的理解?(surface / deeper / fundamental)
54
-
55
- ## 决策
56
- 1. 推荐处理方式(answer / analyze / design / implement / coordinate)
57
- 2. 为什么这样处理?
58
-
59
- ## 路由
60
- 1. 应该调用哪些 Skills?(arch / guardian-fixer / harness-eng / harness-dev / task-arch / crystal-learn)
61
- 2. 需要什么协作模式?(solo / pair / team)
62
-
63
- 请用 JSON 格式输出,格式如下:
64
- {
65
- "understanding": {
66
- "essence": "问题本质",
67
- "coreNeed": "核心需求",
68
- "implicit": ["隐含信息1", "隐含信息2"]
69
- },
70
- "assessment": {
71
- "complexity": "complex",
72
- "complexityReason": "评估理由",
73
- "depth": "deeper"
74
- },
75
- "decision": {
76
- "approach": "design",
77
- "reasoning": "决策理由"
78
- },
79
- "routing": {
80
- "skills": ["arch", "guardian-fixer"],
81
- "collaboration": "pair"
82
- }
34
+ userPromptTemplate: `【当前输入】
35
+ {user_input}
36
+
37
+ 【对话历史】
38
+ {history}
39
+
40
+ 【发送者】
41
+ {sender_name}
42
+
43
+ 请分析以上输入,判断:
44
+
45
+ ## 理解
46
+ 1. 问题本质是什么?(how-to / why / what / should / feasibility)
47
+ 2. 核心需求是什么?
48
+ 3. 有哪些隐含信息需要注意?
49
+
50
+ ## 评估
51
+ 1. 复杂性等级(simple / moderate / complex / profound)
52
+ 2. 为什么是这个等级?
53
+ 3. 需要多深的理解?(surface / deeper / fundamental)
54
+
55
+ ## 决策
56
+ 1. 推荐处理方式(answer / analyze / design / implement / coordinate)
57
+ 2. 为什么这样处理?
58
+
59
+ ## 路由
60
+ 1. 应该调用哪些 Skills?(arch / guardian-fixer / harness-eng / harness-dev / task-arch / crystal-learn)
61
+ 2. 需要什么协作模式?(solo / pair / team)
62
+
63
+ 请用 JSON 格式输出,格式如下:
64
+ {
65
+ "understanding": {
66
+ "essence": "问题本质",
67
+ "coreNeed": "核心需求",
68
+ "implicit": ["隐含信息1", "隐含信息2"]
69
+ },
70
+ "assessment": {
71
+ "complexity": "complex",
72
+ "complexityReason": "评估理由",
73
+ "depth": "deeper"
74
+ },
75
+ "decision": {
76
+ "approach": "design",
77
+ "reasoning": "决策理由"
78
+ },
79
+ "routing": {
80
+ "skills": ["arch", "guardian-fixer"],
81
+ "collaboration": "pair"
82
+ }
83
83
  }`,
84
84
  outputFormat: 'json'
85
85
  },
@@ -87,26 +87,26 @@ export const JUDGMENT_PROMPTS = {
87
87
  architecture: {
88
88
  systemPrompt: '',
89
89
  systemPromptResolver: () => loadRoleLayer('role.architect', '你是一个经验丰富的系统架构师. '),
90
- userPromptTemplate: `【架构设计问题】
91
- {user_input}
92
-
93
- 【上下文】
94
- {context}
95
-
96
- 请进行架构分析,判断是否需要 Harness 介入。
97
-
98
- 分析维度:
99
- 1. 涉及哪些架构维度?(分层、微服务、事件驱动等)
100
- 2. 需要什么级别的架构设计?(概念性、逻辑性、物理性)
101
- 3. 有什么架构风险需要考虑?
102
-
103
- 输出 JSON:
104
- {
105
- "needsHarness": true/false,
106
- "gate": 0-8,
107
- "skills": ["arch", "harness-eng"],
108
- "architectureType": "microservices/layered/event-driven/etc",
109
- "concerns": ["concern1", "concern2"]
90
+ userPromptTemplate: `【架构设计问题】
91
+ {user_input}
92
+
93
+ 【上下文】
94
+ {context}
95
+
96
+ 请进行架构分析,判断是否需要 Harness 介入。
97
+
98
+ 分析维度:
99
+ 1. 涉及哪些架构维度?(分层、微服务、事件驱动等)
100
+ 2. 需要什么级别的架构设计?(概念性、逻辑性、物理性)
101
+ 3. 有什么架构风险需要考虑?
102
+
103
+ 输出 JSON:
104
+ {
105
+ "needsHarness": true/false,
106
+ "gate": 0-8,
107
+ "skills": ["arch", "harness-eng"],
108
+ "architectureType": "microservices/layered/event-driven/etc",
109
+ "concerns": ["concern1", "concern2"]
110
110
  }`,
111
111
  outputFormat: 'json'
112
112
  },
@@ -114,22 +114,22 @@ export const JUDGMENT_PROMPTS = {
114
114
  code: {
115
115
  systemPrompt: '',
116
116
  systemPromptResolver: () => loadRoleLayer('role.implementer', '你是一个高效的代码实现专家. '),
117
- userPromptTemplate: `【代码问题】
118
- {user_input}
119
-
120
- 请判断这个问题:
121
-
122
- 1. 是新功能实现还是修复问题?
123
- 2. 涉及哪些代码层面?(业务逻辑、数据访问、接口设计)
124
- 3. 需要什么测试覆盖?
125
-
126
- 输出 JSON:
127
- {
128
- "needsHarness": true/false,
129
- "gate": 0-8,
130
- "skills": ["harness-dev", "guardian-fixer"],
131
- "codeType": "feature/fix/refactor",
132
- "testCoverage": "unit/integration/e2e"
117
+ userPromptTemplate: `【代码问题】
118
+ {user_input}
119
+
120
+ 请判断这个问题:
121
+
122
+ 1. 是新功能实现还是修复问题?
123
+ 2. 涉及哪些代码层面?(业务逻辑、数据访问、接口设计)
124
+ 3. 需要什么测试覆盖?
125
+
126
+ 输出 JSON:
127
+ {
128
+ "needsHarness": true/false,
129
+ "gate": 0-8,
130
+ "skills": ["harness-dev", "guardian-fixer"],
131
+ "codeType": "feature/fix/refactor",
132
+ "testCoverage": "unit/integration/e2e"
133
133
  }`,
134
134
  outputFormat: 'json'
135
135
  },
@@ -137,23 +137,23 @@ export const JUDGMENT_PROMPTS = {
137
137
  security: {
138
138
  systemPrompt: '',
139
139
  systemPromptResolver: () => loadRoleLayer('role.security', '你是一个严格的安全专家. '),
140
- userPromptTemplate: `【安全问题】
141
- {user_input}
142
-
143
- 请分析安全问题:
144
-
145
- 1. 涉及哪些安全维度?(认证、授权、数据保护、传输安全)
146
- 2. 风险等级?(低/中/高/严重)
147
- 3. 需要什么安全措施?
148
-
149
- 输出 JSON:
150
- {
151
- "needsHarness": true,
152
- "gate": 4,
153
- "skills": ["guardian-fixer", "arch"],
154
- "securityDimensions": ["authentication", "authorization"],
155
- "riskLevel": "high",
156
- "recommendations": ["rec1", "rec2"]
140
+ userPromptTemplate: `【安全问题】
141
+ {user_input}
142
+
143
+ 请分析安全问题:
144
+
145
+ 1. 涉及哪些安全维度?(认证、授权、数据保护、传输安全)
146
+ 2. 风险等级?(低/中/高/严重)
147
+ 3. 需要什么安全措施?
148
+
149
+ 输出 JSON:
150
+ {
151
+ "needsHarness": true,
152
+ "gate": 4,
153
+ "skills": ["guardian-fixer", "arch"],
154
+ "securityDimensions": ["authentication", "authorization"],
155
+ "riskLevel": "high",
156
+ "recommendations": ["rec1", "rec2"]
157
157
  }`,
158
158
  outputFormat: 'json'
159
159
  }
package/dist/llm/pi-ai.js CHANGED
@@ -103,6 +103,14 @@ export class PiAIModel {
103
103
  if (signal?.aborted || error?.name === 'AbortError') {
104
104
  throw error; // 上层 try/catch 处理
105
105
  }
106
+ // 2026-08-11 (Hermes error_classifier + 会话级教训): 分类错误 + 同类只学一次
107
+ // 429/5xx → 退避重试; context overflow → 上层 compact 后重试; network → 重试 1 次;
108
+ // auth → 不重试 (报错给用户). console 只 warn 一次新教训.
109
+ const { ErrorLessonStore } = await import('./error-lessons.js');
110
+ const lesson = (chatErrorLessons ??= new ErrorLessonStore()).learn(error);
111
+ if (lesson.isNewLesson) {
112
+ console.warn(`[llm-lesson] 新错误教训: ${lesson.classified.category} (${lesson.classified.pattern}) → ${lesson.classified.recovery}`);
113
+ }
106
114
  console.error('PiAI chat error:', error);
107
115
  // 2026-06-15: 真实 error 信息 + 明确告诉 LLM "这是 API 错, 不要 retry"
108
116
  // 旧版: "抱歉,AI服务暂时不可用。" → LLM 看到 isTooShort=false(< 50 但 > 0),
@@ -494,12 +502,12 @@ export class PiAIModel {
494
502
  // 降级: 旧硬编码 (layer registry 不可用时不挂)
495
503
  console.warn('[pi-ai] layer registry 不可用, 降级:', err.message?.slice(0, 100));
496
504
  const envDetails = this.getEnvironmentDetails();
497
- return `You are a friendly AI assistant in a P2P document collaboration network.
498
-
499
- ## User Working Directory
500
- ${context || process.cwd()}
501
-
502
- ## Environment
505
+ return `You are a friendly AI assistant in a P2P document collaboration network.
506
+
507
+ ## User Working Directory
508
+ ${context || process.cwd()}
509
+
510
+ ## Environment
503
511
  ${envDetails}`;
504
512
  }
505
513
  }
@@ -507,49 +515,49 @@ ${envDetails}`;
507
515
  // 保留但内部用 sync fallback; 后续可改成 async
508
516
  buildSystemPrompt(context) {
509
517
  const envDetails = this.getEnvironmentDetails();
510
- return `You are a friendly AI assistant in a P2P document collaboration network.
511
-
512
- ## User Working Directory
513
- ${context || process.cwd()}
514
-
515
- ## Environment
518
+ return `You are a friendly AI assistant in a P2P document collaboration network.
519
+
520
+ ## User Working Directory
521
+ ${context || process.cwd()}
522
+
523
+ ## Environment
516
524
  ${envDetails}`;
517
525
  }
518
526
  getEnvironmentDetails() {
519
- return `
520
- ## Available Workflows
521
- - read - Read documents
522
- - summarize - Summarize documents
523
- - improve - Improve documents
524
- - collaborate - Multi-agent collaboration
525
- - query - Query status
526
- - report - Generate reports
527
-
528
- ## System Capabilities
529
- - Document processing (Markdown, Text, PDF, DOCX)
530
- - Multi-agent collaboration (P2P network)
531
- - Workflow engine (constraint layer)
532
- - Quality assessment and auto-send
533
-
534
- ## Current Time
527
+ return `
528
+ ## Available Workflows
529
+ - read - Read documents
530
+ - summarize - Summarize documents
531
+ - improve - Improve documents
532
+ - collaborate - Multi-agent collaboration
533
+ - query - Query status
534
+ - report - Generate reports
535
+
536
+ ## System Capabilities
537
+ - Document processing (Markdown, Text, PDF, DOCX)
538
+ - Multi-agent collaboration (P2P network)
539
+ - Workflow engine (constraint layer)
540
+ - Quality assessment and auto-send
541
+
542
+ ## Current Time
535
543
  ${new Date().toISOString()}`;
536
544
  }
537
545
  buildSummarizePrompt(text, context) {
538
546
  const maxLength = 8000;
539
547
  const truncatedText = text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
540
- let prompt = `Please generate a concise and accurate summary for the following document:
541
-
542
- ${truncatedText}
543
-
544
- Please output in the following format:
545
- ## Summary
546
- [Write summary here]
547
-
548
- ## Quality Self-Assessment
548
+ let prompt = `Please generate a concise and accurate summary for the following document:
549
+
550
+ ${truncatedText}
551
+
552
+ Please output in the following format:
553
+ ## Summary
554
+ [Write summary here]
555
+
556
+ ## Quality Self-Assessment
549
557
  [Score 1-10, with reasoning]`;
550
558
  if (context) {
551
- prompt = `Context: ${context}
552
-
559
+ prompt = `Context: ${context}
560
+
553
561
  ${prompt}`;
554
562
  }
555
563
  return prompt;
@@ -557,17 +565,17 @@ ${prompt}`;
557
565
  buildImprovePrompt(content, requirements, context) {
558
566
  const maxLength = 8000;
559
567
  const truncatedContent = content.length > maxLength ? content.substring(0, maxLength) + '...' : content;
560
- let prompt = `Please improve the document according to the following requirements:
561
-
562
- Requirements: ${requirements}
563
-
564
- Original Document:
565
- ${truncatedContent}
566
-
568
+ let prompt = `Please improve the document according to the following requirements:
569
+
570
+ Requirements: ${requirements}
571
+
572
+ Original Document:
573
+ ${truncatedContent}
574
+
567
575
  Please output only the improved document without additional explanation.`;
568
576
  if (context) {
569
- prompt = `Context: ${context}
570
-
577
+ prompt = `Context: ${context}
578
+
571
579
  ${prompt}`;
572
580
  }
573
581
  return prompt;
@@ -710,4 +718,9 @@ export function getMinimax() {
710
718
  export function initMinimax(config = {}) {
711
719
  return initPiAI(config);
712
720
  }
721
+ /** 2026-08-11: 会话级 LLM 错误教训存储 (Hermes error_classifier 模式) — 同类错误只学一次 */
722
+ let chatErrorLessons = null;
723
+ export function getChatErrorLessons() {
724
+ return chatErrorLessons;
725
+ }
713
726
  export { PiAIModel as MinimaxLLM };
@@ -1,41 +1,41 @@
1
- ---
2
- added_at: 2026-07-10
3
- last_reviewed_at: 2026-07-10
4
- ttl_days: 180
5
- author: yuanjie
6
- ---
7
-
8
- <!-- channel.human-async@1.0.0 -->
9
- # 人类异步回来 (用户几小时/几天没来, hook 唤醒你做后台任务)
10
-
11
- **适用场景**: 当前 channel 标识 `user_away` 或 `goal_continue` 类型, 用户不在本地.
12
- 你被 hook 启动处理"用户离开时积累的请求" (peer 消息 / 监控告警 / 计划任务).
13
-
14
- ## 唤醒后先判断
15
-
16
- - **`list_parked_goals`** (调 goal-resume.ts 暴露的工具) → 拿所有用户离开时挂起的目标
17
- - **优先级排序**: `awaiting_external` > `channel_switch` > `user_away` > `peer_handoff`
18
- - 选 1 个最值得推进的, 调 `resume_goal` 接着干
19
-
20
- ## 异步处理 (用户回来时无缝衔接)
21
-
22
- 处理时**不**写到用户原来的 channel — 开新 channel `auto-async:<timestamp>`,
23
- 挂上 `targetId` (= 原始 goal 的 targetId), 用户回来时:
24
-
25
- ```
26
- 1. 用户登录 → 调 list_parked_goals 查他离开时的进展
27
- 2. 对每个 parked goal: 调 resume_goal 续
28
- 3. 在 UI 显示 "📥 你离开时 X 节点帮你推进了 N 步" — 透明
29
- ```
30
-
31
- ## 自动沉淀用户习性
32
-
33
- 每完成一个完整任务, **主动调 `habit-distill` skill** (`src/bollharness-integration/skill-adapter.ts`),
34
- 抽取用户在本次交互里展现的偏好 (输入习惯 / 术语 / 反复问的主题), 写到
35
- `~/.bolloon/human-values/judgments.json`. 标注 `source: 'habit-distill'`.
36
-
37
- ## 边界 (硬约束)
38
-
39
- - **异步任务超时 > 30min** → 自动 park + 写 judgment "用户可能想优先别的", 退出
40
- - **写入类操作** (create_file / str_replace) → **先在 channel 里写** "我打算改 X 文件, 你回来时确认", 不直接落盘
41
- - **不要主动给对端 peer 发消息** — 用户不在场, 你没授权
1
+ ---
2
+ added_at: 2026-07-10
3
+ last_reviewed_at: 2026-07-10
4
+ ttl_days: 180
5
+ author: yuanjie
6
+ ---
7
+
8
+ <!-- channel.human-async@1.0.0 -->
9
+ # 人类异步回来 (用户几小时/几天没来, hook 唤醒你做后台任务)
10
+
11
+ **适用场景**: 当前 channel 标识 `user_away` 或 `goal_continue` 类型, 用户不在本地.
12
+ 你被 hook 启动处理"用户离开时积累的请求" (peer 消息 / 监控告警 / 计划任务).
13
+
14
+ ## 唤醒后先判断
15
+
16
+ - **`list_parked_goals`** (调 goal-resume.ts 暴露的工具) → 拿所有用户离开时挂起的目标
17
+ - **优先级排序**: `awaiting_external` > `channel_switch` > `user_away` > `peer_handoff`
18
+ - 选 1 个最值得推进的, 调 `resume_goal` 接着干
19
+
20
+ ## 异步处理 (用户回来时无缝衔接)
21
+
22
+ 处理时**不**写到用户原来的 channel — 开新 channel `auto-async:<timestamp>`,
23
+ 挂上 `targetId` (= 原始 goal 的 targetId), 用户回来时:
24
+
25
+ ```
26
+ 1. 用户登录 → 调 list_parked_goals 查他离开时的进展
27
+ 2. 对每个 parked goal: 调 resume_goal 续
28
+ 3. 在 UI 显示 "📥 你离开时 X 节点帮你推进了 N 步" — 透明
29
+ ```
30
+
31
+ ## 自动沉淀用户习性
32
+
33
+ 每完成一个完整任务, **主动调 `habit-distill` skill** (`src/bollharness-integration/skill-adapter.ts`),
34
+ 抽取用户在本次交互里展现的偏好 (输入习惯 / 术语 / 反复问的主题), 写到
35
+ `~/.bolloon/human-values/judgments.json`. 标注 `source: 'habit-distill'`.
36
+
37
+ ## 边界 (硬约束)
38
+
39
+ - **异步任务超时 > 30min** → 自动 park + 写 judgment "用户可能想优先别的", 退出
40
+ - **写入类操作** (create_file / str_replace) → **先在 channel 里写** "我打算改 X 文件, 你回来时确认", 不直接落盘
41
+ - **不要主动给对端 peer 发消息** — 用户不在场, 你没授权
@@ -1,14 +1,14 @@
1
- ---
2
- added_at: 2026-06-15
3
- last_reviewed_at: 2026-06-15
4
- ttl_days: 180
5
- author: yuanjie
6
- ---
7
-
8
- <!-- channel.local@1.0.0 -->
9
- # 本地渠道 (默认, bolloon 跑在用户本机)
10
-
11
- 你跑在用户的本地设备上, 可直接读写用户文件系统. 信任度高.
12
-
13
- 允许: 读写文件、执行命令、调用所有工具.
14
- 边界: 仍遵守 core.refusal / core.wellbeing / 拒绝处理.
1
+ ---
2
+ added_at: 2026-06-15
3
+ last_reviewed_at: 2026-06-15
4
+ ttl_days: 180
5
+ author: yuanjie
6
+ ---
7
+
8
+ <!-- channel.local@1.0.0 -->
9
+ # 本地渠道 (默认, bolloon 跑在用户本机)
10
+
11
+ 你跑在用户的本地设备上, 可直接读写用户文件系统. 信任度高.
12
+
13
+ 允许: 读写文件、执行命令、调用所有工具.
14
+ 边界: 仍遵守 core.refusal / core.wellbeing / 拒绝处理.
@@ -1,18 +1,18 @@
1
- ---
2
- added_at: 2026-06-15
3
- last_reviewed_at: 2026-06-15
4
- ttl_days: 180
5
- author: yuanjie
6
- ---
7
-
8
- <!-- channel.p2p-agent@1.0.0 -->
9
- # P2P 远程智能体 (另一个 bolloon 经 P2P 路由)
10
-
11
- 你是远端 bolloon, 收到的是**另一个 bolloon 实例**的协作请求. 信任度高 (基于 P2P 节点身份验证, 不是基于人类).
12
-
13
- 允许: 读 / 写, 协作推理, 共享上下文.
14
-
15
- 边界:
16
- - 身份验证优先: 先确认对方节点 ID + 公钥签名
17
- - 共享上下文时避免把人类隐私数据 (judgment / persona) 外泄给未知节点
18
- - 协作冲突时回退到 snapshot 重新协商, 不强推修改
1
+ ---
2
+ added_at: 2026-06-15
3
+ last_reviewed_at: 2026-06-15
4
+ ttl_days: 180
5
+ author: yuanjie
6
+ ---
7
+
8
+ <!-- channel.p2p-agent@1.0.0 -->
9
+ # P2P 远程智能体 (另一个 bolloon 经 P2P 路由)
10
+
11
+ 你是远端 bolloon, 收到的是**另一个 bolloon 实例**的协作请求. 信任度高 (基于 P2P 节点身份验证, 不是基于人类).
12
+
13
+ 允许: 读 / 写, 协作推理, 共享上下文.
14
+
15
+ 边界:
16
+ - 身份验证优先: 先确认对方节点 ID + 公钥签名
17
+ - 共享上下文时避免把人类隐私数据 (judgment / persona) 外泄给未知节点
18
+ - 协作冲突时回退到 snapshot 重新协商, 不强推修改