@bolloon/bolloon-agent 0.5.4 → 0.5.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.
Files changed (126) hide show
  1. package/dist/agents/agent-identity-store.js +41 -5
  2. package/dist/agents/background-notices.js +124 -0
  3. package/dist/agents/channel-identity.js +54 -0
  4. package/dist/agents/code-write-gate.js +47 -0
  5. package/dist/agents/deny-pipeline.js +11 -2
  6. package/dist/agents/egress-sanitize.js +69 -0
  7. package/dist/agents/error-classifier.js +67 -5
  8. package/dist/agents/experience-review.js +226 -0
  9. package/dist/agents/gateway-group.js +153 -18
  10. package/dist/agents/iteration-budget.js +64 -0
  11. package/dist/agents/lesson-to-skill.js +211 -0
  12. package/dist/agents/managed-services.js +64 -0
  13. package/dist/agents/parse-tool-call.js +38 -32
  14. package/dist/agents/pi-sdk-session-manager.js +72 -3
  15. package/dist/agents/pi-sdk-tools.js +201 -32
  16. package/dist/agents/pi-sdk.js +463 -21
  17. package/dist/agents/plan-store.js +36 -0
  18. package/dist/agents/process-runner.js +64 -2
  19. package/dist/agents/shell-guard.js +109 -13
  20. package/dist/agents/skill-health.js +90 -0
  21. package/dist/agents/skill-ledger.js +129 -0
  22. package/dist/agents/tool-loop-guard.js +303 -0
  23. package/dist/agents/tool-path-args.js +53 -0
  24. package/dist/agents/tool-result-gate.js +50 -0
  25. package/dist/agents/tool-subset.js +109 -0
  26. package/dist/agents/tool-telemetry.js +97 -0
  27. package/dist/bootstrap/context-collector.js +37 -7
  28. package/dist/bootstrap/lifecycle-hooks.js +12 -3
  29. package/dist/bootstrap/persona-init.js +174 -0
  30. package/dist/bootstrap/persona-loader.js +5 -1
  31. package/dist/cli/ink-app.js +153 -6
  32. package/dist/cli/input-paste.js +218 -0
  33. package/dist/cli/loading-tui.js +3 -1
  34. package/dist/cli/log-gate.js +7 -0
  35. package/dist/cli/mention-data.js +30 -0
  36. package/dist/cli/reasoning-view.js +103 -0
  37. package/dist/cli/startup-notice.js +25 -0
  38. package/dist/cli/status-segments.js +87 -2
  39. package/dist/cli/trace-line.js +54 -0
  40. package/dist/context-compaction/auto-compact.js +37 -2
  41. package/dist/electron-build/agents/agent-identity-store.js +43 -5
  42. package/dist/electron-build/agents/agent-identity-store.js.map +1 -1
  43. package/dist/electron-build/agents/background-notices.js +138 -0
  44. package/dist/electron-build/agents/background-notices.js.map +1 -0
  45. package/dist/electron-build/agents/channel-identity.js +64 -0
  46. package/dist/electron-build/agents/channel-identity.js.map +1 -0
  47. package/dist/electron-build/agents/code-write-gate.js +55 -0
  48. package/dist/electron-build/agents/code-write-gate.js.map +1 -0
  49. package/dist/electron-build/agents/deny-pipeline.js +11 -2
  50. package/dist/electron-build/agents/deny-pipeline.js.map +1 -1
  51. package/dist/electron-build/agents/egress-sanitize.js +76 -0
  52. package/dist/electron-build/agents/egress-sanitize.js.map +1 -0
  53. package/dist/electron-build/agents/error-classifier.js +68 -5
  54. package/dist/electron-build/agents/error-classifier.js.map +1 -1
  55. package/dist/electron-build/agents/experience-review.js +243 -0
  56. package/dist/electron-build/agents/experience-review.js.map +1 -0
  57. package/dist/electron-build/agents/iteration-budget.js +73 -0
  58. package/dist/electron-build/agents/iteration-budget.js.map +1 -0
  59. package/dist/electron-build/agents/lesson-to-skill.js +228 -0
  60. package/dist/electron-build/agents/lesson-to-skill.js.map +1 -0
  61. package/dist/electron-build/agents/managed-services.js +69 -0
  62. package/dist/electron-build/agents/managed-services.js.map +1 -0
  63. package/dist/electron-build/agents/parse-tool-call.js +38 -32
  64. package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
  65. package/dist/electron-build/agents/pi-sdk-session-manager.js +75 -3
  66. package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
  67. package/dist/electron-build/agents/pi-sdk-tools.js +200 -31
  68. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  69. package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
  70. package/dist/electron-build/agents/pi-sdk.js +464 -21
  71. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  72. package/dist/electron-build/agents/plan-store.js +37 -0
  73. package/dist/electron-build/agents/plan-store.js.map +1 -1
  74. package/dist/electron-build/agents/process-runner.js +71 -2
  75. package/dist/electron-build/agents/process-runner.js.map +1 -1
  76. package/dist/electron-build/agents/shell-guard.js +110 -14
  77. package/dist/electron-build/agents/shell-guard.js.map +1 -1
  78. package/dist/electron-build/agents/skill-health.js +103 -0
  79. package/dist/electron-build/agents/skill-health.js.map +1 -0
  80. package/dist/electron-build/agents/skill-ledger.js +146 -0
  81. package/dist/electron-build/agents/skill-ledger.js.map +1 -0
  82. package/dist/electron-build/agents/tool-loop-guard.js +319 -0
  83. package/dist/electron-build/agents/tool-loop-guard.js.map +1 -0
  84. package/dist/electron-build/agents/tool-path-args.js +63 -0
  85. package/dist/electron-build/agents/tool-path-args.js.map +1 -0
  86. package/dist/electron-build/agents/tool-result-gate.js +59 -0
  87. package/dist/electron-build/agents/tool-result-gate.js.map +1 -0
  88. package/dist/electron-build/agents/tool-subset.js +116 -0
  89. package/dist/electron-build/agents/tool-subset.js.map +1 -0
  90. package/dist/electron-build/agents/tool-telemetry.js +108 -0
  91. package/dist/electron-build/agents/tool-telemetry.js.map +1 -0
  92. package/dist/electron-build/bootstrap/context-collector.js +38 -7
  93. package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
  94. package/dist/electron-build/bootstrap/lifecycle-hooks.js +12 -3
  95. package/dist/electron-build/bootstrap/lifecycle-hooks.js.map +1 -1
  96. package/dist/electron-build/bootstrap/persona-init.js +216 -0
  97. package/dist/electron-build/bootstrap/persona-init.js.map +1 -0
  98. package/dist/electron-build/bootstrap/persona-loader.js +5 -1
  99. package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
  100. package/dist/electron-build/context-compaction/auto-compact.js +38 -2
  101. package/dist/electron-build/context-compaction/auto-compact.js.map +1 -1
  102. package/dist/electron-build/external-engines/delegate.js +22 -0
  103. package/dist/electron-build/external-engines/delegate.js.map +1 -1
  104. package/dist/electron-build/orbitdb/cid-database.js +55 -0
  105. package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
  106. package/dist/electron-build/orbitdb/ipfs-node.js +36 -11
  107. package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -1
  108. package/dist/electron-build/web/server-storage.js +26 -5
  109. package/dist/electron-build/web/server-storage.js.map +1 -1
  110. package/dist/external-engines/delegate.js +21 -0
  111. package/dist/index.js +503 -77
  112. package/dist/orbitdb/cid-database.js +55 -0
  113. package/dist/orbitdb/event-index.js +370 -0
  114. package/dist/orbitdb/event-query.js +131 -0
  115. package/dist/orbitdb/event-shell.js +510 -0
  116. package/dist/orbitdb/group-access.js +381 -0
  117. package/dist/orbitdb/group-shards.js +140 -0
  118. package/dist/orbitdb/ipfs-node.js +36 -11
  119. package/dist/web/bolloon-web.json +3 -3
  120. package/dist/web/client.js +3 -2
  121. package/dist/web/mobile-core.js +7762 -6289
  122. package/dist/web/routes-mobile-tasks.js +2 -1
  123. package/dist/web/server-storage.js +26 -5
  124. package/dist/web/server.js +2 -0
  125. package/dist/web/sw.js +1 -1
  126. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"error-classifier.js","sourceRoot":"","sources":["../../../src/agents/error-classifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error-classifier.js","sourceRoot":"","sources":["../../../src/agents/error-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_MIN_INTERVAL_MS = exports.EXPERIENCE_DIR_NAME = void 0;
7
+ exports.experienceDir = experienceDir;
8
+ exports.sanitizeClass = sanitizeClass;
9
+ exports.sanitizeTitle = sanitizeTitle;
10
+ exports.shouldReview = shouldReview;
11
+ exports.shouldReviewTask = shouldReviewTask;
12
+ exports.listExperienceIndex = listExperienceIndex;
13
+ exports.buildReviewPrompt = buildReviewPrompt;
14
+ exports.parseReviewDecision = parseReviewDecision;
15
+ exports.applyExperience = applyExperience;
16
+ exports.runExperienceReview = runExperienceReview;
17
+ /**
18
+ * 回合后自审 → 沉淀可复用经验 (2026-10-01, 用户「落实」)。
19
+ *
20
+ * 为什么: 智能体目前只在**回合内**反应 —— 做完就完了, 经验不落库。飞轮目标里"结束后沉淀可复用经验"
21
+ * 是唯一还没动工的一段。做法学的是运行时那套**回合后自审**的机制, 约束照搬:
22
+ * · 只写**沉淀库**, **绝不碰主对话 / prompt 缓存**(所以纯旁路, 不影响用户看到的内容);
23
+ * · **不阻塞主回合**: 调用方 fire-and-forget, 本模块自己吞掉所有异常;
24
+ * · **工具白名单**: v1 连工具都不用 —— 只把"本回合摘要 + 现有库目录"喂给模型, 要它回一段 JSON;
25
+ * · **fail-open**: 节流/配置读不出来时**放行**(宁可偶尔多审一次, 不要因配置坏掉就永久不审);
26
+ * · **绝不编造**: 没有值得记的就回 none, 那就什么都不写(写空是正常结果, 不是失败)。
27
+ * 库的形态(反囤积): `~/.bolloon/experience/<类>.md`, **类级**文件 + 条目标题去重 ——
28
+ * 「同一教训学两次 = 改那一条, 不是加一条」。
29
+ */
30
+ const node_fs_1 = __importDefault(require("node:fs"));
31
+ const node_path_1 = __importDefault(require("node:path"));
32
+ const node_os_1 = __importDefault(require("node:os"));
33
+ exports.EXPERIENCE_DIR_NAME = 'experience';
34
+ /** 同一个 agent 两次自审的最小间隔 (默认 10 分钟; 可用 BOLLOON_EXPERIENCE_REVIEW_MIN_MS 覆盖) */
35
+ exports.DEFAULT_MIN_INTERVAL_MS = 10 * 60 * 1000;
36
+ function experienceDir(home = node_os_1.default.homedir()) {
37
+ return node_path_1.default.join(home, '.bolloon', exports.EXPERIENCE_DIR_NAME);
38
+ }
39
+ /** 类名净化 (只允许安全字符; 空 ⇒ 'general') */
40
+ function sanitizeClass(k) {
41
+ const s = String(k ?? '').trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, '-').replace(/^-+|-+$/g, '');
42
+ return s || 'general';
43
+ }
44
+ /** 条目标题净化 (空 ⇒ 拒绝写: 没有标题的沉淀无法去重, 宁可不要) */
45
+ function sanitizeTitle(t) {
46
+ return String(t ?? '').trim().replace(/\s+/g, ' ').slice(0, 120);
47
+ }
48
+ /**
49
+ * 节流判据 (纯函数)。**fail-open**: 时间戳坏了/缺失 ⇒ 放行。
50
+ * @param lastAtMs 上一次自审时间 (0/undefined = 从未)
51
+ */
52
+ function shouldReview(nowMs, lastAtMs, minIntervalMs = exports.DEFAULT_MIN_INTERVAL_MS) {
53
+ if (!Number.isFinite(nowMs) || nowMs <= 0)
54
+ return true; // 时钟坏了 ⇒ 放行 (fail-open)
55
+ if (!lastAtMs || !Number.isFinite(lastAtMs) || lastAtMs <= 0)
56
+ return true; // 从未审过 ⇒ 放行
57
+ if (!Number.isFinite(minIntervalMs) || minIntervalMs <= 0)
58
+ return true; // 配置坏了 ⇒ 放行 (fail-open)
59
+ return nowMs - lastAtMs >= minIntervalMs;
60
+ }
61
+ /**
62
+ * **每次任务都复盘** (2026-10-01, 用户: 「自动每次做完任务都要总结经验」)。
63
+ * 与 `shouldReview` 的区别: 那个是"每 10 分钟最多一次" ✗ —— 会漏掉"做完一个任务"这种**事件** ✓;
64
+ * 这条按**任务签名**判: 签名变了(换任务了) ⇒ **立刻复盘** ✓; 同一任务重复 ⇒ 才回到节流 ✓。
65
+ * (成本控制: 只在"这一回合真的干了活"时才算签名 —— 由调用方保证 ✓; 且复盘是 fire-and-forget ✓。)
66
+ */
67
+ function shouldReviewTask(nowMs, lastAtMs, lastSig, sig, minIntervalMs = exports.DEFAULT_MIN_INTERVAL_MS) {
68
+ if (sig && sig !== lastSig)
69
+ return true; // ★ 换了任务 ⇒ 立刻复盘
70
+ return shouldReview(nowMs, lastAtMs, minIntervalMs); // 同一任务 ⇒ 仍按节流, 免得反复审同一段
71
+ }
72
+ /** 现有库的目录 (喂给模型, 让它知道"已经有哪些类/条目", 从而倾向于改而不是加) */
73
+ function listExperienceIndex(home = node_os_1.default.homedir()) {
74
+ const dir = experienceDir(home);
75
+ try {
76
+ const files = node_fs_1.default.readdirSync(dir).filter((f) => f.endsWith('.md'));
77
+ if (!files.length)
78
+ return '(沉淀库还是空的)';
79
+ return files.slice(0, 30).map((f) => {
80
+ const body = node_fs_1.default.readFileSync(node_path_1.default.join(dir, f), 'utf-8');
81
+ const titles = [...body.matchAll(/^##\s+(.+)$/gm)].map((m) => m[1].trim()).slice(0, 20);
82
+ return `- ${f} (${titles.length} 条)\n${titles.map((t) => ` · ${t}`).join('\n')}`;
83
+ }).join('\n');
84
+ }
85
+ catch {
86
+ return '(沉淀库还是空的)';
87
+ }
88
+ }
89
+ /**
90
+ * 自审提示词 (纯函数)。**反囤积**规矩逐条写进去 —— 这是"库会变干净还是变垃圾堆"的分水岭。
91
+ */
92
+ function buildReviewPrompt(turnSummary, existingIndex) {
93
+ return [
94
+ '你在做**回合后自审**: 判断上面这一回合里有没有值得沉淀成"可复用经验"的东西。',
95
+ '',
96
+ '已经沉淀过的(先看这里, 别重复):',
97
+ existingIndex,
98
+ '',
99
+ '这一回合发生了什么:',
100
+ '"""',
101
+ String(turnSummary || '').slice(0, 6000),
102
+ '"""',
103
+ '',
104
+ '规矩(按这个判):',
105
+ '1. **同一教训学两次 = 一条规矩**: 若上面已有同类条目 ⇒ 用同一个 title, 表示"更新那一条"; 否则才算新条目。',
106
+ '2. 只沉淀**可复用**的: 类级规律 · 踩过的坑与判据 · 用户对做法/风格的纠正 · 稳定的环境事实。',
107
+ '3. **不要**沉淀: 本次事件叙述 · 版本号/日期流水 · 一次性任务进度 · 环境依赖型失败(缺二进制、首次安装报错)。',
108
+ '4. 没有值得记的就回 none —— **写空是正常结果**, 不是失败; 编一条凑数比不写更糟。',
109
+ '5. 内容要短: title ≤ 60 字, body ≤ 400 字, body 写"规矩 + 为什么", 不写过程。',
110
+ '',
111
+ '只回一个 JSON(不要别的文字):',
112
+ '{"action":"none"} 或 {"action":"write","class":"类名(小写-连字符)","title":"一句话标题","body":"规矩与理由"}',
113
+ ].join('\n');
114
+ }
115
+ /** 容错解析模型回的那段 JSON (纯函数)。任何异常/不完整 ⇒ none (绝不半写) */
116
+ function parseReviewDecision(text) {
117
+ const raw = String(text || '');
118
+ const m = raw.match(/\{[\s\S]*\}/);
119
+ // 2026-10-01 (用户: 「卡在这就不动了」现场: 日志里连着出现 "审了但没写: 没找到 JSON" ✗ ⇒ 复盘白跑):
120
+ // 模型 Often 不给严格 JSON ⇒ 原来直接当"没写" ✗。现在: ① 没花括号时**宽解析**(从文本里抠字段 ✓);
121
+ // ② 仍解析不出 ⇒ 把**原文头部**记进日志(才能知道它到底回了什么 ✓, 不再瞎 ✗)。
122
+ if (!m) {
123
+ const act = /(?:^|["'\s])action["'\s::]*["']?([a-z_]+)/i.exec(raw)?.[1]
124
+ || (/\bwrite\b/i.test(raw) ? 'write' : (/\bnone\b|不用|无需/i.test(raw) ? 'none' : ''));
125
+ if (act === 'write') {
126
+ const title = /(?:title|标题)["'\s::]*["']?([^"'\n]{2,80})/i.exec(raw)?.[1]?.trim() || '未命名教训';
127
+ const body = /(?:body|内容|教训)["'\s::]*["']?([\s\S]{20,1200}?)(?:["'\n]|$)/i.exec(raw)?.[1]?.trim() || raw.slice(0, 400);
128
+ if (body.length >= 20)
129
+ return { action: 'write', file: 'lessons.md', title, body, klass: 'general', reason: '宽解析' };
130
+ }
131
+ if (act === 'none')
132
+ return { action: 'none', reason: '模型判定无需记录(宽解析)' };
133
+ return { action: 'none', reason: `没找到 JSON(模型原文头部: ${raw.replace(/\s+/g, ' ').slice(0, 120)})` };
134
+ }
135
+ try {
136
+ const j = JSON.parse(m[0]);
137
+ if (String(j?.action || '').toLowerCase() !== 'write')
138
+ return { action: 'none' };
139
+ const title = sanitizeTitle(j.title);
140
+ const body = String(j?.body ?? '').trim().slice(0, 800);
141
+ if (!title || !body)
142
+ return { action: 'none', reason: 'title/body 不全' }; // 宁可丢, 不写半条
143
+ return { action: 'write', klass: sanitizeClass(j.class), title, body };
144
+ }
145
+ catch {
146
+ return { action: 'none', reason: 'JSON 解析失败' };
147
+ }
148
+ }
149
+ /**
150
+ * 落库: **同 title 就更新那一条**(hit+1, 替换正文), 否则追加。
151
+ * @returns 实际动作, 便于测试与日志
152
+ */
153
+ function applyExperience(d, home = node_os_1.default.homedir(), nowIso = new Date().toISOString()) {
154
+ if (d.action !== 'write' || !d.title || !d.body)
155
+ return { wrote: false };
156
+ const dir = experienceDir(home);
157
+ const file = node_path_1.default.join(dir, `${sanitizeClass(d.klass)}.md`);
158
+ try {
159
+ node_fs_1.default.mkdirSync(dir, { recursive: true });
160
+ let cur = '';
161
+ try {
162
+ cur = node_fs_1.default.readFileSync(file, 'utf-8');
163
+ }
164
+ catch {
165
+ cur = '';
166
+ }
167
+ const header = cur.trim() ? cur : `# 可复用经验 · ${sanitizeClass(d.klass)}\n\n> 回合后自审沉淀; 同一教训只留一条(重复出现则更新) · 每条带出现次数与末次时间\n`;
168
+ // 2026-10-01 修: 上一版用正则 `...(?=^## |\Z)` 找条目边界 —— **JS 不支持 \Z**, 它被当成字面量 Z,
169
+ // 而条目的时间戳正好以 Z 结尾 ⇒ 从那儿截断, 更新后留下旧正文残渣(实跑看到: "Z -->" + 旧正文)✗。
170
+ // 改成**按 `## ` 切块再拼** —— 不依赖任何正则边界语义。
171
+ const blockOf = (t, body, hits) => `## ${t}\n<!-- hit:${hits} last:${nowIso} -->\n${body}\n`;
172
+ const parts = header.split(/\n(?=## )/);
173
+ const head = parts[0].trimEnd();
174
+ const entries = parts.slice(1).filter((x) => x.trim().startsWith('## '));
175
+ const titleOf = (blk) => (blk.split('\n')[0] || '').replace(/^##\s*/, '').trim();
176
+ const hitsOf = (blk) => Number((blk.match(/<!--\s*hit:(\d+)/) || [])[1] || 0);
177
+ const idx = entries.findIndex((blk) => titleOf(blk) === d.title);
178
+ if (idx >= 0) {
179
+ const n = hitsOf(entries[idx]) + 1; // 上一次次数 + 本次 (更新 ⇒ 至少 2)
180
+ entries[idx] = blockOf(d.title, d.body, n);
181
+ node_fs_1.default.writeFileSync(file, head + '\n\n' + entries.map((x) => x.trimEnd()).join('\n\n') + '\n', 'utf-8');
182
+ return { wrote: true, file, updated: true };
183
+ }
184
+ entries.push(blockOf(d.title, d.body, 1));
185
+ node_fs_1.default.writeFileSync(file, head + '\n\n' + entries.map((x) => x.trimEnd()).join('\n\n') + '\n', 'utf-8');
186
+ return { wrote: true, file, updated: false };
187
+ }
188
+ catch {
189
+ return { wrote: false };
190
+ }
191
+ }
192
+ function escapeRe(s) {
193
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
194
+ }
195
+ /**
196
+ * 自审编排 (纯旁路, **绝不抛错**)。
197
+ *
198
+ * `chat` 由调用方注入 (便于门测; 生产用现成的单次补全)。整段逻辑:
199
+ * 节流 ⇒ 取库目录 ⇒ 拼提示 ⇒ 一次补全 ⇒ 解析 ⇒ 落库。
200
+ * 任何一步失败都只是"这次没沉淀", 不影响主回合 —— 调用方 fire-and-forget 即可。
201
+ */
202
+ async function runExperienceReview(opts) {
203
+ const home = opts.home || node_os_1.default.homedir();
204
+ const now = opts.nowMs ?? Date.now();
205
+ const log = opts.log || (() => { });
206
+ try {
207
+ if (!opts.force && !shouldReview(now, opts.lastAtMs, opts.minIntervalMs))
208
+ return { reviewed: false, applied: false, reason: 'throttled' };
209
+ const summary = String(opts.turnSummary || '').trim();
210
+ if (summary.length < 40)
211
+ return { reviewed: false, applied: false, reason: '回合太短, 不值得审' };
212
+ const prompt = buildReviewPrompt(summary, listExperienceIndex(home));
213
+ // 2026-10-01 (用户: 「卡在这就不动了」+ 复盘日志里 "开始" 之后没有下文 ✗):
214
+ // review 的 chat 调用**原来没有超时** ⇒ 一旦 provider 慢/挂, 这条就永远不返回 ✓。
215
+ // 现在给**硬超时**(默认 25s, 可配 ✓), 超时如实记一条并放行 ✓ —— 复盘是锦上添花, 绝不许拖住主流程 ✓。
216
+ const chatTimeoutMs = Number(process.env.BOLLOON_REVIEW_TIMEOUT_MS) || 25_000;
217
+ const raw = await Promise.race([
218
+ opts.chat(prompt),
219
+ new Promise((resolve) => setTimeout(() => resolve('__TIMEOUT__'), chatTimeoutMs)),
220
+ ]);
221
+ if (raw === '__TIMEOUT__') {
222
+ log(`审查超时(${chatTimeoutMs}ms) —— 本轮不复盘, 已放行(绝不拖住主流程)`);
223
+ return { reviewed: false, applied: false, reason: 'chat-timeout' };
224
+ }
225
+ const d = parseReviewDecision(raw);
226
+ if (d.action !== 'write')
227
+ return { reviewed: true, applied: false, reason: d.reason || 'none' };
228
+ const r = applyExperience(d, home, new Date(now).toISOString());
229
+ if (r.wrote) {
230
+ log(`[experience] ${r.updated ? '更新' : '新增'} ${node_path_1.default.basename(r.file)} · ${d.title}`);
231
+ try {
232
+ opts.onLesson?.({ title: d.title, body: d.body, klass: d.klass });
233
+ }
234
+ catch { /* 回调绝不影响落库 */ }
235
+ }
236
+ return { reviewed: true, applied: r.wrote, file: r.wrote ? r.file : undefined, updated: r.wrote ? r.updated : undefined };
237
+ }
238
+ catch (e) {
239
+ log(`[experience] 自审跳过(非致命): ${String(e?.message || e).slice(0, 120)}`);
240
+ return { reviewed: false, applied: false, reason: 'error' };
241
+ }
242
+ }
243
+ //# sourceMappingURL=experience-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experience-review.js","sourceRoot":"","sources":["../../../src/agents/experience-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IterationBudget = exports.REFUNDABLE_TOOLS = void 0;
4
+ exports.capsFromEnv = capsFromEnv;
5
+ exports.normalizeWarnRatio = normalizeWarnRatio;
6
+ exports.shouldWarn = shouldWarn;
7
+ exports.isRefundableTool = isRefundableTool;
8
+ /**
9
+ * 这些工具"一次调用可顶多次操作" ⇒ 用它换来的迭代要**退还**。
10
+ * 加新工具时问自己: 它能不能在一次调用里做完 N 件事? 能 ⇒ 加进来。
11
+ */
12
+ exports.REFUNDABLE_TOOLS = new Set(['execute_code']);
13
+ function capsFromEnv(env = process.env) {
14
+ const num = (v, d) => {
15
+ const n = Number(v);
16
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : d;
17
+ };
18
+ return {
19
+ parent: num(env.BOLLOON_MAX_ITERATIONS, 500),
20
+ subagent: num(env.BOLLOON_SUBAGENT_MAX_ITERATIONS, 50),
21
+ };
22
+ }
23
+ /** 警告比例: 严格 (0,1) 的有限数; 否则 null = 关闭该功能 (与"只搬约束"一致) */
24
+ function normalizeWarnRatio(v) {
25
+ if (v === null || v === undefined || typeof v === 'boolean')
26
+ return null;
27
+ const n = Number(v);
28
+ return Number.isFinite(n) && n > 0 && n < 1 ? n : null;
29
+ }
30
+ function shouldWarn(used, maxTotal, ratio = 0.8) {
31
+ const r = normalizeWarnRatio(ratio);
32
+ if (r === null || !Number.isFinite(used) || !Number.isFinite(maxTotal) || maxTotal <= 0)
33
+ return false;
34
+ return used / maxTotal >= r;
35
+ }
36
+ /** 该工具的调用是否值得退还一次迭代 */
37
+ function isRefundableTool(toolName) {
38
+ return exports.REFUNDABLE_TOOLS.has(String(toolName ?? '').trim());
39
+ }
40
+ class IterationBudget {
41
+ maxTotal;
42
+ _used = 0;
43
+ _refunded = 0;
44
+ constructor(maxTotal) {
45
+ this.maxTotal = Number.isFinite(maxTotal) && maxTotal > 0 ? Math.floor(maxTotal) : Number.POSITIVE_INFINITY;
46
+ }
47
+ /** 尝试消费一次; 返回 false = 预算用尽 (调用方据此收尾) */
48
+ consume() {
49
+ if (this._used >= this.maxTotal)
50
+ return false;
51
+ this._used += 1;
52
+ return true;
53
+ }
54
+ /** 归还一次 (批处理工具调用后) —— 这是"奖励批处理"的落点 */
55
+ refund() {
56
+ if (this._used > 0) {
57
+ this._used -= 1;
58
+ this._refunded += 1;
59
+ }
60
+ }
61
+ get used() { return this._used; }
62
+ get refunded() { return this._refunded; }
63
+ get remaining() { return Math.max(0, this.maxTotal - this._used); }
64
+ get depleted() { return this._used >= this.maxTotal; }
65
+ warn(ratio = 0.8) { return shouldWarn(this._used, this.maxTotal, ratio); }
66
+ /** 供 UI/日志: `已用/上限 (退还 N 次)` */
67
+ describe() {
68
+ const cap = Number.isFinite(this.maxTotal) ? String(this.maxTotal) : '∞';
69
+ return `${this._used}/${cap}${this._refunded ? ` (退还 ${this._refunded} 次)` : ''}`;
70
+ }
71
+ }
72
+ exports.IterationBudget = IterationBudget;
73
+ //# sourceMappingURL=iteration-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iteration-budget.js","sourceRoot":"","sources":["../../../src/agents/iteration-budget.ts"],"names":[],"mappings":";;;;;;;AAcA;;;GAGG;AACU,QAAA,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AAI/E,qBAA4B,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC9D,MAAM,GAAG,GAAG,CAAC,CAAqB,EAAE,CAAS,EAAE,EAAE;QAC/C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC;IACF,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,sBAAsB,EAAE,GAAG,CAAC;QAC5C,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,+BAA+B,EAAE,EAAE,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,uDAAuD;AACvD,4BAAmC,CAAU;IAC3C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,oBAA2B,IAAY,EAAE,QAAgB,EAAE,KAAK,GAAG,GAAG;IACpE,MAAM,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtG,OAAO,IAAI,GAAG,QAAQ,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,uBAAuB;AACvB,0BAAiC,QAAiB;IAChD,OAAO,QAAA,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;IACW,QAAQ,CAAS;IAClB,KAAK,GAAG,CAAC,CAAC;IACV,SAAS,GAAG,CAAC,CAAC;IAEtB,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC9G,CAAC;IAED,wCAAwC;IACxC,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9C,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;YAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QAAC,CAAC;IAC/D,CAAC;IAED,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,QAAQ,KAAc,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,GAAG,GAAG,IAAa,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnF,gCAAgC;IAChC,QAAQ;QACN,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACzE,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;CACF"}
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SINK_SKILL_NAME = exports.LESSON_SECTION = exports.LESSON_MATCH_MIN_SCORE = void 0;
7
+ exports.tokens = tokens;
8
+ exports.scoreLessonAgainstSkill = scoreLessonAgainstSkill;
9
+ exports.decideLessonSink = decideLessonSink;
10
+ exports.mergeLessonIntoBody = mergeLessonIntoBody;
11
+ exports.applyLessonToSkill = applyLessonToSkill;
12
+ exports.skillsFromDirs = skillsFromDirs;
13
+ exports.logLessonSuggestions = logLessonSuggestions;
14
+ exports.sinkSkillDir = sinkSkillDir;
15
+ exports.ensureSinkSkill = ensureSinkSkill;
16
+ exports.routeLessonToSkill = routeLessonToSkill;
17
+ /**
18
+ * 教训 ⇒ 技能 (2026-10-01, 用户: 「skills 教训学习, bolloon 有吗
19
+ * 查下来的事实: bolloon **三块都有** —— 回合后自审(`experience-review.ts` ✓) · 技能读写(`skill-loader`/`skill-writer` ✓) ·
20
+ * 技能库(`~/.bolloon/skills/`, 实测 1301 个 ✓) —— **但中间没有线** ✗: 复盘产出的教训只落到
21
+ * `~/.bolloon/experience/<类>.md` ✗, **从不写回技能** ✗ ⇒ 教训与技能库是两座孤岛。
22
+ * 抄来的三条纪律(来自运行时那套的回合后自审流程 ✓, 用 bolloon 自己的话写):
23
+ * ① **先找已有的**(umbrella)再考虑新建 —— 1301 个技能已够碎, 再自动新建只会更碎 ✗;
24
+ * ② **读后写**: 要改某个 SKILL.md 必须先把它读进来(读不到就**不写**, 绝不盲改 ✗);
25
+ * ③ **匹配不够强就不写技能**, 只留经验条目(宁缺勿碎 ✓)。
26
+ * 纯函数为主 ⇒ 可测。
27
+ */
28
+ const node_fs_1 = __importDefault(require("node:fs"));
29
+ const node_path_1 = __importDefault(require("node:path"));
30
+ const node_os_1 = __importDefault(require("node:os"));
31
+ /** 匹配强度门槛: 重叠词数 ≥ 这个值才算"就是讲这件事的技能" */
32
+ exports.LESSON_MATCH_MIN_SCORE = 3;
33
+ const STOP = new Set(['the', 'and', 'for', 'with', 'use', 'when', 'skill', '技能', '的', '和', '与', '在', '是', '要', '不', '有']);
34
+ /** 粗略分词: 英文按词、中文按 2 字滑窗 —— 够用且便宜(不引分词库 ✓) */
35
+ function tokens(text) {
36
+ const s = String(text ?? '').toLowerCase();
37
+ const out = new Set();
38
+ for (const w of s.match(/[a-z0-9_-]{2,}/g) || [])
39
+ if (!STOP.has(w))
40
+ out.add(w);
41
+ const cjk = s.replace(/[^\u4e00-\u9fa5]/g, ' ');
42
+ // 2026-10-01 校准: 中文用 **3 字**窗口 —— 2 字窗口在 1300 个技能里误命中率太高(实测 "提交" 撞无关技能 ✗)
43
+ for (const run of cjk.split(/\s+/))
44
+ for (let i = 0; i + 3 <= run.length; i++)
45
+ out.add(run.slice(i, i + 3));
46
+ return [...out];
47
+ }
48
+ function scoreLessonAgainstSkill(lesson, skill) {
49
+ const lt = new Set(tokens(`${lesson.title} ${lesson.body} ${lesson.klass || ''}`));
50
+ const st = new Set(tokens(`${skill.name} ${skill.description || ''}`));
51
+ let hit = 0;
52
+ for (const t of st)
53
+ if (lt.has(t))
54
+ hit++;
55
+ // 名字里直接出现也算强信号
56
+ if (skill.name && String(lesson.title).toLowerCase().includes(skill.name.toLowerCase()))
57
+ hit += 2;
58
+ return hit;
59
+ }
60
+ /** 决定这条教训该进技能还是只留经验 (③ 匹配不够强就不写技能) */
61
+ function decideLessonSink(lesson, skills) {
62
+ let best;
63
+ let bestScore = 0;
64
+ for (const s of skills) {
65
+ if (!s.file)
66
+ continue; // 没路径的(跨库加载)不参与改写
67
+ const sc = scoreLessonAgainstSkill(lesson, s);
68
+ if (sc > bestScore) {
69
+ bestScore = sc;
70
+ best = s;
71
+ }
72
+ }
73
+ const suggestions = skills
74
+ .map((s) => ({ name: s.name, score: scoreLessonAgainstSkill(lesson, s) }))
75
+ .filter((x) => x.score > 0).sort((a, b) => b.score - a.score).slice(0, 3);
76
+ // 实测校准(2026-10-01): 拿今天 4 条真实教训去撞用户真实的 1300 个技能, 最高分只有 2, 且 top 命中是**瞎的**
77
+ // ⇒ 说明关键词匹配**不足以可靠地自动改技能** ✗ ⇒ 规矩: 只有**强命中**(同名/描述高度重合, 分数够高)才自动写技能 ✓,
78
+ // 否则只留经验 + 附候选, 由人/智能体决定 ✓(宁缺勿碎 ✓)。
79
+ if (best && bestScore >= exports.LESSON_MATCH_MIN_SCORE) {
80
+ return { kind: 'skill', skill: best, score: bestScore, suggestions, reason: `强命中已有技能 ${best.name} (score=${bestScore})` };
81
+ }
82
+ return {
83
+ kind: 'experience-only', suggestions,
84
+ reason: `没有足够强的匹配 (最高 score=${bestScore} < ${exports.LESSON_MATCH_MIN_SCORE}) ⇒ 只留经验, 不自动改写技能(实测自动匹配会瞎撞 ⇒ 宁缺勿碎 ✓)`,
85
+ };
86
+ }
87
+ exports.LESSON_SECTION = '## 教训 (自动沉淀)';
88
+ /**
89
+ * 把一条教训**并进** SKILL.md 正文: 已有同名条目 ⇒ **更新那一条**(不重复堆 ✓); 否则追加。
90
+ */
91
+ function mergeLessonIntoBody(body, lesson) {
92
+ const src = String(body ?? '');
93
+ const line = `- **${lesson.title.trim()}**: ${lesson.body.trim().replace(/\s+/g, ' ')}`;
94
+ const esc = lesson.title.trim().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
95
+ const re = new RegExp(`^- \\*\\*${esc}\\*\\*:[^\\n]*$`, 'm');
96
+ if (re.test(src))
97
+ return { body: src.replace(re, line), updated: true };
98
+ if (src.includes(exports.LESSON_SECTION))
99
+ return { body: `${src.replace(/\s+$/, '')}\n${line}\n`, updated: false };
100
+ return { body: `${src.replace(/\s+$/, '')}\n\n${exports.LESSON_SECTION}\n${line}\n`, updated: false };
101
+ }
102
+ /**
103
+ * 落盘: **读后写**(① 读不到就不写 ✓) + 同标题更新(不堆 ✓)。返回实际动作, 便于日志与测试。
104
+ */
105
+ function applyLessonToSkill(skill, lesson) {
106
+ const file = skill?.file;
107
+ if (!file)
108
+ return { patched: false, reason: '技能没有文件路径(只读库), 不改写' };
109
+ if (!node_fs_1.default.existsSync(file))
110
+ return { patched: false, reason: `找不到 ${file} (读后写: 读不到就不写)` };
111
+ try {
112
+ const body = node_fs_1.default.readFileSync(file, 'utf-8');
113
+ if (!body.trim())
114
+ return { patched: false, reason: '文件是空的, 不盲改' };
115
+ const merged = mergeLessonIntoBody(body, lesson);
116
+ node_fs_1.default.writeFileSync(file, merged.body, 'utf-8');
117
+ return { patched: true, file, updated: merged.updated };
118
+ }
119
+ catch (e) {
120
+ return { patched: false, reason: `写入失败: ${String(e?.message || e).slice(0, 80)}` };
121
+ }
122
+ }
123
+ /** 从一个技能目录收 name/description/file (只读 SKILL.md 头部, 便宜 ✓) */
124
+ function skillsFromDirs(dirs) {
125
+ const out = [];
126
+ for (const dir of dirs) {
127
+ try {
128
+ if (!node_fs_1.default.existsSync(dir))
129
+ continue;
130
+ for (const name of node_fs_1.default.readdirSync(dir)) {
131
+ const file = node_path_1.default.join(dir, name, 'SKILL.md');
132
+ try {
133
+ if (!node_fs_1.default.existsSync(file))
134
+ continue;
135
+ const head = node_fs_1.default.readFileSync(file, 'utf-8').slice(0, 1200);
136
+ const desc = /description:\s*(.+)/.exec(head);
137
+ out.push({ name, description: desc ? desc[1].trim().replace(/^[>\s]+/, '').slice(0, 200) : '', file });
138
+ }
139
+ catch { /* 单个技能读失败不影响其它 */ }
140
+ }
141
+ }
142
+ catch { /* 目录读失败跳过 */ }
143
+ }
144
+ return out;
145
+ }
146
+ /**
147
+ * 把"这条教训可以沉淀进哪些技能"记到日志文件给人/智能体看
148
+ * (实测关键词匹配不足以自动改技能 ⇒ **不替人决定** ✓; 但候选要留痕 ⇒ 写 `~/.bolloon/logs/lesson-suggestions.jsonl` ✓)。
149
+ */
150
+ function logLessonSuggestions(lesson, decision, home = node_os_1.default.homedir()) {
151
+ try {
152
+ const dir = node_path_1.default.join(home, '.bolloon', 'logs');
153
+ node_fs_1.default.mkdirSync(dir, { recursive: true });
154
+ const file = node_path_1.default.join(dir, 'lesson-suggestions.jsonl');
155
+ try {
156
+ if (node_fs_1.default.existsSync(file) && node_fs_1.default.readFileSync(file, 'utf-8').split('\n').length > 300)
157
+ node_fs_1.default.writeFileSync(file, '', 'utf-8');
158
+ }
159
+ catch { /* 忽略 */ }
160
+ node_fs_1.default.appendFileSync(file, JSON.stringify({
161
+ ts: new Date().toISOString(), title: lesson.title, kind: decision.kind,
162
+ reason: decision.reason, suggestions: decision.suggestions,
163
+ }) + '\n', 'utf-8');
164
+ }
165
+ catch { /* 观测失败绝不影响复盘 */ }
166
+ }
167
+ // ─────────────────────────────────────────────────────────────────────────────
168
+ // 2026-10-01 (用户: 「教训…改为都进去进入技能和判断力库」):
169
+ // 原先我给"弱命中"只记候选、不写技能 ✗ —— 用户要求**都进技能库** ✓。
170
+ // 但实测(真教训撞真 1300 技能, 最高分 2 且 top 命中是瞎的)说明**瞎匹配会写错地方** ✗ ⇒ 折中:
171
+ // · 强命中 ⇒ 写进**那个**技能 ✓;
172
+ // · 弱命中 ⇒ 写进一个统一的沉淀技能 `lessons-learned`(按类分节 ✓ + 记下候选技能供人挑拣 ✓)
173
+ // ⇒ **每条教训都进技能库** ✓, 且不污染无关技能 ✓, 也便于人工管理(一个文件看全 ✓)。
174
+ // ─────────────────────────────────────────────────────────────────────────────
175
+ exports.SINK_SKILL_NAME = 'lessons-learned';
176
+ /** 沉淀技能的目录 (用户级技能库, 与 skill-writer 同一处) */
177
+ function sinkSkillDir(home = node_os_1.default.homedir()) {
178
+ return node_path_1.default.join(home, '.bolloon', 'skills', exports.SINK_SKILL_NAME);
179
+ }
180
+ /**
181
+ * 确保沉淀技能存在 (**读后写**: 存在就不动它 ✓; 不存在才创建 ✓)。
182
+ * 返回 SKILL.md 路径。
183
+ */
184
+ function ensureSinkSkill(home = node_os_1.default.homedir()) {
185
+ const dir = sinkSkillDir(home);
186
+ const file = node_path_1.default.join(dir, 'SKILL.md');
187
+ if (node_fs_1.default.existsSync(file))
188
+ return { file, created: false };
189
+ node_fs_1.default.mkdirSync(dir, { recursive: true });
190
+ node_fs_1.default.writeFileSync(file, [
191
+ '---',
192
+ `name: ${exports.SINK_SKILL_NAME}`,
193
+ 'description: 用于**沉淀学到的教训**: 自动把"可复用的规矩/踩过的坑"按类收在这里; 每类一节, 同标题更新不重复堆。',
194
+ '---',
195
+ '',
196
+ `# ${exports.SINK_SKILL_NAME}`,
197
+ '',
198
+ '自动沉淀的教训(每条: **规矩** + 为什么)。同标题 ⇒ 更新那一条, 不重复堆。',
199
+ '若某条教训明显属于某个专门技能(见条目里"候选"), 人工把它挪过去更合适。',
200
+ '',
201
+ ].join('\n'), 'utf-8');
202
+ return { file, created: true };
203
+ }
204
+ /**
205
+ * 一条教训的**唯一出口**: 强命中 ⇒ 写那个技能; 否则 ⇒ 写沉淀技能。**保证每条都进技能库** ✓。
206
+ */
207
+ function routeLessonToSkill(lesson, skills, home = node_os_1.default.homedir()) {
208
+ const d = decideLessonSink(lesson, skills);
209
+ if (d.kind === 'skill' && d.skill?.file) {
210
+ const r = applyLessonToSkill(d.skill, lesson);
211
+ if (r.patched) {
212
+ return { skill: { name: d.skill.name, file: r.file, patched: true, created: false, updated: r.updated }, reason: d.reason, candidates: d.suggestions };
213
+ }
214
+ // 命中了但写不进去(文件读不到/空) ⇒ 退到沉淀技能, 保证"都进去" ✓
215
+ }
216
+ const sink = ensureSinkSkill(home);
217
+ const body = node_fs_1.default.readFileSync(sink.file, 'utf-8');
218
+ const withCandidates = d.suggestions.length
219
+ ? { ...lesson, body: `${lesson.body} (候选技能: ${d.suggestions.map((s) => `${s.name}(${s.score})`).join(', ')})` }
220
+ : lesson;
221
+ const r = applyLessonToSkill({ name: exports.SINK_SKILL_NAME, file: sink.file }, withCandidates);
222
+ return {
223
+ skill: { name: exports.SINK_SKILL_NAME, file: sink.file, patched: r.patched, created: sink.created, updated: r.updated },
224
+ reason: `${d.reason} ⇒ 收进沉淀技能 ${exports.SINK_SKILL_NAME}`,
225
+ candidates: d.suggestions,
226
+ };
227
+ }
228
+ //# sourceMappingURL=lesson-to-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lesson-to-skill.js","sourceRoot":"","sources":["../../../src/agents/lesson-to-skill.ts"],"names":[],"mappings":"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"}