loopforge 3.0.0 → 3.2.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 +128 -145
- package/dist/audit.d.ts +50 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +158 -0
- package/dist/audit.js.map +1 -0
- package/dist/canonical-state.d.ts +28 -20
- package/dist/canonical-state.d.ts.map +1 -1
- package/dist/canonical-state.js +82 -173
- package/dist/canonical-state.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +25 -16
- package/dist/cli.js.map +1 -1
- package/dist/cognitive-governance.d.ts +25 -33
- package/dist/cognitive-governance.d.ts.map +1 -1
- package/dist/cognitive-governance.js +38 -138
- package/dist/cognitive-governance.js.map +1 -1
- package/dist/enforcement-gate.d.ts +76 -0
- package/dist/enforcement-gate.d.ts.map +1 -0
- package/dist/enforcement-gate.js +1071 -0
- package/dist/enforcement-gate.js.map +1 -0
- package/dist/engine.d.ts +99 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +839 -0
- package/dist/engine.js.map +1 -0
- package/dist/evidence-claims.d.ts +50 -0
- package/dist/evidence-claims.d.ts.map +1 -0
- package/dist/evidence-claims.js +134 -0
- package/dist/evidence-claims.js.map +1 -0
- package/dist/evidence-provider.d.ts +21 -23
- package/dist/evidence-provider.d.ts.map +1 -1
- package/dist/evidence-provider.js +74 -34
- package/dist/evidence-provider.js.map +1 -1
- package/dist/generate-schema.js +1 -84
- package/dist/generate-schema.js.map +1 -1
- package/dist/index.d.ts +19 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -15
- package/dist/index.js.map +1 -1
- package/dist/loop-compiler.d.ts +41 -3
- package/dist/loop-compiler.d.ts.map +1 -1
- package/dist/loop-compiler.js +632 -273
- package/dist/loop-compiler.js.map +1 -1
- package/dist/loop-extras-parser.d.ts +2 -2
- package/dist/loop-extras-parser.d.ts.map +1 -1
- package/dist/loop-extras-parser.js +2 -2
- package/dist/loop-extras-parser.js.map +1 -1
- package/dist/loop-projection.d.ts +26 -0
- package/dist/loop-projection.d.ts.map +1 -0
- package/dist/loop-projection.js +142 -0
- package/dist/loop-projection.js.map +1 -0
- package/dist/loop-store.d.ts +112 -24
- package/dist/loop-store.d.ts.map +1 -1
- package/dist/loop-store.js +365 -218
- package/dist/loop-store.js.map +1 -1
- package/dist/mcp/round-lifecycle.d.ts +216 -0
- package/dist/mcp/round-lifecycle.d.ts.map +1 -0
- package/dist/mcp/round-lifecycle.js +926 -0
- package/dist/mcp/round-lifecycle.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +28 -42
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session.d.ts +53 -101
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +306 -1105
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/tools.d.ts +13 -16
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +479 -413
- package/dist/mcp/tools.js.map +1 -1
- package/dist/policy-metrics.d.ts +12 -17
- package/dist/policy-metrics.d.ts.map +1 -1
- package/dist/policy-metrics.js +95 -161
- package/dist/policy-metrics.js.map +1 -1
- package/dist/policy.d.ts +44 -35
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +31 -115
- package/dist/policy.js.map +1 -1
- package/dist/prompt-assembler.d.ts +37 -6
- package/dist/prompt-assembler.d.ts.map +1 -1
- package/dist/prompt-assembler.js +389 -160
- package/dist/prompt-assembler.js.map +1 -1
- package/dist/prompt-policy.d.ts +1 -8
- package/dist/prompt-policy.d.ts.map +1 -1
- package/dist/prompt-policy.js +8 -26
- package/dist/prompt-policy.js.map +1 -1
- package/dist/protocol.d.ts +357 -229
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +139 -15
- package/dist/protocol.js.map +1 -1
- package/dist/replay.d.ts +5 -13
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +19 -55
- package/dist/replay.js.map +1 -1
- package/dist/round-coordinator.d.ts +20 -24
- package/dist/round-coordinator.d.ts.map +1 -1
- package/dist/round-coordinator.js +99 -92
- package/dist/round-coordinator.js.map +1 -1
- package/dist/round-driver.d.ts +14 -13
- package/dist/round-driver.d.ts.map +1 -1
- package/dist/round-driver.js +26 -14
- package/dist/round-driver.js.map +1 -1
- package/dist/round-transaction.d.ts +15 -18
- package/dist/round-transaction.d.ts.map +1 -1
- package/dist/round-transaction.js +38 -47
- package/dist/round-transaction.js.map +1 -1
- package/dist/self-eval.d.ts +53 -0
- package/dist/self-eval.d.ts.map +1 -0
- package/dist/self-eval.js +284 -0
- package/dist/self-eval.js.map +1 -0
- package/dist/storage.d.ts +9 -4
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +18 -6
- package/dist/storage.js.map +1 -1
- package/dist/token-utils.d.ts +15 -3
- package/dist/token-utils.d.ts.map +1 -1
- package/dist/token-utils.js +24 -5
- package/dist/token-utils.js.map +1 -1
- package/dist/verification-gate.d.ts +108 -0
- package/dist/verification-gate.d.ts.map +1 -0
- package/dist/verification-gate.js +971 -0
- package/dist/verification-gate.js.map +1 -0
- package/loop_policy.json +44 -15
- package/package.json +5 -10
- package/skills/perception/SKILL.md +182 -199
- package/dist/canonical-event-writer.d.ts +0 -20
- package/dist/canonical-event-writer.d.ts.map +0 -1
- package/dist/canonical-event-writer.js +0 -131
- package/dist/canonical-event-writer.js.map +0 -1
- package/dist/compiler-subgoals.d.ts +0 -7
- package/dist/compiler-subgoals.d.ts.map +0 -1
- package/dist/compiler-subgoals.js +0 -93
- package/dist/compiler-subgoals.js.map +0 -1
- package/dist/derive-id.d.ts +0 -12
- package/dist/derive-id.d.ts.map +0 -1
- package/dist/derive-id.js +0 -31
- package/dist/derive-id.js.map +0 -1
- package/dist/mcp/session-projection.d.ts +0 -5
- package/dist/mcp/session-projection.d.ts.map +0 -1
- package/dist/mcp/session-projection.js +0 -18
- package/dist/mcp/session-projection.js.map +0 -1
- package/dist/mcp/session-queue.d.ts +0 -3
- package/dist/mcp/session-queue.d.ts.map +0 -1
- package/dist/mcp/session-queue.js +0 -18
- package/dist/mcp/session-queue.js.map +0 -1
- package/dist/mcp/session-types.d.ts +0 -72
- package/dist/mcp/session-types.d.ts.map +0 -1
- package/dist/mcp/session-types.js +0 -2
- package/dist/mcp/session-types.js.map +0 -1
- package/dist/round-commit-store.d.ts +0 -12
- package/dist/round-commit-store.d.ts.map +0 -1
- package/dist/round-commit-store.js +0 -13
- package/dist/round-commit-store.js.map +0 -1
- package/dist/round-gate.d.ts +0 -31
- package/dist/round-gate.d.ts.map +0 -1
- package/dist/round-gate.js +0 -259
- package/dist/round-gate.js.map +0 -1
- package/dist/round-recovery.d.ts +0 -17
- package/dist/round-recovery.d.ts.map +0 -1
- package/dist/round-recovery.js +0 -117
- package/dist/round-recovery.js.map +0 -1
- package/dist/round-report.d.ts +0 -16
- package/dist/round-report.d.ts.map +0 -1
- package/dist/round-report.js +0 -401
- package/dist/round-report.js.map +0 -1
- package/dist/runtime-services.d.ts +0 -59
- package/dist/runtime-services.d.ts.map +0 -1
- package/dist/runtime-services.js +0 -460
- package/dist/runtime-services.js.map +0 -1
- package/dist/vault-format.d.ts +0 -4
- package/dist/vault-format.d.ts.map +0 -1
- package/dist/vault-format.js +0 -4
- package/dist/vault-format.js.map +0 -1
- package/dist/vault-types.d.ts +0 -24
- package/dist/vault-types.d.ts.map +0 -1
- package/dist/vault-types.js +0 -2
- package/dist/vault-types.js.map +0 -1
- package/loopforge-policy.json +0 -340
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round-transaction.d.ts","sourceRoot":"","sources":["../src/round-transaction.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"round-transaction.d.ts","sourceRoot":"","sources":["../src/round-transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
*
|
|
3
3
|
* A logical round has one deterministic roundId. Rejected attempts keep the
|
|
4
4
|
* same identity and before snapshot; only accepted decisions are committed to
|
|
5
|
-
*
|
|
5
|
+
* feedback storage. The committed feedback embeds the decision so replay after
|
|
6
6
|
* a process crash is idempotent.
|
|
7
7
|
*/
|
|
8
8
|
import { diffSnapshotCollections } from "./evidence-provider.js";
|
|
@@ -10,10 +10,8 @@ import { RoundCoordinator, } from "./round-coordinator.js";
|
|
|
10
10
|
import { logEvent } from "./observability.js";
|
|
11
11
|
import { isRecord } from "./token-utils.js";
|
|
12
12
|
import { policyMetrics } from "./policy-metrics.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
import { validateLoopId } from "./policy.js";
|
|
16
|
-
export const ROUND_TRANSACTION_FORMAT = "loopforge.round-transaction";
|
|
13
|
+
import { VaultRoundCommitStore } from "./storage.js";
|
|
14
|
+
export const ROUND_TRANSACTION_SCHEMA_VERSION = 1;
|
|
17
15
|
export function makeRoundId(loopId, round) {
|
|
18
16
|
if (!Number.isInteger(round) || round < 1) {
|
|
19
17
|
throw new Error(`Invalid round number: ${round}`);
|
|
@@ -23,7 +21,7 @@ export function makeRoundId(loopId, round) {
|
|
|
23
21
|
export function prepareRoundTransaction(loopId, round, beforeEvidence, promptArtifact) {
|
|
24
22
|
const now = Date.now();
|
|
25
23
|
return {
|
|
26
|
-
|
|
24
|
+
schemaVersion: ROUND_TRANSACTION_SCHEMA_VERSION,
|
|
27
25
|
roundId: makeRoundId(loopId, round),
|
|
28
26
|
loopId,
|
|
29
27
|
round,
|
|
@@ -54,13 +52,13 @@ export function prepareRejectedAttempt(rejected, promptArtifact) {
|
|
|
54
52
|
phase: "prompted",
|
|
55
53
|
afterEvidence: undefined,
|
|
56
54
|
roundEvidence: undefined,
|
|
57
|
-
|
|
55
|
+
evaluation: undefined,
|
|
58
56
|
result: undefined,
|
|
59
57
|
promptArtifact,
|
|
60
58
|
updatedAt: Date.now(),
|
|
61
59
|
};
|
|
62
60
|
}
|
|
63
|
-
function isProcessResult(value) {
|
|
61
|
+
export function isProcessResult(value) {
|
|
64
62
|
if (!isRecord(value))
|
|
65
63
|
return false;
|
|
66
64
|
return ["continue", "stop", "reject", "terminate", "backtrack"].includes(String(value.action)) && Array.isArray(value.verificationFlags);
|
|
@@ -73,9 +71,7 @@ function parseProviderSnapshots(value) {
|
|
|
73
71
|
if (!isRecord(item))
|
|
74
72
|
return null;
|
|
75
73
|
if (typeof item.provider !== "string" ||
|
|
76
|
-
!item.provider.trim() ||
|
|
77
74
|
typeof item.timestamp !== "number" ||
|
|
78
|
-
!Number.isFinite(item.timestamp) ||
|
|
79
75
|
!Array.isArray(item.files) ||
|
|
80
76
|
!item.files.every((file) => typeof file === "string") ||
|
|
81
77
|
!isRecord(item.data))
|
|
@@ -88,19 +84,11 @@ function parseProviderSnapshots(value) {
|
|
|
88
84
|
export function parseRoundTransactionSnapshot(value) {
|
|
89
85
|
if (!isRecord(value))
|
|
90
86
|
return null;
|
|
91
|
-
if (
|
|
92
|
-
return null;
|
|
93
|
-
if (value.format !== ROUND_TRANSACTION_FORMAT)
|
|
87
|
+
if (value.schemaVersion !== ROUND_TRANSACTION_SCHEMA_VERSION)
|
|
94
88
|
return null;
|
|
95
89
|
if (typeof value.roundId !== "string" || typeof value.loopId !== "string") {
|
|
96
90
|
return null;
|
|
97
91
|
}
|
|
98
|
-
try {
|
|
99
|
-
validateLoopId(value.loopId);
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
92
|
if (!Number.isInteger(value.round) || value.round < 1)
|
|
105
93
|
return null;
|
|
106
94
|
if (!Number.isInteger(value.attempt) || value.attempt < 1)
|
|
@@ -123,18 +111,12 @@ export function parseRoundTransactionSnapshot(value) {
|
|
|
123
111
|
return null;
|
|
124
112
|
if (value.result !== undefined && !isProcessResult(value.result))
|
|
125
113
|
return null;
|
|
126
|
-
if (value.roundReport !== undefined && !parseRoundReport(value.roundReport))
|
|
127
|
-
return null;
|
|
128
114
|
if (value.promptArtifact !== undefined) {
|
|
129
115
|
if (!isRecord(value.promptArtifact))
|
|
130
116
|
return null;
|
|
131
117
|
const artifact = value.promptArtifact;
|
|
132
|
-
if (artifact.
|
|
118
|
+
if (artifact.schemaVersion !== 1 ||
|
|
133
119
|
typeof artifact.roundId !== "string" ||
|
|
134
|
-
artifact.roundId !== value.roundId ||
|
|
135
|
-
!Number.isInteger(artifact.attempt) ||
|
|
136
|
-
artifact.attempt < 1 ||
|
|
137
|
-
artifact.attempt !== value.attempt ||
|
|
138
120
|
typeof artifact.renderedPrompt !== "string" ||
|
|
139
121
|
typeof artifact.promptHash !== "string" ||
|
|
140
122
|
typeof artifact.stateHash !== "string" ||
|
|
@@ -154,12 +136,12 @@ export function parseRoundTransactionSnapshot(value) {
|
|
|
154
136
|
}
|
|
155
137
|
export class RoundTransactionCoordinator {
|
|
156
138
|
engine;
|
|
157
|
-
|
|
139
|
+
store;
|
|
158
140
|
commitStore;
|
|
159
|
-
constructor(engine,
|
|
141
|
+
constructor(engine, store, commitStore) {
|
|
160
142
|
this.engine = engine;
|
|
161
|
-
this.
|
|
162
|
-
this.commitStore = commitStore ?? new VaultRoundCommitStore(this.
|
|
143
|
+
this.store = store ?? engine.getStore();
|
|
144
|
+
this.commitStore = commitStore ?? new VaultRoundCommitStore(this.store);
|
|
163
145
|
}
|
|
164
146
|
process(input) {
|
|
165
147
|
const { snapshot } = input;
|
|
@@ -171,7 +153,11 @@ export class RoundTransactionCoordinator {
|
|
|
171
153
|
if (snapshot.roundId !== expectedRoundId) {
|
|
172
154
|
throw new Error(`Round snapshot identity mismatch: ${snapshot.roundId} !== ${expectedRoundId}`);
|
|
173
155
|
}
|
|
174
|
-
|
|
156
|
+
// v3.2.1: idempotency replay skips committed backtrack decisions — a
|
|
157
|
+
// backtrack rolls the round back for a redo; the redo submission carries
|
|
158
|
+
// the same roundId and must be evaluated, not replayed as the old
|
|
159
|
+
// roll-back directive (which would discard the agent's fix forever).
|
|
160
|
+
const committed = this.readCommitted(snapshot, { skipBacktrack: true });
|
|
175
161
|
if (committed) {
|
|
176
162
|
logEvent("round_transaction_replay", {
|
|
177
163
|
loopId: snapshot.loopId,
|
|
@@ -184,25 +170,20 @@ export class RoundTransactionCoordinator {
|
|
|
184
170
|
? snapshot.attempt + 1
|
|
185
171
|
: snapshot.attempt;
|
|
186
172
|
const roundEvidence = diffSnapshotCollections(snapshot.beforeEvidence, input.actualEvidence);
|
|
187
|
-
const
|
|
188
|
-
if (!sourceReport)
|
|
189
|
-
throw new Error("RoundTransaction requires a canonical RoundReport");
|
|
190
|
-
const verifiedReport = verifyRoundReportEvidence(sourceReport, roundEvidence);
|
|
191
|
-
const coordinator = new RoundCoordinator(this.backend);
|
|
173
|
+
const coordinator = new RoundCoordinator(this.store);
|
|
192
174
|
const result = coordinator.processRound({
|
|
193
175
|
loopId: snapshot.loopId,
|
|
194
176
|
task: input.task,
|
|
195
177
|
currentRound: snapshot.round,
|
|
196
178
|
maxRounds: input.maxRounds,
|
|
197
|
-
|
|
198
|
-
|
|
179
|
+
selfEval: input.selfEval,
|
|
180
|
+
extractionSucceeded: input.extractionSucceeded,
|
|
181
|
+
lastSelfEval: input.lastSelfEval,
|
|
199
182
|
consecutiveRejections: input.consecutiveRejections,
|
|
200
183
|
evidenceSnapshots: roundEvidence,
|
|
201
184
|
successTrajectory: input.successTrajectory,
|
|
202
185
|
backtrackSkippedFiles: input.backtrackSkippedFiles,
|
|
203
186
|
backtrackTargetGitHead: input.backtrackTargetGitHead,
|
|
204
|
-
expectedAction: input.expectedAction,
|
|
205
|
-
escalatedRejectionChecks: input.escalatedRejectionChecks,
|
|
206
187
|
}, input.driftClarificationStreak ?? 0);
|
|
207
188
|
const evaluated = {
|
|
208
189
|
...snapshot,
|
|
@@ -210,7 +191,7 @@ export class RoundTransactionCoordinator {
|
|
|
210
191
|
phase: "evaluated",
|
|
211
192
|
afterEvidence: input.actualEvidence,
|
|
212
193
|
roundEvidence,
|
|
213
|
-
|
|
194
|
+
evaluation: input.selfEval,
|
|
214
195
|
result,
|
|
215
196
|
updatedAt: Date.now(),
|
|
216
197
|
};
|
|
@@ -228,12 +209,12 @@ export class RoundTransactionCoordinator {
|
|
|
228
209
|
updatedAt: Date.now(),
|
|
229
210
|
};
|
|
230
211
|
const metadata = {
|
|
231
|
-
|
|
212
|
+
schema_version: ROUND_TRANSACTION_SCHEMA_VERSION,
|
|
232
213
|
round_id: snapshot.roundId,
|
|
233
214
|
snapshot: committedSnapshot,
|
|
234
215
|
result,
|
|
235
216
|
};
|
|
236
|
-
this.engine.
|
|
217
|
+
this.engine.autoFeedback(input.selfEval, snapshot.loopId, snapshot.round, input.task, metadata);
|
|
237
218
|
const persisted = this.readCommitted(committedSnapshot);
|
|
238
219
|
if (!persisted) {
|
|
239
220
|
throw new Error(`Round transaction commit failed: ${snapshot.roundId}`);
|
|
@@ -254,19 +235,19 @@ export class RoundTransactionCoordinator {
|
|
|
254
235
|
}
|
|
255
236
|
return outcome;
|
|
256
237
|
}
|
|
257
|
-
readCommitted(expected) {
|
|
258
|
-
const taskId = `loop:${expected.loopId}:r${expected.round}:
|
|
238
|
+
readCommitted(expected, opts) {
|
|
239
|
+
const taskId = `loop:${expected.loopId}:r${expected.round}:feedback`;
|
|
259
240
|
const entries = this.commitStore.find(expected.loopId, expected.round);
|
|
260
241
|
for (const entry of entries) {
|
|
261
242
|
if (entry.task_id !== taskId)
|
|
262
243
|
continue;
|
|
263
|
-
const outcome = this.outcomeFromEntry(entry, expected.roundId);
|
|
244
|
+
const outcome = this.outcomeFromEntry(entry, expected.roundId, opts?.skipBacktrack === true);
|
|
264
245
|
if (outcome)
|
|
265
246
|
return outcome;
|
|
266
247
|
}
|
|
267
248
|
return null;
|
|
268
249
|
}
|
|
269
|
-
outcomeFromEntry(entry, expectedRoundId) {
|
|
250
|
+
outcomeFromEntry(entry, expectedRoundId, skipBacktrack = false) {
|
|
270
251
|
const lineage = isRecord(entry.loop_lineage) ? entry.loop_lineage : null;
|
|
271
252
|
const transaction = lineage && isRecord(lineage.round_transaction)
|
|
272
253
|
? lineage.round_transaction
|
|
@@ -277,6 +258,16 @@ export class RoundTransactionCoordinator {
|
|
|
277
258
|
const result = transaction.result;
|
|
278
259
|
if (!snapshot || !isProcessResult(result))
|
|
279
260
|
return null;
|
|
261
|
+
// v3.2.1: a committed backtrack is a roll-back directive, not a terminal
|
|
262
|
+
// decision. The restored round reuses the same roundId, so replaying it
|
|
263
|
+
// would silently discard the agent's redo submission and re-emit the
|
|
264
|
+
// backtrack prompt forever (the redo's work is never evaluated, and the
|
|
265
|
+
// R4/R9 terminate guards never run because evaluation is short-circuited).
|
|
266
|
+
// Crash recovery still replays backtracks (recover() → reconcileCommittedRound
|
|
267
|
+
// resets the round counter from the committed decision); only the advance
|
|
268
|
+
// path skips them so the redo is evaluated normally.
|
|
269
|
+
if (skipBacktrack && result.action === "backtrack")
|
|
270
|
+
return null;
|
|
280
271
|
return { snapshot, result, replayed: true };
|
|
281
272
|
}
|
|
282
273
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round-transaction.js","sourceRoot":"","sources":["../src/round-transaction.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"round-transaction.js","sourceRoot":"","sources":["../src/round-transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Self-evaluation extraction and parsing — pure functions.
|
|
2
|
+
*
|
|
3
|
+
* These functions parse an Agent's raw output into a structured
|
|
4
|
+
* SelfEvaluation. They have no dependency on Engine state, file I/O,
|
|
5
|
+
* or external services. They are shared by both the MCP tool handler
|
|
6
|
+
* (which receives structured JSON directly) and the legacy invoke
|
|
7
|
+
* path (which regex-scans free-text Agent output).
|
|
8
|
+
*/
|
|
9
|
+
import { type CriterionRevision, type ExecutionEvidence, type RoundOutcome, type SelfEvaluation } from "./protocol.js";
|
|
10
|
+
/** Parse ExecutionEvidence from a raw JSON object. */
|
|
11
|
+
export declare function parseExecutionEvidence(raw: Record<string, unknown> | undefined | null): ExecutionEvidence | undefined;
|
|
12
|
+
/** Parse CriterionRevision[] from a raw JSON array. */
|
|
13
|
+
export declare function parseCriterionRevisions(raw: unknown): CriterionRevision[];
|
|
14
|
+
/** Parse WorkerResult[] from a raw JSON array. */
|
|
15
|
+
export declare function parseWorkerResults(raw: unknown): import("./protocol.js").WorkerResult[];
|
|
16
|
+
/** Extract a structured SelfEvaluation from agent output text.
|
|
17
|
+
* Returns null if no valid self-eval block is found.
|
|
18
|
+
* The agent is instructed to output JSON between the delimiters. */
|
|
19
|
+
export declare function extractSelfEvaluation(text: string): SelfEvaluation | null;
|
|
20
|
+
/** v2.12: The effective round outcome — declared outcome wins, otherwise
|
|
21
|
+
* derived from `success`. "partial" can only be declared explicitly (never
|
|
22
|
+
* silently derived from success=false, which would quietly change the
|
|
23
|
+
* success-class enforcement surface). */
|
|
24
|
+
export declare function effectiveOutcome(selfEval: SelfEvaluation): RoundOutcome;
|
|
25
|
+
/** v2.12: Whether the effective outcome is a success claim. Shared by the
|
|
26
|
+
* verification gate (success-class checks) and enforcement gate (R3). */
|
|
27
|
+
export declare function effectiveSuccess(selfEval: SelfEvaluation): boolean;
|
|
28
|
+
/** v2.12: Minimal outcome inference from free text — DIAGNOSTICS ONLY.
|
|
29
|
+
* The runtime never guesses state from text; this only tells the agent
|
|
30
|
+
* what was recognizable so it can resubmit a structured evaluation. */
|
|
31
|
+
export declare function inferOutcomeFromText(text: string): {
|
|
32
|
+
outcome: "success" | "partial" | "failed";
|
|
33
|
+
summary: string;
|
|
34
|
+
} | null;
|
|
35
|
+
/** v2.12: Why structured extraction failed — for actionable diagnostics. */
|
|
36
|
+
export type ExtractionFailureReason = "no_eval_block" | "json_parse_failed" | "missing_required_fields";
|
|
37
|
+
/** v2.12: Extraction with a structured failure reason. Behavior identical
|
|
38
|
+
* to extractSelfEvaluation on success; the reason powers the stalled
|
|
39
|
+
* diagnostic message so the agent knows exactly what to fix. */
|
|
40
|
+
export declare function extractSelfEvaluationWithDiagnostics(text: string): {
|
|
41
|
+
selfEval: SelfEvaluation | null;
|
|
42
|
+
reason: ExtractionFailureReason | null;
|
|
43
|
+
};
|
|
44
|
+
/** v2.12: Field-level validation gaps — diagnostics only. Collects what
|
|
45
|
+
* buildSelfEvaluation silently tolerates, without changing acceptance. */
|
|
46
|
+
export declare function collectSelfEvalGaps(raw: Record<string, unknown>): {
|
|
47
|
+
field: string;
|
|
48
|
+
issue: string;
|
|
49
|
+
}[];
|
|
50
|
+
/** Build a SelfEvaluation from a parsed JSON object.
|
|
51
|
+
* Lenient parsing: missing optional fields get sensible defaults. */
|
|
52
|
+
export declare function buildSelfEvaluation(raw: Record<string, unknown>): SelfEvaluation;
|
|
53
|
+
//# sourceMappingURL=self-eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-eval.d.ts","sourceRoot":"","sources":["../src/self-eval.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAuBvB,sDAAsD;AACtD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAC9C,iBAAiB,GAAG,SAAS,CAwB/B;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,GACX,iBAAiB,EAAE,CAWrB;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,GACX,OAAO,eAAe,EAAE,YAAY,EAAE,CAyBxC;AAID;;qEAEqE;AACrE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAEzE;AAED;;;0CAG0C;AAC1C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY,CAMvE;AAED;0EAC0E;AAC1E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAElE;AAED;;wEAEwE;AACxE,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GACX;IAAE,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASvE;AAED,4EAA4E;AAC5E,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,mBAAmB,GACnB,yBAAyB,CAAC;AAE9B;;iEAEiE;AACjE,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,MAAM,GACX;IAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAA;CAAE,CAoB7E;AAED;2EAC2E;AAC3E,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAsBpC;AAED;sEACsE;AACtE,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,cAAc,CAwEhB"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/** Self-evaluation extraction and parsing — pure functions.
|
|
2
|
+
*
|
|
3
|
+
* These functions parse an Agent's raw output into a structured
|
|
4
|
+
* SelfEvaluation. They have no dependency on Engine state, file I/O,
|
|
5
|
+
* or external services. They are shared by both the MCP tool handler
|
|
6
|
+
* (which receives structured JSON directly) and the legacy invoke
|
|
7
|
+
* path (which regex-scans free-text Agent output).
|
|
8
|
+
*/
|
|
9
|
+
import { makeExecutionEvidence, makeSelfEvaluation, SELF_EVAL_REGEX, } from "./protocol.js";
|
|
10
|
+
// ── Raw parsing helpers ───────────────────────────────────────────────────
|
|
11
|
+
/** v2.12: Parse retroactive claims — {round ≥ 1, claim non-empty}, capped at
|
|
12
|
+
* 20 entries. Invalid entries are silently dropped (lenient parsing). */
|
|
13
|
+
function parseRetroactiveClaims(raw) {
|
|
14
|
+
if (!Array.isArray(raw))
|
|
15
|
+
return [];
|
|
16
|
+
const claims = [];
|
|
17
|
+
for (const item of raw) {
|
|
18
|
+
if (claims.length >= 20)
|
|
19
|
+
break;
|
|
20
|
+
if (typeof item !== "object" || item === null || Array.isArray(item))
|
|
21
|
+
continue;
|
|
22
|
+
const record = item;
|
|
23
|
+
if (typeof record.round !== "number" || !Number.isInteger(record.round) ||
|
|
24
|
+
record.round < 1 || typeof record.claim !== "string" ||
|
|
25
|
+
record.claim.trim().length === 0) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
claims.push({ round: record.round, claim: record.claim.slice(0, 500) });
|
|
29
|
+
}
|
|
30
|
+
return claims;
|
|
31
|
+
}
|
|
32
|
+
/** Parse ExecutionEvidence from a raw JSON object. */
|
|
33
|
+
export function parseExecutionEvidence(raw) {
|
|
34
|
+
if (!raw || typeof raw !== "object")
|
|
35
|
+
return undefined;
|
|
36
|
+
const testResults = raw.test_results;
|
|
37
|
+
return makeExecutionEvidence({
|
|
38
|
+
files_changed: Array.isArray(raw.files_changed)
|
|
39
|
+
? raw.files_changed.filter((v) => typeof v === "string")
|
|
40
|
+
: [],
|
|
41
|
+
test_results: testResults && typeof testResults.passed === "number"
|
|
42
|
+
? {
|
|
43
|
+
passed: testResults.passed,
|
|
44
|
+
failed: testResults.failed ?? 0,
|
|
45
|
+
skipped: testResults.skipped ?? 0,
|
|
46
|
+
}
|
|
47
|
+
: null,
|
|
48
|
+
success_criteria_met: Array.isArray(raw.success_criteria_met)
|
|
49
|
+
? raw.success_criteria_met.filter((v) => typeof v === "string")
|
|
50
|
+
: [],
|
|
51
|
+
success_criteria_remaining: Array.isArray(raw.success_criteria_remaining)
|
|
52
|
+
? raw.success_criteria_remaining.filter((v) => typeof v === "string")
|
|
53
|
+
: [],
|
|
54
|
+
progress_estimate: typeof raw.progress_estimate === "number"
|
|
55
|
+
? Math.max(0, Math.min(1, raw.progress_estimate))
|
|
56
|
+
: 0.0,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Parse CriterionRevision[] from a raw JSON array. */
|
|
60
|
+
export function parseCriterionRevisions(raw) {
|
|
61
|
+
if (!Array.isArray(raw))
|
|
62
|
+
return [];
|
|
63
|
+
return raw
|
|
64
|
+
.filter((v) => typeof v === "object" && v !== null &&
|
|
65
|
+
typeof v.old === "string" &&
|
|
66
|
+
typeof v.new === "string")
|
|
67
|
+
.map((v) => {
|
|
68
|
+
const r = v;
|
|
69
|
+
return { old: r.old, new: r.new };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** Parse WorkerResult[] from a raw JSON array. */
|
|
73
|
+
export function parseWorkerResults(raw) {
|
|
74
|
+
if (!Array.isArray(raw))
|
|
75
|
+
return [];
|
|
76
|
+
return raw
|
|
77
|
+
.filter((v) => typeof v === "object" && v !== null &&
|
|
78
|
+
typeof v.agentId === "string" &&
|
|
79
|
+
typeof v.subTask === "string" &&
|
|
80
|
+
typeof v.resultSummary === "string")
|
|
81
|
+
.map((v) => {
|
|
82
|
+
const w = v;
|
|
83
|
+
return {
|
|
84
|
+
agentId: w.agentId,
|
|
85
|
+
subAgentType: typeof w.subAgentType === "string" ? w.subAgentType : "general-purpose",
|
|
86
|
+
subTask: w.subTask,
|
|
87
|
+
resultSummary: w.resultSummary,
|
|
88
|
+
success: typeof w.success === "boolean" ? w.success : false,
|
|
89
|
+
// v2.12: Declared outcome wins; derived from success when absent.
|
|
90
|
+
outcome: w.outcome === "success" || w.outcome === "partial" || w.outcome === "failed"
|
|
91
|
+
? w.outcome
|
|
92
|
+
: undefined,
|
|
93
|
+
discoveredConstraints: Array.isArray(w.discoveredConstraints)
|
|
94
|
+
? w.discoveredConstraints.filter((c) => typeof c === "string")
|
|
95
|
+
: [],
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// ── Self-evaluation extraction ───────────────────────────────────────────
|
|
100
|
+
/** Extract a structured SelfEvaluation from agent output text.
|
|
101
|
+
* Returns null if no valid self-eval block is found.
|
|
102
|
+
* The agent is instructed to output JSON between the delimiters. */
|
|
103
|
+
export function extractSelfEvaluation(text) {
|
|
104
|
+
return extractSelfEvaluationWithDiagnostics(text).selfEval;
|
|
105
|
+
}
|
|
106
|
+
/** v2.12: The effective round outcome — declared outcome wins, otherwise
|
|
107
|
+
* derived from `success`. "partial" can only be declared explicitly (never
|
|
108
|
+
* silently derived from success=false, which would quietly change the
|
|
109
|
+
* success-class enforcement surface). */
|
|
110
|
+
export function effectiveOutcome(selfEval) {
|
|
111
|
+
if (selfEval.outcome === "success" || selfEval.outcome === "partial" ||
|
|
112
|
+
selfEval.outcome === "failed" || selfEval.outcome === "blocked") {
|
|
113
|
+
return selfEval.outcome;
|
|
114
|
+
}
|
|
115
|
+
return selfEval.success ? "success" : "failed";
|
|
116
|
+
}
|
|
117
|
+
/** v2.12: Whether the effective outcome is a success claim. Shared by the
|
|
118
|
+
* verification gate (success-class checks) and enforcement gate (R3). */
|
|
119
|
+
export function effectiveSuccess(selfEval) {
|
|
120
|
+
return effectiveOutcome(selfEval) === "success";
|
|
121
|
+
}
|
|
122
|
+
/** v2.12: Minimal outcome inference from free text — DIAGNOSTICS ONLY.
|
|
123
|
+
* The runtime never guesses state from text; this only tells the agent
|
|
124
|
+
* what was recognizable so it can resubmit a structured evaluation. */
|
|
125
|
+
export function inferOutcomeFromText(text) {
|
|
126
|
+
const trimmed = typeof text === "string" ? text.trim() : "";
|
|
127
|
+
if (trimmed.length === 0)
|
|
128
|
+
return null;
|
|
129
|
+
let outcome = "partial";
|
|
130
|
+
// NOTE: \b is ASCII-word based, so CJK keywords are matched without it.
|
|
131
|
+
if (/(?:completed?|success|done|finished)\b|完成|成功/i.test(trimmed))
|
|
132
|
+
outcome = "success";
|
|
133
|
+
else if (/(?:failed?|error|cannot|unable)\b|失败|错误/i.test(trimmed))
|
|
134
|
+
outcome = "failed";
|
|
135
|
+
const summary = trimmed.length > 200 ? `${trimmed.slice(0, 197)}...` : trimmed;
|
|
136
|
+
return { outcome, summary };
|
|
137
|
+
}
|
|
138
|
+
/** v2.12: Extraction with a structured failure reason. Behavior identical
|
|
139
|
+
* to extractSelfEvaluation on success; the reason powers the stalled
|
|
140
|
+
* diagnostic message so the agent knows exactly what to fix. */
|
|
141
|
+
export function extractSelfEvaluationWithDiagnostics(text) {
|
|
142
|
+
const match = text.match(SELF_EVAL_REGEX);
|
|
143
|
+
if (!match)
|
|
144
|
+
return { selfEval: null, reason: "no_eval_block" };
|
|
145
|
+
let parsed;
|
|
146
|
+
try {
|
|
147
|
+
parsed = JSON.parse(match[1]);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return { selfEval: null, reason: "json_parse_failed" };
|
|
151
|
+
}
|
|
152
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
153
|
+
return { selfEval: null, reason: "json_parse_failed" };
|
|
154
|
+
}
|
|
155
|
+
const record = parsed;
|
|
156
|
+
if (typeof record.success !== "boolean" ||
|
|
157
|
+
typeof record.output_summary !== "string" ||
|
|
158
|
+
!Array.isArray(record.constraint_violations) ||
|
|
159
|
+
typeof record.should_continue !== "boolean") {
|
|
160
|
+
return { selfEval: null, reason: "missing_required_fields" };
|
|
161
|
+
}
|
|
162
|
+
return { selfEval: buildSelfEvaluation(record), reason: null };
|
|
163
|
+
}
|
|
164
|
+
/** v2.12: Field-level validation gaps — diagnostics only. Collects what
|
|
165
|
+
* buildSelfEvaluation silently tolerates, without changing acceptance. */
|
|
166
|
+
export function collectSelfEvalGaps(raw) {
|
|
167
|
+
const gaps = [];
|
|
168
|
+
if (typeof raw.success !== "boolean")
|
|
169
|
+
gaps.push({ field: "success", issue: "must be a boolean" });
|
|
170
|
+
if (typeof raw.output_summary !== "string") {
|
|
171
|
+
gaps.push({ field: "output_summary", issue: "must be a string" });
|
|
172
|
+
}
|
|
173
|
+
if (!Array.isArray(raw.constraint_violations)) {
|
|
174
|
+
gaps.push({ field: "constraint_violations", issue: "must be an array" });
|
|
175
|
+
}
|
|
176
|
+
if (typeof raw.should_continue !== "boolean") {
|
|
177
|
+
gaps.push({ field: "should_continue", issue: "must be a boolean" });
|
|
178
|
+
}
|
|
179
|
+
if (raw.outcome !== undefined && typeof raw.outcome !== "string") {
|
|
180
|
+
gaps.push({ field: "outcome", issue: "must be a string enum (success|partial|failed|blocked)" });
|
|
181
|
+
}
|
|
182
|
+
if (raw.blocker !== undefined && typeof raw.blocker !== "string") {
|
|
183
|
+
gaps.push({ field: "blocker", issue: "must be a string" });
|
|
184
|
+
}
|
|
185
|
+
if (raw.retroactiveClaims !== undefined && !Array.isArray(raw.retroactiveClaims)) {
|
|
186
|
+
gaps.push({ field: "retroactiveClaims", issue: "must be an array of {round, claim}" });
|
|
187
|
+
}
|
|
188
|
+
return gaps;
|
|
189
|
+
}
|
|
190
|
+
/** Build a SelfEvaluation from a parsed JSON object.
|
|
191
|
+
* Lenient parsing: missing optional fields get sensible defaults. */
|
|
192
|
+
export function buildSelfEvaluation(raw) {
|
|
193
|
+
const executionEvidence = parseExecutionEvidence(raw.execution_evidence);
|
|
194
|
+
const retractedConstraints = Array.isArray(raw.retracted_constraints)
|
|
195
|
+
? raw.retracted_constraints.filter((v) => typeof v === "string")
|
|
196
|
+
: [];
|
|
197
|
+
const revisedCriteria = parseCriterionRevisions(raw.revised_success_criteria);
|
|
198
|
+
const wrongAssumptions = Array.isArray(raw.wrong_assumptions)
|
|
199
|
+
? raw.wrong_assumptions.filter((v) => typeof v === "string")
|
|
200
|
+
: [];
|
|
201
|
+
const workerResults = parseWorkerResults(raw.worker_results);
|
|
202
|
+
return makeSelfEvaluation({
|
|
203
|
+
success: typeof raw.success === "boolean" ? raw.success : false,
|
|
204
|
+
output_summary: typeof raw.output_summary === "string" ? raw.output_summary : "",
|
|
205
|
+
constraint_violations: Array.isArray(raw.constraint_violations)
|
|
206
|
+
? raw.constraint_violations.filter((v) => typeof v === "string")
|
|
207
|
+
: [],
|
|
208
|
+
should_continue: typeof raw.should_continue === "boolean" ? raw.should_continue : true,
|
|
209
|
+
discovered_constraints: Array.isArray(raw.discovered_constraints)
|
|
210
|
+
? raw.discovered_constraints.filter((v) => typeof v === "string")
|
|
211
|
+
: [],
|
|
212
|
+
objective_refinement: typeof raw.objective_refinement === "string"
|
|
213
|
+
? raw.objective_refinement
|
|
214
|
+
: "",
|
|
215
|
+
emerged_subtasks: Array.isArray(raw.emerged_subtasks)
|
|
216
|
+
? raw.emerged_subtasks.filter((v) => typeof v === "string")
|
|
217
|
+
: [],
|
|
218
|
+
execution_evidence: executionEvidence,
|
|
219
|
+
retracted_constraints: retractedConstraints,
|
|
220
|
+
revised_success_criteria: revisedCriteria,
|
|
221
|
+
wrong_assumptions: wrongAssumptions,
|
|
222
|
+
worker_results: workerResults,
|
|
223
|
+
compression_checkpoint: typeof raw.compression_checkpoint === "boolean" ? raw.compression_checkpoint : false,
|
|
224
|
+
checkpoint_label: typeof raw.checkpoint_label === "string" ? raw.checkpoint_label : "",
|
|
225
|
+
next_action: typeof raw.next_action === "string" ? raw.next_action : undefined,
|
|
226
|
+
completed_subtasks: Array.isArray(raw.completed_subtasks)
|
|
227
|
+
? raw.completed_subtasks.filter((v) => typeof v === "string")
|
|
228
|
+
: [],
|
|
229
|
+
blocked_subtasks: Array.isArray(raw.blocked_subtasks)
|
|
230
|
+
? raw.blocked_subtasks.filter((v) => typeof v === "string")
|
|
231
|
+
: [],
|
|
232
|
+
canceled_subtasks: Array.isArray(raw.canceled_subtasks)
|
|
233
|
+
? raw.canceled_subtasks.filter((v) => typeof v === "string")
|
|
234
|
+
: [],
|
|
235
|
+
stop_reason: raw.stop_reason === "gave_up" || raw.stop_reason === "blocked" || raw.stop_reason === "needs_human_input"
|
|
236
|
+
? raw.stop_reason
|
|
237
|
+
: undefined,
|
|
238
|
+
outcome: raw.outcome === "success" || raw.outcome === "partial" ||
|
|
239
|
+
raw.outcome === "failed" || raw.outcome === "blocked"
|
|
240
|
+
? raw.outcome
|
|
241
|
+
: undefined,
|
|
242
|
+
blocker: typeof raw.blocker === "string" && raw.blocker.trim().length > 0
|
|
243
|
+
? raw.blocker.slice(0, 500)
|
|
244
|
+
: undefined,
|
|
245
|
+
retroactiveClaims: parseRetroactiveClaims(raw.retroactiveClaims),
|
|
246
|
+
no_change_reason: typeof raw.no_change_reason === "string" && raw.no_change_reason.trim().length > 0
|
|
247
|
+
? raw.no_change_reason.slice(0, 200)
|
|
248
|
+
: undefined,
|
|
249
|
+
drift_clarification: typeof raw.drift_clarification === "string" ? raw.drift_clarification : undefined,
|
|
250
|
+
prompt_requests: parsePromptRequests(raw.prompt_requests),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/** Parse a PromptRequests object from raw JSON input.
|
|
254
|
+
* Lenient: missing or invalid fields get sensible defaults.
|
|
255
|
+
* Returns undefined if the raw value is absent or not an object,
|
|
256
|
+
* so makeSelfEvaluation can distinguish "not set" from "empty". */
|
|
257
|
+
function parsePromptRequests(raw) {
|
|
258
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
259
|
+
return undefined;
|
|
260
|
+
const obj = raw;
|
|
261
|
+
const emphasize = Array.isArray(obj.emphasize)
|
|
262
|
+
? obj.emphasize.filter((v) => typeof v === "string").slice(0, 10)
|
|
263
|
+
: [];
|
|
264
|
+
const validExpands = new Set([
|
|
265
|
+
"milestones", "sub_goals", "constraint_lifecycle",
|
|
266
|
+
"agent_trust", "progress", "loop_synthesis",
|
|
267
|
+
]);
|
|
268
|
+
const expand = Array.isArray(obj.expand)
|
|
269
|
+
? obj.expand.filter((v) => typeof v === "string" && validExpands.has(v))
|
|
270
|
+
: [];
|
|
271
|
+
const confusionPoints = Array.isArray(obj.confusion_points)
|
|
272
|
+
? obj.confusion_points.filter((v) => typeof v === "string").slice(0, 5)
|
|
273
|
+
: [];
|
|
274
|
+
// Return undefined when all fields are empty — semantically equivalent
|
|
275
|
+
// to "not set", avoids carrying an empty object through the pipeline.
|
|
276
|
+
if (emphasize.length === 0 && expand.length === 0 && confusionPoints.length === 0) {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
return { emphasize, expand, confusion_points: confusionPoints };
|
|
280
|
+
}
|
|
281
|
+
// v2.6: heuristicSelfEvaluation removed — if structured extraction fails,
|
|
282
|
+
// the round is stalled. The 20-line keyword heuristic was dead weight; an
|
|
283
|
+
// agent that can't produce a structured self-evaluation is genuinely stuck.
|
|
284
|
+
//# sourceMappingURL=self-eval.js.map
|