@lmzhen/dsh-evolution-review 0.1.0-rc.28 → 0.1.0-rc.29

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.
Files changed (2) hide show
  1. package/lib/index.js +33 -19
  2. package/package.json +7 -7
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import z from "@deepseek-ai/schemastery";
3
- import { CallId, createUserMessage } from "@deepseek-ai/dsh-llm";
4
- import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, PROMPT_BUNDLE, advanceReview, foldTurn, reviewPrompt, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
3
+ import { createUserMessage } from "@deepseek-ai/dsh-llm";
4
+ import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, PROMPT_BUNDLE, SkillLibrary, advanceReview, evolutionIoAdapter, foldTurn, reviewPrompt, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
5
5
  import { validateEvolutionPlan } from "@lmzhen/dsh-evolution-plan-validator";
6
6
  //#region lib/types/redact.js
7
7
  /**
@@ -92,6 +92,8 @@ function apply(ctx, rawConfig) {
92
92
  substantiveMinAgentChars: snapshot?.substantiveMinAgentChars ?? 500
93
93
  });
94
94
  await stateService?.saveReviewState(session.id, state);
95
+ const cumulative = (cumulativeToolCalls.get(session.id) ?? 0) + signal.toolCalls;
96
+ cumulativeToolCalls.set(session.id, cumulative);
95
97
  if (kind) {
96
98
  session.append("evolution/review-scheduled", {
97
99
  kind,
@@ -116,8 +118,6 @@ function apply(ctx, rawConfig) {
116
118
  const trigger = config.skillReviewTrigger;
117
119
  if (trigger !== "completion" && trigger !== "both") return;
118
120
  if (completionInjected.has(session.id)) return;
119
- const cumulative = (cumulativeToolCalls.get(session.id) ?? 0) + signal.toolCalls;
120
- cumulativeToolCalls.set(session.id, cumulative);
121
121
  if (!shouldCompletionReview(event.data.reason, cumulative, config.skillReviewCompletionMinToolCalls)) return;
122
122
  completionInjected.add(session.id);
123
123
  session.append("evolution/review-scheduled", {
@@ -194,7 +194,7 @@ function apply(ctx, rawConfig) {
194
194
  const acceptedSkillOps = validation.accepted.skillOps ?? [];
195
195
  const skippedUnread = filterUnreadSkillOps(acceptedSkillOps, collectReadSkillNames(session));
196
196
  validation.accepted.skillOps = acceptedSkillOps;
197
- const actions = await executePlan(validation.accepted, agent);
197
+ const actions = await executePlan(validation.accepted);
198
198
  const evidenceQuotes = [...validation.accepted.memoryOps ?? [], ...acceptedSkillOps].reduce((total, op) => total + (Array.isArray(op.evidence) ? op.evidence.length : 0), 0);
199
199
  session.append("evolution/plan-applied", {
200
200
  planId: randomUUID(),
@@ -223,7 +223,7 @@ function apply(ctx, rawConfig) {
223
223
  return false;
224
224
  }
225
225
  }
226
- async function executePlan(plan, parent) {
226
+ async function executePlan(plan) {
227
227
  const memory = ctx.get("memory");
228
228
  const approval = ctx.get("evolutionApproval");
229
229
  const actions = [];
@@ -247,7 +247,7 @@ function apply(ctx, rawConfig) {
247
247
  operation: args,
248
248
  origin: "background_review"
249
249
  };
250
- if ((approval ? await runApproved("skill", `skill ${op.action ?? "patch"} ${op.name}`, runnerArgs, runnerArgs) : await executeSkillTool(parent, args))?.ok) actions.push(`Skill ${op.name} ${op.action ?? "patch"}`);
250
+ if ((approval ? await runApproved("skill", `skill ${op.action ?? "patch"} ${op.name}`, runnerArgs, runnerArgs) : await executeSkillDirect(args))?.ok) actions.push(`Skill ${op.name} ${op.action ?? "patch"}`);
251
251
  }
252
252
  return actions;
253
253
  async function runApproved(kind, summary, stored, runnerArgs) {
@@ -264,19 +264,32 @@ function apply(ctx, rawConfig) {
264
264
  };
265
265
  return await approval.run(kind, runnerArgs);
266
266
  }
267
- async function executeSkillTool(agent, args) {
268
- return (await ctx.tools.execute({
269
- callId: CallId(`evolution-${randomUUID()}`),
270
- name: "skill_manage",
271
- arguments: args,
272
- agent,
273
- signal: AbortSignal.timeout(config.executionTimeoutMs)
274
- })).isError ? {
267
+ /**
268
+ * Approval-disabled path: execute the skill op through SkillLibrary with an
269
+ * EXPLICIT background_review origin. Going through ctx.tools.execute would
270
+ * make tool-skill-manage infer origin from the parent agent's header
271
+ * (not 'subagent'), silently escaping the .hermes-managed marker and the
272
+ * pinned write guard.
273
+ */
274
+ async function executeSkillDirect(skillArgs) {
275
+ const io = ctx.get("evolutionIo");
276
+ if (!io) return {
277
+ ok: false,
278
+ message: "evolution-io service not mounted"
279
+ };
280
+ const library = new SkillLibrary(void 0, evolutionIoAdapter(() => io.provider()));
281
+ const op = skillArgs;
282
+ const name = op.name ?? "";
283
+ const origin = "background_review";
284
+ if (op.action === "create") return await library.create(name, op.content ?? "", origin);
285
+ if (op.action === "edit" || op.action === "update") return await library.update(name, op.content ?? "", origin);
286
+ if (op.action === "patch") return await library.patch(name, op.old_string ?? "", op.new_string ?? "", op.file_path ?? "", false, origin);
287
+ if (op.action === "delete") return await library.archive(name, op.absorbed_into ? { absorbedInto: op.absorbed_into } : {});
288
+ if (op.action === "write_file") return await library.writeSupportFile(name, op.file_path ?? "", op.file_content ?? op.content ?? "", origin);
289
+ if (op.action === "remove_file") return await library.removeSupportFile(name, op.file_path ?? "", origin);
290
+ return {
275
291
  ok: false,
276
- message: "skill_manage execution failed"
277
- } : {
278
- ok: true,
279
- message: "skill_manage executed"
292
+ message: `Unknown skill action "${op.action ?? ""}"`
280
293
  };
281
294
  }
282
295
  }
@@ -322,6 +335,7 @@ function filterUnreadSkillOps(ops, readNames) {
322
335
  "edit",
323
336
  "update",
324
337
  "patch",
338
+ "delete",
325
339
  "write_file",
326
340
  "remove_file"
327
341
  ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-review",
3
3
  "description": "Background review orchestration (community build)",
4
- "version": "0.1.0-rc.28",
4
+ "version": "0.1.0-rc.29",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -33,8 +33,8 @@
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
35
  "@deepseek-ai/schemastery": "^3.18.1",
36
- "@lmzhen/dsh-evolution-core": "^0.1.0-rc.28",
37
- "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.28"
36
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.29",
37
+ "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.29"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@deepseek-ai/cordis": "^4.0.1",
@@ -43,7 +43,7 @@
43
43
  "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
44
44
  "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
45
45
  "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
46
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.28"
46
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.29"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
@@ -52,8 +52,8 @@
52
52
  "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
53
53
  "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
54
54
  "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
55
- "@lmzhen/dsh-evolution-core": "^0.1.0-rc.28",
56
- "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.28",
57
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.28"
55
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.29",
56
+ "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.29",
57
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.29"
58
58
  }
59
59
  }