@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 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?.session;
245
- const input = (invocation.rawInput ?? "").trim();
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 = await Promise.all(names.map((name) => skills.read(name)));
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?.header?.origin);
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?.id ? { sessionId: session.id } : {},
316
- ...session ? { session } : {},
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?.header?.origin);
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?.id ? { sessionId: session.id } : {},
345
- ...session ? { session } : {},
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?.header?.origin);
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?.id ? { sessionId: session.id } : {},
379
- ...session ? { session } : {},
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?.header?.origin);
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?.id ? { sessionId: session.id } : {},
407
- ...session ? { session } : {},
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);
@@ -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.66",
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.66",
35
- "@lmzhen/dsh-evolution-core": "^0.3.66"
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
  }