dsh-continual-evolve 0.11.0 → 0.12.1

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 (161) hide show
  1. package/README.md +42 -115
  2. package/README.zh.md +33 -93
  3. package/client/client.js +253 -0
  4. package/cordis.patch.yml +2 -2
  5. package/lib/card-routes.d.ts +32 -0
  6. package/lib/card-routes.js +92 -0
  7. package/lib/index.d.ts +65 -217
  8. package/lib/index.js +74 -234
  9. package/lib/known-workspaces.d.ts +22 -0
  10. package/lib/known-workspaces.js +42 -0
  11. package/lib/memory-guide.d.ts +13 -14
  12. package/lib/memory-guide.js +34 -21
  13. package/lib/memory-section.d.ts +77 -0
  14. package/lib/memory-section.js +189 -0
  15. package/lib/memory-snapshot.d.ts +54 -0
  16. package/lib/memory-snapshot.js +125 -0
  17. package/package.json +8 -17
  18. package/lib/apply.d.ts +0 -22
  19. package/lib/apply.js +0 -157
  20. package/lib/approval.d.ts +0 -73
  21. package/lib/approval.js +0 -127
  22. package/lib/audit-log.d.ts +0 -19
  23. package/lib/audit-log.js +0 -52
  24. package/lib/auto.d.ts +0 -236
  25. package/lib/auto.js +0 -773
  26. package/lib/autocase.d.ts +0 -38
  27. package/lib/autocase.js +0 -76
  28. package/lib/benchmark-command.d.ts +0 -9
  29. package/lib/benchmark-command.js +0 -357
  30. package/lib/benchmark.d.ts +0 -151
  31. package/lib/benchmark.js +0 -250
  32. package/lib/command-util.d.ts +0 -70
  33. package/lib/command-util.js +0 -123
  34. package/lib/command.d.ts +0 -13
  35. package/lib/command.js +0 -134
  36. package/lib/consolidate.d.ts +0 -90
  37. package/lib/consolidate.js +0 -180
  38. package/lib/copy.d.ts +0 -37
  39. package/lib/copy.js +0 -58
  40. package/lib/declines.d.ts +0 -103
  41. package/lib/declines.js +0 -179
  42. package/lib/evaluate.d.ts +0 -74
  43. package/lib/evaluate.js +0 -271
  44. package/lib/evolve-event.d.ts +0 -40
  45. package/lib/evolve-event.js +0 -60
  46. package/lib/extraction-phase.d.ts +0 -132
  47. package/lib/extraction-phase.js +0 -236
  48. package/lib/failures.d.ts +0 -42
  49. package/lib/failures.js +0 -171
  50. package/lib/fate.d.ts +0 -130
  51. package/lib/fate.js +0 -350
  52. package/lib/goal-command.d.ts +0 -7
  53. package/lib/goal-command.js +0 -37
  54. package/lib/goal.d.ts +0 -72
  55. package/lib/goal.js +0 -72
  56. package/lib/inject.d.ts +0 -90
  57. package/lib/inject.js +0 -164
  58. package/lib/injection-caps.d.ts +0 -4
  59. package/lib/injection-caps.js +0 -4
  60. package/lib/injection-directory.d.ts +0 -29
  61. package/lib/injection-directory.js +0 -78
  62. package/lib/injection-rank.d.ts +0 -85
  63. package/lib/injection-rank.js +0 -161
  64. package/lib/listener.d.ts +0 -45
  65. package/lib/listener.js +0 -199
  66. package/lib/llm-text.d.ts +0 -104
  67. package/lib/llm-text.js +0 -140
  68. package/lib/logfile.d.ts +0 -71
  69. package/lib/logfile.js +0 -159
  70. package/lib/maintenance-commands.d.ts +0 -23
  71. package/lib/maintenance-commands.js +0 -136
  72. package/lib/memory-agent.d.ts +0 -93
  73. package/lib/memory-agent.js +0 -300
  74. package/lib/memory-apply.d.ts +0 -44
  75. package/lib/memory-apply.js +0 -202
  76. package/lib/memory-benchmark.d.ts +0 -76
  77. package/lib/memory-benchmark.js +0 -170
  78. package/lib/memory-index.d.ts +0 -114
  79. package/lib/memory-index.js +0 -197
  80. package/lib/memory-manifest.d.ts +0 -16
  81. package/lib/memory-manifest.js +0 -70
  82. package/lib/message-source.d.ts +0 -23
  83. package/lib/message-source.js +0 -12
  84. package/lib/mount-command.d.ts +0 -10
  85. package/lib/mount-command.js +0 -48
  86. package/lib/mount.d.ts +0 -42
  87. package/lib/mount.js +0 -212
  88. package/lib/notify.d.ts +0 -48
  89. package/lib/notify.js +0 -57
  90. package/lib/plan-command.d.ts +0 -12
  91. package/lib/plan-command.js +0 -38
  92. package/lib/plan.d.ts +0 -16
  93. package/lib/plan.js +0 -126
  94. package/lib/planner.d.ts +0 -61
  95. package/lib/planner.js +0 -144
  96. package/lib/pool.d.ts +0 -7
  97. package/lib/pool.js +0 -25
  98. package/lib/prefix-cache.d.ts +0 -79
  99. package/lib/prefix-cache.js +0 -168
  100. package/lib/project.d.ts +0 -28
  101. package/lib/project.js +0 -66
  102. package/lib/projection.d.ts +0 -22
  103. package/lib/projection.js +0 -112
  104. package/lib/promotion.d.ts +0 -94
  105. package/lib/promotion.js +0 -171
  106. package/lib/recall.d.ts +0 -85
  107. package/lib/recall.js +0 -142
  108. package/lib/record-language.d.ts +0 -85
  109. package/lib/record-language.js +0 -152
  110. package/lib/render.d.ts +0 -13
  111. package/lib/render.js +0 -80
  112. package/lib/review-scheduler.d.ts +0 -38
  113. package/lib/review-scheduler.js +0 -183
  114. package/lib/review.d.ts +0 -60
  115. package/lib/review.js +0 -145
  116. package/lib/rollback.d.ts +0 -9
  117. package/lib/rollback.js +0 -68
  118. package/lib/rubric.d.ts +0 -29
  119. package/lib/rubric.js +0 -119
  120. package/lib/runtime-commands.d.ts +0 -14
  121. package/lib/runtime-commands.js +0 -115
  122. package/lib/runtime.d.ts +0 -24
  123. package/lib/runtime.js +0 -87
  124. package/lib/score.d.ts +0 -64
  125. package/lib/score.js +0 -191
  126. package/lib/search.d.ts +0 -83
  127. package/lib/search.js +0 -136
  128. package/lib/service.d.ts +0 -63
  129. package/lib/service.js +0 -253
  130. package/lib/skill-render.d.ts +0 -23
  131. package/lib/skill-render.js +0 -69
  132. package/lib/skill.d.ts +0 -15
  133. package/lib/skill.js +0 -80
  134. package/lib/skillquality.d.ts +0 -85
  135. package/lib/skillquality.js +0 -320
  136. package/lib/source.d.ts +0 -30
  137. package/lib/source.js +0 -43
  138. package/lib/state.d.ts +0 -26
  139. package/lib/state.js +0 -151
  140. package/lib/store.d.ts +0 -61
  141. package/lib/store.js +0 -164
  142. package/lib/token-usage.d.ts +0 -68
  143. package/lib/token-usage.js +0 -211
  144. package/lib/tool.d.ts +0 -34
  145. package/lib/tool.js +0 -320
  146. package/lib/turn-snapshot.d.ts +0 -78
  147. package/lib/turn-snapshot.js +0 -252
  148. package/lib/types.d.ts +0 -218
  149. package/lib/types.js +0 -133
  150. package/lib/usage.d.ts +0 -36
  151. package/lib/usage.js +0 -98
  152. package/lib/validate.d.ts +0 -28
  153. package/lib/validate.js +0 -181
  154. package/lib/wrapup-candidates.d.ts +0 -127
  155. package/lib/wrapup-candidates.js +0 -161
  156. package/lib/wrapup-command.d.ts +0 -10
  157. package/lib/wrapup-command.js +0 -243
  158. package/lib/wrapup-proposals.d.ts +0 -101
  159. package/lib/wrapup-proposals.js +0 -281
  160. package/lib/wrapup.d.ts +0 -56
  161. 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