@bolloon/bolloon-agent 0.5.4 → 0.6.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.
- package/dist/agents/agent-identity-store.js +41 -5
- package/dist/agents/background-notices.js +124 -0
- package/dist/agents/channel-identity.js +54 -0
- package/dist/agents/code-write-gate.js +47 -0
- package/dist/agents/deny-pipeline.js +11 -2
- package/dist/agents/egress-sanitize.js +69 -0
- package/dist/agents/error-classifier.js +67 -5
- package/dist/agents/experience-review.js +226 -0
- package/dist/agents/gateway-group.js +153 -18
- package/dist/agents/iteration-budget.js +64 -0
- package/dist/agents/lesson-to-skill.js +211 -0
- package/dist/agents/managed-services.js +64 -0
- package/dist/agents/parse-tool-call.js +43 -32
- package/dist/agents/pi-sdk-session-factory.js +36 -3
- package/dist/agents/pi-sdk-session-manager.js +72 -3
- package/dist/agents/pi-sdk-tools.js +201 -32
- package/dist/agents/pi-sdk.js +798 -206
- package/dist/agents/plan-store.js +36 -0
- package/dist/agents/process-runner.js +64 -2
- package/dist/agents/run-context.js +20 -0
- package/dist/agents/runner-resolver.js +2 -1
- package/dist/agents/shell-guard.js +109 -13
- package/dist/agents/skill-health.js +90 -0
- package/dist/agents/skill-ledger.js +129 -0
- package/dist/agents/tool-loop-guard.js +303 -0
- package/dist/agents/tool-path-args.js +53 -0
- package/dist/agents/tool-result-gate.js +50 -0
- package/dist/agents/tool-subset.js +109 -0
- package/dist/agents/tool-telemetry.js +97 -0
- package/dist/bootstrap/context-collector.js +37 -7
- package/dist/bootstrap/lifecycle-hooks.js +12 -3
- package/dist/bootstrap/persona-init.js +174 -0
- package/dist/bootstrap/persona-loader.js +5 -1
- package/dist/cli/ink-app.js +153 -6
- package/dist/cli/input-paste.js +218 -0
- package/dist/cli/loading-tui.js +3 -1
- package/dist/cli/log-gate.js +7 -0
- package/dist/cli/mention-data.js +30 -0
- package/dist/cli/reasoning-view.js +103 -0
- package/dist/cli/startup-notice.js +25 -0
- package/dist/cli/status-segments.js +87 -2
- package/dist/cli/trace-line.js +54 -0
- package/dist/context-compaction/auto-compact.js +37 -2
- package/dist/electron-build/agents/agent-identity-store.js +43 -5
- package/dist/electron-build/agents/agent-identity-store.js.map +1 -1
- package/dist/electron-build/agents/background-notices.js +138 -0
- package/dist/electron-build/agents/background-notices.js.map +1 -0
- package/dist/electron-build/agents/channel-identity.js +64 -0
- package/dist/electron-build/agents/channel-identity.js.map +1 -0
- package/dist/electron-build/agents/code-write-gate.js +55 -0
- package/dist/electron-build/agents/code-write-gate.js.map +1 -0
- package/dist/electron-build/agents/deny-pipeline.js +11 -2
- package/dist/electron-build/agents/deny-pipeline.js.map +1 -1
- package/dist/electron-build/agents/egress-sanitize.js +76 -0
- package/dist/electron-build/agents/egress-sanitize.js.map +1 -0
- package/dist/electron-build/agents/error-classifier.js +68 -5
- package/dist/electron-build/agents/error-classifier.js.map +1 -1
- package/dist/electron-build/agents/experience-review.js +243 -0
- package/dist/electron-build/agents/experience-review.js.map +1 -0
- package/dist/electron-build/agents/iteration-budget.js +73 -0
- package/dist/electron-build/agents/iteration-budget.js.map +1 -0
- package/dist/electron-build/agents/lesson-to-skill.js +228 -0
- package/dist/electron-build/agents/lesson-to-skill.js.map +1 -0
- package/dist/electron-build/agents/managed-services.js +69 -0
- package/dist/electron-build/agents/managed-services.js.map +1 -0
- package/dist/electron-build/agents/parse-tool-call.js +43 -32
- package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-factory.js +36 -3
- package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-manager.js +75 -3
- package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-tools.js +200 -31
- package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +799 -206
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/plan-store.js +37 -0
- package/dist/electron-build/agents/plan-store.js.map +1 -1
- package/dist/electron-build/agents/process-runner.js +71 -2
- package/dist/electron-build/agents/process-runner.js.map +1 -1
- package/dist/electron-build/agents/run-context.js +24 -0
- package/dist/electron-build/agents/run-context.js.map +1 -0
- package/dist/electron-build/agents/runner-resolver.js +2 -1
- package/dist/electron-build/agents/runner-resolver.js.map +1 -1
- package/dist/electron-build/agents/shell-guard.js +110 -14
- package/dist/electron-build/agents/shell-guard.js.map +1 -1
- package/dist/electron-build/agents/skill-health.js +103 -0
- package/dist/electron-build/agents/skill-health.js.map +1 -0
- package/dist/electron-build/agents/skill-ledger.js +146 -0
- package/dist/electron-build/agents/skill-ledger.js.map +1 -0
- package/dist/electron-build/agents/tool-loop-guard.js +319 -0
- package/dist/electron-build/agents/tool-loop-guard.js.map +1 -0
- package/dist/electron-build/agents/tool-path-args.js +63 -0
- package/dist/electron-build/agents/tool-path-args.js.map +1 -0
- package/dist/electron-build/agents/tool-result-gate.js +59 -0
- package/dist/electron-build/agents/tool-result-gate.js.map +1 -0
- package/dist/electron-build/agents/tool-subset.js +116 -0
- package/dist/electron-build/agents/tool-subset.js.map +1 -0
- package/dist/electron-build/agents/tool-telemetry.js +108 -0
- package/dist/electron-build/agents/tool-telemetry.js.map +1 -0
- package/dist/electron-build/bootstrap/context-collector.js +38 -7
- package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
- package/dist/electron-build/bootstrap/lifecycle-hooks.js +12 -3
- package/dist/electron-build/bootstrap/lifecycle-hooks.js.map +1 -1
- package/dist/electron-build/bootstrap/persona-init.js +216 -0
- package/dist/electron-build/bootstrap/persona-init.js.map +1 -0
- package/dist/electron-build/bootstrap/persona-loader.js +5 -1
- package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
- package/dist/electron-build/context-compaction/auto-compact.js +38 -2
- package/dist/electron-build/context-compaction/auto-compact.js.map +1 -1
- package/dist/electron-build/external-engines/delegate.js +22 -0
- package/dist/electron-build/external-engines/delegate.js.map +1 -1
- package/dist/electron-build/kernel/channel-actor.js +314 -0
- package/dist/electron-build/kernel/channel-actor.js.map +1 -0
- package/dist/electron-build/orbitdb/cid-database.js +55 -0
- package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
- package/dist/electron-build/orbitdb/ipfs-node.js +36 -11
- package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -1
- package/dist/electron-build/web/server-storage.js +26 -5
- package/dist/electron-build/web/server-storage.js.map +1 -1
- package/dist/external-engines/delegate.js +21 -0
- package/dist/index.js +526 -95
- package/dist/kernel/channel-actor.js +297 -0
- package/dist/kernel/control.js +95 -0
- package/dist/kernel/gate-scan.js +1036 -0
- package/dist/kernel/model-runtime.js +472 -0
- package/dist/kernel/plan-channel-actor.js +298 -0
- package/dist/kernel/plan-constraint.js +165 -0
- package/dist/kernel/plan-deletion.js +32 -0
- package/dist/kernel/plan-modelruntime.js +60 -0
- package/dist/kernel/plan-runcontext.js +163 -0
- package/dist/kernel/plan.js +153 -0
- package/dist/kernel/roster.js +242 -0
- package/dist/orbitdb/cid-database.js +55 -0
- package/dist/orbitdb/event-index.js +370 -0
- package/dist/orbitdb/event-query.js +131 -0
- package/dist/orbitdb/event-shell.js +510 -0
- package/dist/orbitdb/group-access.js +381 -0
- package/dist/orbitdb/group-shards.js +140 -0
- package/dist/orbitdb/ipfs-node.js +36 -11
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/client.js +4 -2
- package/dist/web/mobile-core.js +7762 -6289
- package/dist/web/routes-mobile-tasks.js +2 -1
- package/dist/web/routes-tasks.js +5 -1
- package/dist/web/server-storage.js +26 -5
- package/dist/web/server.js +60 -18
- package/dist/web/sw.js +1 -1
- package/dist/web/ui/message-renderer.js +473 -29
- package/dist/web/ui/step-timeline.js +13 -12
- package/package.json +2 -1
- package/scripts/build-web.ts +74 -1
- package/dist/constraint-runtime/_archive_helper.d.ts +0 -1
- package/dist/constraint-runtime/_archive_helper.js +0 -9
- package/dist/constraint-runtime/assistant/index.d.ts +0 -11
- package/dist/constraint-runtime/assistant/index.js +0 -12
- package/dist/constraint-runtime/bootstrap/index.d.ts +0 -11
- package/dist/constraint-runtime/bootstrap/index.js +0 -12
- package/dist/constraint-runtime/bridge/index.d.ts +0 -11
- package/dist/constraint-runtime/bridge/index.js +0 -12
- package/dist/constraint-runtime/buddy/index.d.ts +0 -11
- package/dist/constraint-runtime/buddy/index.js +0 -12
- package/dist/constraint-runtime/cli/index.d.ts +0 -11
- package/dist/constraint-runtime/cli/index.js +0 -12
- package/dist/constraint-runtime/components/index.d.ts +0 -11
- package/dist/constraint-runtime/components/index.js +0 -12
- package/dist/constraint-runtime/constants/index.d.ts +0 -11
- package/dist/constraint-runtime/constants/index.js +0 -12
- package/dist/constraint-runtime/coordinator/index.d.ts +0 -11
- package/dist/constraint-runtime/coordinator/index.js +0 -12
- package/dist/constraint-runtime/cost_hook.d.ts +0 -2
- package/dist/constraint-runtime/cost_hook.js +0 -4
- package/dist/constraint-runtime/entrypoints/index.d.ts +0 -11
- package/dist/constraint-runtime/entrypoints/index.js +0 -12
- package/dist/constraint-runtime/execution_registry.d.ts +0 -20
- package/dist/constraint-runtime/execution_registry.js +0 -44
- package/dist/constraint-runtime/hooks/index.d.ts +0 -11
- package/dist/constraint-runtime/hooks/index.js +0 -12
- package/dist/constraint-runtime/ink.d.ts +0 -1
- package/dist/constraint-runtime/ink.js +0 -4
- package/dist/constraint-runtime/keybindings/index.d.ts +0 -11
- package/dist/constraint-runtime/keybindings/index.js +0 -12
- package/dist/constraint-runtime/memdir/index.d.ts +0 -11
- package/dist/constraint-runtime/memdir/index.js +0 -12
- package/dist/constraint-runtime/migrations/index.d.ts +0 -11
- package/dist/constraint-runtime/migrations/index.js +0 -12
- package/dist/constraint-runtime/moreright/index.d.ts +0 -11
- package/dist/constraint-runtime/moreright/index.js +0 -12
- package/dist/constraint-runtime/native_ts/index.d.ts +0 -11
- package/dist/constraint-runtime/native_ts/index.js +0 -12
- package/dist/constraint-runtime/output_styles/index.d.ts +0 -11
- package/dist/constraint-runtime/output_styles/index.js +0 -12
- package/dist/constraint-runtime/plugins/index.d.ts +0 -11
- package/dist/constraint-runtime/plugins/index.js +0 -12
- package/dist/constraint-runtime/port_manifest.d.ts +0 -7
- package/dist/constraint-runtime/port_manifest.js +0 -11
- package/dist/constraint-runtime/query.d.ts +0 -6
- package/dist/constraint-runtime/query.js +0 -1
- package/dist/constraint-runtime/remote/index.d.ts +0 -11
- package/dist/constraint-runtime/remote/index.js +0 -12
- package/dist/constraint-runtime/schemas/index.d.ts +0 -11
- package/dist/constraint-runtime/schemas/index.js +0 -12
- package/dist/constraint-runtime/screens/index.d.ts +0 -11
- package/dist/constraint-runtime/screens/index.js +0 -12
- package/dist/constraint-runtime/server/index.d.ts +0 -11
- package/dist/constraint-runtime/server/index.js +0 -12
- package/dist/constraint-runtime/services/index.d.ts +0 -11
- package/dist/constraint-runtime/services/index.js +0 -12
- package/dist/constraint-runtime/state/index.d.ts +0 -11
- package/dist/constraint-runtime/state/index.js +0 -12
- package/dist/constraint-runtime/system_init.d.ts +0 -1
- package/dist/constraint-runtime/system_init.js +0 -20
- package/dist/constraint-runtime/types/index.d.ts +0 -11
- package/dist/constraint-runtime/types/index.js +0 -12
- package/dist/constraint-runtime/upstream_proxy/index.d.ts +0 -11
- package/dist/constraint-runtime/upstream_proxy/index.js +0 -12
- package/dist/constraint-runtime/utils/index.d.ts +0 -11
- package/dist/constraint-runtime/utils/index.js +0 -12
- package/dist/constraint-runtime/vim/index.d.ts +0 -11
- package/dist/constraint-runtime/vim/index.js +0 -12
- package/dist/constraint-runtime/voice/index.d.ts +0 -11
- package/dist/constraint-runtime/voice/index.js +0 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-classifier.js","sourceRoot":"","sources":["../../../src/agents/error-classifier.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG
|
|
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":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;GAYG;AACH,sDAAyB;AACzB,0DAA6B;AAC7B,sDAAyB;AAEZ,QAAA,mBAAmB,GAAG,YAAY,CAAC;AAChD,6EAA6E;AAChE,QAAA,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAWtD,uBAA8B,IAAI,GAAG,iBAAE,CAAC,OAAO,EAAE;IAC/C,OAAO,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,QAAA,mBAAmB,CAAC,CAAC;AAC1D,CAAC;AAED,oCAAoC;AACpC,uBAA8B,CAAU;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACtG,OAAO,CAAC,IAAI,SAAS,CAAC;AACxB,CAAC;AAED,0CAA0C;AAC1C,uBAA8B,CAAU;IACtC,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,sBACE,KAAa,EACb,QAA4B,EAC5B,aAAa,GAAW,QAAA,uBAAuB;IAE/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAU,wBAAwB;IACzF,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,YAAY;IACvF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAI,wBAAwB;IACnG,OAAO,KAAK,GAAG,QAAQ,IAAI,aAAa,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,0BACE,KAAa,EACb,QAA4B,EAC5B,OAA2B,EAC3B,GAAW,EACX,aAAa,GAAW,QAAA,uBAAuB;IAE/C,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,CAAiB,gBAAgB;IACzE,OAAO,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAK,wBAAwB;AACnF,CAAC;AAED,iDAAiD;AACjD,6BAAoC,IAAI,GAAG,iBAAE,CAAC,OAAO,EAAE;IACrD,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,iBAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,WAAW,CAAC;QACtC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,iBAAE,CAAC,YAAY,CAAC,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxF,OAAO,KAAK,CAAC,KAAK,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,2BAAkC,WAAmB,EAAE,aAAqB;IAC1E,OAAO;QACL,4CAA4C;QAC5C,EAAE;QACF,oBAAoB;QACpB,aAAa;QACb,EAAE;QACF,YAAY;QACZ,KAAK;QACL,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QACxC,KAAK;QACL,EAAE;QACF,WAAW;QACX,oEAAoE;QACpE,yDAAyD;QACzD,kEAAkE;QAClE,oDAAoD;QACpD,8DAA8D;QAC9D,EAAE;QACF,oBAAoB;QACpB,4FAA4F;KAC7F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,mDAAmD;AACnD,6BAAoC,IAAY;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACnC,oEAAoE;IACpE,oEAAoE;IACpE,mDAAmD;IACnD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,GAAG,GAAG,4CAA4C,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;eAClE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,4CAA4C,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC;YAC7F,MAAM,IAAI,GAAG,6DAA6D,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvH,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;gBAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAS,CAAC;QAC7H,CAAC;QACD,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QACvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACnG,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACjF,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAG,YAAY;QACvF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,yBAAgC,CAAiB,EAAE,IAAI,GAAG,iBAAE,CAAC,OAAO,EAAE,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IAEvG,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzE,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,iBAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YAAC,GAAG,GAAG,iBAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,GAAG,GAAG,EAAE,CAAC;QAAC,CAAC;QACjE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,mDAAmD,CAAC;QACzH,2EAA2E;QAC3E,+DAA+D;QAC/D,uCAAuC;QACvC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,IAAY,EAAE,IAAY,EAAU,EAAE,CAChE,MAAM,CAAC,cAAc,IAAI,SAAS,MAAM,SAAS,IAAI,IAAI,CAAC;QAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzF,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAc,yBAAyB;YAC1E,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3C,iBAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;YACrG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,iBAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QACrG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAGD;;;;;;GAMG;AACI,KAAK,8BAA8B,IAYzC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,iBAAE,CAAC,OAAO,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAY,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAC1I,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAC1F,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,mDAAmD;QACnD,8DAA8D;QAC9D,mEAAmE;QACnE,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,MAAM,CAAC;QAC9E,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YACjB,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;SAC1F,CAAC,CAAC;QACH,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YAC1B,GAAG,CAAC,QAAQ,aAAa,4BAA4B,CAAC,CAAC;YACvD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACrE,CAAC;QACD,MAAM,CAAC,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;YAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QAChG,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,GAAG,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,mBAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC;gBAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QACvG,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IAC5H,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,GAAG,CAAC,2BAA2B,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -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":"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"}
|
|
@@ -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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"}
|