@lmzhen/dsh-evolution-learning-graph 0.3.66 → 0.3.68
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 +32 -15
- package/lib/types/index.d.ts +0 -18
- package/package.json +5 -3
package/lib/index.js
CHANGED
|
@@ -13,6 +13,9 @@ import { SKILL_NAME_RE, SkillLibrary, contentHash, evolutionIoAdapter, relatedSk
|
|
|
13
13
|
* edit/delete can reject a stale index (E-21).
|
|
14
14
|
* @module @lmzhen/dsh-evolution-learning-graph
|
|
15
15
|
*/
|
|
16
|
+
/** V27 INS-04: how many skill files one `/graph` batch reads concurrently.
|
|
17
|
+
* Bounded so a large library cannot open every file at once (EMFILE). */
|
|
18
|
+
const SKILL_READ_BATCH = 16;
|
|
16
19
|
function graphDensity(graph) {
|
|
17
20
|
const linked = /* @__PURE__ */ new Set();
|
|
18
21
|
let relatedEdges = 0;
|
|
@@ -241,8 +244,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
241
244
|
const usage = usageService;
|
|
242
245
|
const memory = memoryService;
|
|
243
246
|
const io = ioService;
|
|
244
|
-
const session = invocation.agent
|
|
245
|
-
const input =
|
|
247
|
+
const session = invocation.agent.session;
|
|
248
|
+
const input = invocation.rawInput.trim();
|
|
246
249
|
const detail = /^detail\s+(\S+)$/.exec(input);
|
|
247
250
|
if (detail && detail[1]) return await nodeDetail(detail[1]);
|
|
248
251
|
const edit = /^edit\s+(\S+)\s+([\s\S]+)$/.exec(input);
|
|
@@ -258,7 +261,21 @@ function apply(ctx, rawConfig = {}) {
|
|
|
258
261
|
const userEntries = await memory.read("user");
|
|
259
262
|
const skills = withSkills();
|
|
260
263
|
const names = [...usageMap.keys()];
|
|
261
|
-
const contents =
|
|
264
|
+
const contents = [];
|
|
265
|
+
let unreadable = 0;
|
|
266
|
+
for (let offset = 0; offset < names.length; offset += SKILL_READ_BATCH) {
|
|
267
|
+
const batch = names.slice(offset, offset + SKILL_READ_BATCH);
|
|
268
|
+
const batchContents = await Promise.all(batch.map(async (name) => {
|
|
269
|
+
try {
|
|
270
|
+
return await skills.read(name);
|
|
271
|
+
} catch {
|
|
272
|
+
unreadable += 1;
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
}));
|
|
276
|
+
contents.push(...batchContents);
|
|
277
|
+
}
|
|
278
|
+
if (unreadable > 0) ctx.logger.warn(`evolution-learning-graph: ${unreadable} skill file(s) could not be read; their related_skills edges are missing from this graph`);
|
|
262
279
|
const related = /* @__PURE__ */ new Map();
|
|
263
280
|
names.forEach((name, index) => {
|
|
264
281
|
const content = contents[index];
|
|
@@ -291,7 +308,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
291
308
|
if (parsed === null) return err(`Invalid node id "${id}". Skill names or memory:<source>:<index> expected.`);
|
|
292
309
|
if (parsed.kind === "skill") {
|
|
293
310
|
const approval = ctx.get("evolutionApproval");
|
|
294
|
-
const origins = resolveOrigins(session
|
|
311
|
+
const origins = resolveOrigins(session.header.origin);
|
|
295
312
|
if (approval) {
|
|
296
313
|
const sessionPolicyEdit = effectiveSessionPolicy(ctx, session);
|
|
297
314
|
const stagesForeground = approval.stageForeground !== false;
|
|
@@ -312,8 +329,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
312
329
|
libraryOrigin: origins.library
|
|
313
330
|
},
|
|
314
331
|
origin: origins.approval,
|
|
315
|
-
...session
|
|
316
|
-
|
|
332
|
+
...session.id ? { sessionId: session.id } : {},
|
|
333
|
+
session,
|
|
317
334
|
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
318
335
|
});
|
|
319
336
|
if (decision.action === "staged") return ok(decision.message);
|
|
@@ -326,7 +343,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
326
343
|
if (!check.ok) return err(check.message ?? "Memory index check failed.");
|
|
327
344
|
const memoryApproval = ctx.get("evolutionApproval");
|
|
328
345
|
if (memoryApproval) {
|
|
329
|
-
const originsM = resolveOrigins(session
|
|
346
|
+
const originsM = resolveOrigins(session.header.origin);
|
|
330
347
|
const sessionPolicyM = effectiveSessionPolicy(ctx, session);
|
|
331
348
|
if (memoryApproval.isEnabled !== false && sessionPolicyM !== "never" && (originsM.approval === "background_review" || memoryApproval.stageForeground !== false) && !memoryApproval.hasRunner("memory")) return err("Graph memory write cannot be staged: no memory replay runner is registered — mount the tool-memory row (evolution-all bundle, or the evolution-preset overlay; the host bundle does not carry it) or disable evolution-approval.");
|
|
332
349
|
const decision = await memoryApproval.request({
|
|
@@ -341,8 +358,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
341
358
|
}]
|
|
342
359
|
},
|
|
343
360
|
origin: originsM.approval,
|
|
344
|
-
...session
|
|
345
|
-
|
|
361
|
+
...session.id ? { sessionId: session.id } : {},
|
|
362
|
+
session,
|
|
346
363
|
...sessionPolicyM !== void 0 ? { sessionPolicy: sessionPolicyM } : {}
|
|
347
364
|
});
|
|
348
365
|
if (decision.action === "staged") return ok(decision.message);
|
|
@@ -360,7 +377,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
360
377
|
if (parsed.kind === "skill") {
|
|
361
378
|
const approval = ctx.get("evolutionApproval");
|
|
362
379
|
if (approval) {
|
|
363
|
-
const origins = resolveOrigins(session
|
|
380
|
+
const origins = resolveOrigins(session.header.origin);
|
|
364
381
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
365
382
|
if (approval.isEnabled !== false && sessionPolicy !== "never" && (origins.approval === "background_review" || approval.stageForeground !== false) && !approval.hasRunner("skill")) return err("Graph skill delete cannot be staged: no skill replay runner is registered — mount the tool-skill-manage row (evolution-agent preset) or disable evolution-approval.");
|
|
366
383
|
const decision = await approval.request({
|
|
@@ -375,8 +392,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
375
392
|
libraryOrigin: origins.library
|
|
376
393
|
},
|
|
377
394
|
origin: origins.approval,
|
|
378
|
-
...session
|
|
379
|
-
|
|
395
|
+
...session.id ? { sessionId: session.id } : {},
|
|
396
|
+
session,
|
|
380
397
|
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
381
398
|
});
|
|
382
399
|
if (decision.action === "staged") return ok(decision.message);
|
|
@@ -389,7 +406,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
389
406
|
if (!check.ok) return err(check.message ?? "Memory index check failed.");
|
|
390
407
|
const memoryApproval = ctx.get("evolutionApproval");
|
|
391
408
|
if (memoryApproval) {
|
|
392
|
-
const origins = resolveOrigins(session
|
|
409
|
+
const origins = resolveOrigins(session.header.origin);
|
|
393
410
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
394
411
|
if (memoryApproval.isEnabled !== false && sessionPolicy !== "never" && (origins.approval === "background_review" || memoryApproval.stageForeground !== false) && !memoryApproval.hasRunner("memory")) return err("Graph memory delete cannot be staged: no memory replay runner is registered — mount the tool-memory row (evolution-all bundle, or the evolution-preset overlay; the host bundle does not carry it) or disable evolution-approval.");
|
|
395
412
|
const decision = await memoryApproval.request({
|
|
@@ -403,8 +420,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
403
420
|
}]
|
|
404
421
|
},
|
|
405
422
|
origin: origins.approval,
|
|
406
|
-
...session
|
|
407
|
-
|
|
423
|
+
...session.id ? { sessionId: session.id } : {},
|
|
424
|
+
session,
|
|
408
425
|
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
409
426
|
});
|
|
410
427
|
if (decision.action === "staged") return ok(decision.message);
|
package/lib/types/index.d.ts
CHANGED
|
@@ -37,24 +37,6 @@ export interface GraphDensity {
|
|
|
37
37
|
edgesPerNode: number;
|
|
38
38
|
isolatedPct: number;
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
41
|
-
* The command invocation contract (N1, v12): the platform command handler
|
|
42
|
-
* freezes the invoking agent onto the invocation object — evolution-commands
|
|
43
|
-
* `/evolution learn` already reads `invocation.agent` — so the graph can pass
|
|
44
|
-
* `agent.session` to the approval service (tool-skill-manage pattern) instead
|
|
45
|
-
* of deriving every approval as foreground.
|
|
46
|
-
*/
|
|
47
|
-
export interface GraphInvocation {
|
|
48
|
-
rawInput?: string;
|
|
49
|
-
agent?: {
|
|
50
|
-
session?: {
|
|
51
|
-
id?: string;
|
|
52
|
-
header?: {
|
|
53
|
-
origin?: string;
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
40
|
export declare function graphDensity(graph: LearningGraph): GraphDensity;
|
|
59
41
|
/**
|
|
60
42
|
* Render one node's display line for `/evolution graph`.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-learning-graph",
|
|
3
3
|
"description": "Learning graph over skills and memory (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.68",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,14 +31,16 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-approval": "^0.3.
|
|
35
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-approval": "^0.3.68",
|
|
35
|
+
"@lmzhen/dsh-evolution-core": "^0.3.68"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
+
"@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
|
|
38
39
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
39
40
|
"@deepseek-ai/cordis": "^4.0.1"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
43
|
+
"@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
|
|
42
44
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2"
|
|
43
45
|
}
|
|
44
46
|
}
|