@lmzhen/dsh-evolution-learning-graph 0.3.61 → 0.3.63
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/README.md +1 -1
- package/lib/index.js +58 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Memory node ids carry a trailing snapshot token (`memory:<source>:<index>:<snaps
|
|
|
10
10
|
|
|
11
11
|
Memory→skill edges are word-level, not substring: the entry is tokenized on non-letter/digit/hyphen runs and a skill name links only when it is a whole token. This prevents a skill named `run` from linking the words `running`/`grunt`.
|
|
12
12
|
|
|
13
|
-
`graph edit`/`graph delete`
|
|
13
|
+
`graph edit`/`graph delete` route through the evolution approval seam when it is mounted (soft-probed; the write executes directly when it is absent) — for BOTH skill nodes and memory nodes (P2-6, v15; memory staged args mirror the `memory` tool runner's replay shape). Before staging, the seam's `hasRunner` is checked (P2-7, v15): with approval enabled, a session policy that is not `never`, and the write actually staging (foreground stages per approval `stageForeground`; subagent origins always stage), a missing replay runner's row (tool-skill-manage / tool-memory) refuses the write; allow-direct combinations execute unchanged instead of creating a pending record no approver could replay. Each approved/executed edit bumps the skill's patch counter and a delete archives it, matching `skill_manage` — including the no-op gate: an edit whose content is byte-equivalent to the current file (`noop`) writes nothing and does not bump the patch counter, exactly as `skill_manage` treats an unchanged update/patch. The command invocation's session rides the approval request (v12 N1), so a `never`-policy session stages nothing instead of deriving every graph write as foreground.
|
|
14
14
|
|
|
15
15
|
## Model Experience
|
|
16
16
|
|
package/lib/index.js
CHANGED
|
@@ -255,12 +255,14 @@ function apply(ctx, rawConfig = {}) {
|
|
|
255
255
|
const memoryEntries = await memory.read("memory");
|
|
256
256
|
const userEntries = await memory.read("user");
|
|
257
257
|
const skills = withSkills();
|
|
258
|
+
const names = [...usageMap.keys()];
|
|
259
|
+
const contents = await Promise.all(names.map((name) => skills.read(name)));
|
|
258
260
|
const related = /* @__PURE__ */ new Map();
|
|
259
|
-
|
|
260
|
-
const content =
|
|
261
|
-
if (content === null)
|
|
261
|
+
names.forEach((name, index) => {
|
|
262
|
+
const content = contents[index];
|
|
263
|
+
if (content === null || content === void 0) return;
|
|
262
264
|
related.set(name, relatedSkillNames(content, name));
|
|
263
|
-
}
|
|
265
|
+
});
|
|
264
266
|
const graph = buildLearningGraph(usageMap, memoryEntries, userEntries, related);
|
|
265
267
|
const nodeBlock = capRenderedLines(graph.nodes.map((node) => renderNodeLine(node)));
|
|
266
268
|
const edgeBlock = capRenderedLines(graph.edges.map((edge) => edge.from + " --" + edge.type + "--> " + edge.to));
|
|
@@ -287,9 +289,12 @@ function apply(ctx, rawConfig = {}) {
|
|
|
287
289
|
if (parsed === null) return err(`Invalid node id "${id}". Skill names or memory:<source>:<index> expected.`);
|
|
288
290
|
if (parsed.kind === "skill") {
|
|
289
291
|
const approval = ctx.get("evolutionApproval");
|
|
292
|
+
const origins = resolveOrigins(session?.header?.origin);
|
|
290
293
|
if (approval) {
|
|
291
|
-
const
|
|
292
|
-
const
|
|
294
|
+
const sessionPolicyEdit = effectiveSessionPolicy(ctx, session);
|
|
295
|
+
const stagesForeground = approval.stageForeground !== false;
|
|
296
|
+
if (approval.isEnabled !== false && sessionPolicyEdit !== "never" && (origins.approval === "background_review" || stagesForeground) && !approval.hasRunner("skill")) return err("Graph skill write cannot be staged: no skill replay runner is registered — mount the tool-skill-manage row (evolution-agent preset) or disable evolution-approval.");
|
|
297
|
+
const sessionPolicy = sessionPolicyEdit;
|
|
293
298
|
const decision = await approval.request({
|
|
294
299
|
kind: "skill",
|
|
295
300
|
summary: `graph edit ${parsed.name}`,
|
|
@@ -309,12 +314,35 @@ function apply(ctx, rawConfig = {}) {
|
|
|
309
314
|
});
|
|
310
315
|
if (decision.action === "staged") return ok(decision.message);
|
|
311
316
|
}
|
|
312
|
-
const result = await withSkills().update(parsed.name, content,
|
|
317
|
+
const result = await withSkills().update(parsed.name, content, origins.library);
|
|
313
318
|
if (result.ok && result.noop !== true) await usageService.record?.(parsed.name, "patch");
|
|
314
319
|
return result.ok ? ok(result.message) : err(result.message);
|
|
315
320
|
}
|
|
316
321
|
const check = readMemoryIndex(parsed, await memory.read(parsed.source));
|
|
317
322
|
if (!check.ok) return err(check.message ?? "Memory index check failed.");
|
|
323
|
+
const memoryApproval = ctx.get("evolutionApproval");
|
|
324
|
+
if (memoryApproval) {
|
|
325
|
+
const originsM = resolveOrigins(session?.header?.origin);
|
|
326
|
+
const sessionPolicyM = effectiveSessionPolicy(ctx, session);
|
|
327
|
+
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-host/evolution-all bundle) or disable evolution-approval.");
|
|
328
|
+
const decision = await memoryApproval.request({
|
|
329
|
+
kind: "memory",
|
|
330
|
+
summary: `graph edit memory:${parsed.source}:${parsed.index}`,
|
|
331
|
+
args: {
|
|
332
|
+
target: parsed.source,
|
|
333
|
+
operations: [{
|
|
334
|
+
action: "replace",
|
|
335
|
+
old_text: check.entry ?? "",
|
|
336
|
+
facts: content
|
|
337
|
+
}]
|
|
338
|
+
},
|
|
339
|
+
origin: originsM.approval,
|
|
340
|
+
...session?.id ? { sessionId: session.id } : {},
|
|
341
|
+
...session ? { session } : {},
|
|
342
|
+
...sessionPolicyM !== void 0 ? { sessionPolicy: sessionPolicyM } : {}
|
|
343
|
+
});
|
|
344
|
+
if (decision.action === "staged") return ok(decision.message);
|
|
345
|
+
}
|
|
318
346
|
const result = await memory.applyBatch(parsed.source, [{
|
|
319
347
|
action: "replace",
|
|
320
348
|
old_text: check.entry ?? "",
|
|
@@ -330,6 +358,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
330
358
|
if (approval) {
|
|
331
359
|
const origins = resolveOrigins(session?.header?.origin);
|
|
332
360
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
361
|
+
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.");
|
|
333
362
|
const decision = await approval.request({
|
|
334
363
|
kind: "skill",
|
|
335
364
|
summary: `graph delete ${parsed.name}`,
|
|
@@ -354,6 +383,28 @@ function apply(ctx, rawConfig = {}) {
|
|
|
354
383
|
}
|
|
355
384
|
const check = readMemoryIndex(parsed, await memory.read(parsed.source));
|
|
356
385
|
if (!check.ok) return err(check.message ?? "Memory index check failed.");
|
|
386
|
+
const memoryApproval = ctx.get("evolutionApproval");
|
|
387
|
+
if (memoryApproval) {
|
|
388
|
+
const origins = resolveOrigins(session?.header?.origin);
|
|
389
|
+
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
390
|
+
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-host/evolution-all bundle) or disable evolution-approval.");
|
|
391
|
+
const decision = await memoryApproval.request({
|
|
392
|
+
kind: "memory",
|
|
393
|
+
summary: `graph delete memory:${parsed.source}:${parsed.index}`,
|
|
394
|
+
args: {
|
|
395
|
+
target: parsed.source,
|
|
396
|
+
operations: [{
|
|
397
|
+
action: "remove",
|
|
398
|
+
old_text: check.entry ?? ""
|
|
399
|
+
}]
|
|
400
|
+
},
|
|
401
|
+
origin: origins.approval,
|
|
402
|
+
...session?.id ? { sessionId: session.id } : {},
|
|
403
|
+
...session ? { session } : {},
|
|
404
|
+
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
405
|
+
});
|
|
406
|
+
if (decision.action === "staged") return ok(decision.message);
|
|
407
|
+
}
|
|
357
408
|
const result = await memory.applyBatch(parsed.source, [{
|
|
358
409
|
action: "remove",
|
|
359
410
|
old_text: check.entry ?? ""
|
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.63",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,8 +31,8 @@
|
|
|
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.63",
|
|
35
|
+
"@lmzhen/dsh-evolution-core": "^0.3.63"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|