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.
- package/README.md +42 -115
- package/README.zh.md +33 -93
- package/client/client.js +253 -0
- package/cordis.patch.yml +2 -2
- package/lib/card-routes.d.ts +32 -0
- package/lib/card-routes.js +92 -0
- package/lib/index.d.ts +65 -217
- package/lib/index.js +74 -234
- package/lib/known-workspaces.d.ts +22 -0
- package/lib/known-workspaces.js +42 -0
- package/lib/memory-guide.d.ts +13 -14
- package/lib/memory-guide.js +34 -21
- package/lib/memory-section.d.ts +77 -0
- package/lib/memory-section.js +189 -0
- package/lib/memory-snapshot.d.ts +54 -0
- package/lib/memory-snapshot.js +125 -0
- package/package.json +8 -17
- package/lib/apply.d.ts +0 -22
- package/lib/apply.js +0 -157
- package/lib/approval.d.ts +0 -73
- package/lib/approval.js +0 -127
- package/lib/audit-log.d.ts +0 -19
- package/lib/audit-log.js +0 -52
- package/lib/auto.d.ts +0 -236
- package/lib/auto.js +0 -773
- package/lib/autocase.d.ts +0 -38
- package/lib/autocase.js +0 -76
- package/lib/benchmark-command.d.ts +0 -9
- package/lib/benchmark-command.js +0 -357
- package/lib/benchmark.d.ts +0 -151
- package/lib/benchmark.js +0 -250
- package/lib/command-util.d.ts +0 -70
- package/lib/command-util.js +0 -123
- package/lib/command.d.ts +0 -13
- package/lib/command.js +0 -134
- package/lib/consolidate.d.ts +0 -90
- package/lib/consolidate.js +0 -180
- package/lib/copy.d.ts +0 -37
- package/lib/copy.js +0 -58
- package/lib/declines.d.ts +0 -103
- package/lib/declines.js +0 -179
- package/lib/evaluate.d.ts +0 -74
- package/lib/evaluate.js +0 -271
- package/lib/evolve-event.d.ts +0 -40
- package/lib/evolve-event.js +0 -60
- package/lib/extraction-phase.d.ts +0 -132
- package/lib/extraction-phase.js +0 -236
- package/lib/failures.d.ts +0 -42
- package/lib/failures.js +0 -171
- package/lib/fate.d.ts +0 -130
- package/lib/fate.js +0 -350
- package/lib/goal-command.d.ts +0 -7
- package/lib/goal-command.js +0 -37
- package/lib/goal.d.ts +0 -72
- package/lib/goal.js +0 -72
- package/lib/inject.d.ts +0 -90
- package/lib/inject.js +0 -164
- package/lib/injection-caps.d.ts +0 -4
- package/lib/injection-caps.js +0 -4
- package/lib/injection-directory.d.ts +0 -29
- package/lib/injection-directory.js +0 -78
- package/lib/injection-rank.d.ts +0 -85
- package/lib/injection-rank.js +0 -161
- package/lib/listener.d.ts +0 -45
- package/lib/listener.js +0 -199
- package/lib/llm-text.d.ts +0 -104
- package/lib/llm-text.js +0 -140
- package/lib/logfile.d.ts +0 -71
- package/lib/logfile.js +0 -159
- package/lib/maintenance-commands.d.ts +0 -23
- package/lib/maintenance-commands.js +0 -136
- package/lib/memory-agent.d.ts +0 -93
- package/lib/memory-agent.js +0 -300
- package/lib/memory-apply.d.ts +0 -44
- package/lib/memory-apply.js +0 -202
- package/lib/memory-benchmark.d.ts +0 -76
- package/lib/memory-benchmark.js +0 -170
- package/lib/memory-index.d.ts +0 -114
- package/lib/memory-index.js +0 -197
- package/lib/memory-manifest.d.ts +0 -16
- package/lib/memory-manifest.js +0 -70
- package/lib/message-source.d.ts +0 -23
- package/lib/message-source.js +0 -12
- package/lib/mount-command.d.ts +0 -10
- package/lib/mount-command.js +0 -48
- package/lib/mount.d.ts +0 -42
- package/lib/mount.js +0 -212
- package/lib/notify.d.ts +0 -48
- package/lib/notify.js +0 -57
- package/lib/plan-command.d.ts +0 -12
- package/lib/plan-command.js +0 -38
- package/lib/plan.d.ts +0 -16
- package/lib/plan.js +0 -126
- package/lib/planner.d.ts +0 -61
- package/lib/planner.js +0 -144
- package/lib/pool.d.ts +0 -7
- package/lib/pool.js +0 -25
- package/lib/prefix-cache.d.ts +0 -79
- package/lib/prefix-cache.js +0 -168
- package/lib/project.d.ts +0 -28
- package/lib/project.js +0 -66
- package/lib/projection.d.ts +0 -22
- package/lib/projection.js +0 -112
- package/lib/promotion.d.ts +0 -94
- package/lib/promotion.js +0 -171
- package/lib/recall.d.ts +0 -85
- package/lib/recall.js +0 -142
- package/lib/record-language.d.ts +0 -85
- package/lib/record-language.js +0 -152
- package/lib/render.d.ts +0 -13
- package/lib/render.js +0 -80
- package/lib/review-scheduler.d.ts +0 -38
- package/lib/review-scheduler.js +0 -183
- package/lib/review.d.ts +0 -60
- package/lib/review.js +0 -145
- package/lib/rollback.d.ts +0 -9
- package/lib/rollback.js +0 -68
- package/lib/rubric.d.ts +0 -29
- package/lib/rubric.js +0 -119
- package/lib/runtime-commands.d.ts +0 -14
- package/lib/runtime-commands.js +0 -115
- package/lib/runtime.d.ts +0 -24
- package/lib/runtime.js +0 -87
- package/lib/score.d.ts +0 -64
- package/lib/score.js +0 -191
- package/lib/search.d.ts +0 -83
- package/lib/search.js +0 -136
- package/lib/service.d.ts +0 -63
- package/lib/service.js +0 -253
- package/lib/skill-render.d.ts +0 -23
- package/lib/skill-render.js +0 -69
- package/lib/skill.d.ts +0 -15
- package/lib/skill.js +0 -80
- package/lib/skillquality.d.ts +0 -85
- package/lib/skillquality.js +0 -320
- package/lib/source.d.ts +0 -30
- package/lib/source.js +0 -43
- package/lib/state.d.ts +0 -26
- package/lib/state.js +0 -151
- package/lib/store.d.ts +0 -61
- package/lib/store.js +0 -164
- package/lib/token-usage.d.ts +0 -68
- package/lib/token-usage.js +0 -211
- package/lib/tool.d.ts +0 -34
- package/lib/tool.js +0 -320
- package/lib/turn-snapshot.d.ts +0 -78
- package/lib/turn-snapshot.js +0 -252
- package/lib/types.d.ts +0 -218
- package/lib/types.js +0 -133
- package/lib/usage.d.ts +0 -36
- package/lib/usage.js +0 -98
- package/lib/validate.d.ts +0 -28
- package/lib/validate.js +0 -181
- package/lib/wrapup-candidates.d.ts +0 -127
- package/lib/wrapup-candidates.js +0 -161
- package/lib/wrapup-command.d.ts +0 -10
- package/lib/wrapup-command.js +0 -243
- package/lib/wrapup-proposals.d.ts +0 -101
- package/lib/wrapup-proposals.js +0 -281
- package/lib/wrapup.d.ts +0 -56
- 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
|
package/lib/evolve-event.d.ts
DELETED
|
@@ -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
|
package/lib/evolve-event.js
DELETED
|
@@ -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
|