@lmzhen/dsh-evolution-curator 0.30.37 → 0.30.38
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/lib/index.js +65 -10
- package/lib/types/index.d.ts +9 -0
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Service } from "@deepseek-ai/cordis";
|
|
2
|
-
import { BASELINE_ACTION, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_LIMITS, DEFAULT_STALE_AFTER_DAYS, EvolutionGateSet, INSTANCE_KEYS, MAX_TIMER_DELAY_MS, PROMPT_BUNDLE, SKILL_NAME_RE, acquireTreeWriteLock, authorityFrom, blobPath, buildCuratorRunReport, claimInstance, clampOnce, clampedNumber, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, emptyRecord, entryTarget, evolutionHome, evolutionIoAdapter, executeUnitUndo, foldCuratorFields, historyIndexFile, isPresent, isUnknown, lintSkill, liveBool, loadSuppressedNames, loadUsage, markerEntryName, mutateUsage, newSkillLibrary, paramRowId, parseCuratorNominations, parseFrontmatter, parseHistoryIndex, pickWithPolicy, planUnitUndoAcross, policyStageLimits, probeList, probeText, readNumberParam, relatedSkillNames, releaseInstance, renderCuratorReportMarkdown, reportTime, reportsSweepLockTarget, resolveUnitMembers, sessionLastEventTime, staleRouteStubs, sweepReports, transactIo, unitMembersAreComplete, unwrapLive, updateSuppressedNames, usageObserved, userSetKeys, verifyPromptBundle, withTreeWrite } from "@lmzhen/dsh-evolution-core";
|
|
2
|
+
import { BASELINE_ACTION, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_LIMITS, DEFAULT_STALE_AFTER_DAYS, EXTRACT_PROMPT_HASH, EvolutionGateSet, INSTANCE_KEYS, MAX_TIMER_DELAY_MS, PROMPT_BUNDLE, SKILL_NAME_RE, acquireTreeWriteLock, authorityFrom, blobPath, buildCuratorRunReport, claimInstance, clampOnce, clampedNumber, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, emptyRecord, entryTarget, eventsFile, evolutionHome, evolutionIoAdapter, executeUnitUndo, foldCuratorFields, historyIndexFile, isPresent, isUnknown, lintSkill, liveBool, loadSuppressedNames, loadUsage, markerEntryName, mutateUsage, newSkillLibrary, paramRowId, parseCuratorNominations, parseFrontmatter, parseHistoryIndex, pickWithPolicy, planUnitUndoAcross, policyStageLimits, probeList, probeText, readEvolutionEvents, readNumberParam, relatedSkillNames, releaseInstance, renderCuratorReportMarkdown, reportTime, reportsSweepLockTarget, resolveUnitMembers, sessionLastEventTime, staleRouteStubs, sweepReports, transactIo, unitMembersAreComplete, unwrapLive, updateSuppressedNames, usageObserved, userSetKeys, verifyPromptBundle, withTreeWrite, writeProposalReport } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { join } from "node:path";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
5
|
import { BlockAssembler, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
6
6
|
import z from "@deepseek-ai/schemastery";
|
|
7
7
|
//#region lib/types/unit-undo-plan.js
|
|
@@ -1372,23 +1372,33 @@ var EvolutionCurator = class extends Service {
|
|
|
1372
1372
|
const thresholds = {
|
|
1373
1373
|
softBodyChars: settings.healthSoftBodyChars,
|
|
1374
1374
|
stampDensityPerKb: settings.healthStampDensityPerKb,
|
|
1375
|
-
churnMinPatches: settings.healthChurnMinPatches
|
|
1375
|
+
churnMinPatches: settings.healthChurnMinPatches,
|
|
1376
|
+
hardCapMinHits: DEFAULT_HEALTH_THRESHOLDS.hardCapMinHits
|
|
1376
1377
|
};
|
|
1378
|
+
const eventLog = await readEvolutionEvents(this.io, eventsFile(dirname(this.skills.root)));
|
|
1379
|
+
const hardCapHits = /* @__PURE__ */ new Map();
|
|
1380
|
+
for (const event of eventLog.events) {
|
|
1381
|
+
if (event.type !== "hard-cap" || event.target === void 0) continue;
|
|
1382
|
+
hardCapHits.set(event.target, (hardCapHits.get(event.target) ?? 0) + 1);
|
|
1383
|
+
}
|
|
1377
1384
|
const usage = await loadUsage(this.skills.root, this.io);
|
|
1378
1385
|
const observed = usageObserved(usage);
|
|
1379
1386
|
const rows = [];
|
|
1380
|
-
for (const summary of await this.skills.list()) {
|
|
1387
|
+
for (const summary of await this.skills.model.list()) {
|
|
1381
1388
|
const record = usage.get(summary.name);
|
|
1382
1389
|
const assessment = await this.skills.assessHealth(summary.name, thresholds, observed && record ? {
|
|
1383
1390
|
patchCount: record.patch_count,
|
|
1384
|
-
readCount: record.view_count
|
|
1385
|
-
|
|
1391
|
+
readCount: record.view_count,
|
|
1392
|
+
...eventLog.malformed ? { hardCapHits: null } : { hardCapHits: hardCapHits.get(summary.name) ?? 0 }
|
|
1393
|
+
} : eventLog.malformed ? { hardCapHits: null } : { hardCapHits: hardCapHits.get(summary.name) ?? 0 });
|
|
1386
1394
|
if (assessment !== null) {
|
|
1387
1395
|
rows.push({
|
|
1388
1396
|
name: summary.name,
|
|
1389
1397
|
verdict: assessment.verdict,
|
|
1390
1398
|
dims: assessment.dims,
|
|
1391
|
-
findings: assessment.findings
|
|
1399
|
+
findings: assessment.findings,
|
|
1400
|
+
hardCapHits: eventLog.malformed ? null : hardCapHits.get(summary.name) ?? 0,
|
|
1401
|
+
...summary.protectedBy === null ? {} : { protection: summary.protectedBy }
|
|
1392
1402
|
});
|
|
1393
1403
|
continue;
|
|
1394
1404
|
}
|
|
@@ -1402,13 +1412,15 @@ var EvolutionCurator = class extends Service {
|
|
|
1402
1412
|
supportGroups: 0,
|
|
1403
1413
|
supportFiles: null,
|
|
1404
1414
|
churnPatches: null,
|
|
1405
|
-
churnReads: null
|
|
1415
|
+
churnReads: null,
|
|
1416
|
+
hardCapHits: null
|
|
1406
1417
|
},
|
|
1407
1418
|
softLineChars: thresholds.softBodyChars,
|
|
1408
1419
|
overSoftLine: false,
|
|
1409
1420
|
overTwiceSoftLine: false,
|
|
1410
1421
|
stampLimitPerKb: thresholds.stampDensityPerKb,
|
|
1411
1422
|
churnMinPatches: thresholds.churnMinPatches,
|
|
1423
|
+
hardCapMinHits: thresholds.hardCapMinHits,
|
|
1412
1424
|
readable: false
|
|
1413
1425
|
});
|
|
1414
1426
|
rows.push({
|
|
@@ -1421,7 +1433,8 @@ var EvolutionCurator = class extends Service {
|
|
|
1421
1433
|
supportGroups: 0,
|
|
1422
1434
|
supportFiles: null,
|
|
1423
1435
|
churnPatches: null,
|
|
1424
|
-
churnReads: null
|
|
1436
|
+
churnReads: null,
|
|
1437
|
+
readable: false
|
|
1425
1438
|
},
|
|
1426
1439
|
findings
|
|
1427
1440
|
});
|
|
@@ -1614,6 +1627,48 @@ var EvolutionCurator = class extends Service {
|
|
|
1614
1627
|
* @param unitId - the unit to undo; omitted takes the newest unit the index carries.
|
|
1615
1628
|
* @returns the outcome; the message names what was reverted, or why nothing was written.
|
|
1616
1629
|
*/
|
|
1630
|
+
/** E12: curator proposer — oversized skills get a keep proposal, never an automatic split. */
|
|
1631
|
+
async proposeKeeps() {
|
|
1632
|
+
const model = this.ctx.get("evolutionPolicy")?.get?.()?.curatorModel ?? DEFAULT_CURATOR_MODEL;
|
|
1633
|
+
const rows = await this.healthView();
|
|
1634
|
+
let count = 0;
|
|
1635
|
+
const at = Date.now();
|
|
1636
|
+
for (const row of rows) {
|
|
1637
|
+
if (row.protection !== void 0 && row.protection !== null) continue;
|
|
1638
|
+
if (!row.findings.some((finding) => finding.rule === "body-oversize" || finding.rule === "body-oversize-2x")) continue;
|
|
1639
|
+
const runId = "curator-keep-" + at.toString(36) + "-" + String(count);
|
|
1640
|
+
const proposal = {
|
|
1641
|
+
version: 1,
|
|
1642
|
+
id: "extract-" + runId + "-" + row.name,
|
|
1643
|
+
source: row.name,
|
|
1644
|
+
outcome: "keep",
|
|
1645
|
+
parts: [],
|
|
1646
|
+
owner: {
|
|
1647
|
+
mode: "covered",
|
|
1648
|
+
name: row.name,
|
|
1649
|
+
triggerCovers: true,
|
|
1650
|
+
outcomeCovers: true,
|
|
1651
|
+
reason: "keep: the current owner remains"
|
|
1652
|
+
},
|
|
1653
|
+
warnings: ["keep is valid: size alone does not require a split"],
|
|
1654
|
+
provenance: {
|
|
1655
|
+
promptVersion: "v1",
|
|
1656
|
+
promptHash: EXTRACT_PROMPT_HASH,
|
|
1657
|
+
model,
|
|
1658
|
+
runId,
|
|
1659
|
+
at
|
|
1660
|
+
},
|
|
1661
|
+
status: "proposed"
|
|
1662
|
+
};
|
|
1663
|
+
await writeProposalReport(this.io, proposal);
|
|
1664
|
+
count += 1;
|
|
1665
|
+
}
|
|
1666
|
+
return {
|
|
1667
|
+
ok: true,
|
|
1668
|
+
count,
|
|
1669
|
+
message: count === 0 ? "没有需要 keep 提案的 body-oversize 技能。" : "已写入 " + String(count) + " 条 keep 提案。"
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1617
1672
|
async undoUnit(name, unitId) {
|
|
1618
1673
|
const versions = await this.skills.listVersions(name);
|
|
1619
1674
|
if (versions.length === 0) return {
|
|
@@ -1635,7 +1690,7 @@ var EvolutionCurator = class extends Service {
|
|
|
1635
1690
|
ok: false,
|
|
1636
1691
|
message: `单元 ${unit} 不在「${name}」已记录的历史里 —— 拒绝瞎猜、不做写入。`
|
|
1637
1692
|
};
|
|
1638
|
-
const head = members[0];
|
|
1693
|
+
const head = members.find((entry) => entry.unitHead?.sources !== void 0) ?? members[0];
|
|
1639
1694
|
const headLike = head !== void 0 && head.unitHead !== void 0 ? head.unitHead : void 0;
|
|
1640
1695
|
const sources = headLike?.sources;
|
|
1641
1696
|
if (sources !== void 0 && sources.length > 0) {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -522,6 +522,7 @@ export declare class EvolutionCurator extends Service {
|
|
|
522
522
|
supportFiles: number | null;
|
|
523
523
|
churnPatches: number | null;
|
|
524
524
|
churnReads: number | null;
|
|
525
|
+
readable?: boolean;
|
|
525
526
|
};
|
|
526
527
|
findings: Array<{
|
|
527
528
|
severity: 'warn' | 'error';
|
|
@@ -529,6 +530,8 @@ export declare class EvolutionCurator extends Service {
|
|
|
529
530
|
message: string;
|
|
530
531
|
count: number;
|
|
531
532
|
}>;
|
|
533
|
+
hardCapHits?: number | null;
|
|
534
|
+
protection?: string | null;
|
|
532
535
|
}>>;
|
|
533
536
|
/** Whether the library has ANY observed read evidence (C observation-window gate for churn signals). */
|
|
534
537
|
usageObserved(): Promise<boolean>;
|
|
@@ -582,6 +585,12 @@ export declare class EvolutionCurator extends Service {
|
|
|
582
585
|
* @param unitId - the unit to undo; omitted takes the newest unit the index carries.
|
|
583
586
|
* @returns the outcome; the message names what was reverted, or why nothing was written.
|
|
584
587
|
*/
|
|
588
|
+
/** E12: curator proposer — oversized skills get a keep proposal, never an automatic split. */
|
|
589
|
+
proposeKeeps(): Promise<{
|
|
590
|
+
ok: true;
|
|
591
|
+
count: number;
|
|
592
|
+
message: string;
|
|
593
|
+
}>;
|
|
585
594
|
undoUnit(name: string, unitId?: string): Promise<SkillActionResult>;
|
|
586
595
|
/** The content the live bytes replaced: the CHAIN first, the recorded order as the fallback.
|
|
587
596
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-curator",
|
|
3
3
|
"description": "Deterministic skill lifecycle and recovery (community build)",
|
|
4
|
-
"version": "0.30.
|
|
4
|
+
"version": "0.30.38",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,21 +27,21 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.5",
|
|
30
|
-
"@lmzhen/dsh-evolution-core": "^0.30.
|
|
30
|
+
"@lmzhen/dsh-evolution-core": "^0.30.38"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@deepseek-ai/cordis": "^4.0.5",
|
|
34
34
|
"@deepseek-ai/dsh-llm": "^0.2.1-rc.2",
|
|
35
35
|
"@deepseek-ai/dsh-session": "^0.2.1-rc.2",
|
|
36
|
-
"@lmzhen/dsh-evolution-io": "^0.30.
|
|
37
|
-
"@lmzhen/dsh-evolution-state": "^0.30.
|
|
36
|
+
"@lmzhen/dsh-evolution-io": "^0.30.38",
|
|
37
|
+
"@lmzhen/dsh-evolution-state": "^0.30.38"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@deepseek-ai/dsh-llm": "^0.2.1-rc.2",
|
|
41
41
|
"@deepseek-ai/dsh-session": "^0.2.1-rc.2",
|
|
42
|
-
"@lmzhen/dsh-evolution-core": "^0.30.
|
|
43
|
-
"@lmzhen/dsh-evolution-io": "^0.30.
|
|
44
|
-
"@lmzhen/dsh-evolution-state": "^0.30.
|
|
42
|
+
"@lmzhen/dsh-evolution-core": "^0.30.38",
|
|
43
|
+
"@lmzhen/dsh-evolution-io": "^0.30.38",
|
|
44
|
+
"@lmzhen/dsh-evolution-state": "^0.30.38"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"dsh": ">=0.2.1-rc.2 <0.2.2-0"
|