@lmzhen/dsh-evolution-curator 0.1.0-rc.48 → 0.1.0-rc.49
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 +42 -2
- package/lib/types/index.d.ts +7 -0
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { BlockAssembler, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
|
-
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, EvolutionGateSet, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, relatedSkillNames, saveSuppressedNames, saveUsage } from "@lmzhen/dsh-evolution-core";
|
|
6
|
+
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, EvolutionGateSet, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, relatedSkillNames, renderCuratorReportMarkdown, saveSuppressedNames, saveUsage } from "@lmzhen/dsh-evolution-core";
|
|
7
7
|
//#region lib/types/index.js
|
|
8
8
|
/**
|
|
9
9
|
* Deterministic skill lifecycle curator with interval gate and archive.
|
|
@@ -63,7 +63,9 @@ var EvolutionCurator = class extends Service {
|
|
|
63
63
|
constructor(ctx, config = {}) {
|
|
64
64
|
super(ctx, "evolutionCurator");
|
|
65
65
|
this.io = evolutionIoAdapter(() => ctx.evolutionIo.provider());
|
|
66
|
-
this.skills = new SkillLibrary(void 0, this.io)
|
|
66
|
+
this.skills = new SkillLibrary(void 0, this.io, void 0, (event) => {
|
|
67
|
+
this.ctx.emit("evolution/skill-mutated", event);
|
|
68
|
+
});
|
|
67
69
|
this.enabled = config.enabled ?? true;
|
|
68
70
|
this.intervalHours = config.intervalHours ?? DEFAULT_CURATOR_INTERVAL_HOURS;
|
|
69
71
|
this.staleAfterDays = config.staleAfterDays ?? DEFAULT_STALE_AFTER_DAYS;
|
|
@@ -386,6 +388,8 @@ var EvolutionCurator = class extends Service {
|
|
|
386
388
|
const reportsRoot = join(evolutionHome(), "reports");
|
|
387
389
|
try {
|
|
388
390
|
await this.io.writeText(join(reportsRoot, `curator-${runId}.json`), JSON.stringify(report, null, 2));
|
|
391
|
+
await this.io.writeText(join(reportsRoot, `curator-${runId}.md`), renderCuratorReportMarkdown(report));
|
|
392
|
+
await this.retainReports(20);
|
|
389
393
|
} catch (error) {
|
|
390
394
|
this.ctx.logger.warn(`evolution-curator: failed to persist report ${runId}`);
|
|
391
395
|
this.ctx.logger.warn(error);
|
|
@@ -560,6 +564,42 @@ var EvolutionCurator = class extends Service {
|
|
|
560
564
|
}
|
|
561
565
|
return latest > 0 && Date.now() - latest < this.minIdleHours * 36e5;
|
|
562
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Keep only the newest N curator reports, ordered by the report's own
|
|
569
|
+
* `startedAt` (the runId is a UUID and cannot order history). Best-effort
|
|
570
|
+
* like `retainSnapshots`: a failed removal must not fail the run that just
|
|
571
|
+
* persisted its report. The paired `.md` digest is pruned with its JSON.
|
|
572
|
+
*/
|
|
573
|
+
async retainReports(keep) {
|
|
574
|
+
const reportsRoot = join(evolutionHome(), "reports");
|
|
575
|
+
let entries;
|
|
576
|
+
try {
|
|
577
|
+
entries = await this.io.list(reportsRoot);
|
|
578
|
+
} catch {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const dated = [];
|
|
582
|
+
for (const name of entries.filter((entry) => entry.startsWith("curator-") && entry.endsWith(".json"))) try {
|
|
583
|
+
const raw = await this.io.readText(join(reportsRoot, name));
|
|
584
|
+
if (raw === null) continue;
|
|
585
|
+
const parsed = JSON.parse(raw);
|
|
586
|
+
const startedAt = typeof parsed.startedAt === "string" ? Date.parse(parsed.startedAt) : NaN;
|
|
587
|
+
if (Number.isFinite(startedAt)) dated.push({
|
|
588
|
+
name,
|
|
589
|
+
startedAt
|
|
590
|
+
});
|
|
591
|
+
} catch {}
|
|
592
|
+
dated.sort((a, b) => b.startedAt - a.startedAt);
|
|
593
|
+
for (const oldReport of dated.slice(keep)) {
|
|
594
|
+
const stem = oldReport.name.replace(/\.json$/, "");
|
|
595
|
+
try {
|
|
596
|
+
await this.io.remove(join(reportsRoot, oldReport.name));
|
|
597
|
+
} catch {}
|
|
598
|
+
try {
|
|
599
|
+
await this.io.remove(join(reportsRoot, `${stem}.md`));
|
|
600
|
+
} catch {}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
563
603
|
async latestReport() {
|
|
564
604
|
const reportsRoot = join(evolutionHome(), "reports");
|
|
565
605
|
const latest = (await this.io.list(reportsRoot)).filter((name) => name.startsWith("curator-") && name.endsWith(".json")).sort().reverse()[0];
|
package/lib/types/index.d.ts
CHANGED
|
@@ -186,6 +186,13 @@ export declare class EvolutionCurator extends Service {
|
|
|
186
186
|
*/
|
|
187
187
|
private applyMutations;
|
|
188
188
|
private recentSessionActive;
|
|
189
|
+
/**
|
|
190
|
+
* Keep only the newest N curator reports, ordered by the report's own
|
|
191
|
+
* `startedAt` (the runId is a UUID and cannot order history). Best-effort
|
|
192
|
+
* like `retainSnapshots`: a failed removal must not fail the run that just
|
|
193
|
+
* persisted its report. The paired `.md` digest is pruned with its JSON.
|
|
194
|
+
*/
|
|
195
|
+
private retainReports;
|
|
189
196
|
latestReport(): Promise<CuratorRunReport | null>;
|
|
190
197
|
/**
|
|
191
198
|
* Read-only lifecycle scope classification: which skills are in scope,
|
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.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.49",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
36
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
36
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.49"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
40
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
41
41
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
42
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
43
|
-
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.
|
|
42
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.49",
|
|
43
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.49"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
47
47
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
48
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
49
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
50
|
-
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.
|
|
48
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.49",
|
|
49
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.49",
|
|
50
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.49"
|
|
51
51
|
}
|
|
52
52
|
}
|