dsh-continual-evolve 0.11.0 → 0.12.0

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 (154) hide show
  1. package/README.md +35 -115
  2. package/README.zh.md +26 -93
  3. package/cordis.patch.yml +2 -2
  4. package/lib/index.d.ts +44 -225
  5. package/lib/index.js +30 -239
  6. package/lib/memory-guide.d.ts +13 -14
  7. package/lib/memory-guide.js +32 -21
  8. package/lib/memory-section.d.ts +77 -0
  9. package/lib/memory-section.js +189 -0
  10. package/package.json +2 -17
  11. package/lib/apply.d.ts +0 -22
  12. package/lib/apply.js +0 -157
  13. package/lib/approval.d.ts +0 -73
  14. package/lib/approval.js +0 -127
  15. package/lib/audit-log.d.ts +0 -19
  16. package/lib/audit-log.js +0 -52
  17. package/lib/auto.d.ts +0 -236
  18. package/lib/auto.js +0 -773
  19. package/lib/autocase.d.ts +0 -38
  20. package/lib/autocase.js +0 -76
  21. package/lib/benchmark-command.d.ts +0 -9
  22. package/lib/benchmark-command.js +0 -357
  23. package/lib/benchmark.d.ts +0 -151
  24. package/lib/benchmark.js +0 -250
  25. package/lib/command-util.d.ts +0 -70
  26. package/lib/command-util.js +0 -123
  27. package/lib/command.d.ts +0 -13
  28. package/lib/command.js +0 -134
  29. package/lib/consolidate.d.ts +0 -90
  30. package/lib/consolidate.js +0 -180
  31. package/lib/copy.d.ts +0 -37
  32. package/lib/copy.js +0 -58
  33. package/lib/declines.d.ts +0 -103
  34. package/lib/declines.js +0 -179
  35. package/lib/evaluate.d.ts +0 -74
  36. package/lib/evaluate.js +0 -271
  37. package/lib/evolve-event.d.ts +0 -40
  38. package/lib/evolve-event.js +0 -60
  39. package/lib/extraction-phase.d.ts +0 -132
  40. package/lib/extraction-phase.js +0 -236
  41. package/lib/failures.d.ts +0 -42
  42. package/lib/failures.js +0 -171
  43. package/lib/fate.d.ts +0 -130
  44. package/lib/fate.js +0 -350
  45. package/lib/goal-command.d.ts +0 -7
  46. package/lib/goal-command.js +0 -37
  47. package/lib/goal.d.ts +0 -72
  48. package/lib/goal.js +0 -72
  49. package/lib/inject.d.ts +0 -90
  50. package/lib/inject.js +0 -164
  51. package/lib/injection-caps.d.ts +0 -4
  52. package/lib/injection-caps.js +0 -4
  53. package/lib/injection-directory.d.ts +0 -29
  54. package/lib/injection-directory.js +0 -78
  55. package/lib/injection-rank.d.ts +0 -85
  56. package/lib/injection-rank.js +0 -161
  57. package/lib/listener.d.ts +0 -45
  58. package/lib/listener.js +0 -199
  59. package/lib/llm-text.d.ts +0 -104
  60. package/lib/llm-text.js +0 -140
  61. package/lib/logfile.d.ts +0 -71
  62. package/lib/logfile.js +0 -159
  63. package/lib/maintenance-commands.d.ts +0 -23
  64. package/lib/maintenance-commands.js +0 -136
  65. package/lib/memory-agent.d.ts +0 -93
  66. package/lib/memory-agent.js +0 -300
  67. package/lib/memory-apply.d.ts +0 -44
  68. package/lib/memory-apply.js +0 -202
  69. package/lib/memory-benchmark.d.ts +0 -76
  70. package/lib/memory-benchmark.js +0 -170
  71. package/lib/memory-index.d.ts +0 -114
  72. package/lib/memory-index.js +0 -197
  73. package/lib/memory-manifest.d.ts +0 -16
  74. package/lib/memory-manifest.js +0 -70
  75. package/lib/message-source.d.ts +0 -23
  76. package/lib/message-source.js +0 -12
  77. package/lib/mount-command.d.ts +0 -10
  78. package/lib/mount-command.js +0 -48
  79. package/lib/mount.d.ts +0 -42
  80. package/lib/mount.js +0 -212
  81. package/lib/notify.d.ts +0 -48
  82. package/lib/notify.js +0 -57
  83. package/lib/plan-command.d.ts +0 -12
  84. package/lib/plan-command.js +0 -38
  85. package/lib/plan.d.ts +0 -16
  86. package/lib/plan.js +0 -126
  87. package/lib/planner.d.ts +0 -61
  88. package/lib/planner.js +0 -144
  89. package/lib/pool.d.ts +0 -7
  90. package/lib/pool.js +0 -25
  91. package/lib/prefix-cache.d.ts +0 -79
  92. package/lib/prefix-cache.js +0 -168
  93. package/lib/project.d.ts +0 -28
  94. package/lib/project.js +0 -66
  95. package/lib/projection.d.ts +0 -22
  96. package/lib/projection.js +0 -112
  97. package/lib/promotion.d.ts +0 -94
  98. package/lib/promotion.js +0 -171
  99. package/lib/recall.d.ts +0 -85
  100. package/lib/recall.js +0 -142
  101. package/lib/record-language.d.ts +0 -85
  102. package/lib/record-language.js +0 -152
  103. package/lib/render.d.ts +0 -13
  104. package/lib/render.js +0 -80
  105. package/lib/review-scheduler.d.ts +0 -38
  106. package/lib/review-scheduler.js +0 -183
  107. package/lib/review.d.ts +0 -60
  108. package/lib/review.js +0 -145
  109. package/lib/rollback.d.ts +0 -9
  110. package/lib/rollback.js +0 -68
  111. package/lib/rubric.d.ts +0 -29
  112. package/lib/rubric.js +0 -119
  113. package/lib/runtime-commands.d.ts +0 -14
  114. package/lib/runtime-commands.js +0 -115
  115. package/lib/runtime.d.ts +0 -24
  116. package/lib/runtime.js +0 -87
  117. package/lib/score.d.ts +0 -64
  118. package/lib/score.js +0 -191
  119. package/lib/search.d.ts +0 -83
  120. package/lib/search.js +0 -136
  121. package/lib/service.d.ts +0 -63
  122. package/lib/service.js +0 -253
  123. package/lib/skill-render.d.ts +0 -23
  124. package/lib/skill-render.js +0 -69
  125. package/lib/skill.d.ts +0 -15
  126. package/lib/skill.js +0 -80
  127. package/lib/skillquality.d.ts +0 -85
  128. package/lib/skillquality.js +0 -320
  129. package/lib/source.d.ts +0 -30
  130. package/lib/source.js +0 -43
  131. package/lib/state.d.ts +0 -26
  132. package/lib/state.js +0 -151
  133. package/lib/store.d.ts +0 -61
  134. package/lib/store.js +0 -164
  135. package/lib/token-usage.d.ts +0 -68
  136. package/lib/token-usage.js +0 -211
  137. package/lib/tool.d.ts +0 -34
  138. package/lib/tool.js +0 -320
  139. package/lib/turn-snapshot.d.ts +0 -78
  140. package/lib/turn-snapshot.js +0 -252
  141. package/lib/types.d.ts +0 -218
  142. package/lib/types.js +0 -133
  143. package/lib/usage.d.ts +0 -36
  144. package/lib/usage.js +0 -98
  145. package/lib/validate.d.ts +0 -28
  146. package/lib/validate.js +0 -181
  147. package/lib/wrapup-candidates.d.ts +0 -127
  148. package/lib/wrapup-candidates.js +0 -161
  149. package/lib/wrapup-command.d.ts +0 -10
  150. package/lib/wrapup-command.js +0 -243
  151. package/lib/wrapup-proposals.d.ts +0 -101
  152. package/lib/wrapup-proposals.js +0 -281
  153. package/lib/wrapup.d.ts +0 -56
  154. package/lib/wrapup.js +0 -105
package/lib/evaluate.js DELETED
@@ -1,271 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { mapPool } from "./pool.js";
3
- import { decryptRubric, deriveKey, DEV_RUBRIC_KEY } from "./rubric.js";
4
- /** Key used when the caller did not resolve one: mirrors resolveRubricKey's last-resort dev fallback. */
5
- function devRubricKey() {
6
- return deriveKey(DEV_RUBRIC_KEY);
7
- }
8
- /** Stage 1: the agent under test — sees the task, never the rubric. */
9
- const EXECUTOR_SYSTEM_PROMPT = `You are one evaluation unit in a benchmark matrix.
10
-
11
- You are the agent under evaluation. Perform the case task using your tools.
12
- You are NOT asked to grade yourself: a separate evaluator will judge your
13
- work against criteria you do not see. Instead, record CONCRETE, VERIFIABLE
14
- EVIDENCE of what you did and found — the actual commands/reads you performed,
15
- what the harness state contains, the exact text you produced. Evidence is
16
- what your work will be scored from; vague self-assessment earns nothing.
17
-
18
- The harness guidance attached to the state under test is included in the task.
19
- Your reply is structured (see the requested output schema): caseId, run, and
20
- evidence (the concrete artifact/report of your execution).`;
21
- /** Stage 2: the independent grader — sees the rubric, never executes the task. */
22
- const REVIEWER_SYSTEM_PROMPT = `You are an independent evaluator in a benchmark matrix.
23
-
24
- You did NOT perform the task and you cannot interact with the runtime: grade
25
- strictly from the EVIDENCE produced by the agent under evaluation, against
26
- the rubric. The harness guidance under test is included for context so you
27
- can judge whether the evidence genuinely reflects the state under test
28
- (e.g. whether the agent actually inspected the harness store).
29
-
30
- Score YOUR JUDGMENT of the evidence against the rubric criteria: a
31
- 0-100 score, and passed (true iff score >= the stated threshold). Cite in
32
- notes the concrete rubric criteria and the evidence that supports the score.
33
- Do not inflate: grade the evidence as presented, not what the agent might
34
- have meant.`;
35
- const EXECUTOR_SCHEMA = {
36
- type: "object",
37
- additionalProperties: false,
38
- properties: {
39
- caseId: { type: "string" },
40
- run: { type: "number" },
41
- evidence: { type: "string" },
42
- },
43
- required: ["caseId", "run", "evidence"],
44
- };
45
- const CELL_SCHEMA = {
46
- type: "object",
47
- additionalProperties: false,
48
- properties: {
49
- caseId: { type: "string" },
50
- run: { type: "number" },
51
- score: { type: "number" },
52
- passed: { type: "boolean" },
53
- notes: { type: "string" },
54
- },
55
- required: ["caseId", "run", "score", "passed", "notes"],
56
- };
57
- /** How many evaluation units may run concurrently (bounded subagent fan-out). */
58
- export const DEFAULT_EVALUATION_CONCURRENCY = 4;
59
- /** Evidence handed to the reviewer is capped so the grading call stays bounded. */
60
- export const MAX_EVIDENCE_CHARS = 8000;
61
- export async function evaluateState(ctx, agent, options) {
62
- if (!agent.options.provider || !agent.options.model) {
63
- throw new Error("evolve: benchmark evaluation requires a provider/model route");
64
- }
65
- const subagents = ctx.subagents;
66
- if (!subagents) {
67
- throw new Error("evolve: benchmark evaluation requires the subagents service");
68
- }
69
- const units = [];
70
- for (const c of options.cases) {
71
- for (let run = 1; run <= options.runs; run += 1) {
72
- units.push({ case: c, run });
73
- }
74
- }
75
- const cells = await mapPool(units, DEFAULT_EVALUATION_CONCURRENCY, (unit) => runUnit(subagents, agent, options, unit.case, unit.run));
76
- return { label: options.label, cells, stopReason: "completed" };
77
- }
78
- /** A cell that could not be produced: never a zero, excluded by aggregation. */
79
- function failedCell(caseId, run, message) {
80
- return { caseId, run, status: "failed", score: 0, passed: false, notes: message };
81
- }
82
- /**
83
- * Deterministic hash of a case's statement + rubric envelope (gap A3):
84
- * a 16-char SHA-256 prefix, hex-encoded. Used to detect material changes
85
- * between reference and candidate evaluation runs (see
86
- * `score.flagMaterialDrift`).
87
- */
88
- export function caseHash(caseItem) {
89
- const material = `${caseItem.statement}\n${caseItem.rubric}`;
90
- return createHash("sha256").update(material).digest("hex").slice(0, 16);
91
- }
92
- async function runUnit(subagents, agent, options, c, run) {
93
- // Gap C3: track wall-clock duration of the entire cell evaluation.
94
- const cellStart = Date.now();
95
- // The ONLY rubric decryption point: the envelope is opened here, in the
96
- // host, and the plaintext goes ONLY into the reviewer prompt — the
97
- // executor branch never touches it (gap A1).
98
- let rubric;
99
- try {
100
- rubric = decryptRubric(c.rubric, options.rubricKey ?? devRubricKey());
101
- }
102
- catch (cause) {
103
- return { ...failedCell(c.id, run, `rubric decrypt failed: ${cause instanceof Error ? cause.message : String(cause)}`), durationMs: Date.now() - cellStart };
104
- }
105
- // Runtime evidence (gap A3): record actual provider/model from the host,
106
- // and compute a material hash of the case for change detection.
107
- const actualProvider = agent.options.provider ?? "unknown";
108
- const actualModel = agent.options.model ?? "unknown";
109
- const hash = caseHash(c);
110
- // Stage 1: executor — task + evidence, NO rubric.
111
- let evidence;
112
- let sessionId;
113
- try {
114
- const executorRun = await subagents.start("spawn", {
115
- label: `${c.id} r${run} execute`,
116
- prompt: [
117
- {
118
- type: "text",
119
- text: [
120
- EXECUTOR_SYSTEM_PROMPT,
121
- "---",
122
- "Your harness guidance (state under test):",
123
- `<harness_overview>\n${options.harnessOverview}\n</harness_overview>`,
124
- `Case ${c.id} — task (statement):\n${c.statement}`,
125
- `Run ${run} of ${options.runs}.`,
126
- "Execute the task with your tools, then produce the structured evidence.",
127
- ].join("\n\n"),
128
- },
129
- ],
130
- parent: agent,
131
- signal: options.signal ?? new AbortController().signal,
132
- outputSchema: EXECUTOR_SCHEMA,
133
- });
134
- try {
135
- const settled = await executorRun.result;
136
- if (settled.stopReason !== "completed") {
137
- throw new Error(`executor stopped: ${settled.stopReason ?? "unknown"}`);
138
- }
139
- const parsed = normalizeExecutor(settled.structured, c.id, run) ?? fromEvidenceText(settled.output, c.id, run);
140
- if (!parsed) {
141
- throw new Error("executor returned neither a structured value nor usable text");
142
- }
143
- evidence = parsed;
144
- sessionId = executorRun.id || undefined;
145
- }
146
- finally {
147
- executorRun.dispose();
148
- }
149
- }
150
- catch (cause) {
151
- return { ...failedCell(c.id, run, `executor failed: ${cause instanceof Error ? cause.message : String(cause)}`), provider: actualProvider, model: actualModel, caseHash: hash, durationMs: Date.now() - cellStart };
152
- }
153
- // Stage 2: independent reviewer — rubric + evidence, NO task execution.
154
- try {
155
- const reviewerRun = await subagents.start("spawn", {
156
- label: `${c.id} r${run} grade`,
157
- prompt: [
158
- {
159
- type: "text",
160
- text: [
161
- REVIEWER_SYSTEM_PROMPT,
162
- "---",
163
- "Your harness guidance (state under test):",
164
- `<harness_overview>\n${options.harnessOverview}\n</harness_overview>`,
165
- `Case ${c.id} — task (statement):\n${c.statement}`,
166
- `Rubric — grade the evidence strictly against these criteria:\n${rubric}`,
167
- `Evidence produced by the agent under evaluation:\n<evidence>\n${trimEvidence(evidence.evidence)}\n</evidence>`,
168
- `Run ${run} of ${options.runs}. passThreshold = ${options.passThreshold}.`,
169
- "Produce the structured score.",
170
- ].join("\n\n"),
171
- },
172
- ],
173
- parent: agent,
174
- signal: options.signal ?? new AbortController().signal,
175
- outputSchema: CELL_SCHEMA,
176
- });
177
- try {
178
- const settled = await reviewerRun.result;
179
- if (settled.stopReason !== "completed") {
180
- throw new Error(`reviewer stopped: ${settled.stopReason ?? "unknown"}`);
181
- }
182
- const cell = normalizeCell(settled.structured, c.id, run, options.passThreshold) ??
183
- fromOutputText(settled.output, c.id, run, options.passThreshold);
184
- if (!cell) {
185
- throw new Error("reviewer returned neither a structured value nor usable text");
186
- }
187
- return { ...cell, ...(sessionId !== undefined ? { sessionId } : {}), provider: actualProvider, model: actualModel, caseHash: hash, durationMs: Date.now() - cellStart };
188
- }
189
- finally {
190
- reviewerRun.dispose();
191
- }
192
- }
193
- catch (cause) {
194
- return { ...failedCell(c.id, run, `reviewer failed: ${cause instanceof Error ? cause.message : String(cause)}`), provider: actualProvider, model: actualModel, caseHash: hash, durationMs: Date.now() - cellStart };
195
- }
196
- }
197
- /** Cap the evidence handed to the reviewer so the grading call stays bounded. */
198
- function trimEvidence(text) {
199
- if (text.length <= MAX_EVIDENCE_CHARS)
200
- return text;
201
- return `${text.slice(0, MAX_EVIDENCE_CHARS)}\n…[evidence truncated at ${MAX_EVIDENCE_CHARS} chars]`;
202
- }
203
- /** Validate a provider-validated executor result; returns undefined when malformed. */
204
- export function normalizeExecutor(value, caseId, run) {
205
- if (typeof value !== "object" || value === null || Array.isArray(value))
206
- return undefined;
207
- const record = value;
208
- const evidence = typeof record["evidence"] === "string" ? record["evidence"] : "";
209
- if (evidence.trim().length === 0)
210
- return undefined;
211
- return {
212
- caseId: typeof record["caseId"] === "string" && record["caseId"].length > 0 ? record["caseId"] : caseId,
213
- run: typeof record["run"] === "number" && Number.isFinite(record["run"]) ? Math.trunc(record["run"]) : run,
214
- evidence,
215
- };
216
- }
217
- /** Fallback: recover the executor result from its text blocks when no structured value arrived. */
218
- function fromEvidenceText(blocks, caseId, run) {
219
- if (!Array.isArray(blocks))
220
- return undefined;
221
- const text = blocks
222
- .filter((block) => block.type === "text")
223
- .map((block) => block.text ?? "")
224
- .join("\n");
225
- const trimmed = text.trim();
226
- if (trimmed.length === 0)
227
- return undefined;
228
- try {
229
- return normalizeExecutor(JSON.parse(trimmed), caseId, run);
230
- }
231
- catch {
232
- // Not JSON — keep the raw text as the evidence.
233
- return { caseId, run, evidence: trimmed };
234
- }
235
- }
236
- /** Validate a provider-validated structured cell; returns undefined when malformed. */
237
- export function normalizeCell(value, caseId, run, passThreshold) {
238
- if (typeof value !== "object" || value === null || Array.isArray(value))
239
- return undefined;
240
- const record = value;
241
- const score = Number(record["score"]);
242
- if (!Number.isFinite(score))
243
- return undefined;
244
- return {
245
- caseId: typeof record["caseId"] === "string" && record["caseId"].length > 0 ? record["caseId"] : caseId,
246
- run: typeof record["run"] === "number" && Number.isFinite(record["run"]) ? Math.trunc(record["run"]) : run,
247
- status: "ok",
248
- score: Math.min(100, Math.max(0, score)),
249
- passed: record["passed"] === true || score >= passThreshold,
250
- notes: typeof record["notes"] === "string" ? record["notes"] : "",
251
- };
252
- }
253
- /** Fallback: recover a cell from the child's text blocks when no structured value arrived. */
254
- function fromOutputText(blocks, caseId, run, passThreshold) {
255
- if (!Array.isArray(blocks))
256
- return undefined;
257
- const text = blocks
258
- .filter((block) => block.type === "text")
259
- .map((block) => block.text ?? "")
260
- .join("\n");
261
- if (text.length === 0)
262
- return undefined;
263
- try {
264
- const value = JSON.parse(text);
265
- return normalizeCell(value, caseId, run, passThreshold);
266
- }
267
- catch {
268
- return undefined;
269
- }
270
- }
271
- //# sourceMappingURL=evaluate.js.map
@@ -1,40 +0,0 @@
1
- import type { RefinementResult } from "./types.js";
2
- /** The structured event payload emitted after every successful refinement. */
3
- export interface EvolveCompleteEvent {
4
- /** Event discriminator for consumers. */
5
- type: "evolve_complete";
6
- /** The refinement id (same as the result). */
7
- refinementId: string;
8
- /** One-line summary of the refinement. */
9
- summary: string;
10
- /** Number of edits that were actually applied. */
11
- appliedEdits: number;
12
- /** Number of edits that failed to apply. */
13
- failedEdits: number;
14
- /** Scope of the refinement ("local" or "global"). */
15
- scope: string;
16
- /** What triggered this refinement (e.g. "auto_review", "manual_plan", "manual_tool"). */
17
- trigger: string;
18
- /** Session id that owns the refinement (auto or manual). */
19
- sessionId: string;
20
- /** ISO timestamp. */
21
- timestamp: string;
22
- /** Per-edit summaries (kind + id + action) for consumers that want detail. */
23
- edits: {
24
- action: string;
25
- kind: string;
26
- id: string;
27
- applied: boolean;
28
- }[];
29
- }
30
- /** Build a structured evolve-complete event from a refinement result. */
31
- export declare function buildEvolveCompleteEvent(result: RefinementResult, trigger: string, sessionId: string): EvolveCompleteEvent;
32
- /**
33
- * Emit an evolve_complete event to the reviews.jsonl audit trail. The event
34
- * is JSONL-formatted (one line) so consumers can tail and parse it. This is
35
- * a best-effort write — failure never blocks the refinement path. Storage
36
- * hygiene (#20): the trail is truncated to its tail after the append so the
37
- * audit file cannot grow without bound; readers only need a recent window.
38
- */
39
- export declare function emitEvolveComplete(baseDir: string, event: EvolveCompleteEvent, reviewsRetain?: number): void;
40
- //# sourceMappingURL=evolve-event.d.ts.map
@@ -1,60 +0,0 @@
1
- /**
2
- * Structured "evolve complete" events (gap C4): a durable, machine-readable
3
- * record emitted after every successful refinement application — whether
4
- * auto-gated or manual. Third-party consumers can observe these events via
5
- * the plugin log (JSONL) and the reviews.jsonl audit trail.
6
- *
7
- * Design: prime-agent `/refine` emits `refine_complete{id,summary,
8
- * appliedEdits,scope}` extension events. We follow the same pattern with
9
- * added provenance (trigger, source) so consumers know WHY the refinement
10
- * happened and WHO initiated it.
11
- */
12
- import { appendFileSync, mkdirSync } from "node:fs";
13
- import { join } from "node:path";
14
- import { DEFAULT_REVIEWS_RETAIN } from "./types.js";
15
- import { pruneJsonlFile, reviewsPath } from "./store.js";
16
- /** Build a structured evolve-complete event from a refinement result. */
17
- export function buildEvolveCompleteEvent(result, trigger, sessionId) {
18
- return {
19
- type: "evolve_complete",
20
- refinementId: result.id,
21
- summary: result.summary,
22
- appliedEdits: result.appliedEdits.filter((e) => e.applied).length,
23
- failedEdits: result.appliedEdits.filter((e) => !e.applied).length,
24
- scope: result.scope ?? "local",
25
- trigger,
26
- sessionId,
27
- timestamp: new Date().toISOString(),
28
- edits: result.appliedEdits.map((e) => ({
29
- action: e.action,
30
- kind: e.kind,
31
- id: e.id,
32
- applied: e.applied,
33
- })),
34
- };
35
- }
36
- /**
37
- * Emit an evolve_complete event to the reviews.jsonl audit trail. The event
38
- * is JSONL-formatted (one line) so consumers can tail and parse it. This is
39
- * a best-effort write — failure never blocks the refinement path. Storage
40
- * hygiene (#20): the trail is truncated to its tail after the append so the
41
- * audit file cannot grow without bound; readers only need a recent window.
42
- */
43
- export function emitEvolveComplete(baseDir, event, reviewsRetain = DEFAULT_REVIEWS_RETAIN) {
44
- try {
45
- const dir = join(baseDir, "evolve");
46
- mkdirSync(dir, { recursive: true });
47
- appendFileSync(join(dir, "reviews.jsonl"), `${JSON.stringify(event)}\n`, "utf8");
48
- }
49
- catch {
50
- // Event emission is diagnostic; never interrupt the refinement path.
51
- return;
52
- }
53
- try {
54
- pruneJsonlFile(reviewsPath(baseDir), reviewsRetain);
55
- }
56
- catch {
57
- // ignored — the next emission retries
58
- }
59
- }
60
- //# sourceMappingURL=evolve-event.js.map
@@ -1,132 +0,0 @@
1
- /**
2
- * The dedicated memory extraction phase: one bounded ZCode-style loop over a
3
- * scheduler snapshot. Owns its request loop, frozen manifest, scope approval
4
- * bookkeeping, and the phase-specific memory checkpoint that advances after a
5
- * successful/no-op outcome — memory failures leave the boundary retryable.
6
- *
7
- * Triggered only by the low-frequency moments wired in `listener.ts`;
8
- * per-turn extraction was removed with the 2026-10-03 B verdict.
9
- */
10
- import type { Context } from "@deepseek-ai/cordis";
11
- import type { Agent } from "@deepseek-ai/dsh-agent";
12
- import type { EvolutionEngine } from "./service.js";
13
- import { type TurnSnapshot } from "./turn-snapshot.js";
14
- import type { HarnessState, ScopeApprovalDecision } from "./types.js";
15
- import type { PlannerPrefixCacheMode } from "./types.js";
16
- import { type RecordLanguagePreference } from "./record-language.js";
17
- export interface GateState {
18
- turns: number;
19
- /** Latest successful turn boundary seen by the listener. */
20
- completedTurn: number;
21
- /** Latest successful/no-op memory boundary. */
22
- memoryCheckpoint?: string;
23
- /** Per-boundary/scope approval decisions retained until the memory phase settles. */
24
- memoryDecisions: Record<string, ScopeApprovalDecision>;
25
- lastReviewAt: number;
26
- /**
27
- * Consecutive idle probes that observed the goal phase "blocked".
28
- * Reset to 0 by any non-blocked probe and after a triggered moment.
29
- */
30
- goalBlockStreak: number;
31
- }
32
- export interface AutoReviewConfig {
33
- /** Initial runtime state when no runtime.json exists. */
34
- enabledByDefault?: boolean;
35
- /** ZCode-style minimum lexical words in one direct user text part. */
36
- memoryMinUserWords?: number;
37
- /** Trajectory slice handed to the extractor, in characters. */
38
- maxInputChars: number;
39
- /** Output budget for the extraction loop. */
40
- budgetTokens: number;
41
- /** Queue a visible receipt follow-up after an applied goal-blocked moment. */
42
- notifyOnAutoReview: boolean;
43
- /**
44
- * Optional model override for the extractor (cheaper model).
45
- * Format: "provider/model" or just "model" (same provider as the agent).
46
- * When absent, the extractor uses the agent's own provider/model.
47
- */
48
- reviewModel?: string;
49
- /** Dedicated memory-agent writes to project/global require the normal human approval boundary. */
50
- requireGlobalApproval?: boolean;
51
- /**
52
- * Authoring language for this run's records. Absent/`auto` resolves per
53
- * call through the record-language chain (durable client preference,
54
- * then trajectory detection, then `en`); `zh`/`en` pin it.
55
- */
56
- recordLanguage?: RecordLanguagePreference;
57
- /**
58
- * Prefix-cache routing for the extraction input. Absent mode → auto-detect;
59
- * absent budget → the default prefix budget.
60
- */
61
- prefixCacheMode?: PlannerPrefixCacheMode;
62
- prefixMaxChars?: number;
63
- /**
64
- * Goal-blocked trigger: after this many CONSECUTIVE idle probes that
65
- * observe the session goal in phase "blocked", run one memory extraction
66
- * so the blocked encounter is distilled. 0 disables. The streak resets on
67
- * any non-blocked probe and after each triggered moment.
68
- */
69
- goalBlockedWrapupTurns: number;
70
- /**
71
- * Storage hygiene (#20): tail lines kept in the shared reviews.jsonl
72
- * audit trail. Absent → the store default (readers need a recent
73
- * window, not the full past).
74
- */
75
- reviewsRetain?: number;
76
- /**
77
- * Session-close bounded drain: how long a disposed session's in-flight
78
- * extraction may settle before its owner signal aborts. Absent → 15s;
79
- * 0 restores the legacy immediate abort.
80
- */
81
- sessionCloseDrainMs?: number;
82
- }
83
- export interface ReviewRecord {
84
- timestamp: string;
85
- sessionId: string;
86
- reason: TurnSnapshot["reason"];
87
- turnsSinceLastReview: number;
88
- outcome: "approved" | "declined" | "failed" | "assessed" | "deferred" | "skipped" | "armed" | "applied" | "noop";
89
- rationale?: string;
90
- refinementId?: string;
91
- /** P1 extraction stats (§6.7): wall time of the memory phase. */
92
- durationMs?: number;
93
- /** Extractor loop turns / manifest searches behind this row. */
94
- memoryTurns?: number;
95
- memorySearches?: number;
96
- /** Applied edit count carried by an applied row. */
97
- appliedEdits?: number;
98
- }
99
- export type ReviewRecorder = (entry: Omit<ReviewRecord, "timestamp">) => void;
100
- export declare function stateFor(map: Map<string, GateState>, sessionId: string): GateState;
101
- export declare function advanceMemoryCheckpoint(state: GateState, next: string): void;
102
- /**
103
- * The state view the extractor judges: the session's local entries merged
104
- * with the project and global stores, each entry carrying its real scope.
105
- * Without the global half the extractor cannot see that a topic is already
106
- * covered cross-session and happily re-sediments a local duplicate of it.
107
- *
108
- * The merged view is read-only context — applying still targets the raw
109
- * local state (baseline checks compare local entries only).
110
- */
111
- export declare function loadGateHarnessView(engine: EvolutionEngine, sessionId: string, opts?: {
112
- projectKey?: string;
113
- }): HarnessState;
114
- /**
115
- * Gap C1: parse a "provider/model" or "model" string into its components.
116
- * Returns undefined when the input is empty (no override). A bare model name
117
- * falls back to the agent's provider, then "deepseek".
118
- * Exported for unit testing; production resolves it inside
119
- * runMemoryExtractionPhase.
120
- */
121
- export declare function parseReviewModel(reviewModel: string | undefined, fallbackProvider: string | undefined): {
122
- provider: string;
123
- model: string;
124
- } | undefined;
125
- /**
126
- * One extraction run over a scheduler snapshot. Records noop / applied /
127
- * declined audit rows with duration and loop stats, advances the memory
128
- * checkpoint on settled outcomes, and queues a visible receipt only for an
129
- * applied goal-blocked moment (compaction and session-close stay audit-only).
130
- */
131
- export declare function runMemoryExtractionPhase(ctx: Context, engine: EvolutionEngine, agent: Agent, config: AutoReviewConfig, state: GateState, snapshot: TurnSnapshot, record: ReviewRecorder, signal?: AbortSignal): Promise<void>;
132
- //# sourceMappingURL=extraction-phase.d.ts.map