@lmzhen/dsh-evolution-curator 0.1.0-rc.14 → 0.1.0-rc.15
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 +108 -55
- package/lib/types/index.d.ts +21 -8
- 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_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, 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, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, 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.
|
|
@@ -23,6 +23,8 @@ var EvolutionCurator = class extends Service {
|
|
|
23
23
|
excludeSkillNames: z.array(z.string()).default([]),
|
|
24
24
|
manageUnmanaged: z.boolean().default(false),
|
|
25
25
|
pruneBuiltins: z.boolean().default(false),
|
|
26
|
+
referencedSkillNames: z.array(z.string()).default([]),
|
|
27
|
+
autoStart: z.boolean().default(true),
|
|
26
28
|
curatorReviewMaxTokens: z.number().default(2048)
|
|
27
29
|
});
|
|
28
30
|
skills;
|
|
@@ -38,6 +40,7 @@ var EvolutionCurator = class extends Service {
|
|
|
38
40
|
excludeSkillNames;
|
|
39
41
|
manageUnmanaged;
|
|
40
42
|
pruneBuiltins;
|
|
43
|
+
referencedSkillNames;
|
|
41
44
|
curatorReviewMaxTokens;
|
|
42
45
|
lastRun = 0;
|
|
43
46
|
timer;
|
|
@@ -56,6 +59,7 @@ var EvolutionCurator = class extends Service {
|
|
|
56
59
|
this.excludeSkillNames = new Set(config.excludeSkillNames ?? []);
|
|
57
60
|
this.manageUnmanaged = config.manageUnmanaged ?? false;
|
|
58
61
|
this.pruneBuiltins = config.pruneBuiltins ?? false;
|
|
62
|
+
this.referencedSkillNames = new Set(config.referencedSkillNames ?? []);
|
|
59
63
|
this.curatorReviewMaxTokens = config.curatorReviewMaxTokens ?? 2048;
|
|
60
64
|
this.lastRun = Date.now();
|
|
61
65
|
this.ctx.effect(() => {
|
|
@@ -63,6 +67,7 @@ var EvolutionCurator = class extends Service {
|
|
|
63
67
|
this.stop();
|
|
64
68
|
};
|
|
65
69
|
}, "evolution-curator.stop");
|
|
70
|
+
if (config.autoStart ?? true) this.start();
|
|
66
71
|
}
|
|
67
72
|
lifecycle() {
|
|
68
73
|
const snapshot = this.ctx.get("evolutionPolicy")?.get();
|
|
@@ -84,23 +89,28 @@ var EvolutionCurator = class extends Service {
|
|
|
84
89
|
this.timer = void 0;
|
|
85
90
|
}
|
|
86
91
|
/**
|
|
87
|
-
* Optional Hermes-curator LLM pass. The model may only NOMINATE pruning
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
92
|
+
* Optional Hermes-curator LLM pass. The model may only NOMINATE pruning and
|
|
93
|
+
* consolidation; every move stays a control-plane operation and each
|
|
94
|
+
* nomination is re-validated against the tree and protected markers before
|
|
95
|
+
* any file move. `dryRun` prepends the report-only banner.
|
|
91
96
|
*/
|
|
92
|
-
async recommend(candidates) {
|
|
93
|
-
|
|
97
|
+
async recommend(candidates, options = {}) {
|
|
98
|
+
const empty = {
|
|
99
|
+
prunings: [],
|
|
100
|
+
consolidations: []
|
|
101
|
+
};
|
|
102
|
+
if (candidates.length === 0) return empty;
|
|
94
103
|
const llm = this.ctx.get("llm");
|
|
95
|
-
if (!llm) return
|
|
104
|
+
if (!llm) return empty;
|
|
96
105
|
const model = this.ctx.get("evolutionPolicy")?.get().curatorModel ?? "deepseek-v4-pro";
|
|
97
106
|
const prompt = [
|
|
107
|
+
options.dryRun ? CURATOR_DRY_RUN_BANNER : "",
|
|
98
108
|
CURATOR_PROMPT,
|
|
99
109
|
"",
|
|
100
|
-
|
|
110
|
+
`Stale candidates observed by the deterministic lifecycle scanner:${candidates.length === 0 ? " (none)" : ""}`,
|
|
101
111
|
...candidates.map((name) => `- ${name}`),
|
|
102
112
|
"",
|
|
103
|
-
"Return a YAML summary with
|
|
113
|
+
"Return a YAML summary with consolidations and prunings lists. Nominate only actions whose archival/merge is clearly safe."
|
|
104
114
|
].join("\n");
|
|
105
115
|
try {
|
|
106
116
|
const assembler = new BlockAssembler();
|
|
@@ -122,13 +132,13 @@ var EvolutionCurator = class extends Service {
|
|
|
122
132
|
maxTokens: this.curatorReviewMaxTokens,
|
|
123
133
|
purpose: "evolution-curator"
|
|
124
134
|
})) assembler.push(chunk);
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
135
|
+
const parsed = parseCuratorNominations(assembler.blocks().filter((block) => block.type === "text").map((block) => block.text).join("\n"));
|
|
136
|
+
return {
|
|
137
|
+
prunings: parsed.prunings.filter((name) => candidates.includes(name)),
|
|
138
|
+
consolidations: parsed.consolidations
|
|
139
|
+
};
|
|
130
140
|
} catch {
|
|
131
|
-
return
|
|
141
|
+
return empty;
|
|
132
142
|
}
|
|
133
143
|
}
|
|
134
144
|
skippedReport(runId, startedAt) {
|
|
@@ -145,22 +155,25 @@ var EvolutionCurator = class extends Service {
|
|
|
145
155
|
}
|
|
146
156
|
/**
|
|
147
157
|
* Run one curator pass. `ignoreGates` skips the interval and idle gates so an
|
|
148
|
-
* explicit `/evolution curator run` always executes (manual-run semantics)
|
|
158
|
+
* explicit `/evolution curator run` always executes (manual-run semantics):
|
|
159
|
+
* `dryRun` computes the lifecycle and the LLM nominations but performs no
|
|
160
|
+
* mutation, reports what WOULD happen, and does not push out the next run.
|
|
149
161
|
*/
|
|
150
162
|
async run(options = {}) {
|
|
163
|
+
const { ignoreGates = false, dryRun = false } = options;
|
|
151
164
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
152
165
|
const runId = randomUUID();
|
|
153
166
|
const stateService = this.ctx.get("evolutionState");
|
|
154
167
|
const lifecycle = this.lifecycle();
|
|
155
168
|
const persisted = await stateService?.loadCuratorState();
|
|
156
|
-
if (!
|
|
169
|
+
if (!ignoreGates && persisted && Date.now() - persisted.lastRunAt < lifecycle.intervalHours * 36e5) return {
|
|
157
170
|
stale: [],
|
|
158
171
|
archived: [],
|
|
159
172
|
errors: [],
|
|
160
173
|
report: this.skippedReport(runId, startedAt),
|
|
161
174
|
skipped: "interval"
|
|
162
175
|
};
|
|
163
|
-
if (!
|
|
176
|
+
if (!ignoreGates && this.minIdleHours > 0 && this.recentSessionActive()) return {
|
|
164
177
|
stale: [],
|
|
165
178
|
archived: [],
|
|
166
179
|
errors: [],
|
|
@@ -168,10 +181,11 @@ var EvolutionCurator = class extends Service {
|
|
|
168
181
|
skipped: "active-session"
|
|
169
182
|
};
|
|
170
183
|
const root = this.skills.root;
|
|
171
|
-
const
|
|
172
|
-
const usage =
|
|
184
|
+
const rawUsage = await loadUsage(root, this.io);
|
|
185
|
+
const usage = dryRun ? new Map([...rawUsage].map(([name, record]) => [name, { ...record }])) : rawUsage;
|
|
186
|
+
const snapshotPath = dryRun ? void 0 : await this.skills.snapshotAll("pre-curator-run");
|
|
173
187
|
const suppressedNames = new Set(await loadSuppressedNames(root, this.io));
|
|
174
|
-
const bundledNames = await this.seedBaseline(usage);
|
|
188
|
+
const { bundledNames, treeNames } = await this.seedBaseline(usage);
|
|
175
189
|
const result = computeLifecycleTransitions(usage, {
|
|
176
190
|
staleAfterDays: lifecycle.staleAfterDays,
|
|
177
191
|
archiveAfterDays: lifecycle.archiveAfterDays,
|
|
@@ -180,41 +194,72 @@ var EvolutionCurator = class extends Service {
|
|
|
180
194
|
manageUnmanaged: this.manageUnmanaged,
|
|
181
195
|
pruneBuiltins: this.pruneBuiltins,
|
|
182
196
|
bundledNames,
|
|
183
|
-
suppressedNames
|
|
197
|
+
suppressedNames,
|
|
198
|
+
referencedSkillNames: this.referencedSkillNames
|
|
184
199
|
});
|
|
185
200
|
const errors = [];
|
|
186
201
|
const archivedSkills = [];
|
|
187
|
-
const
|
|
202
|
+
const nominations = this.llmReview ? await this.recommend(result.markStale, { dryRun }) : {
|
|
203
|
+
prunings: [],
|
|
204
|
+
consolidations: []
|
|
205
|
+
};
|
|
206
|
+
const llmNominations = nominations.prunings;
|
|
188
207
|
const archiveCandidates = [...new Set([...result.archive, ...llmNominations])];
|
|
189
208
|
let suppressedChanged = false;
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (!archived.ok) {
|
|
196
|
-
const record = usage.get(name);
|
|
197
|
-
if (record) record.state = "active";
|
|
198
|
-
errors.push(`${name}: ${archived.message}`);
|
|
199
|
-
} else {
|
|
200
|
-
archivedSkills.push({
|
|
201
|
-
name,
|
|
202
|
-
path: archived.path ?? "",
|
|
203
|
-
reason: "Lifecycle: reached archive threshold"
|
|
209
|
+
if (!dryRun) {
|
|
210
|
+
for (const name of archiveCandidates) {
|
|
211
|
+
const archived = await this.skills.archive(name, {
|
|
212
|
+
reason: "Lifecycle: reached archive threshold",
|
|
213
|
+
allowBundled: this.pruneBuiltins
|
|
204
214
|
});
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
if (!archived.ok) {
|
|
216
|
+
const record = usage.get(name);
|
|
217
|
+
if (record) record.state = "active";
|
|
218
|
+
errors.push(`${name}: ${archived.message}`);
|
|
219
|
+
} else {
|
|
220
|
+
archivedSkills.push({
|
|
221
|
+
name,
|
|
222
|
+
path: archived.path ?? "",
|
|
223
|
+
reason: "Lifecycle: reached archive threshold"
|
|
224
|
+
});
|
|
225
|
+
if (bundledNames.has(name)) {
|
|
226
|
+
suppressedNames.add(name);
|
|
227
|
+
suppressedChanged = true;
|
|
228
|
+
}
|
|
208
229
|
}
|
|
209
230
|
}
|
|
231
|
+
const alreadyArchived = new Set(archiveCandidates);
|
|
232
|
+
for (const nomination of nominations.consolidations) {
|
|
233
|
+
if (alreadyArchived.has(nomination.from)) continue;
|
|
234
|
+
if (!treeNames.has(nomination.from) || !treeNames.has(nomination.into)) {
|
|
235
|
+
errors.push(`${nomination.from}: consolidation target or source missing from the skill tree`);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const consolidated = await this.skills.consolidate(nomination.into, [nomination.from], "background_review");
|
|
239
|
+
if (!consolidated.ok) {
|
|
240
|
+
errors.push(`${nomination.from}: ${consolidated.message}`);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const record = usage.get(nomination.from);
|
|
244
|
+
if (record) {
|
|
245
|
+
record.state = "archived";
|
|
246
|
+
record.archived_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
247
|
+
}
|
|
248
|
+
alreadyArchived.add(nomination.from);
|
|
249
|
+
archivedSkills.push({
|
|
250
|
+
name: nomination.from,
|
|
251
|
+
path: consolidated.path ?? "",
|
|
252
|
+
reason: `Consolidated into ${nomination.into}`
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (suppressedChanged) try {
|
|
256
|
+
await saveSuppressedNames(root, suppressedNames, this.io);
|
|
257
|
+
} catch {
|
|
258
|
+
this.ctx.logger.warn("evolution-curator: failed to persist suppressed names; archived built-ins may re-enter the lifecycle");
|
|
259
|
+
}
|
|
260
|
+
await saveUsage(root, usage, this.io);
|
|
210
261
|
}
|
|
211
|
-
if (
|
|
212
|
-
await saveSuppressedNames(root, suppressedNames, this.io);
|
|
213
|
-
} catch {
|
|
214
|
-
this.ctx.logger.warn("evolution-curator: failed to persist suppressed names; archived built-ins may re-enter the lifecycle");
|
|
215
|
-
}
|
|
216
|
-
await saveUsage(root, usage, this.io);
|
|
217
|
-
this.lastRun = Date.now();
|
|
262
|
+
if (!dryRun) this.lastRun = Date.now();
|
|
218
263
|
const report = buildCuratorRunReport({
|
|
219
264
|
runId,
|
|
220
265
|
startedAt,
|
|
@@ -229,7 +274,7 @@ var EvolutionCurator = class extends Service {
|
|
|
229
274
|
reason: errors.find((item) => item.startsWith(`${name}:`))?.slice(name.length + 2) ?? "unknown"
|
|
230
275
|
};
|
|
231
276
|
}),
|
|
232
|
-
snapshotPath
|
|
277
|
+
...snapshotPath === void 0 ? {} : { snapshotPath }
|
|
233
278
|
});
|
|
234
279
|
const reportsRoot = join(evolutionHome(), "reports");
|
|
235
280
|
try {
|
|
@@ -238,31 +283,39 @@ var EvolutionCurator = class extends Service {
|
|
|
238
283
|
this.ctx.logger.warn(`evolution-curator: failed to persist report ${runId}`);
|
|
239
284
|
this.ctx.logger.warn(error);
|
|
240
285
|
}
|
|
286
|
+
const summary = `${dryRun ? "dry-run" : "auto"}: stale:${result.markStale.length} archived:${archivedSkills.length} consolidated:${nominations.consolidations.length}`;
|
|
241
287
|
await stateService?.saveCuratorState({
|
|
242
|
-
lastRunAt: this.lastRun,
|
|
243
|
-
runCount: (persisted?.runCount ?? 0) + 1,
|
|
244
|
-
lastSummary:
|
|
288
|
+
lastRunAt: dryRun ? persisted?.lastRunAt ?? this.lastRun : this.lastRun,
|
|
289
|
+
runCount: dryRun ? persisted?.runCount ?? 0 : (persisted?.runCount ?? 0) + 1,
|
|
290
|
+
lastSummary: summary,
|
|
245
291
|
paused: false
|
|
246
292
|
});
|
|
247
293
|
return {
|
|
248
294
|
stale: result.markStale,
|
|
249
295
|
archived: archivedSkills.map((item) => item.name),
|
|
250
296
|
errors,
|
|
251
|
-
report
|
|
297
|
+
report,
|
|
298
|
+
...this.llmReview ? { nominations } : {}
|
|
252
299
|
};
|
|
253
300
|
}
|
|
254
301
|
/**
|
|
255
302
|
* Seed baseline records for tree skills the sidecar has not seen yet, so
|
|
256
303
|
* their inactivity clock starts now (first-sight defer) and bundled skills
|
|
257
|
-
* become known candidates only when prune-builtins opts them in.
|
|
304
|
+
* become known candidates only when prune-builtins opts them in. Also
|
|
305
|
+
* returns the full active tree names for nomination validation.
|
|
258
306
|
*/
|
|
259
307
|
async seedBaseline(usage) {
|
|
260
308
|
const bundledNames = /* @__PURE__ */ new Set();
|
|
309
|
+
const treeNames = /* @__PURE__ */ new Set();
|
|
261
310
|
for (const summary of await this.skills.list()) {
|
|
311
|
+
treeNames.add(summary.name);
|
|
262
312
|
if (!usage.has(summary.name)) usage.set(summary.name, emptyRecord());
|
|
263
313
|
if (await this.skills.isBundled(summary.name)) bundledNames.add(summary.name);
|
|
264
314
|
}
|
|
265
|
-
return
|
|
315
|
+
return {
|
|
316
|
+
bundledNames,
|
|
317
|
+
treeNames
|
|
318
|
+
};
|
|
266
319
|
}
|
|
267
320
|
recentSessionActive() {
|
|
268
321
|
const agents = this.ctx.get("agents");
|
package/lib/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
6
6
|
import type Schema from '@deepseek-ai/schemastery';
|
|
7
7
|
import { SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
-
import { type CuratorRunReport, type SkillActionResult } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
+
import { type CuratorNominations, type CuratorRunReport, type SkillActionResult } from '@deepseek-ai/dsh-evolution-core';
|
|
9
9
|
declare module '@deepseek-ai/cordis' {
|
|
10
10
|
interface Context {
|
|
11
11
|
evolutionCurator: EvolutionCurator;
|
|
@@ -29,6 +29,10 @@ export interface Config {
|
|
|
29
29
|
manageUnmanaged?: boolean;
|
|
30
30
|
/** Archive long-unused bundled skills too (with suppression against re-seeds). */
|
|
31
31
|
pruneBuiltins?: boolean;
|
|
32
|
+
/** Static scheduled-task skill references; such skills never auto-transition. */
|
|
33
|
+
referencedSkillNames?: string[];
|
|
34
|
+
/** Start the interval timer on context ready (auto-curation). Default true. */
|
|
35
|
+
autoStart?: boolean;
|
|
32
36
|
/** Max tokens for the optional LLM nomination pass. */
|
|
33
37
|
curatorReviewMaxTokens?: number;
|
|
34
38
|
}
|
|
@@ -39,6 +43,8 @@ export interface CuratorRunOutcome {
|
|
|
39
43
|
errors: string[];
|
|
40
44
|
report: CuratorRunReport;
|
|
41
45
|
skipped?: string;
|
|
46
|
+
/** LLM nominations when the optional review pass is enabled (audit visibility). */
|
|
47
|
+
nominations?: CuratorNominations;
|
|
42
48
|
}
|
|
43
49
|
export declare class EvolutionCurator extends Service {
|
|
44
50
|
static inject: string[];
|
|
@@ -56,6 +62,7 @@ export declare class EvolutionCurator extends Service {
|
|
|
56
62
|
private readonly excludeSkillNames;
|
|
57
63
|
private readonly manageUnmanaged;
|
|
58
64
|
private readonly pruneBuiltins;
|
|
65
|
+
private readonly referencedSkillNames;
|
|
59
66
|
private readonly curatorReviewMaxTokens;
|
|
60
67
|
private lastRun;
|
|
61
68
|
private timer;
|
|
@@ -64,24 +71,30 @@ export declare class EvolutionCurator extends Service {
|
|
|
64
71
|
start(): void;
|
|
65
72
|
stop(): void;
|
|
66
73
|
/**
|
|
67
|
-
* Optional Hermes-curator LLM pass. The model may only NOMINATE pruning
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
74
|
+
* Optional Hermes-curator LLM pass. The model may only NOMINATE pruning and
|
|
75
|
+
* consolidation; every move stays a control-plane operation and each
|
|
76
|
+
* nomination is re-validated against the tree and protected markers before
|
|
77
|
+
* any file move. `dryRun` prepends the report-only banner.
|
|
71
78
|
*/
|
|
72
|
-
recommend(candidates: string[]
|
|
79
|
+
recommend(candidates: string[], options?: {
|
|
80
|
+
dryRun?: boolean;
|
|
81
|
+
}): Promise<CuratorNominations>;
|
|
73
82
|
private skippedReport;
|
|
74
83
|
/**
|
|
75
84
|
* Run one curator pass. `ignoreGates` skips the interval and idle gates so an
|
|
76
|
-
* explicit `/evolution curator run` always executes (manual-run semantics)
|
|
85
|
+
* explicit `/evolution curator run` always executes (manual-run semantics):
|
|
86
|
+
* `dryRun` computes the lifecycle and the LLM nominations but performs no
|
|
87
|
+
* mutation, reports what WOULD happen, and does not push out the next run.
|
|
77
88
|
*/
|
|
78
89
|
run(options?: {
|
|
79
90
|
ignoreGates?: boolean;
|
|
91
|
+
dryRun?: boolean;
|
|
80
92
|
}): Promise<CuratorRunOutcome>;
|
|
81
93
|
/**
|
|
82
94
|
* Seed baseline records for tree skills the sidecar has not seen yet, so
|
|
83
95
|
* their inactivity clock starts now (first-sight defer) and bundled skills
|
|
84
|
-
* become known candidates only when prune-builtins opts them in.
|
|
96
|
+
* become known candidates only when prune-builtins opts them in. Also
|
|
97
|
+
* returns the full active tree names for nomination validation.
|
|
85
98
|
*/
|
|
86
99
|
private seedBaseline;
|
|
87
100
|
private recentSessionActive;
|
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.15",
|
|
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.15"
|
|
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.15",
|
|
43
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.15"
|
|
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.15",
|
|
49
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.15",
|
|
50
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.15"
|
|
51
51
|
}
|
|
52
52
|
}
|