dsh-llm-verifier 0.1.20 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/lib/client.js +39 -17
- package/lib/client.js.map +1 -1
- package/lib/index.js +147 -37
- package/lib/index.js.map +1 -1
- package/lib/types/auto.d.ts +5 -0
- package/lib/types/auto.d.ts.map +1 -1
- package/lib/types/auto.js.map +1 -1
- package/lib/types/client-i18n.d.ts +17 -1
- package/lib/types/client-i18n.d.ts.map +1 -1
- package/lib/types/client-i18n.js +27 -15
- package/lib/types/client-i18n.js.map +1 -1
- package/lib/types/client.d.ts +3 -2
- package/lib/types/client.d.ts.map +1 -1
- package/lib/types/client.js +4 -4
- package/lib/types/client.js.map +1 -1
- package/lib/types/config.d.ts +9 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/config.js +4 -2
- package/lib/types/config.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +55 -5
- package/lib/types/index.js.map +1 -1
- package/lib/types/router.d.ts +10 -0
- package/lib/types/router.d.ts.map +1 -1
- package/lib/types/router.js +60 -22
- package/lib/types/router.js.map +1 -1
- package/package.json +1 -1
- package/src/auto.ts +5 -0
- package/src/client-i18n.ts +27 -15
- package/src/client.test.ts +17 -11
- package/src/client.tsx +5 -4
- package/src/config.test.ts +23 -0
- package/src/config.ts +13 -2
- package/src/index.ts +55 -6
- package/src/router.test.ts +79 -1
- package/src/router.ts +63 -22
package/lib/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const Config = z.object({
|
|
|
24
24
|
]).default("smart"),
|
|
25
25
|
autoVerifyThreshold: z.number().min(0).max(1).default(.65),
|
|
26
26
|
autoVerifyRepeats: z.number().step(1).min(1).default(1),
|
|
27
|
+
autoVerifyFinalRepeats: z.number().step(1).min(1).default(2),
|
|
27
28
|
autoVerifyMinToolCalls: z.number().step(1).min(1).default(3),
|
|
28
29
|
autoVerifyMaxChars: z.number().step(1).min(1e3).default(8e4),
|
|
29
30
|
autoVerifyMaxPerTask: z.number().step(1).min(1).default(2),
|
|
@@ -36,7 +37,7 @@ const Config = z.object({
|
|
|
36
37
|
autoTrackCompletionThreshold: z.number().min(0).max(1).default(.8),
|
|
37
38
|
autoRouteMaxItemChars: z.number().step(1).min(100).default(2e4),
|
|
38
39
|
autoRouteMaxInputChars: z.number().step(1).min(1e3).default(6e4),
|
|
39
|
-
autoMaxModelCallsPerTask: z.number().step(1).min(1).default(
|
|
40
|
+
autoMaxModelCallsPerTask: z.number().step(1).min(1).default(96),
|
|
40
41
|
autoMaxModelCallsPerSession: z.number().step(1).min(1).default(240),
|
|
41
42
|
autoVerifyTeamTasks: z.boolean().default(true),
|
|
42
43
|
autoVerifyPlanMode: z.boolean().default(true),
|
|
@@ -97,6 +98,7 @@ function resolveConfig(config = {}) {
|
|
|
97
98
|
if (!Number.isFinite(temperature) || temperature < 0 || temperature > 2) throw new Error("llm-verifier: temperature must be between 0 and 2");
|
|
98
99
|
const values = {
|
|
99
100
|
autoVerifyRepeats: config.autoVerifyRepeats ?? 1,
|
|
101
|
+
autoVerifyFinalRepeats: config.autoVerifyFinalRepeats ?? 2,
|
|
100
102
|
autoVerifyMinToolCalls: config.autoVerifyMinToolCalls ?? 3,
|
|
101
103
|
autoVerifyMaxChars: config.autoVerifyMaxChars ?? 8e4,
|
|
102
104
|
autoVerifyMaxPerTask: config.autoVerifyMaxPerTask ?? 2,
|
|
@@ -106,7 +108,7 @@ function resolveConfig(config = {}) {
|
|
|
106
108
|
autoRouteMaxPerSession: config.autoRouteMaxPerSession ?? 8,
|
|
107
109
|
autoRouteMaxItemChars: config.autoRouteMaxItemChars ?? 2e4,
|
|
108
110
|
autoRouteMaxInputChars: config.autoRouteMaxInputChars ?? 6e4,
|
|
109
|
-
autoMaxModelCallsPerTask: config.autoMaxModelCallsPerTask ??
|
|
111
|
+
autoMaxModelCallsPerTask: config.autoMaxModelCallsPerTask ?? 96,
|
|
110
112
|
autoMaxModelCallsPerSession: config.autoMaxModelCallsPerSession ?? 240,
|
|
111
113
|
maxTokens: config.maxTokens ?? 32768,
|
|
112
114
|
timeoutMs: config.timeoutMs ?? 3e5,
|
|
@@ -1169,14 +1171,16 @@ function buildEvidenceIndex(events) {
|
|
|
1169
1171
|
teamTasks
|
|
1170
1172
|
};
|
|
1171
1173
|
}
|
|
1172
|
-
function parseTrustedWorkflow(value, callId, callSeq, resultSeq, maxCandidates, maxItemChars) {
|
|
1174
|
+
function parseTrustedWorkflow(value, callId, callSeq, resultSeq, maxCandidates, maxItemChars, maxInputChars) {
|
|
1173
1175
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return [];
|
|
1174
1176
|
const envelope = value;
|
|
1175
1177
|
if (envelope.protocol !== "dsh-verifier-candidates" || envelope.version !== TRUSTED_WORKFLOW_VERSION || typeof envelope.groupId !== "string" || !envelope.groupId.trim() || !Array.isArray(envelope.candidates)) return [];
|
|
1176
1178
|
const groupId = envelope.groupId.trim();
|
|
1177
1179
|
const seen = /* @__PURE__ */ new Set();
|
|
1178
1180
|
const candidates = [];
|
|
1179
|
-
|
|
1181
|
+
const considered = envelope.candidates.slice(0, maxCandidates);
|
|
1182
|
+
const perItem = itemBudget(considered.length, maxItemChars, maxInputChars);
|
|
1183
|
+
for (const item of considered) {
|
|
1180
1184
|
if (typeof item !== "object" || item === null || Array.isArray(item)) return [];
|
|
1181
1185
|
const row = item;
|
|
1182
1186
|
if (row.status !== "completed" || typeof row.id !== "string" || !row.id.trim() || seen.has(row.id.trim()) || typeof row.content !== "string" || !row.content.trim()) return [];
|
|
@@ -1186,8 +1190,8 @@ function parseTrustedWorkflow(value, callId, callSeq, resultSeq, maxCandidates,
|
|
|
1186
1190
|
candidates.push({
|
|
1187
1191
|
id,
|
|
1188
1192
|
groupId,
|
|
1189
|
-
label: sanitizeVerifierText(label, 120),
|
|
1190
|
-
content: sanitizeVerifierText(row.content,
|
|
1193
|
+
label: sanitizeVerifierText(label, Math.min(120, perItem)),
|
|
1194
|
+
content: sanitizeVerifierText(row.content, perItem),
|
|
1191
1195
|
callId,
|
|
1192
1196
|
fromSeq: callSeq,
|
|
1193
1197
|
toSeq: resultSeq
|
|
@@ -1242,17 +1246,61 @@ function checkpointEvidence(index, seq, budget) {
|
|
|
1242
1246
|
return prefix + sanitizeVerifierText(latest.text, budget - prefix.length);
|
|
1243
1247
|
}
|
|
1244
1248
|
/**
|
|
1245
|
-
*
|
|
1249
|
+
* Per-item character budget for a decision with a known item count.
|
|
1250
|
+
*
|
|
1251
|
+
* boundDecision() enforces the COMBINED cap, so spending maxItemChars per item
|
|
1252
|
+
* drops the whole decision as soon as the items are numerous or large. Splitting
|
|
1253
|
+
* the combined budget keeps both caps satisfied by construction; a single item
|
|
1254
|
+
* still gets the full maxItemChars.
|
|
1255
|
+
* @param count - number of items that will be rendered.
|
|
1256
|
+
* @param maxItemChars - hard per-item cap enforced by boundDecision().
|
|
1257
|
+
* @param maxInputChars - hard combined cap enforced by boundDecision().
|
|
1258
|
+
* @returns The per-item character budget, never below 1.
|
|
1259
|
+
*/
|
|
1260
|
+
function itemBudget(count, maxItemChars, maxInputChars) {
|
|
1261
|
+
return Math.max(1, Math.min(maxItemChars, Math.floor(maxInputChars / Math.max(1, count))));
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Upper bound on the checkpoints rendered into one routed track decision.
|
|
1265
|
+
*
|
|
1266
|
+
* boundDecision() rejects the WHOLE decision once the rendered steps exceed
|
|
1267
|
+
* maxInputChars, while the number of durable snapshots is unbounded (every changed
|
|
1268
|
+
* todo/team snapshot becomes a checkpoint). A long task therefore used to lose
|
|
1269
|
+
* progress routing exactly when it needed it, so only the most recent checkpoints
|
|
1270
|
+
* are kept and the combined input budget is split across them.
|
|
1271
|
+
*/
|
|
1272
|
+
const MAX_ROUTED_CHECKPOINTS = 6;
|
|
1273
|
+
/**
|
|
1274
|
+
* Render progress checkpoints as "state + the output that proves it".
|
|
1275
|
+
*
|
|
1276
|
+
* The result fits both caps by construction: each step is at most min(maxItemChars,
|
|
1277
|
+
* maxInputChars / kept.length) characters, so the combined length can never exceed
|
|
1278
|
+
* maxInputChars and boundDecision() no longer drops the whole route.
|
|
1246
1279
|
* @param index - evidence index of the current task.
|
|
1247
|
-
* @param
|
|
1248
|
-
* @param body - todo/team task rendering.
|
|
1249
|
-
* @param seq - checkpoint sequence number.
|
|
1280
|
+
* @param sources - checkpoints in chronological order.
|
|
1250
1281
|
* @param maxItemChars - hard per-item cap enforced by boundDecision().
|
|
1251
|
-
* @
|
|
1282
|
+
* @param maxInputChars - hard combined cap enforced by boundDecision().
|
|
1283
|
+
* @returns The rendered steps plus the sequence numbers they were built from.
|
|
1252
1284
|
*/
|
|
1253
|
-
function
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1285
|
+
function renderCheckpointSteps(index, sources, maxItemChars, maxInputChars) {
|
|
1286
|
+
const kept = sources.slice(-6);
|
|
1287
|
+
const omitted = sources.length - kept.length;
|
|
1288
|
+
if (kept.length === 0) return {
|
|
1289
|
+
steps: [],
|
|
1290
|
+
evidenceSeqs: [],
|
|
1291
|
+
omitted: 0
|
|
1292
|
+
};
|
|
1293
|
+
const stepCap = itemBudget(kept.length, maxItemChars, maxInputChars);
|
|
1294
|
+
const evidenceBudget = Math.max(0, Math.min(Math.floor(maxInputChars / 2), Math.floor(maxItemChars / 2), Math.floor(stepCap / 2)));
|
|
1295
|
+
return {
|
|
1296
|
+
steps: kept.map((source, position) => {
|
|
1297
|
+
const note = position === 0 && omitted > 0 ? "Earlier " + omitted + " checkpoint(s) omitted; showing the " + kept.length + " most recent.\n" : "";
|
|
1298
|
+
const evidence = checkpointEvidence(index, source.seq, evidenceBudget);
|
|
1299
|
+
return sanitizeVerifierText(note + source.label + source.body, Math.max(1, stepCap - evidence.length)) + evidence;
|
|
1300
|
+
}),
|
|
1301
|
+
evidenceSeqs: kept.map((source) => source.seq),
|
|
1302
|
+
omitted
|
|
1303
|
+
};
|
|
1256
1304
|
}
|
|
1257
1305
|
function canonicalTeamTaskSnapshots(index) {
|
|
1258
1306
|
const values = [];
|
|
@@ -1278,7 +1326,7 @@ function analyzeStructuredRoute(events, maxCandidates = 8, maxItemChars = 2e4, m
|
|
|
1278
1326
|
const groups = [];
|
|
1279
1327
|
for (const [callId, pair] of index.calls) {
|
|
1280
1328
|
if (pair.name !== "workflow") continue;
|
|
1281
|
-
const candidates = parseTrustedWorkflow(strictJson(pair.text), callId, pair.callSeq, pair.resultSeq, maxCandidates, maxItemChars);
|
|
1329
|
+
const candidates = parseTrustedWorkflow(strictJson(pair.text), callId, pair.callSeq, pair.resultSeq, maxCandidates, maxItemChars, maxInputChars);
|
|
1282
1330
|
if (candidates.length >= 2) groups.push(candidates);
|
|
1283
1331
|
}
|
|
1284
1332
|
groups.sort((a, b) => b.length - a.length || b[0].toSeq - a[0].toSeq);
|
|
@@ -1308,8 +1356,11 @@ function analyzeStructuredRoute(events, maxCandidates = 8, maxItemChars = 2e4, m
|
|
|
1308
1356
|
if (!explicit.has("track")) {
|
|
1309
1357
|
const snapshots = canonicalTodoSnapshots(index);
|
|
1310
1358
|
if (snapshots.length >= 2 && snapshots.some((snapshot) => snapshot.todos.length >= 2)) {
|
|
1311
|
-
const
|
|
1312
|
-
|
|
1359
|
+
const rendered = renderCheckpointSteps(index, snapshots.map((snapshot) => ({
|
|
1360
|
+
seq: snapshot.seq,
|
|
1361
|
+
label: "Todo checkpoint seq " + snapshot.seq + ":\n",
|
|
1362
|
+
body: snapshot.todos.map((todo) => "- [" + todo.status + "] " + todo.content).join("\n")
|
|
1363
|
+
})), maxItemChars, maxInputChars);
|
|
1313
1364
|
return {
|
|
1314
1365
|
kind: "track",
|
|
1315
1366
|
source: "structured",
|
|
@@ -1319,15 +1370,18 @@ function analyzeStructuredRoute(events, maxCandidates = 8, maxItemChars = 2e4, m
|
|
|
1319
1370
|
kind: "track",
|
|
1320
1371
|
snapshots
|
|
1321
1372
|
}),
|
|
1322
|
-
steps,
|
|
1323
|
-
checkpoints,
|
|
1324
|
-
evidenceSeqs:
|
|
1373
|
+
steps: rendered.steps,
|
|
1374
|
+
checkpoints: rendered.steps.map((_, i) => i + 1),
|
|
1375
|
+
evidenceSeqs: rendered.evidenceSeqs
|
|
1325
1376
|
};
|
|
1326
1377
|
}
|
|
1327
1378
|
const teamSnapshots = canonicalTeamTaskSnapshots(index);
|
|
1328
1379
|
if (teamSnapshots.length >= 2) {
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1380
|
+
const rendered = renderCheckpointSteps(index, teamSnapshots.map((snapshot) => ({
|
|
1381
|
+
seq: snapshot.seq,
|
|
1382
|
+
label: "Team task checkpoint seq " + snapshot.seq + ":\n",
|
|
1383
|
+
body: snapshot.tasks.map((task) => "- [" + task.status + "] " + task.subject + (task.description ? " (" + task.description + ")" : "")).join("\n")
|
|
1384
|
+
})), maxItemChars, maxInputChars);
|
|
1331
1385
|
return {
|
|
1332
1386
|
kind: "track",
|
|
1333
1387
|
source: "structured",
|
|
@@ -1337,9 +1391,9 @@ function analyzeStructuredRoute(events, maxCandidates = 8, maxItemChars = 2e4, m
|
|
|
1337
1391
|
kind: "track",
|
|
1338
1392
|
teamSnapshots
|
|
1339
1393
|
}),
|
|
1340
|
-
steps,
|
|
1341
|
-
checkpoints,
|
|
1342
|
-
evidenceSeqs:
|
|
1394
|
+
steps: rendered.steps,
|
|
1395
|
+
checkpoints: rendered.steps.map((_, i) => i + 1),
|
|
1396
|
+
evidenceSeqs: rendered.evidenceSeqs
|
|
1343
1397
|
};
|
|
1344
1398
|
}
|
|
1345
1399
|
}
|
|
@@ -1436,7 +1490,11 @@ function semanticDecision(output, events, maxItemChars = 2e4, maxInputChars = 6e
|
|
|
1436
1490
|
todos: index.todos.get(seq)
|
|
1437
1491
|
})).filter((item) => item.todos !== void 0);
|
|
1438
1492
|
if (snapshots.length !== output.checkpointSeqs.length) return void 0;
|
|
1439
|
-
const
|
|
1493
|
+
const rendered = renderCheckpointSteps(index, snapshots.map((snapshot) => ({
|
|
1494
|
+
seq: snapshot.seq,
|
|
1495
|
+
label: "Todo checkpoint seq " + snapshot.seq + ":\n",
|
|
1496
|
+
body: snapshot.todos.map((todo) => "- [" + todo.status + "] " + todo.content).join("\n")
|
|
1497
|
+
})), maxItemChars, maxInputChars);
|
|
1440
1498
|
return {
|
|
1441
1499
|
kind: "track",
|
|
1442
1500
|
source: "semantic",
|
|
@@ -1445,20 +1503,21 @@ function semanticDecision(output, events, maxItemChars = 2e4, maxInputChars = 6e
|
|
|
1445
1503
|
fingerprint: stableHash({
|
|
1446
1504
|
kind: "track",
|
|
1447
1505
|
seqs: output.checkpointSeqs,
|
|
1448
|
-
steps
|
|
1506
|
+
steps: rendered.steps
|
|
1449
1507
|
}),
|
|
1450
|
-
steps,
|
|
1451
|
-
checkpoints: steps.map((_, i) => i + 1),
|
|
1452
|
-
evidenceSeqs:
|
|
1508
|
+
steps: rendered.steps,
|
|
1509
|
+
checkpoints: rendered.steps.map((_, i) => i + 1),
|
|
1510
|
+
evidenceSeqs: rendered.evidenceSeqs
|
|
1453
1511
|
};
|
|
1454
1512
|
}
|
|
1513
|
+
const perItem = itemBudget(output.candidateCallIds.length, maxItemChars, maxInputChars);
|
|
1455
1514
|
const candidates = output.candidateCallIds.map((callId, i) => {
|
|
1456
1515
|
const pair = index.calls.get(callId);
|
|
1457
1516
|
return pair ? {
|
|
1458
1517
|
id: callId,
|
|
1459
1518
|
groupId: "semantic",
|
|
1460
1519
|
label: pair.name + " " + (i + 1),
|
|
1461
|
-
content: sanitizeVerifierText(pair.text,
|
|
1520
|
+
content: sanitizeVerifierText(pair.text, perItem),
|
|
1462
1521
|
callId,
|
|
1463
1522
|
fromSeq: pair.callSeq,
|
|
1464
1523
|
toSeq: pair.resultSeq
|
|
@@ -2873,6 +2932,40 @@ function apply(ctx, config = {}) {
|
|
|
2873
2932
|
throw error;
|
|
2874
2933
|
}
|
|
2875
2934
|
};
|
|
2935
|
+
/** The registered tool each routable decision kind maps to. */
|
|
2936
|
+
const ROUTED_TOOL_BY_KIND = {
|
|
2937
|
+
compare: "verifier_compare",
|
|
2938
|
+
select: "verifier_select",
|
|
2939
|
+
track: "verifier_track"
|
|
2940
|
+
};
|
|
2941
|
+
/**
|
|
2942
|
+
* Record a routed decision the plugin built but could not execute.
|
|
2943
|
+
*
|
|
2944
|
+
* A decision rejected by the evidence caps (or one whose semantic references
|
|
2945
|
+
* disappeared) used to vanish without a trace: the dashboard showed a task that
|
|
2946
|
+
* was never verified and gave no reason why. Nothing failed here — no model call
|
|
2947
|
+
* was made — so the row is a successful invocation carrying an explanatory verdict.
|
|
2948
|
+
* @param agent - Agent whose task produced the decision.
|
|
2949
|
+
* @param kind - The routed decision kind that was dropped.
|
|
2950
|
+
* @param phase - Routing phase that produced it (structured | semantic).
|
|
2951
|
+
* @param outcome - Why it was dropped.
|
|
2952
|
+
*/
|
|
2953
|
+
const recordSkippedRoute = async (agent, kind, phase, outcome) => {
|
|
2954
|
+
const selected = current();
|
|
2955
|
+
await topic(agent.session.header).statistics.record({
|
|
2956
|
+
toolName: ROUTED_TOOL_BY_KIND[kind],
|
|
2957
|
+
sessionId: String(agent.id),
|
|
2958
|
+
startedAt: Date.now(),
|
|
2959
|
+
success: true,
|
|
2960
|
+
provider: selected.provider,
|
|
2961
|
+
model: selected.model,
|
|
2962
|
+
stats: emptyRunStats(),
|
|
2963
|
+
verdict: {
|
|
2964
|
+
phase,
|
|
2965
|
+
outcome
|
|
2966
|
+
}
|
|
2967
|
+
}).catch(() => {});
|
|
2968
|
+
};
|
|
2876
2969
|
const verifySession = async (agent, options, signal, phase = "explicit") => record("verifier_current_session", agent, async () => {
|
|
2877
2970
|
const extracted = await extractSession(agent, async (ref) => {
|
|
2878
2971
|
const stored = await services.attachments.readImage(ref, signal);
|
|
@@ -3184,7 +3277,12 @@ function apply(ctx, config = {}) {
|
|
|
3184
3277
|
}
|
|
3185
3278
|
}
|
|
3186
3279
|
}
|
|
3187
|
-
|
|
3280
|
+
const structured = analyzeStructuredRoute(snapshot, selected.autoRouteMaxCandidates, selected.autoRouteMaxItemChars, selected.autoRouteMaxInputChars);
|
|
3281
|
+
let decision = boundDecision(structured, policy);
|
|
3282
|
+
if (structured !== void 0 && decision === void 0) {
|
|
3283
|
+
ctx.logger.warn("llm-verifier automatic " + structured.kind + " route dropped: its evidence exceeds the per-item/total routing caps (" + selected.autoRouteMaxItemChars + "/" + selected.autoRouteMaxInputChars + " characters)");
|
|
3284
|
+
await recordSkippedRoute(agent, structured.kind, "structured", "dropped-over-budget");
|
|
3285
|
+
}
|
|
3188
3286
|
if (decision === void 0 && selected.autoRouteSemantic && (selected.autoVerifyMode === "strict" || semanticRouteHint(snapshot))) {
|
|
3189
3287
|
const fingerprint = stableHash({
|
|
3190
3288
|
phase: "semantic",
|
|
@@ -3202,7 +3300,17 @@ function apply(ctx, config = {}) {
|
|
|
3202
3300
|
}
|
|
3203
3301
|
const parsed = parseSemanticRoute(classified.text, selected.autoRouteMaxCandidates);
|
|
3204
3302
|
if (!parsed) throw new Error("semantic router returned invalid strict JSON");
|
|
3205
|
-
|
|
3303
|
+
if (parsed.confidence >= selected.autoRouteMinConfidence) {
|
|
3304
|
+
const resolved = semanticDecision(parsed, snapshot, selected.autoRouteMaxItemChars, selected.autoRouteMaxInputChars);
|
|
3305
|
+
decision = boundDecision(resolved, policy);
|
|
3306
|
+
if (resolved !== void 0 && decision === void 0) {
|
|
3307
|
+
ctx.logger.warn("llm-verifier semantic " + resolved.kind + " route dropped: its evidence exceeds the per-item/total routing caps (" + selected.autoRouteMaxItemChars + "/" + selected.autoRouteMaxInputChars + " characters)");
|
|
3308
|
+
await recordSkippedRoute(agent, resolved.kind, "semantic", "dropped-over-budget");
|
|
3309
|
+
} else if (resolved === void 0 && parsed.kind !== "none") {
|
|
3310
|
+
ctx.logger.warn("llm-verifier semantic router returned " + parsed.kind + " but referenced evidence missing from the session snapshot");
|
|
3311
|
+
await recordSkippedRoute(agent, parsed.kind, "semantic", "invalid-references");
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3206
3314
|
autoRouter.commit(agent, reservation);
|
|
3207
3315
|
} catch (error) {
|
|
3208
3316
|
autoRouter.fail(agent, reservation, selected.autoVerifyMode === "strict");
|
|
@@ -3226,7 +3334,9 @@ function apply(ctx, config = {}) {
|
|
|
3226
3334
|
const reservation = autoRouter.reserve(agent, decision.kind, decision.fingerprint, expectedCalls, policy);
|
|
3227
3335
|
if (reservation === void 0) {
|
|
3228
3336
|
const exhausted = autoRouter.budgetExhausted(agent, expectedCalls, policy);
|
|
3229
|
-
|
|
3337
|
+
const alreadyRan = autoRouter.completedFingerprint(agent, decision.fingerprint);
|
|
3338
|
+
const refusal = exhausted ? "the task/session budget cannot cover " + expectedCalls + " model calls" : alreadyRan ? "this exact evidence was already routed" : "another verifier is active";
|
|
3339
|
+
ctx.logger.warn("llm-verifier automatic " + decision.kind + " route skipped: " + refusal);
|
|
3230
3340
|
if (exhausted && selected.autoVerifyMode === "strict" && autoRouter.claimExhaustedNotice(agent)) {
|
|
3231
3341
|
agent.steer(createUserMessage({
|
|
3232
3342
|
content: [{
|
|
@@ -3312,7 +3422,7 @@ function apply(ctx, config = {}) {
|
|
|
3312
3422
|
from: finalFromSeq,
|
|
3313
3423
|
to: admittedLastSeq
|
|
3314
3424
|
});
|
|
3315
|
-
const finalReservation = autoRouter.reserve(agent, "final", finalFingerprint, Math.max(1,
|
|
3425
|
+
const finalReservation = autoRouter.reserve(agent, "final", finalFingerprint, Math.max(1, DEFAULT_CRITERIA.length * selected.autoVerifyFinalRepeats) * selected.judges.length, policy);
|
|
3316
3426
|
if (!finalReservation) {
|
|
3317
3427
|
if (selected.autoVerifyMode === "strict" && (forcedFromSeq !== void 0 || autoRouter.strictBlocked(agent))) if (autoRouter.claimExhaustedNotice(agent)) agent.steer(createUserMessage({
|
|
3318
3428
|
content: [{
|
|
@@ -3333,7 +3443,7 @@ function apply(ctx, config = {}) {
|
|
|
3333
3443
|
toSeq: admittedLastSeq,
|
|
3334
3444
|
includeAssistantText: true,
|
|
3335
3445
|
maxChars: selected.autoVerifyMaxChars,
|
|
3336
|
-
repeats: selected.
|
|
3446
|
+
repeats: selected.autoVerifyFinalRepeats
|
|
3337
3447
|
}, signal, "final");
|
|
3338
3448
|
if (!stillCurrent()) {
|
|
3339
3449
|
autoRouter.fail(agent, finalReservation, false);
|
|
@@ -3733,6 +3843,6 @@ function apply(ctx, config = {}) {
|
|
|
3733
3843
|
}));
|
|
3734
3844
|
}
|
|
3735
3845
|
//#endregion
|
|
3736
|
-
export { AutoVerificationBudget, AutoVerifierRouter, Config, DEFAULT_CRITERIA, DEFAULT_GROUND_TRUTH_NOTE, GRANULARITY, LETTERS, MAX_TEAM_TASK_METADATA_CHARS, RequestLimiter, SCALE_DESCRIPTION, ScoreCache, SingleFlight, StatisticsStore, UNTRUSTED_EVIDENCE_NOTE, VERIFIER_TOOL_NAMES, VerifierEngine, accumulatePairs, analyzeAutoTask, analyzeStructuredRoute, apply, automaticFeedback, boundDecision, bradleyTerry, buildEvidenceIndex, buildPairwisePrompt, buildPlanPreReviewPrompt, buildProgressPrompt, buildSemanticRoutePrompt, buildTeamTaskVerificationPrompt, callVerifier, emptyRunStats, errorDetails, estimateRoutedCalls, evidenceNonce, extractProgressScore, extractScore, inject, inspectTeamTasks, isSubagentSession, latestDirectUserSeq, mergeStatisticsOverviews, name, normalizeCriteria, normalizeScoreLetter, parseSemanticRoute, parseStatisticsQuery, parseVerdictLetter, pivotRoundPairs, planFromArguments, rankScores, renderDelimitedBlock, resolveCacheFile, resolveStatisticsFile, resolveTopicDataDir, ringCycle, seededRandom, semanticDecision, semanticRouteHint, stableHash, topPivots };
|
|
3846
|
+
export { AutoVerificationBudget, AutoVerifierRouter, Config, DEFAULT_CRITERIA, DEFAULT_GROUND_TRUTH_NOTE, GRANULARITY, LETTERS, MAX_ROUTED_CHECKPOINTS, MAX_TEAM_TASK_METADATA_CHARS, RequestLimiter, SCALE_DESCRIPTION, ScoreCache, SingleFlight, StatisticsStore, UNTRUSTED_EVIDENCE_NOTE, VERIFIER_TOOL_NAMES, VerifierEngine, accumulatePairs, analyzeAutoTask, analyzeStructuredRoute, apply, automaticFeedback, boundDecision, bradleyTerry, buildEvidenceIndex, buildPairwisePrompt, buildPlanPreReviewPrompt, buildProgressPrompt, buildSemanticRoutePrompt, buildTeamTaskVerificationPrompt, callVerifier, emptyRunStats, errorDetails, estimateRoutedCalls, evidenceNonce, extractProgressScore, extractScore, inject, inspectTeamTasks, isSubagentSession, latestDirectUserSeq, mergeStatisticsOverviews, name, normalizeCriteria, normalizeScoreLetter, parseSemanticRoute, parseStatisticsQuery, parseVerdictLetter, pivotRoundPairs, planFromArguments, rankScores, renderDelimitedBlock, resolveCacheFile, resolveStatisticsFile, resolveTopicDataDir, ringCycle, seededRandom, semanticDecision, semanticRouteHint, stableHash, topPivots };
|
|
3737
3847
|
|
|
3738
3848
|
//# sourceMappingURL=index.js.map
|