@lmzhen/dsh-evolution-review 0.3.65 → 0.3.67
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 +164 -36
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Independent of request-prefix construction. This package does not alter the asse
|
|
|
25
25
|
- Review subagents run as `spawn` children on the deployment default preset rather than inheriting the parent agent's composition (`fork`): a fork child is always promoted by the Anchored Standard bootstrap and its narrowed resident catalog would drop the plain `skill` tool from the review allow-list.
|
|
26
26
|
- The review request text is redacted for credential-shaped patterns before it reaches the subagent, but redaction is pattern-based and best-effort, not a security boundary.
|
|
27
27
|
- Read-before-write tracks only reads through the `skill` tool. `skill_manage` has no per-skill read action (`list`/`review` are whole-library, not targeted at one name), so a skill that was only listed via `skill_manage` is not marked as read — a background review may still reject a patch to it until it is actually loaded.
|
|
28
|
-
- The completion-channel counters (`cumulativeToolCalls` / `completionInjected`) are in-memory only. A process restart resets them, which is accepted behavior: the completion review is a one-per-session post-task adaptation and a restart is treated as a fresh conversation boundary. The cadence state (`turnsSinceMemory` / `turnsSinceSkill`) is persisted via `ReviewState` and survives restart.
|
|
28
|
+
- The completion-channel counters (`cumulativeToolCalls` / `completionInjected`) are in-memory only. A process restart resets them, which is accepted behavior: the completion review is a one-per-session post-task adaptation and a restart is treated as a fresh conversation boundary. The cadence state (`turnsSinceMemory` / `turnsSinceSkill`) is persisted via `ReviewState` and survives restart — bounded by `REVIEW_STATE_SESSION_CAP` (500, seam constant): the least-recently-active sessions are pruned on save, so a very old session restarting resumes from a fresh cadence baseline rather than an unbounded store.
|
|
29
29
|
- `evolution/review-scheduled` and `evolution/review-error` are emitted for platform/user wiring only — this family has no in-repo production `ctx.on` consumer for them. They are declared externally owned (the platform side wires consumption), which matches the `EXEMPT_ORPHANS` set in `scripts/verify-event-pairing.mjs`.
|
|
30
30
|
- When the `evolution-state` service is not mounted, the memory/skill cadence state is not persisted and every turn restarts from a clean `{ turnsSinceMemory: 0, turnsSinceSkill: 0 }` baseline — the review schedule is stateless and re-decided each turn rather than accumulating across the conversation. The loss is surfaced once per process as a logger warning at the first turn/end.
|
|
31
31
|
- Read-before-write can see the review subagent's own `skill` reads only when the subagent backend exposes `localAgent` (the in-process driver does; out-of-process backends such as ACP and the CLI providers set `localAgent: undefined`). With a remote backend the subagent's reads are invisible, so a plan item patching a skill the subagent itself loaded is dropped as "unread" — the review then falls back to the parent session's reads only. Documented rather than worked around: recovering the child read set needs a `SubagentLike` contract change (v14 P2-6).
|
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
3
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
4
|
-
import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_USER_CHAR_LIMIT, PROMPT_BUNDLE, SkillLibrary, advanceReview, clampedNumber, evolutionIoAdapter, foldTurn, redactSecrets, resolveOrigins, resolveRootConfig, resolveSkillsRoot, reviewPrompt, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
|
|
4
|
+
import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_USER_CHAR_LIMIT, PROMPT_BUNDLE, SkillLibrary, advanceReview, clampedNumber, contentHash, evolutionIoAdapter, foldTurn, redactSecrets, resolveOrigins, resolveRootConfig, resolveSkillsRoot, reviewPrompt, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
|
|
5
5
|
import { validateEvolutionPlan } from "@lmzhen/dsh-evolution-plan-validator";
|
|
6
6
|
//#region lib/types/index.js
|
|
7
7
|
/**
|
|
@@ -93,8 +93,18 @@ function apply(ctx, rawConfig = {}) {
|
|
|
93
93
|
const cadenceResetWarned = /* @__PURE__ */ new Set();
|
|
94
94
|
let reviewInFlight = false;
|
|
95
95
|
const policy = () => ctx.get("evolutionPolicy")?.get();
|
|
96
|
+
const reviewStateLocks = /* @__PURE__ */ new Map();
|
|
97
|
+
async function withReviewStateLock(id, task) {
|
|
98
|
+
const next = (reviewStateLocks.get(id) ?? Promise.resolve()).catch(() => {}).then(task);
|
|
99
|
+
reviewStateLocks.set(id, next);
|
|
100
|
+
try {
|
|
101
|
+
return await next;
|
|
102
|
+
} finally {
|
|
103
|
+
if (reviewStateLocks.get(id) === next) reviewStateLocks.delete(id);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
96
106
|
ctx.on("session/event", (session, event) => {
|
|
97
|
-
if (event.type === "turn/start") turnStarts.set(session.id, session.seq - 1);
|
|
107
|
+
if (event.type === "turn/start" && session.header.origin !== "subagent") turnStarts.set(session.id, session.seq - 1);
|
|
98
108
|
if (event.type !== "turn/end") return;
|
|
99
109
|
if (turnStarts.size >= COUNTER_SWEEP_THRESHOLD || cumulativeToolCalls.size >= COUNTER_SWEEP_THRESHOLD || completionInjected.size >= COUNTER_SWEEP_THRESHOLD || pendingCadenceReviews.size >= COUNTER_SWEEP_THRESHOLD || skipNextCadenceFire.size >= COUNTER_SWEEP_THRESHOLD || cadenceResetWarned.size >= COUNTER_SWEEP_THRESHOLD) {
|
|
100
110
|
const isAlive = (id) => ctx.agents.get(id) !== void 0;
|
|
@@ -132,24 +142,32 @@ function apply(ctx, rawConfig = {}) {
|
|
|
132
142
|
statelessReviewStateWarned = true;
|
|
133
143
|
ctx.logger.warn("dsh-evolution-review: evolution-state service not mounted — memory/skill review cadence is not persisted and resets every turn (see README Known Limitations).");
|
|
134
144
|
}
|
|
135
|
-
const
|
|
145
|
+
const snapshot = policy();
|
|
146
|
+
const skipFire = skipNextCadenceFire.get(session.id) ?? false;
|
|
147
|
+
if (skipFire) skipNextCadenceFire.delete(session.id);
|
|
148
|
+
let state = {
|
|
136
149
|
turnsSinceMemory: 0,
|
|
137
150
|
turnsSinceSkill: 0,
|
|
138
151
|
lastTurn: -1
|
|
139
152
|
};
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
const advanced = { kind: null };
|
|
154
|
+
await withReviewStateLock(session.id, async () => {
|
|
155
|
+
state = await stateService?.loadReviewState(session.id) ?? {
|
|
156
|
+
turnsSinceMemory: 0,
|
|
157
|
+
turnsSinceSkill: 0,
|
|
158
|
+
lastTurn: -1
|
|
159
|
+
};
|
|
160
|
+
advanced.kind = advanceReview(state, event.data.turn, signal, {
|
|
161
|
+
memoryInterval: snapshot?.reviewMemoryInterval ?? config.memoryInterval,
|
|
162
|
+
skillInterval: snapshot?.reviewSkillInterval ?? config.skillInterval,
|
|
163
|
+
substantiveMinToolCalls: snapshot?.substantiveMinToolCalls ?? 3,
|
|
164
|
+
substantiveMinUserChars: snapshot?.substantiveMinUserChars ?? 200,
|
|
165
|
+
substantiveMinAgentChars: snapshot?.substantiveMinAgentChars ?? 500,
|
|
166
|
+
resetOnFire: false
|
|
167
|
+
});
|
|
168
|
+
await stateService?.saveReviewState(session.id, state);
|
|
150
169
|
});
|
|
151
|
-
const kind = skipFire ? null :
|
|
152
|
-
await stateService?.saveReviewState(session.id, state);
|
|
170
|
+
const kind = skipFire ? null : advanced.kind;
|
|
153
171
|
const cumulative = (cumulativeToolCalls.get(session.id) ?? 0) + signal.toolCalls;
|
|
154
172
|
cumulativeToolCalls.set(session.id, cumulative);
|
|
155
173
|
if (event.data.reason.kind === "completed") {
|
|
@@ -158,29 +176,60 @@ function apply(ctx, rawConfig = {}) {
|
|
|
158
176
|
pendingCadenceReviews.delete(session.id);
|
|
159
177
|
if ((policy()?.reviewMode ?? config.reviewMode) === "inject") try {
|
|
160
178
|
deliverMessage(agent, reviewPrompt(pendingKind), "auto-review");
|
|
179
|
+
try {
|
|
180
|
+
ctx.emit("evolution/review-scheduled", {
|
|
181
|
+
sessionId: session.id,
|
|
182
|
+
kind: pendingKind,
|
|
183
|
+
toolCalls: signal.toolCalls,
|
|
184
|
+
userChars: signal.userChars,
|
|
185
|
+
assistantChars: signal.assistantChars,
|
|
186
|
+
channel: "inject"
|
|
187
|
+
});
|
|
188
|
+
} catch (emitError) {
|
|
189
|
+
ctx.logger.warn(`dsh-evolution-review: review-scheduled emit failed: ${emitError instanceof Error ? emitError.message : String(emitError)}`);
|
|
190
|
+
}
|
|
161
191
|
} catch (injectError) {
|
|
162
192
|
ctx.logger.warn(`dsh-evolution-review: deferred review inject failed: ${injectError instanceof Error ? injectError.message : String(injectError)}`);
|
|
163
193
|
}
|
|
164
|
-
else
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
194
|
+
else {
|
|
195
|
+
const reviewOutcome = await trySubagentReview(session, agent, pendingKind, signal);
|
|
196
|
+
if (reviewOutcome === true) try {
|
|
197
|
+
ctx.emit("evolution/review-scheduled", {
|
|
198
|
+
sessionId: session.id,
|
|
199
|
+
kind: pendingKind,
|
|
200
|
+
toolCalls: signal.toolCalls,
|
|
201
|
+
userChars: signal.userChars,
|
|
202
|
+
assistantChars: signal.assistantChars,
|
|
203
|
+
channel: "subagent"
|
|
204
|
+
});
|
|
205
|
+
} catch (emitError) {
|
|
206
|
+
ctx.logger.warn(`dsh-evolution-review: review-scheduled emit failed: ${emitError instanceof Error ? emitError.message : String(emitError)}`);
|
|
207
|
+
}
|
|
208
|
+
else if (reviewOutcome !== "deferred") try {
|
|
209
|
+
deliverMessage(agent, reviewPrompt(pendingKind), "auto-review");
|
|
210
|
+
try {
|
|
211
|
+
ctx.emit("evolution/review-scheduled", {
|
|
212
|
+
sessionId: session.id,
|
|
213
|
+
kind: pendingKind,
|
|
214
|
+
toolCalls: signal.toolCalls,
|
|
215
|
+
userChars: signal.userChars,
|
|
216
|
+
assistantChars: signal.assistantChars,
|
|
217
|
+
channel: "inject"
|
|
218
|
+
});
|
|
219
|
+
} catch (emitError) {
|
|
220
|
+
ctx.logger.warn(`dsh-evolution-review: review-scheduled emit failed: ${emitError instanceof Error ? emitError.message : String(emitError)}`);
|
|
221
|
+
}
|
|
222
|
+
} catch (injectError) {
|
|
223
|
+
ctx.logger.warn(`dsh-evolution-review: deferred review inject failed: ${injectError instanceof Error ? injectError.message : String(injectError)}`);
|
|
224
|
+
}
|
|
179
225
|
}
|
|
180
|
-
state.turnsSinceMemory = 0;
|
|
181
|
-
state.turnsSinceSkill = 0;
|
|
182
226
|
try {
|
|
183
|
-
await
|
|
227
|
+
await withReviewStateLock(session.id, async () => {
|
|
228
|
+
const fresh = await stateService?.loadReviewState(session.id) ?? state;
|
|
229
|
+
fresh.turnsSinceMemory = 0;
|
|
230
|
+
fresh.turnsSinceSkill = 0;
|
|
231
|
+
await stateService?.saveReviewState(session.id, fresh);
|
|
232
|
+
});
|
|
184
233
|
} catch (resetError) {
|
|
185
234
|
if (!cadenceResetWarned.has(session.id)) {
|
|
186
235
|
cadenceResetWarned.add(session.id);
|
|
@@ -204,6 +253,22 @@ function apply(ctx, rawConfig = {}) {
|
|
|
204
253
|
if (completionInjected.has(session.id)) return;
|
|
205
254
|
if (!shouldCompletionReview(event.data.reason, cumulative, config.skillReviewCompletionMinToolCalls)) return;
|
|
206
255
|
completionInjected.add(session.id);
|
|
256
|
+
if (reviewInFlight) {
|
|
257
|
+
if (deferredFallbackReviews.length < DEFERRED_REVIEW_CAP) deferredFallbackReviews.push({
|
|
258
|
+
agent,
|
|
259
|
+
sessionId: session.id,
|
|
260
|
+
kind: "skill",
|
|
261
|
+
prompt: COMPLETION_SKILL_REVIEW_PROMPT,
|
|
262
|
+
label: "completion review",
|
|
263
|
+
channel: "completion",
|
|
264
|
+
counts: signal
|
|
265
|
+
});
|
|
266
|
+
else {
|
|
267
|
+
completionInjected.delete(session.id);
|
|
268
|
+
ctx.logger.warn(`dsh-evolution-review: deferred-review queue at cap (${DEFERRED_REVIEW_CAP}) — dropped one deferred completion review prompt; the completion gate re-arms for the next completed turn`);
|
|
269
|
+
}
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
207
272
|
try {
|
|
208
273
|
deliverMessage(agent, COMPLETION_SKILL_REVIEW_PROMPT, "completion review");
|
|
209
274
|
} catch (injectError) {
|
|
@@ -217,7 +282,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
217
282
|
kind: "skill",
|
|
218
283
|
toolCalls: signal.toolCalls,
|
|
219
284
|
userChars: signal.userChars,
|
|
220
|
-
assistantChars: signal.assistantChars
|
|
285
|
+
assistantChars: signal.assistantChars,
|
|
286
|
+
channel: "completion"
|
|
221
287
|
});
|
|
222
288
|
} catch (emitError) {
|
|
223
289
|
ctx.logger.warn(`dsh-evolution-review: review-scheduled emit failed: ${emitError instanceof Error ? emitError.message : String(emitError)}`);
|
|
@@ -246,11 +312,40 @@ function apply(ctx, rawConfig = {}) {
|
|
|
246
312
|
skipNextCadenceFire.set(agent.session.id, true);
|
|
247
313
|
} else agent.inject(message);
|
|
248
314
|
};
|
|
315
|
+
const withTimeout = (promise, ms, label) => new Promise((resolve, reject) => {
|
|
316
|
+
const timer = setTimeout(() => {
|
|
317
|
+
reject(/* @__PURE__ */ new Error(`dsh-evolution-review: ${label} timed out after ${ms}ms`));
|
|
318
|
+
}, ms);
|
|
319
|
+
promise.then((value) => {
|
|
320
|
+
clearTimeout(timer);
|
|
321
|
+
resolve(value);
|
|
322
|
+
}, (error) => {
|
|
323
|
+
clearTimeout(timer);
|
|
324
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
const deferredFallbackReviews = [];
|
|
328
|
+
const DEFERRED_REVIEW_CAP = 16;
|
|
329
|
+
ctx.effect(() => () => {
|
|
330
|
+
deferredFallbackReviews.length = 0;
|
|
331
|
+
}, "dsh-evolution-review.deferred-drain");
|
|
249
332
|
async function trySubagentReview(session, agent, kind, signal) {
|
|
250
333
|
if ((policy()?.reviewMode ?? config.reviewMode) === "inject") return false;
|
|
251
334
|
const subagents = ctx.get("subagents");
|
|
252
335
|
if (!subagents) return false;
|
|
253
|
-
if (reviewInFlight)
|
|
336
|
+
if (reviewInFlight) {
|
|
337
|
+
if (deferredFallbackReviews.length < DEFERRED_REVIEW_CAP) deferredFallbackReviews.push({
|
|
338
|
+
agent,
|
|
339
|
+
sessionId: session.id,
|
|
340
|
+
kind,
|
|
341
|
+
prompt: reviewPrompt(kind),
|
|
342
|
+
label: "auto-review",
|
|
343
|
+
channel: "inject",
|
|
344
|
+
counts: signal
|
|
345
|
+
});
|
|
346
|
+
else ctx.logger.warn(`dsh-evolution-review: deferred-review queue at cap (${DEFERRED_REVIEW_CAP}) — dropping one fallback review prompt`);
|
|
347
|
+
return "deferred";
|
|
348
|
+
}
|
|
254
349
|
reviewInFlight = true;
|
|
255
350
|
try {
|
|
256
351
|
const snapshot = policy();
|
|
@@ -296,7 +391,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
296
391
|
});
|
|
297
392
|
const acceptedSkillOps = validation.accepted.skillOps ?? [];
|
|
298
393
|
const skippedUnread = filterUnreadSkillOps(acceptedSkillOps, new Set([...collectReadSkillNames(session), ...childReads]));
|
|
299
|
-
const executed = await executePlan(validation.accepted, session);
|
|
394
|
+
const executed = await withTimeout(executePlan(validation.accepted, session), config.reviewTimeoutMs, "review plan execution");
|
|
300
395
|
const actions = executed.actions;
|
|
301
396
|
const evidenceQuotes = [...validation.accepted.memoryOps ?? [], ...acceptedSkillOps].reduce((total, op) => total + (Array.isArray(op.evidence) ? op.evidence.length : 0), 0);
|
|
302
397
|
if (actions.length > 0) {
|
|
@@ -347,15 +442,43 @@ function apply(ctx, rawConfig = {}) {
|
|
|
347
442
|
}
|
|
348
443
|
} catch (error) {
|
|
349
444
|
ctx.logger.warn(`dsh-evolution-review: subagent review failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
445
|
+
if (error instanceof Error && error.message.includes("plan execution timed out")) ctx.logger.warn("dsh-evolution-review: plan execution abandoned on timeout — any late write it lands has NO plan-applied record and races the fallback inject; inspect the skill tree and usage sidecar");
|
|
350
446
|
return false;
|
|
351
447
|
} finally {
|
|
352
448
|
reviewInFlight = false;
|
|
449
|
+
const deferred = deferredFallbackReviews.splice(0);
|
|
450
|
+
for (const { agent: waitingAgent, sessionId: entrySession, kind: waitingKind, prompt, label, channel, counts: entryCounts } of deferred) {
|
|
451
|
+
try {
|
|
452
|
+
deliverMessage(waitingAgent, prompt, label);
|
|
453
|
+
} catch (injectError) {
|
|
454
|
+
if (channel === "completion") completionInjected.delete(entrySession);
|
|
455
|
+
ctx.logger.warn(`dsh-evolution-review: deferred review inject failed: ${injectError instanceof Error ? injectError.message : String(injectError)}`);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
ctx.emit("evolution/review-scheduled", {
|
|
460
|
+
sessionId: entrySession,
|
|
461
|
+
kind: waitingKind,
|
|
462
|
+
toolCalls: entryCounts.toolCalls,
|
|
463
|
+
userChars: entryCounts.userChars,
|
|
464
|
+
assistantChars: entryCounts.assistantChars,
|
|
465
|
+
channel
|
|
466
|
+
});
|
|
467
|
+
} catch (emitError) {
|
|
468
|
+
ctx.logger.warn(`dsh-evolution-review: review-scheduled emit failed: ${emitError instanceof Error ? emitError.message : String(emitError)}`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
353
471
|
}
|
|
354
472
|
}
|
|
355
473
|
async function executePlan(plan, session) {
|
|
356
474
|
const sessionId = session?.id;
|
|
357
475
|
const memory = ctx.get("memory");
|
|
358
476
|
const approval = ctx.get("evolutionApproval");
|
|
477
|
+
const hashLibrary = (() => {
|
|
478
|
+
const io = ctx.get("evolutionIo");
|
|
479
|
+
if (!io) return null;
|
|
480
|
+
return new SkillLibrary(resolveSkillsRoot({ root: rootConfig.root }), evolutionIoAdapter(() => io.provider()));
|
|
481
|
+
})();
|
|
359
482
|
const origins = resolveOrigins(void 0, true);
|
|
360
483
|
const actions = [];
|
|
361
484
|
const failedOps = [];
|
|
@@ -390,6 +513,10 @@ function apply(ctx, rawConfig = {}) {
|
|
|
390
513
|
...op,
|
|
391
514
|
evidence: op.evidence
|
|
392
515
|
};
|
|
516
|
+
if ((args.action === "update" || args.action === "edit") && hashLibrary && typeof args.name === "string" && args.name !== "") {
|
|
517
|
+
const stageCurrent = await hashLibrary.read(args.name).catch(() => null);
|
|
518
|
+
if (stageCurrent !== null) args.staged_from_sha256 = contentHash(stageCurrent);
|
|
519
|
+
}
|
|
393
520
|
const runnerArgs = {
|
|
394
521
|
operation: args,
|
|
395
522
|
origin: origins.library
|
|
@@ -516,6 +643,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
516
643
|
pendingCadenceWarned.clear();
|
|
517
644
|
skipNextCadenceFire.clear();
|
|
518
645
|
cadenceResetWarned.clear();
|
|
646
|
+
reviewStateLocks.clear();
|
|
519
647
|
}, "dsh-evolution-review.cleanup");
|
|
520
648
|
}
|
|
521
649
|
/** Completion-channel decision: task finished normally AND the session is proven long. */
|
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.3.
|
|
4
|
+
"version": "0.3.67",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,9 +31,9 @@
|
|
|
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.
|
|
36
|
-
"@lmzhen/dsh-evolution-plan-validator": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-approval": "^0.3.67",
|
|
35
|
+
"@lmzhen/dsh-evolution-core": "^0.3.67",
|
|
36
|
+
"@lmzhen/dsh-evolution-plan-validator": "^0.3.67"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
|
|
43
43
|
"@deepseek-ai/dsh-session": "^0.1.1-rc.2",
|
|
44
44
|
"@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
|
|
45
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
46
|
-
"@lmzhen/dsh-evolution-policy": "^0.3.
|
|
45
|
+
"@lmzhen/dsh-evolution-state": "^0.3.67",
|
|
46
|
+
"@lmzhen/dsh-evolution-policy": "^0.3.67"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"@deepseek-ai/dsh-session-persistence": "^0.1.1-rc.2",
|
|
55
55
|
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.1-rc.2",
|
|
56
56
|
"@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
|
|
57
|
-
"@lmzhen/dsh-evolution-approval": "^0.3.
|
|
58
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
59
|
-
"@lmzhen/dsh-evolution-plan-validator": "^0.3.
|
|
60
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
57
|
+
"@lmzhen/dsh-evolution-approval": "^0.3.67",
|
|
58
|
+
"@lmzhen/dsh-evolution-core": "^0.3.67",
|
|
59
|
+
"@lmzhen/dsh-evolution-plan-validator": "^0.3.67",
|
|
60
|
+
"@lmzhen/dsh-evolution-state": "^0.3.67"
|
|
61
61
|
}
|
|
62
62
|
}
|