ppxans-harness 2.6.0 → 3.2.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/LICENSE +201 -201
- package/README.md +218 -262
- package/bin/ppx-channels.js +2 -2
- package/bin/ppx-serve.js +5 -5
- package/bin/ppx-setup.js +124 -0
- package/bin/ppx-web.js +140 -0
- package/bin/ppx.js +2 -2
- package/config/identity.md +6 -6
- package/config/ishiki.md +16 -16
- package/config/ppx.json +6 -124
- package/config/ppx.json.example +143 -0
- package/package.json +16 -6
- package/skills/.usage.json +6 -0
- package/skills/agent-professional-training/SKILL.md +94 -0
- package/skills/brainstorm/SKILL.md +24 -0
- package/skills/cupid-lover-comms/SKILL.md +37 -0
- package/skills/debug/SKILL.md +26 -0
- package/skills/plan/SKILL.md +25 -0
- package/skills/ponytail/SKILL.md +25 -0
- package/skills/ppx-memory/SKILL.md +91 -0
- package/skills/ppx-memory/scripts/cli.js +192 -0
- package/skills/ppx-memory/scripts/experience.js +133 -0
- package/skills/ppx-memory/scripts/fact-store.js +842 -0
- package/skills/ppx-memory/scripts/l0.js +52 -0
- package/skills/ppx-memory/scripts/l2.js +146 -0
- package/skills/ppx-memory/scripts/l3.js +112 -0
- package/skills/ppx-memory/scripts/memory-ticker.js +238 -0
- package/skills/ppx-memory/scripts/pii.js +42 -0
- package/skills/ppx-memory/scripts/schema.js +80 -0
- package/skills/ppx-memory/scripts/session.js +398 -0
- package/skills/ppx-memory/scripts/similarity.js +43 -0
- package/skills/ppx-memory/scripts/store.js +116 -0
- package/skills/ppx-memory/scripts/wal.js +38 -0
- package/skills/ppx-selfheal/SKILL.md +24 -0
- package/skills/ppx-selfheal/scripts/cli.js +80 -0
- package/skills/ppx-selfheal/scripts/healer.js +184 -0
- package/skills/ppx-selfheal/scripts/logger.js +17 -0
- package/skills/ppx-selfheal/scripts/store.js +116 -0
- package/skills/prompt-depth-kit/SKILL.md +28 -0
- package/skills/session-naming/SKILL.md +36 -0
- package/skills/verify/SKILL.md +25 -0
- package/src/agent/index.js +1340 -717
- package/src/agent/prompts.js +46 -2
- package/src/aml-server.js +197 -151
- package/src/ans/eviction.js +123 -143
- package/src/ans/guard.js +159 -120
- package/src/ans/lifecycle.js +96 -93
- package/src/ans/proactive.js +112 -129
- package/src/ans/reward.js +95 -111
- package/src/ans/values.js +15 -15
- package/src/audit/audit-chain.js +43 -7
- package/src/audit/verifier.js +157 -120
- package/src/bus/circuit-breaker.js +9 -1
- package/src/bus/runtime-bus.js +107 -93
- package/src/channels/base.js +57 -34
- package/src/channels/feishu.js +118 -126
- package/src/channels/http.js +1090 -651
- package/src/channels/index.js +111 -110
- package/src/channels/log.js +29 -29
- package/src/channels/wechat-crypto.js +73 -74
- package/src/channels/wechat.js +191 -197
- package/src/channels/workspace.js +94 -0
- package/src/channels-cli.js +126 -124
- package/src/cli.js +129 -120
- package/src/commands/index.js +142 -0
- package/src/config/channels.js +137 -170
- package/src/config/index.js +277 -224
- package/src/config/placeholder.js +31 -0
- package/src/config/providers.js +148 -182
- package/src/config/settings.js +156 -182
- package/src/core/policy.js +69 -18
- package/src/core/trace.js +8 -6
- package/src/edit/editblock.js +266 -0
- package/src/edit/snapshot.js +67 -0
- package/src/evidence/index.js +153 -0
- package/src/evolve/playbook.js +9 -10
- package/src/hooks/index.js +113 -0
- package/src/llm/client.js +4 -3
- package/src/llm/dsml.js +74 -74
- package/src/llm/embedder.js +41 -35
- package/src/llm/fence.js +52 -52
- package/src/llm/index.js +4 -4
- package/src/llm/local-embedder.js +94 -0
- package/src/llm/presets.js +113 -0
- package/src/llm/pricing.js +93 -0
- package/src/llm/retry.js +73 -73
- package/src/llm/router.js +92 -89
- package/src/mcp/admin.js +44 -10
- package/src/mcp/client.js +487 -477
- package/src/mcp/http.js +23 -37
- package/src/mcp/index.js +116 -116
- package/src/mcp/server.js +23 -18
- package/src/mcp/tasks.js +9 -14
- package/src/memory/asset-hub.js +6 -11
- package/src/memory/canvas.js +2 -5
- package/src/memory/compaction.js +28 -28
- package/src/memory/experience.js +133 -122
- package/src/memory/fact-store.js +914 -698
- package/src/memory/failure-episode.js +20 -11
- package/src/memory/fork.js +17 -8
- package/src/memory/index.js +8 -6
- package/src/memory/l0.js +53 -52
- package/src/memory/l2.js +145 -130
- package/src/memory/l3.js +111 -111
- package/src/memory/legion-board.js +71 -0
- package/src/memory/memory-ticker.js +239 -240
- package/src/memory/session.js +398 -397
- package/src/memory/sqlite-store.js +581 -0
- package/src/mode/blackboard.js +49 -49
- package/src/mode/graph.js +42 -41
- package/src/mode/index.js +64 -64
- package/src/mode/legion.js +54 -51
- package/src/mode/plan-exec.js +50 -50
- package/src/mode/router.js +28 -40
- package/src/orchestrator/agent-worker.js +69 -69
- package/src/orchestrator/dag.js +90 -83
- package/src/orchestrator/experts.js +76 -0
- package/src/orchestrator/index.js +1 -1
- package/src/orchestrator/legion.js +179 -187
- package/src/orchestrator/supervisor.js +6 -8
- package/src/permissions/index.js +378 -0
- package/src/persona/index.js +28 -29
- package/src/plugin/builtin.js +313 -215
- package/src/plugin/context.js +80 -79
- package/src/plugin/index.js +62 -62
- package/src/plugin/v3.js +73 -0
- package/src/protocol/index.js +148 -0
- package/src/repomap/index.js +309 -0
- package/src/review/index.js +393 -0
- package/src/seam/registry.js +3 -0
- package/src/seam/shell.js +55 -55
- package/src/security/injection.js +79 -0
- package/src/selfheal/evolve.js +67 -67
- package/src/selfheal/healer.js +184 -167
- package/src/selfheal/run.js +9 -9
- package/src/server.js +63 -60
- package/src/services/diagnose.js +180 -0
- package/src/services/learning-service.js +9 -0
- package/src/services/memory-health.js +34 -6
- package/src/services/memory-service.js +42 -9
- package/src/services/triage.js +138 -0
- package/src/session/parts.js +76 -0
- package/src/session/projection.js +73 -0
- package/src/session/rollout.js +54 -0
- package/src/session/turn.js +137 -0
- package/src/skills/lint.js +72 -0
- package/src/skills/loader.js +231 -150
- package/src/skills/search.js +58 -0
- package/src/skills/verify.js +95 -100
- package/src/tools/advanced.js +388 -352
- package/src/tools/builtin.js +384 -297
- package/src/tools/catalog.js +283 -159
- package/src/tools/command-guard.js +112 -112
- package/src/tools/custom.js +47 -47
- package/src/tools/delegate.js +383 -297
- package/src/tools/document.js +254 -253
- package/src/tools/git.js +151 -0
- package/src/tools/governance.js +47 -20
- package/src/tools/index.js +16 -11
- package/src/tools/methods.js +178 -178
- package/src/tools/ocr.js +59 -59
- package/src/tools/sandbox-worker.js +40 -0
- package/src/tools/sandbox.js +92 -0
- package/src/tools/seam.js +162 -125
- package/src/tools/selfmod.js +196 -176
- package/src/tools/v3.js +225 -0
- package/src/tools/vad.js +176 -0
- package/src/tools/voice.js +238 -0
- package/src/utils/async.js +14 -0
- package/src/utils/config-file.js +53 -0
- package/src/utils/crashguard.js +88 -0
- package/src/utils/http.js +53 -0
- package/src/utils/id.js +8 -0
- package/src/utils/json-state.js +33 -0
- package/src/utils/logger.js +17 -17
- package/src/utils/ndjson.js +25 -0
- package/src/utils/pii.js +42 -42
- package/src/utils/rate-limit.js +50 -0
- package/src/utils/schema.js +80 -0
- package/src/utils/similarity.js +43 -0
- package/src/utils/store.js +170 -108
- package/src/utils/text.js +15 -15
- package/src/utils/trace.js +153 -153
- package/src/utils/wal.js +39 -0
- package/src/utils/winutf8.js +16 -15
- package/src/wiki/index.js +170 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/skills/search.js - 技能检索与高置信匹配 (蓝皮书 2026: 发现机制是技能生态的瓶颈)
|
|
2
|
+
// 1) scoreSkills: name 命中加权 3 > description 命中 1, 按分数降序, 无交叠不返回
|
|
3
|
+
// 2) matchSkill: 高置信阈值 —— 单 bigram 噪音不触发 (需 >= 2 次命中), 并列同分不押注 (返回 null)
|
|
4
|
+
// tokenize: 英文/数字取整词, CJK 取 2-gram (与 memory/fact-store 的粗召回口径一致)
|
|
5
|
+
export function tokenize(text) {
|
|
6
|
+
const s = String(text || "").toLowerCase();
|
|
7
|
+
const out = new Set();
|
|
8
|
+
const re = /[a-z0-9_]+|[\u4e00-\u9fff]+/g;
|
|
9
|
+
for (const m of s.matchAll(re)) {
|
|
10
|
+
const t = m[0];
|
|
11
|
+
if (/^[a-z0-9_]+$/.test(t)) {
|
|
12
|
+
out.add(t);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (t.length === 1) {
|
|
16
|
+
out.add(t);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i + 1 < t.length; i++) out.add(t.slice(i, i + 2));
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function overlap(a, b) {
|
|
25
|
+
let n = 0;
|
|
26
|
+
for (const x of a) if (b.has(x)) n++;
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 对全部技能打分并降序返回 (score > 0 才有条目)
|
|
31
|
+
export function scoreSkills(loader, query, { nameWeight = 3, descWeight = 1 } = {}) {
|
|
32
|
+
const q = tokenize(query);
|
|
33
|
+
if (!q.size) return [];
|
|
34
|
+
const skills = typeof loader?.list === "function" ? loader.list() : [];
|
|
35
|
+
const ranked = [];
|
|
36
|
+
for (const s of skills) {
|
|
37
|
+
const nHits = overlap(q, tokenize(s.name || s.id));
|
|
38
|
+
const dHits = overlap(q, tokenize(s.description || ""));
|
|
39
|
+
const score = nHits * nameWeight + dHits * descWeight;
|
|
40
|
+
if (score <= 0) continue;
|
|
41
|
+
ranked.push({ ...s, score, hits: nHits + dHits, nameHits: nHits, descHits: dHits });
|
|
42
|
+
}
|
|
43
|
+
// 稳定排序: 分数降序 → 原始顺序 (list 已按 id 排序)
|
|
44
|
+
return ranked
|
|
45
|
+
.map((r, i) => ({ r, i }))
|
|
46
|
+
.sort((a, b) => b.r.score - a.r.score || a.i - b.i)
|
|
47
|
+
.map((x) => x.r);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 高置信单技能匹配: 命中不足以形成信号时返回 null, 并列歧义也不押注
|
|
51
|
+
export function matchSkill(loader, query, { minHits = 2 } = {}) {
|
|
52
|
+
const ranked = scoreSkills(loader, query);
|
|
53
|
+
if (!ranked.length) return null;
|
|
54
|
+
const top = ranked[0];
|
|
55
|
+
if (top.hits < minHits) return null;
|
|
56
|
+
if (ranked[1] && ranked[1].score === top.score) return null; // 并列 → 不押注
|
|
57
|
+
return top;
|
|
58
|
+
}
|
package/src/skills/verify.js
CHANGED
|
@@ -1,100 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
return { ok:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return { ok: false, reason: "升级版正文缩水 (" + bodyNow.length + "<" + Math.ceil(bodyPrev.length * 0.6) + "), 疑似退化" };
|
|
97
|
-
}
|
|
98
|
-
const changed = bodyNow !== bodyPrev;
|
|
99
|
-
return { ok: true, changed };
|
|
100
|
-
}
|
|
1
|
+
// src/skills/verify.js - 技能入库/升级验证闸门 (零 LLM, 确定性)
|
|
2
|
+
// 设计依据: self-evolution "reliable verification" —— gate before persist.
|
|
3
|
+
// 入库闸门 (verifySkill): 结构(## 流程 + ## 验证) + 接地(正文引用高频工具) + 轨迹背书(该工具有足够成功调用)
|
|
4
|
+
// 升级闸门 (verifyUpgradeSkill): 结构不缩水 + 正文不缩水(防退化) + 有实质变化
|
|
5
|
+
// 目标: 幻觉技能/退化技能一律拦在落盘之前, 保证 skills/ 目录只进"被真实轨迹背书"的方法。
|
|
6
|
+
import { parseSections } from "./loader.js";
|
|
7
|
+
|
|
8
|
+
// 技能正文必须包含的章节 (与 learning-service 的 "## Process + ## Verify" 语义一致)
|
|
9
|
+
export const requiredSections = ["流程", "验证"];
|
|
10
|
+
|
|
11
|
+
// 正文长度下限 (低于视为"只写了标题没写实质")
|
|
12
|
+
export const MIN_CONTENT_LEN = 20;
|
|
13
|
+
|
|
14
|
+
// 升级版相对旧版的最小长度比 (低于即判"缩水退步")
|
|
15
|
+
export const MIN_UPGRADE_RATIO = 0.8;
|
|
16
|
+
|
|
17
|
+
// 正文是否真实引用了高频工具 (按整词匹配, 避免子串误判)。命中返回工具名, 否则 null。
|
|
18
|
+
export function groundedInTools(content, hotTools = []) {
|
|
19
|
+
const text = String(content || "");
|
|
20
|
+
for (const t of hotTools) {
|
|
21
|
+
const name = String(t || "").trim();
|
|
22
|
+
if (!name) continue;
|
|
23
|
+
const esc = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24
|
+
if (new RegExp(`(^|[^a-zA-Z0-9_])${esc}([^a-zA-Z0-9_]|$)`).test(text)) return name;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 章节齐全性检查 → 缺失章节数组
|
|
30
|
+
export function missingSections(content) {
|
|
31
|
+
const secs = parseSections(String(content || ""));
|
|
32
|
+
return requiredSections.filter((s) => !secs[s] || !String(secs[s]).trim());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 入库闸门: 结构 + 接地 + 轨迹背书
|
|
36
|
+
// opts: { name, content, hotTools, okTraces, minFreq, heldOutTraces }
|
|
37
|
+
export function verifySkill({ name = "", content = "", hotTools = [], okTraces = [], minFreq = 2, heldOutTraces = null } = {}) {
|
|
38
|
+
const body = String(content || "").trim();
|
|
39
|
+
if (!body) return { ok: false, reason: "内容为空" };
|
|
40
|
+
|
|
41
|
+
// 1) 结构: 必需章节齐全
|
|
42
|
+
const missing = missingSections(body);
|
|
43
|
+
if (missing.length) return { ok: false, reason: "缺少必要章节: " + missing.join(" / ") };
|
|
44
|
+
|
|
45
|
+
// 2) 实质: 长度下限 (必须在接地检查之前 —— 空壳正文应报"太短"而非"未引用")
|
|
46
|
+
if (body.length < MIN_CONTENT_LEN) return { ok: false, reason: `内容太短 (< ${MIN_CONTENT_LEN} 字), 疑似空壳` };
|
|
47
|
+
|
|
48
|
+
// 3) 接地: 必须引用至少一个高频工具
|
|
49
|
+
const matchedTool = groundedInTools(body, hotTools);
|
|
50
|
+
if (!matchedTool) {
|
|
51
|
+
const list = (hotTools || []).filter(Boolean).slice(0, 6).join(", ") || "(无)";
|
|
52
|
+
return { ok: false, reason: `内容未引用任何高频工具, 疑似幻觉技能. 应引用的工具: ${list}` };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 4) 轨迹背书: 该高频工具要有足够成功调用 (minFreq 为频次门槛)
|
|
56
|
+
const traceCount = (okTraces || []).filter((t) => t && t.tool === matchedTool).length;
|
|
57
|
+
if (traceCount < minFreq) {
|
|
58
|
+
return { ok: false, reason: `高频工具 ${matchedTool} 的成功轨迹不足 (${traceCount}/${minFreq})`, matchedTool, traceCount };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 5) held-out 回归 (可选): 样本够多时切出的未见子集也要有背书, 防过拟合
|
|
62
|
+
if (Array.isArray(heldOutTraces) && heldOutTraces.length) {
|
|
63
|
+
const heldCount = heldOutTraces.filter((t) => t && t.tool === matchedTool).length;
|
|
64
|
+
if (heldCount < 1) {
|
|
65
|
+
return { ok: false, reason: `held-out 子集中无 ${matchedTool} 的背书 (疑似过拟合)`, matchedTool, traceCount };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { ok: true, reason: null, matchedTool, traceCount, name };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 升级闸门: 防退化 (结构不缩水 + 正文不缩水) + 必须真的有变化
|
|
73
|
+
// opts: { content, prevContent }
|
|
74
|
+
export function verifyUpgradeSkill({ content = "", prevContent = "" } = {}) {
|
|
75
|
+
const next = String(content || "").trim();
|
|
76
|
+
const prev = String(prevContent || "");
|
|
77
|
+
if (!next) return { ok: false, reason: "升级结果为空" };
|
|
78
|
+
|
|
79
|
+
// 1) 结构: 不得丢掉必需章节 (防"改着改着把验证段删了")
|
|
80
|
+
const missing = missingSections(next);
|
|
81
|
+
if (missing.length) return { ok: false, reason: "升级版缺少必要章节: " + missing.join(" / ") };
|
|
82
|
+
|
|
83
|
+
// 2) 实质长度
|
|
84
|
+
if (next.length < MIN_CONTENT_LEN) return { ok: false, reason: `升级版内容太短 (< ${MIN_CONTENT_LEN} 字)` };
|
|
85
|
+
|
|
86
|
+
// 3) 缩水检测: 相对旧版大幅变短即判退化
|
|
87
|
+
if (prev.trim() && next.length < prev.trim().length * MIN_UPGRADE_RATIO) {
|
|
88
|
+
return { ok: false, reason: `升级版正文缩水 (${next.length} < ${prev.trim().length} × ${MIN_UPGRADE_RATIO})` };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const changed = next !== prev.trim();
|
|
92
|
+
if (!changed) return { ok: false, reason: "升级版与旧版完全相同, 无实质变化", changed: false };
|
|
93
|
+
|
|
94
|
+
return { ok: true, reason: null, changed: true };
|
|
95
|
+
}
|