dsh-llm-verifier 0.4.0 → 0.6.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 +133 -25
- package/lib/{auto-B5V49e-A.js → auto-DAMeKRkK.js} +775 -170
- package/lib/auto-DAMeKRkK.js.map +1 -0
- package/lib/{caller-DR_C7ueP.js → caller-BUK7OgUs.js} +168 -14
- package/lib/caller-BUK7OgUs.js.map +1 -0
- package/lib/caller.js +2 -2
- package/lib/client.js +1847 -846
- package/lib/client.js.map +1 -1
- package/lib/core.js +267 -11
- package/lib/core.js.map +1 -1
- package/lib/index.js +2985 -364
- package/lib/index.js.map +1 -1
- package/lib/replay.js +290 -3
- package/lib/replay.js.map +1 -1
- package/lib/types/auto.d.ts +69 -2
- package/lib/types/auto.d.ts.map +1 -1
- package/lib/types/auto.js +216 -23
- package/lib/types/auto.js.map +1 -1
- package/lib/types/cache.d.ts +9 -0
- package/lib/types/cache.d.ts.map +1 -1
- package/lib/types/cache.js +1 -1
- package/lib/types/cache.js.map +1 -1
- package/lib/types/caller.d.ts +23 -0
- package/lib/types/caller.d.ts.map +1 -1
- package/lib/types/caller.js +180 -14
- package/lib/types/caller.js.map +1 -1
- package/lib/types/client-fields.d.ts +174 -0
- package/lib/types/client-fields.d.ts.map +1 -0
- package/lib/types/client-fields.js +456 -0
- package/lib/types/client-fields.js.map +1 -0
- package/lib/types/client-i18n.d.ts +255 -1
- package/lib/types/client-i18n.d.ts.map +1 -1
- package/lib/types/client-i18n.js +180 -4
- package/lib/types/client-i18n.js.map +1 -1
- package/lib/types/client.d.ts +57 -44
- package/lib/types/client.d.ts.map +1 -1
- package/lib/types/client.js +286 -43
- package/lib/types/client.js.map +1 -1
- package/lib/types/config.d.ts +36 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/config.js +21 -0
- package/lib/types/config.js.map +1 -1
- package/lib/types/core.d.ts +155 -4
- package/lib/types/core.d.ts.map +1 -1
- package/lib/types/core.js +271 -10
- package/lib/types/core.js.map +1 -1
- package/lib/types/engine.d.ts +76 -2
- package/lib/types/engine.d.ts.map +1 -1
- package/lib/types/engine.js +364 -94
- package/lib/types/engine.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +906 -126
- package/lib/types/index.js.map +1 -1
- package/lib/types/process-activity.d.ts +109 -0
- package/lib/types/process-activity.d.ts.map +1 -0
- package/lib/types/process-activity.js +135 -0
- package/lib/types/process-activity.js.map +1 -0
- package/lib/types/process-selection.d.ts +572 -0
- package/lib/types/process-selection.d.ts.map +1 -0
- package/lib/types/process-selection.js +1183 -0
- package/lib/types/process-selection.js.map +1 -0
- package/lib/types/replay.d.ts +188 -0
- package/lib/types/replay.d.ts.map +1 -1
- package/lib/types/replay.js +231 -1
- package/lib/types/replay.js.map +1 -1
- package/lib/types/router.d.ts +321 -5
- package/lib/types/router.d.ts.map +1 -1
- package/lib/types/router.js +600 -100
- package/lib/types/router.js.map +1 -1
- package/lib/types/session.d.ts.map +1 -1
- package/lib/types/session.js +5 -1
- package/lib/types/session.js.map +1 -1
- package/lib/types/statistics.d.ts +92 -0
- package/lib/types/statistics.d.ts.map +1 -1
- package/lib/types/statistics.js +116 -2
- package/lib/types/statistics.js.map +1 -1
- package/package.json +2 -2
- package/scripts/eval-replay.mjs +55 -5
- package/scripts/sync-installed-profiles.mjs +113 -0
- package/src/auto.test.ts +195 -4
- package/src/auto.ts +249 -28
- package/src/cache.ts +10 -1
- package/src/caller.test.ts +202 -3
- package/src/caller.ts +195 -13
- package/src/client-fields.test.ts +309 -0
- package/src/client-fields.ts +619 -0
- package/src/client-i18n.ts +212 -3
- package/src/client.test.ts +45 -2
- package/src/client.tsx +470 -162
- package/src/config.test.ts +37 -0
- package/src/config.ts +57 -0
- package/src/core.test.ts +210 -0
- package/src/core.ts +327 -10
- package/src/engine.test.ts +322 -2
- package/src/engine.ts +426 -105
- package/src/index.test.ts +1210 -3
- package/src/index.ts +880 -110
- package/src/parity.test.ts +50 -1
- package/src/process-activity.test.ts +91 -0
- package/src/process-activity.ts +177 -0
- package/src/process-selection.test.ts +911 -0
- package/src/process-selection.ts +1429 -0
- package/src/replay.test.ts +168 -1
- package/src/replay.ts +333 -1
- package/src/router.test.ts +725 -1
- package/src/router.ts +772 -89
- package/src/session.test.ts +34 -0
- package/src/session.ts +5 -1
- package/src/statistics.test.ts +157 -0
- package/src/statistics.ts +178 -2
- package/lib/auto-B5V49e-A.js.map +0 -1
- package/lib/caller-DR_C7ueP.js.map +0 -1
|
@@ -263,17 +263,98 @@ var TopLogprobCapabilityCache = class {
|
|
|
263
263
|
};
|
|
264
264
|
//#endregion
|
|
265
265
|
//#region src/caller.ts
|
|
266
|
+
/**
|
|
267
|
+
* Deep-freeze a call-options graph, leaving any live AbortSignal mutable.
|
|
268
|
+
*
|
|
269
|
+
* The host re-exports its own `deepFreeze` from `@deepseek-ai/dsh-llm` on the 0.1.1 line; the
|
|
270
|
+
* 0.1.5 line moved the helper to `@deepseek-ai/dsh-util-values` and no longer re-exports it, so
|
|
271
|
+
* the fallback below is what actually runs there. Both implementations must carry the same rule
|
|
272
|
+
* ("leaving live AbortSignal objects mutable" — the host's own wording), because freezing a
|
|
273
|
+
* signal breaks the transport twice over: Node >= 26.5 initializes the signal's internal event
|
|
274
|
+
* map lazily, so the first `addEventListener` throws "Cannot assign to read only property
|
|
275
|
+
* 'Symbol(kEvents)'", and on every Node version the attempt timeout's `controller.abort()` throws
|
|
276
|
+
* the same way on 'Symbol(kAborted)'. The signal belongs to this call's retry loop and is still
|
|
277
|
+
* unsubscribed when the options are frozen, which is what makes the ordering fatal.
|
|
278
|
+
*/
|
|
266
279
|
function deepFreeze(value) {
|
|
267
280
|
const mod = LlmModule;
|
|
268
281
|
if (typeof mod.deepFreeze === "function") return mod.deepFreeze(value);
|
|
282
|
+
return fallbackDeepFreeze(value);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* The graph walk used when the host exports no `deepFreeze`; exported for tests.
|
|
286
|
+
* @param value - value to freeze.
|
|
287
|
+
* @returns The same value, with every reachable enumerable child frozen except live AbortSignals.
|
|
288
|
+
*/
|
|
289
|
+
function fallbackDeepFreeze(value) {
|
|
290
|
+
if (value instanceof AbortSignal) return value;
|
|
269
291
|
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
270
292
|
Object.freeze(value);
|
|
271
|
-
for (const key of Object.keys(value))
|
|
293
|
+
for (const key of Object.keys(value)) fallbackDeepFreeze(value[key]);
|
|
272
294
|
}
|
|
273
295
|
return value;
|
|
274
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Where a finally-failed request records how many attempts it already spent.
|
|
299
|
+
*
|
|
300
|
+
* A failure that never returned usage leaves the tokens UNKNOWN, not zero. The attempt
|
|
301
|
+
* count is the one fact the transport does know, so it is carried on the error itself
|
|
302
|
+
* (the engine catches per-judge errors) instead of being discarded.
|
|
303
|
+
*/
|
|
304
|
+
const REQUEST_ATTEMPTS = Symbol("llm-verifier.requestAttempts");
|
|
305
|
+
/** Attempts one failed verifier request already spent; 0 when the error carries none. */
|
|
306
|
+
function requestAttempts(error) {
|
|
307
|
+
if (typeof error !== "object" || error === null) return 0;
|
|
308
|
+
const value = error[REQUEST_ATTEMPTS];
|
|
309
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : 0;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Usage the transport DID return for a response that then turned out unusable.
|
|
313
|
+
*
|
|
314
|
+
* A parse failure or a truncated judge answer happened after the request was billed, so the
|
|
315
|
+
* engine must not fold it into a zero-cost failure. The usage rides on the error next to the
|
|
316
|
+
* attempt count; one error can carry both (a retried call whose final answer also failed).
|
|
317
|
+
*/
|
|
318
|
+
const PARTIAL_USAGE = Symbol("llm-verifier.partialUsage");
|
|
319
|
+
/** Usage a completed-but-unusable response already cost; undefined when the error carries none. */
|
|
320
|
+
function partialUsage(error) {
|
|
321
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
322
|
+
const value = error[PARTIAL_USAGE];
|
|
323
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
324
|
+
}
|
|
325
|
+
/** Attach the usage a completed-but-unusable response already cost to its error. */
|
|
326
|
+
function attachUsage(error, usage) {
|
|
327
|
+
if (typeof error === "object" && error !== null) error[PARTIAL_USAGE] = usage;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* An error for a response that came back and was billed but produced no usable verdict.
|
|
331
|
+
*
|
|
332
|
+
* The usage is attached so the failure row reports known requests and tokens instead of zero.
|
|
333
|
+
*/
|
|
334
|
+
function unusable(reason, attempt, raw) {
|
|
335
|
+
const error = /* @__PURE__ */ new Error("llm-verifier: " + reason);
|
|
336
|
+
attachUsage(error, usage(attempt, raw ?? {}));
|
|
337
|
+
return error;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Describe why a finished stream is unusable.
|
|
341
|
+
*
|
|
342
|
+
* `FinishReason.failure` is the host's SERIALIZABLE facts record (`{message, code, status?,
|
|
343
|
+
* providerRetryAfterMs?, requestId?}`), not the error the adapter threw: `normalizeLlmFailure`
|
|
344
|
+
* detaches the facts at the adapter boundary, so the stack and the cause are already gone before
|
|
345
|
+
* this plugin sees them. The machine code and the provider status ARE carried, and dropping them
|
|
346
|
+
* left the board with one line and no way to tell an auth failure from a transport one.
|
|
347
|
+
*/
|
|
275
348
|
function failureMessage(finish) {
|
|
276
|
-
if (finish.kind === "error" || finish.kind === "aborted")
|
|
349
|
+
if (finish.kind === "error" || finish.kind === "aborted") {
|
|
350
|
+
const failure = finish.failure;
|
|
351
|
+
const facts = [
|
|
352
|
+
failure.code,
|
|
353
|
+
failure.status === void 0 ? void 0 : "HTTP " + failure.status,
|
|
354
|
+
failure.requestId === void 0 ? void 0 : "request " + failure.requestId
|
|
355
|
+
].filter((fact) => typeof fact === "string" && fact.length > 0);
|
|
356
|
+
return facts.length > 0 ? failure.message + " [" + facts.join(", ") + "]" : failure.message;
|
|
357
|
+
}
|
|
277
358
|
if (finish.kind === "max-tokens") return "verifier response reached max tokens before completing its answer";
|
|
278
359
|
}
|
|
279
360
|
async function delay(ms, signal) {
|
|
@@ -311,10 +392,56 @@ const RETRYABLE_MESSAGE = /rate|quota|timeout|timed out|temporar|network|fetch|s
|
|
|
311
392
|
* @param run - one attempt; receives its own deadline signal and 1-based attempt number.
|
|
312
393
|
* @returns The first successful completion.
|
|
313
394
|
*/
|
|
395
|
+
function attachAttempts(error, attempt) {
|
|
396
|
+
if (typeof error === "object" && error !== null) error[REQUEST_ATTEMPTS] = attempt;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* A fresh error for one aborted call.
|
|
400
|
+
*
|
|
401
|
+
* Never annotate and rethrow the shared `signal.reason`: several concurrent requests share it,
|
|
402
|
+
* and the engine attaches its accumulator to the thrown error, so one object carries several
|
|
403
|
+
* accumulators and they get merged repeatedly. The wrapper preserves the message and name.
|
|
404
|
+
*/
|
|
405
|
+
function abortFailure(reason, attempt) {
|
|
406
|
+
const source = reason instanceof Error ? reason : new Error(reason === void 0 ? "llm-verifier: request aborted" : String(reason));
|
|
407
|
+
const error = new Error(source.message);
|
|
408
|
+
error.name = source.name;
|
|
409
|
+
attachAttempts(error, attempt);
|
|
410
|
+
return error;
|
|
411
|
+
}
|
|
412
|
+
/** Token-only addition: call/attempt counters already describe the logical request. */
|
|
413
|
+
function addTokens(target, source) {
|
|
414
|
+
target.inputTokens += source.inputTokens;
|
|
415
|
+
target.cachedInputTokens += source.cachedInputTokens;
|
|
416
|
+
target.outputTokens += source.outputTokens;
|
|
417
|
+
target.reasoningTokens += source.reasoningTokens;
|
|
418
|
+
}
|
|
314
419
|
async function retrying(config, signal, run) {
|
|
315
420
|
let attempt = 0;
|
|
421
|
+
const carried = {
|
|
422
|
+
inputTokens: 0,
|
|
423
|
+
cachedInputTokens: 0,
|
|
424
|
+
outputTokens: 0,
|
|
425
|
+
reasoningTokens: 0
|
|
426
|
+
};
|
|
427
|
+
let unknownFailure = false;
|
|
428
|
+
const spent = (billed, unknown) => ({
|
|
429
|
+
calls: billed === void 0 ? 0 : billed.calls,
|
|
430
|
+
attempts: attempt,
|
|
431
|
+
retries: Math.max(0, attempt - 1),
|
|
432
|
+
inputTokens: carried.inputTokens + (billed?.inputTokens ?? 0),
|
|
433
|
+
cachedInputTokens: carried.cachedInputTokens + (billed?.cachedInputTokens ?? 0),
|
|
434
|
+
outputTokens: carried.outputTokens + (billed?.outputTokens ?? 0),
|
|
435
|
+
reasoningTokens: carried.reasoningTokens + (billed?.reasoningTokens ?? 0),
|
|
436
|
+
...unknown ? { usageIncomplete: true } : {}
|
|
437
|
+
});
|
|
438
|
+
const cancel = (reason, billed, unknown) => {
|
|
439
|
+
const error = abortFailure(reason, attempt);
|
|
440
|
+
attachUsage(error, spent(billed, unknown));
|
|
441
|
+
throw error;
|
|
442
|
+
};
|
|
316
443
|
while (true) {
|
|
317
|
-
if (signal?.aborted)
|
|
444
|
+
if (signal?.aborted) cancel(signal.reason, void 0, false);
|
|
318
445
|
attempt += 1;
|
|
319
446
|
const controller = new AbortController();
|
|
320
447
|
let timedOut = false;
|
|
@@ -325,12 +452,33 @@ async function retrying(config, signal, run) {
|
|
|
325
452
|
const abort = () => controller.abort(signal?.reason);
|
|
326
453
|
signal?.addEventListener("abort", abort, { once: true });
|
|
327
454
|
try {
|
|
328
|
-
|
|
455
|
+
const value = await run(controller.signal, attempt);
|
|
456
|
+
if (typeof value === "object" && value !== null) {
|
|
457
|
+
const usage = value.usage;
|
|
458
|
+
if (usage !== void 0) {
|
|
459
|
+
addTokens(usage, carried);
|
|
460
|
+
if (unknownFailure) usage.usageIncomplete = true;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return value;
|
|
329
464
|
} catch (error) {
|
|
330
|
-
|
|
465
|
+
const billed = partialUsage(error);
|
|
466
|
+
if (signal?.aborted) cancel(signal.reason ?? error, billed, unknownFailure || billed === void 0);
|
|
331
467
|
const retryable = timedOut || error instanceof Error && RETRYABLE_MESSAGE.test(error.message);
|
|
332
|
-
if (attempt > config.maxRetries || !retryable)
|
|
333
|
-
|
|
468
|
+
if (attempt > config.maxRetries || !retryable) {
|
|
469
|
+
if (billed === void 0) unknownFailure = true;
|
|
470
|
+
const failure = typeof error === "object" && error !== null ? error : new Error(String(error));
|
|
471
|
+
attachAttempts(failure, attempt);
|
|
472
|
+
attachUsage(failure, spent(billed, unknownFailure || billed === void 0));
|
|
473
|
+
throw failure;
|
|
474
|
+
}
|
|
475
|
+
if (billed === void 0) unknownFailure = true;
|
|
476
|
+
else addTokens(carried, billed);
|
|
477
|
+
try {
|
|
478
|
+
await delay(Math.min(3e4, config.retryBaseDelayMs * 2 ** (attempt - 1) * (.8 + Math.random() * .4)), signal);
|
|
479
|
+
} catch (waitError) {
|
|
480
|
+
cancel(signal?.reason ?? waitError, void 0, unknownFailure);
|
|
481
|
+
}
|
|
334
482
|
} finally {
|
|
335
483
|
clearTimeout(timeout);
|
|
336
484
|
signal?.removeEventListener("abort", abort);
|
|
@@ -397,14 +545,14 @@ async function callTextCompletion(config, prompt, signal, images, attempt, toler
|
|
|
397
545
|
for await (const chunk of config.llm.stream(options)) assembler.push(chunk);
|
|
398
546
|
let truncated = false;
|
|
399
547
|
if (assembler.finish.kind === "max-tokens") {
|
|
400
|
-
if (!tolerateTruncation) throw
|
|
548
|
+
if (!tolerateTruncation) throw unusable("model call failed: " + failureMessage(assembler.finish), attempt, assembler.usage);
|
|
401
549
|
truncated = true;
|
|
402
550
|
} else {
|
|
403
551
|
const failed = failureMessage(assembler.finish);
|
|
404
|
-
if (failed !== void 0) throw
|
|
552
|
+
if (failed !== void 0) throw unusable("model call failed: " + failed, attempt, assembler.usage);
|
|
405
553
|
}
|
|
406
554
|
const text = assembler.blocks().filter((block) => block.type === "text").map((block) => block.text).join("");
|
|
407
|
-
if (!text.trim()) throw
|
|
555
|
+
if (!text.trim()) throw unusable("selected DSH model produced no text", attempt, assembler.usage);
|
|
408
556
|
return {
|
|
409
557
|
text,
|
|
410
558
|
tokens: [],
|
|
@@ -461,6 +609,7 @@ async function predictScoringChannel(config) {
|
|
|
461
609
|
}
|
|
462
610
|
async function callAutomatic(config, prompt, signal, images, attempt) {
|
|
463
611
|
await config.topLogprobCapabilities.ensureLoaded();
|
|
612
|
+
let fellBack = false;
|
|
464
613
|
if (!config.topLogprobCapabilities.isUnsupported(config.provider, config.model)) {
|
|
465
614
|
const route = await resolveTopLogprobRoute(config.ctx, config.provider);
|
|
466
615
|
if (route !== void 0) try {
|
|
@@ -468,10 +617,15 @@ async function callAutomatic(config, prompt, signal, images, attempt) {
|
|
|
468
617
|
} catch (error) {
|
|
469
618
|
if (!(error instanceof TopLogprobsUnsupportedError)) throw error;
|
|
470
619
|
config.topLogprobCapabilities.markUnsupported(config.provider, config.model);
|
|
620
|
+
fellBack = true;
|
|
471
621
|
}
|
|
472
622
|
else config.topLogprobCapabilities.markUnsupported(config.provider, config.model);
|
|
473
623
|
}
|
|
474
|
-
|
|
624
|
+
const completion = await callExplicitTag(config, prompt, signal, images, attempt);
|
|
625
|
+
return fellBack ? {
|
|
626
|
+
...completion,
|
|
627
|
+
channelFallback: true
|
|
628
|
+
} : completion;
|
|
475
629
|
}
|
|
476
630
|
async function callVerifier(config, prompt, signal, images) {
|
|
477
631
|
const invoke = () => retrying(config, signal, (attemptSignal, attempt) => callAutomatic(config, prompt, attemptSignal, images, attempt));
|
|
@@ -571,7 +725,7 @@ function addUsage(target, source) {
|
|
|
571
725
|
"cachedInputTokens",
|
|
572
726
|
"outputTokens",
|
|
573
727
|
"reasoningTokens"
|
|
574
|
-
]) target[key] += source[key];
|
|
728
|
+
]) target[key] += source[key] ?? 0;
|
|
575
729
|
}
|
|
576
730
|
function emptyUsage() {
|
|
577
731
|
return {
|
|
@@ -585,6 +739,6 @@ function emptyUsage() {
|
|
|
585
739
|
};
|
|
586
740
|
}
|
|
587
741
|
//#endregion
|
|
588
|
-
export {
|
|
742
|
+
export { attachUsage as a, emptyUsage as c, generationClient as d, partialUsage as f, resolveCapabilityFile as g, TopLogprobCapabilityCache as h, addUsage as i, fallbackDeepFreeze as l, requestAttempts as m, GENERATION_TEMPERATURE as n, callVerifier as o, predictScoringChannel as p, RequestLimiter as r, callVerifierText as s, GENERATION_MAX_TOKENS as t, generateCandidate as u };
|
|
589
743
|
|
|
590
|
-
//# sourceMappingURL=caller-
|
|
744
|
+
//# sourceMappingURL=caller-BUK7OgUs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller-BUK7OgUs.js","names":[],"sources":["../src/top-logprobs.ts","../src/caller.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport { credentialRef } from '@deepseek-ai/dsh-credentials'\nimport { mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport type { CompletionLogprobs, TokenAlternative } from './core.ts'\nimport type { UsageStats, VerifierImage } from './caller.ts'\n\n/**\n * The two scoring channels are the logprob expectation (this file) and the explicit tag reply\n * (caller.ts). Upstream has a THIRD one worth knowing about before inventing anything new:\n * when an open-model server does not emit the score tags at all, it prefills the tag itself and\n * constrains the next token to the twenty scale letters, then reads that token's distribution\n * (llm-as-a-verifier `_score_tags_by_prefill`: vLLM/SGLang `continue_final_message` plus\n * `structured_outputs`). That turns ANY OpenAI-compatible server into a distribution-scoring\n * judge, which is strictly more informative than our explicit-tag channel's single sampled letter\n * — it is why upstream can run K=1 and we average repeats instead.\n *\n * NOT implemented here, deliberately: the direct transport below speaks to whichever\n * OpenAI-compatible endpoint a provider declares, and the prefill/grammar parameters are\n * vLLM/SGLang extensions that a normal endpoint rejects. Two preconditions before adding it:\n * (1) the DSH stream adapter exposes prefill or a constrained-decoding option, or the route is\n * known to be a local inference server; (2) the capability probe can detect support at runtime and\n * degrade to explicit tags — NEVER keyed off a provider or model name (AGENTS.md rule 7). If it\n * lands, it belongs in `callTopLogprobs` as an opt-in third mode, and `autoTrackRepeats` could\n * then drop.\n */\nexport interface TopLogprobRoute {\n baseURL: string\n apiKey?: string\n headers?: Record<string, string>\n deepSeekThinking: boolean\n}\nexport interface TopLogprobCompletion extends CompletionLogprobs { usage: UsageStats; scoringMode: 'top-logprobs' }\nexport class TopLogprobsUnsupportedError extends Error { constructor(message: string) { super(message); this.name = 'TopLogprobsUnsupportedError' } }\n/**\n * A provider-level rejection of the direct transport that is not a logprobs\n * capability answer (bad request, auth, quota, malformed body). It downgrades\n * this topic to the DSH stream instead of failing the whole verification.\n */\nexport class TopLogprobsRouteError extends TopLogprobsUnsupportedError { constructor(message: string, readonly status?: number) { super(message); this.name = 'TopLogprobsRouteError' } }\n\nfunction object(value: unknown): Record<string, unknown> | undefined { return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined }\nfunction text(value: unknown): string | undefined { return typeof value === 'string' && value.trim() ? value.trim() : undefined }\nfunction endpoint(baseURL: string): string { return baseURL.replace(/\\/+$/, '') + '/chat/completions' }\nfunction dataUrl(image: VerifierImage): string { return 'data:' + image.mediaType + ';base64,' + Buffer.from(image.data.buffer, image.data.byteOffset, image.data.byteLength).toString('base64') }\n\nasync function credential(ctx: Context, name: string | undefined): Promise<string | undefined> {\n if (!name) return undefined\n const provider = ctx.get('credentials')\n return (await provider?.resolve(credentialRef(name)))?.value\n}\n\nexport async function resolveTopLogprobRoute(ctx: Context, provider: string): Promise<TopLogprobRoute | undefined> {\n const settings = ctx.get('settings')\n if (provider === 'deepseek-official') {\n const value = settings ? object(settings.get('llm-deepseek' as never)) ?? {} : {}\n const apiKeyEnv = text(value.apiKeyEnv) ?? 'DEEPSEEK_API_KEY'\n const apiKey = await credential(ctx, apiKeyEnv)\n if (!apiKey) return undefined\n return { baseURL: text(value.baseURL) ?? 'https://api.deepseek.com', apiKey, deepSeekThinking: true }\n }\n if (!settings) return undefined\n const root = object(settings.get('llm-pi-ai' as never))\n const profiles = object(root?.providers)\n const profile = object(profiles?.[provider])\n // Only explicitly OpenAI-compatible profiles are safe to serialize directly.\n // Other DSH adapters keep their private protocol and use the explicit-tag fallback.\n if (!profile || profile.api !== 'openai-completions') return undefined\n const baseURL = text(profile.baseURL)\n if (!baseURL || !/^https:\\/\\//i.test(baseURL)) return undefined\n const apiKey = await credential(ctx, text(profile.apiKeyEnv))\n const rawHeaders = object(profile.headers)\n const headers = rawHeaders === undefined ? undefined : Object.fromEntries(Object.entries(rawHeaders).filter((entry): entry is [string, string] => typeof entry[1] === 'string'))\n return { baseURL, ...(apiKey ? { apiKey } : {}), ...(headers ? { headers } : {}), deepSeekThinking: false }\n}\n\nexport async function callTopLogprobs(route: TopLogprobRoute, model: string, prompt: string, maxTokens: number, reasoningEffort: string | undefined, signal?: AbortSignal, images?: readonly VerifierImage[], attempt = 1, temperature = 0.2): Promise<TopLogprobCompletion> {\n const content: string | Record<string, unknown>[] = images?.length ? [{ type: 'text', text: prompt }, ...images.map(image => ({ type: 'image_url', image_url: { url: dataUrl(image) } }))] : prompt\n const thinking = route.deepSeekThinking && reasoningEffort ? reasoningEffort === 'off' ? { thinking: { type: 'disabled' } } : { thinking: { type: 'enabled' }, reasoning_effort: reasoningEffort } : {}\n const response = await fetch(endpoint(route.baseURL), {\n method: 'POST', redirect: 'error', signal,\n headers: { 'content-type': 'application/json', ...(route.apiKey ? { authorization: 'Bearer ' + route.apiKey } : {}), ...route.headers },\n body: JSON.stringify({ model, messages: [{ role: 'user', content }], max_tokens: maxTokens, temperature, logprobs: true, top_logprobs: 20, ...thinking }),\n })\n const raw = await response.text()\n if (!response.ok) {\n const excerpt = raw.slice(0, 1000)\n const message = 'llm-verifier: top_logprobs request failed with HTTP ' + response.status + ': ' + excerpt\n if ([400, 404, 405, 415, 422].includes(response.status) && /logprob|top_logprobs|unsupported|unknown (?:field|parameter)|unrecognized (?:field|parameter)|not support/i.test(excerpt)) throw new TopLogprobsUnsupportedError('provider rejected top_logprobs: HTTP ' + response.status + ' ' + excerpt)\n // Throttling and server faults stay generic so the shared retry wrapper can\n // attempt again; every other rejection downgrades to the DSH stream.\n if (response.status === 408 || response.status === 409 || response.status === 429 || response.status >= 500) throw new Error(message)\n throw new TopLogprobsRouteError(message, response.status)\n }\n let body: Record<string, unknown>\n try { body = object(JSON.parse(raw)) ?? {} } catch { throw new TopLogprobsRouteError('llm-verifier: top_logprobs endpoint returned invalid JSON', response.status) }\n const choices = Array.isArray(body.choices) ? body.choices : []\n const choice = object(choices[0])\n const message = object(choice?.message)\n const answer = typeof message?.content === 'string' ? message.content : ''\n const logprobs = object(choice?.logprobs)\n const rows = Array.isArray(logprobs?.content) ? logprobs.content : []\n if (!rows.length) throw new TopLogprobsUnsupportedError('provider returned no token logprobs')\n const tokens: string[] = []\n const positions: TokenAlternative[][] = []\n for (const rawRow of rows) {\n const row = object(rawRow) ?? {}\n const token = typeof row.token === 'string' ? row.token : ''\n tokens.push(token)\n const top = Array.isArray(row.top_logprobs) ? row.top_logprobs : []\n const alternatives = top.flatMap(value => { const item = object(value); return item && typeof item.token === 'string' && typeof item.logprob === 'number' ? [{ token: item.token, logprob: item.logprob }] : [] })\n if (!alternatives.length && typeof row.logprob === 'number') alternatives.push({ token, logprob: row.logprob })\n positions.push(alternatives)\n }\n const rawUsage = object(body.usage) ?? {}\n const promptDetails = object(rawUsage.prompt_tokens_details) ?? {}\n const completionDetails = object(rawUsage.completion_tokens_details) ?? {}\n const cached = Number(rawUsage.prompt_cache_hit_tokens ?? promptDetails.cached_tokens ?? 0) || 0\n const input = Number(rawUsage.prompt_tokens ?? 0) || 0\n return { text: answer, tokens, positions, scoringMode: 'top-logprobs', usage: { calls: 1, attempts: attempt, retries: attempt - 1, inputTokens: Math.max(0, input - cached), cachedInputTokens: cached, outputTokens: Number(rawUsage.completion_tokens ?? 0) || 0, reasoningTokens: Number(completionDetails.reasoning_tokens ?? 0) || 0 } }\n}\n\n/** Marks older than this are dropped on hydration so a provider that later gains logprobs support is re-probed. */\nexport const CAPABILITY_TTL_MS = 24 * 60 * 60 * 1000\n\ninterface CapabilityDocument { version: 1; entries: Record<string, number> }\n\n/** Resolves the capability memory file beside the score cache inside the topic verifier directory. */\nexport function resolveCapabilityFile(cacheDir: string, cwd = process.cwd()): string {\n const root = isAbsolute(cacheDir) ? cacheDir : resolve(cwd, cacheDir)\n return join(root, 'capabilities-v1.json')\n}\n\nexport class TopLogprobCapabilityCache {\n private readonly unsupported = new Map<string, number>()\n private loaded = false\n private hydrating: Promise<void> | undefined\n private writing: Promise<void> = Promise.resolve()\n\n constructor(private readonly file?: string, private readonly now: () => number = Date.now) {}\n\n /** Expired marks are dropped so a provider that later gains logprobs support is re-probed. */\n isUnsupported(provider: string, model: string): boolean {\n const key = provider + '\\0' + model\n const markedAt = this.unsupported.get(key)\n if (markedAt === undefined) return false\n if (this.now() - markedAt > CAPABILITY_TTL_MS) { this.unsupported.delete(key); return false }\n return true\n }\n\n /** Hydrates persisted marks once; in-process marks always win over file contents. */\n async ensureLoaded(): Promise<void> {\n if (this.loaded || this.file === undefined) return\n this.hydrating ??= (async () => {\n try {\n const document = JSON.parse(await readFile(this.file!, 'utf8')) as CapabilityDocument\n const entries = document !== null && typeof document === 'object' && document.version === 1 && typeof document.entries === 'object' && document.entries !== null ? document.entries : {}\n const now = this.now()\n for (const [key, markedAt] of Object.entries(entries)) {\n if (typeof markedAt !== 'number' || !Number.isFinite(markedAt) || markedAt < 0 || now - markedAt > CAPABILITY_TTL_MS) continue\n // Max-merge: never let an older persisted stamp clobber a fresher in-process probe.\n const existing = this.unsupported.get(key)\n if (existing === undefined || existing < markedAt) this.unsupported.set(key, markedAt)\n }\n } catch { /* a missing or unreadable file simply starts empty */ }\n this.loaded = true\n })()\n await this.hydrating\n }\n\n markUnsupported(provider: string, model: string): void {\n this.unsupported.set(provider + '\\0' + model, this.now())\n this.persist()\n }\n\n /**\n * Forget one provider/model mark so the next call re-probes instead of replaying a cached answer.\n *\n * The judge probe exists to answer \"which scoring channel is this judge on\". Replaying a mark\n * written up to {@link CAPABILITY_TTL_MS} ago — possibly under a different provider\n * configuration — would answer a different, stale question. The removal is persisted, so a host\n * restart cannot resurrect the old mark.\n *\n * The delete is repeated INSIDE the serialized write: hydration max-merges the file into memory,\n * so deleting only beforehand would let the very write we schedule put the entry back.\n * @param provider - provider id the mark belongs to.\n * @param model - model id the mark belongs to.\n */\n forget(provider: string, model: string): void {\n const key = provider + '\\0' + model\n this.unsupported.delete(key)\n if (this.file === undefined) return\n this.writing = this.writing\n .then(() => this.ensureLoaded())\n .then(() => { this.unsupported.delete(key); return this.writeDocument() })\n .catch(() => { /* capability memory is best-effort */ })\n }\n\n /** Serialize behind hydration so an early mark never clobbers not-yet-loaded entries. */\n private persist(): void {\n if (this.file === undefined) return\n this.writing = this.writing\n .then(() => this.ensureLoaded())\n .then(() => this.writeDocument())\n .catch(() => { /* capability memory is best-effort; the next mark rewrites the file */ })\n }\n\n private async writeDocument(): Promise<void> {\n const snapshot: CapabilityDocument = { version: 1, entries: Object.fromEntries(this.unsupported) }\n await mkdir(dirname(this.file!), { recursive: true })\n const temporary = this.file! + '.tmp-' + process.pid\n await writeFile(temporary, JSON.stringify(snapshot), 'utf8')\n try { await rename(temporary, this.file!) } catch (error) { await unlink(temporary).catch(() => {}); throw error }\n }\n\n /** Resolves once the trailing persistence attempt settles; exposed for tests. */\n flush(): Promise<void> { return this.writing }\n}\n","import { BlockAssembler, ReasoningEffortId, createUserMessage, type ContentBlock, type FinishReason, type LlmRuntime } from '@deepseek-ai/dsh-llm'\nimport * as LlmModule from '@deepseek-ai/dsh-llm'\n\n/**\n * Deep-freeze a call-options graph, leaving any live AbortSignal mutable.\n *\n * The host re-exports its own `deepFreeze` from `@deepseek-ai/dsh-llm` on the 0.1.1 line; the\n * 0.1.5 line moved the helper to `@deepseek-ai/dsh-util-values` and no longer re-exports it, so\n * the fallback below is what actually runs there. Both implementations must carry the same rule\n * (\"leaving live AbortSignal objects mutable\" — the host's own wording), because freezing a\n * signal breaks the transport twice over: Node >= 26.5 initializes the signal's internal event\n * map lazily, so the first `addEventListener` throws \"Cannot assign to read only property\n * 'Symbol(kEvents)'\", and on every Node version the attempt timeout's `controller.abort()` throws\n * the same way on 'Symbol(kAborted)'. The signal belongs to this call's retry loop and is still\n * unsubscribed when the options are frozen, which is what makes the ordering fatal.\n */\nfunction deepFreeze<T>(value: T): T {\n const mod = LlmModule as unknown as Record<string, unknown>\n if (typeof mod.deepFreeze === 'function') {\n return (mod.deepFreeze as Function)(value)\n }\n return fallbackDeepFreeze(value)\n}\n\n/**\n * The graph walk used when the host exports no `deepFreeze`; exported for tests.\n * @param value - value to freeze.\n * @returns The same value, with every reachable enumerable child frozen except live AbortSignals.\n */\nexport function fallbackDeepFreeze<T>(value: T): T {\n // See deepFreeze(): a frozen signal fails on the transport's first subscription.\n if (value instanceof AbortSignal) return value\n if (value && typeof value === 'object' && !Object.isFrozen(value)) {\n Object.freeze(value)\n for (const key of Object.keys(value)) {\n fallbackDeepFreeze((value as Record<string, unknown>)[key])\n }\n }\n return value\n}\nimport type { AttachmentStore } from '@deepseek-ai/dsh-attachment'\nimport type { CompletionLogprobs } from './core.ts'\nimport { TopLogprobCapabilityCache, TopLogprobsUnsupportedError, callTopLogprobs, resolveTopLogprobRoute } from './top-logprobs.ts'\nimport type { Context } from '@deepseek-ai/cordis'\n\nexport interface VerifierClientConfig {\n ctx: Context\n llm: LlmRuntime\n attachments: AttachmentStore\n topLogprobCapabilities: TopLogprobCapabilityCache\n provider: string\n model: string\n /** User-facing judge name for tool output; cosmetic only, never part of the scoring cache identity. */\n label?: string\n reasoningEffort?: string\n maxTokens: number\n temperature: number\n timeoutMs: number\n maxRetries: number\n retryBaseDelayMs: number\n limiter?: RequestLimiter\n}\n\nexport interface VerifierImage {\n data: Uint8Array\n mediaType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'\n}\n\nexport interface UsageStats {\n calls: number\n attempts: number\n retries: number\n inputTokens: number\n cachedInputTokens: number\n outputTokens: number\n reasoningTokens: number\n /**\n * At least one attempt's usage is UNKNOWN (an earlier attempt failed and was retried, or a\n * response came back unusable). The token counts are a floor, never a confident total.\n */\n usageIncomplete?: boolean\n}\n\nexport type ScoringMode = 'top-logprobs' | 'explicit-tag'\nexport interface VerifierCompletion extends CompletionLogprobs {\n usage: UsageStats\n scoringMode: ScoringMode\n /**\n * The direct logprob transport was attempted and the provider rejected it, so this\n * answer came from the explicit-tag fallback. Diagnostics only: it never changes the\n * score, and it is recorded so a silent downgrade is visible in the statistics.\n */\n channelFallback?: boolean\n}\n\n/**\n * Where a finally-failed request records how many attempts it already spent.\n *\n * A failure that never returned usage leaves the tokens UNKNOWN, not zero. The attempt\n * count is the one fact the transport does know, so it is carried on the error itself\n * (the engine catches per-judge errors) instead of being discarded.\n */\nconst REQUEST_ATTEMPTS = Symbol('llm-verifier.requestAttempts')\n\n/** Attempts one failed verifier request already spent; 0 when the error carries none. */\nexport function requestAttempts(error: unknown): number {\n if (typeof error !== 'object' || error === null) return 0\n const value = (error as { [REQUEST_ATTEMPTS]?: unknown })[REQUEST_ATTEMPTS]\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : 0\n}\n\n/**\n * Usage the transport DID return for a response that then turned out unusable.\n *\n * A parse failure or a truncated judge answer happened after the request was billed, so the\n * engine must not fold it into a zero-cost failure. The usage rides on the error next to the\n * attempt count; one error can carry both (a retried call whose final answer also failed).\n */\nconst PARTIAL_USAGE = Symbol('llm-verifier.partialUsage')\n\n/** Usage a completed-but-unusable response already cost; undefined when the error carries none. */\nexport function partialUsage<T = UsageStats>(error: unknown): T | undefined {\n if (typeof error !== 'object' || error === null) return undefined\n const value = (error as { [PARTIAL_USAGE]?: unknown })[PARTIAL_USAGE]\n return typeof value === 'object' && value !== null ? value as T : undefined\n}\n\n/** Attach the usage a completed-but-unusable response already cost to its error. */\nexport function attachUsage(error: unknown, usage: UsageStats): void {\n if (typeof error === 'object' && error !== null) (error as { [PARTIAL_USAGE]?: UsageStats })[PARTIAL_USAGE] = usage\n}\n\n/**\n * An error for a response that came back and was billed but produced no usable verdict.\n *\n * The usage is attached so the failure row reports known requests and tokens instead of zero.\n */\nfunction unusable(reason: string, attempt: number, raw: { inputTokens?: number; outputTokens?: number; cacheReadTokens?: number; cacheWriteTokens?: number; reasoningTokens?: number } | undefined): Error {\n const error = new Error('llm-verifier: ' + reason)\n attachUsage(error, usage(attempt, raw ?? {}))\n return error\n}\n\n/**\n * Describe why a finished stream is unusable.\n *\n * `FinishReason.failure` is the host's SERIALIZABLE facts record (`{message, code, status?,\n * providerRetryAfterMs?, requestId?}`), not the error the adapter threw: `normalizeLlmFailure`\n * detaches the facts at the adapter boundary, so the stack and the cause are already gone before\n * this plugin sees them. The machine code and the provider status ARE carried, and dropping them\n * left the board with one line and no way to tell an auth failure from a transport one.\n */\nfunction failureMessage(finish: FinishReason): string | undefined {\n if (finish.kind === 'error' || finish.kind === 'aborted') {\n const failure = finish.failure\n const facts = [\n failure.code,\n failure.status === undefined ? undefined : 'HTTP ' + failure.status,\n failure.requestId === undefined ? undefined : 'request ' + failure.requestId,\n ].filter((fact): fact is string => typeof fact === 'string' && fact.length > 0)\n return facts.length > 0 ? failure.message + ' [' + facts.join(', ') + ']' : failure.message\n }\n if (finish.kind === 'max-tokens') return 'verifier response reached max tokens before completing its answer'\n return undefined\n}\n\nasync function delay(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) throw signal.reason\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms)\n const abort = () => { clearTimeout(timer); reject(signal?.reason) }\n signal?.addEventListener('abort', abort, { once: true })\n })\n}\n\nfunction usage(attempts: number, value = {} as { inputTokens?: number; outputTokens?: number; cacheReadTokens?: number; cacheWriteTokens?: number; reasoningTokens?: number }): UsageStats {\n return { calls: 1, attempts, retries: attempts - 1, inputTokens: value.inputTokens ?? 0, cachedInputTokens: (value.cacheReadTokens ?? 0) + (value.cacheWriteTokens ?? 0), outputTokens: value.outputTokens ?? 0, reasoningTokens: value.reasoningTokens ?? 0 }\n}\n\n/** Transient failures worth another attempt; anything else fails fast. */\nconst RETRYABLE_MESSAGE = /rate|quota|timeout|timed out|temporar|network|fetch|socket|5\\d\\d/i\n\n/**\n * Run one logical verifier request under the configured timeout, retrying\n * transient failures with exponential backoff.\n *\n * Every channel goes through this wrapper — including the direct top_logprobs\n * transport, which used to bypass both the timeout and the retry budget.\n * @param config - resolved verifier client configuration.\n * @param signal - caller's abort signal (tool call or turn boundary).\n * @param run - one attempt; receives its own deadline signal and 1-based attempt number.\n * @returns The first successful completion.\n */\nfunction attachAttempts(error: unknown, attempt: number): void {\n if (typeof error === 'object' && error !== null) (error as { [REQUEST_ATTEMPTS]?: number })[REQUEST_ATTEMPTS] = attempt\n}\n\n/**\n * A fresh error for one aborted call.\n *\n * Never annotate and rethrow the shared `signal.reason`: several concurrent requests share it,\n * and the engine attaches its accumulator to the thrown error, so one object carries several\n * accumulators and they get merged repeatedly. The wrapper preserves the message and name.\n */\nfunction abortFailure(reason: unknown, attempt: number): Error {\n const source = reason instanceof Error ? reason : new Error(reason === undefined ? 'llm-verifier: request aborted' : String(reason))\n const error = new Error(source.message)\n error.name = source.name\n attachAttempts(error, attempt)\n return error\n}\n\n/** Token-only addition: call/attempt counters already describe the logical request. */\nfunction addTokens(target: Pick<UsageStats, 'inputTokens' | 'cachedInputTokens' | 'outputTokens' | 'reasoningTokens'>, source: Pick<UsageStats, 'inputTokens' | 'cachedInputTokens' | 'outputTokens' | 'reasoningTokens'>): void {\n target.inputTokens += source.inputTokens\n target.cachedInputTokens += source.cachedInputTokens\n target.outputTokens += source.outputTokens\n target.reasoningTokens += source.reasoningTokens\n}\n\nasync function retrying<T>(config: VerifierClientConfig, signal: AbortSignal | undefined, run: (signal: AbortSignal, attempt: number) => Promise<T>): Promise<T> {\n let attempt = 0\n // Tokens an earlier attempt already paid for but never delivered a usable result. They are\n // real cost, so they follow the chain into whichever exit happens (success, final failure or\n // cancellation) instead of being discarded when no attempt ultimately succeeds.\n const carried = { inputTokens: 0, cachedInputTokens: 0, outputTokens: 0, reasoningTokens: 0 }\n let unknownFailure = false\n // The usage the chain must be able to report: everything already spent plus this attempt's own\n // billed response. `unknown` (some attempt's tokens never came back) is what makes it a floor.\n const spent = (billed: UsageStats | undefined, unknown: boolean): UsageStats => ({\n calls: billed === undefined ? 0 : billed.calls,\n attempts: attempt,\n retries: Math.max(0, attempt - 1),\n inputTokens: carried.inputTokens + (billed?.inputTokens ?? 0),\n cachedInputTokens: carried.cachedInputTokens + (billed?.cachedInputTokens ?? 0),\n outputTokens: carried.outputTokens + (billed?.outputTokens ?? 0),\n reasoningTokens: carried.reasoningTokens + (billed?.reasoningTokens ?? 0),\n ...(unknown ? { usageIncomplete: true } : {}),\n })\n const cancel = (reason: unknown, billed: UsageStats | undefined, unknown: boolean): never => {\n const error = abortFailure(reason, attempt)\n attachUsage(error, spent(billed, unknown))\n throw error\n }\n while (true) {\n if (signal?.aborted) cancel(signal.reason, undefined, false)\n attempt += 1\n const controller = new AbortController()\n let timedOut = false\n const timeout = setTimeout(() => { timedOut = true; controller.abort(new Error('llm-verifier: request timed out')) }, config.timeoutMs)\n const abort = () => controller.abort(signal?.reason)\n signal?.addEventListener('abort', abort, { once: true })\n try {\n const value = await run(controller.signal, attempt)\n if (typeof value === 'object' && value !== null) {\n const usage = (value as { usage?: UsageStats }).usage\n if (usage !== undefined) {\n addTokens(usage, carried)\n // Only a failed attempt whose tokens never came back makes the total a floor.\n if (unknownFailure) usage.usageIncomplete = true\n }\n }\n return value\n } catch (error) {\n const billed = partialUsage<UsageStats>(error)\n if (signal?.aborted) cancel(signal.reason ?? error, billed, unknownFailure || billed === undefined)\n // A deadline abort is retryable even when the adapter wraps the reason in\n // its own error type with an unrelated message.\n const retryable = timedOut || (error instanceof Error && RETRYABLE_MESSAGE.test(error.message))\n if (attempt > config.maxRetries || !retryable) {\n // Every attempt of the chain goes onto the thrown error: the last response alone would\n // report a fraction of the requests and tokens the invocation really spent.\n if (billed === undefined) unknownFailure = true\n const failure = typeof error === 'object' && error !== null ? error : new Error(String(error))\n attachAttempts(failure, attempt)\n attachUsage(failure, spent(billed, unknownFailure || billed === undefined))\n throw failure\n }\n if (billed === undefined) unknownFailure = true\n else addTokens(carried, billed)\n try {\n await delay(Math.min(30000, config.retryBaseDelayMs * 2 ** (attempt - 1) * (0.8 + Math.random() * 0.4)), signal)\n } catch (waitError) {\n // Cancelled while waiting to retry: the attempts and the tokens already spent are real.\n cancel(signal?.reason ?? waitError, undefined, unknownFailure)\n }\n } finally {\n clearTimeout(timeout)\n signal?.removeEventListener('abort', abort)\n }\n }\n}\n\n/** One attachment per image object per process: retries must not duplicate attachments. */\nconst imageRefs = new WeakMap<VerifierImage, Promise<unknown>>()\n\n/**\n * One plain-text completion through the DSH stream.\n *\n * Shared by the explicit-tag judge path and by best-of-N generation, which differ in exactly one\n * place: a `max-tokens` finish. A truncated JUDGE answer is unusable — its verdict tags may never\n * have been emitted — so it stays a hard error. A truncated DRAFT is still a candidate the operator\n * already paid for, and the judge can see that the text stops mid-sentence and score it accordingly,\n * so generation receives the text plus a `truncated` flag.\n * @param config - resolved verifier client configuration.\n * @param prompt - the rendered prompt.\n * @param signal - the attempt's deadline signal.\n * @param images - attachments to send, if any.\n * @param attempt - 1-based attempt number for usage accounting.\n * @param tolerateTruncation - return the text of a max-tokens finish instead of throwing.\n * @returns The completion (with `truncated`) when it produced text.\n */\nasync function callTextCompletion(config: VerifierClientConfig, prompt: string, signal: AbortSignal | undefined, images: readonly VerifierImage[] | undefined, attempt: number, tolerateTruncation: boolean): Promise<VerifierCompletion & { truncated: boolean }> {\n const content: ContentBlock[] = [{ type: 'text', text: prompt }]\n for (const image of images ?? []) {\n let pending = imageRefs.get(image)\n if (pending === undefined) {\n const promise = Promise.resolve()\n .then(() => config.attachments.saveImage({ data: image.data, mediaType: image.mediaType }))\n .catch(error => {\n if (imageRefs.get(image) === pending) {\n imageRefs.delete(image)\n }\n throw error\n })\n pending = promise\n imageRefs.set(image, pending)\n }\n content.push({ type: 'image', attachment: await pending as never })\n }\n const messages = [createUserMessage({ content, source: { kind: 'plugin', plugin: 'dsh-llm-verifier' } })]\n const assembler = new BlockAssembler()\n const options = deepFreeze({\n provider: config.provider,\n model: config.model,\n ...(config.reasoningEffort ? { reasoningEffort: ReasoningEffortId(config.reasoningEffort) } : {}),\n messages,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n signal,\n })\n for await (const chunk of config.llm.stream(options)) assembler.push(chunk)\n let truncated = false\n if (assembler.finish.kind === 'max-tokens') {\n if (!tolerateTruncation) throw unusable('model call failed: ' + failureMessage(assembler.finish), attempt, assembler.usage)\n truncated = true\n } else {\n const failed = failureMessage(assembler.finish)\n if (failed !== undefined) throw unusable('model call failed: ' + failed, attempt, assembler.usage)\n }\n const text = assembler.blocks().filter((block): block is Extract<ContentBlock, { type: 'text' }> => block.type === 'text').map(block => block.text).join('')\n if (!text.trim()) throw unusable('selected DSH model produced no text', attempt, assembler.usage)\n // DSH adapters expose provider-neutral text/usage but not top-logprob candidates.\n // extractScore() therefore uses the model's explicit final A–T tags.\n return { text, tokens: [], positions: [], scoringMode: 'explicit-tag', usage: usage(attempt, assembler.usage), truncated }\n}\n\n/** Explicit-tag judge completion: fail-closed, so a truncated answer is an error and never a score. */\nasync function callExplicitTag(config: VerifierClientConfig, prompt: string, signal: AbortSignal | undefined, images: readonly VerifierImage[] | undefined, attempt: number): Promise<VerifierCompletion> {\n return callTextCompletion(config, prompt, signal, images, attempt, false)\n}\n\nexport class RequestLimiter {\n private active = 0\n private readonly queue: Array<() => void> = []\n constructor(readonly limit: number) { if (!Number.isSafeInteger(limit) || limit < 1) throw new Error('llm-verifier: request concurrency limit must be a positive integer') }\n async run<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n if (signal?.aborted) throw signal.reason\n if (this.active >= this.limit) await new Promise<void>((resolve, reject) => {\n const enter = () => { signal?.removeEventListener('abort', abort); resolve() }\n const abort = () => { const index = this.queue.indexOf(enter); if (index >= 0) this.queue.splice(index, 1); reject(signal?.reason) }\n this.queue.push(enter); signal?.addEventListener('abort', abort, { once: true })\n })\n if (signal?.aborted) {\n this.queue.shift()?.()\n throw signal.reason\n }\n this.active += 1\n try { return await operation() } finally { this.active -= 1; this.queue.shift()?.() }\n }\n}\n\n/** Best-effort pre-call channel prediction for cache identity only; callAutomatic() stays the runtime source of truth. */\nexport async function predictScoringChannel(config: VerifierClientConfig): Promise<ScoringMode> {\n await config.topLogprobCapabilities.ensureLoaded()\n return config.topLogprobCapabilities.isUnsupported(config.provider, config.model) ? 'explicit-tag' : 'top-logprobs'\n}\n\nasync function callAutomatic(config: VerifierClientConfig, prompt: string, signal: AbortSignal | undefined, images: readonly VerifierImage[] | undefined, attempt: number): Promise<VerifierCompletion> {\n await config.topLogprobCapabilities.ensureLoaded()\n let fellBack = false\n if (!config.topLogprobCapabilities.isUnsupported(config.provider, config.model)) {\n const route = await resolveTopLogprobRoute(config.ctx, config.provider)\n if (route !== undefined) {\n try { return await callTopLogprobs(route, config.model, prompt, config.maxTokens, config.reasoningEffort, signal, images, attempt, config.temperature) }\n catch (error) {\n // Both a capability rejection and a non-retryable provider rejection of\n // the direct transport fall back to the DSH stream instead of failing\n // the whole verification.\n if (!(error instanceof TopLogprobsUnsupportedError)) throw error\n config.topLogprobCapabilities.markUnsupported(config.provider, config.model)\n // A runtime downgrade AFTER a live attempt, unlike the capability probe that\n // finds no route at all: only this one is a fallback worth counting.\n fellBack = true\n }\n } else config.topLogprobCapabilities.markUnsupported(config.provider, config.model)\n }\n const completion = await callExplicitTag(config, prompt, signal, images, attempt)\n return fellBack ? { ...completion, channelFallback: true } : completion\n}\n\nexport async function callVerifier(config: VerifierClientConfig, prompt: string, signal?: AbortSignal, images?: readonly VerifierImage[]): Promise<VerifierCompletion> {\n const invoke = () => retrying(config, signal, (attemptSignal, attempt) => callAutomatic(config, prompt, attemptSignal, images, attempt))\n return config.limiter === undefined ? invoke() : config.limiter.run(invoke, signal)\n}\n\n/**\n * Best-of-N generation sampling constants.\n *\n * Deliberately NOT the judge's temperature: best-of-N only pays off when the drafts actually\n * differ, and the judge's low default (0.2) would produce N near-copies — the tool would then\n * spend N times the money choosing between the same answer.\n */\nexport const GENERATION_TEMPERATURE = 1\n/**\n * Output ceiling for one draft.\n *\n * 4096 was a guess in the plan, and the first real end-to-end acceptance disproved it: a\n * \"function + 12 test cases + a note\" task truncated ALL THREE drafts, so the tool returned\n * nothing at all. The measured cause is reasoning tokens: on a trivial 2-draft run the session\n * model (deepseek-official/deepseek-flash) spent 16363 reasoning tokens out of 17254 output\n * tokens — roughly 8k of reasoning PER DRAFT, which eats any 4096 budget before the answer starts.\n *\n * 16384 is about 2x that measured per-draft spend, and it is also the largest ceiling that keeps\n * a pairwise judge prompt inside the plugin's own evidence limit: two drafts at 16384 tokens are\n * roughly 130k characters against a 240k explicit-evidence ceiling (EXPLICIT_MAX_TOTAL_CHARS).\n * `maxTokens` is a ceiling rather than a reservation, so a draft that needs less room costs\n * exactly what it did before. A task whose answer genuinely needs more is too large for this tool,\n * and its truncation is REPORTED instead of being silently returned.\n */\nexport const GENERATION_MAX_TOKENS = 16384\n\nexport interface GenerationTarget {\n provider: string\n model: string\n reasoningEffort?: string\n}\n\n/** One draft: plain text, never scored, plus whether it ran into the output ceiling. */\nexport interface GeneratedCandidate extends VerifierCompletion { truncated: boolean }\n\n/**\n * Re-point an existing verifier client at the model that should draft the candidates.\n *\n * Everything transport-shaped (context, llm runtime, attachments, capability memory, limiter,\n * timeout, retry budget) is inherited; only the route and the two generation-specific scalars\n * are replaced. `reasoningEffort` comes from the target and is never inherited from the base,\n * because the base is a judge: a leftover judge effort would silently draft with the wrong model\n * settings.\n * @param base - any configured verifier client (the primary judge is the cheapest source).\n * @param target - the model that writes the drafts.\n * @param maxTokens - output ceiling for this attempt.\n * @returns A client config safe to pass to {@link callGeneratedText}.\n */\nexport function generationClient(base: VerifierClientConfig, target: GenerationTarget, maxTokens = GENERATION_MAX_TOKENS): VerifierClientConfig {\n return {\n ctx: base.ctx,\n llm: base.llm,\n attachments: base.attachments,\n topLogprobCapabilities: base.topLogprobCapabilities,\n provider: target.provider,\n model: target.model,\n label: target.provider + '/' + target.model,\n ...(target.reasoningEffort === undefined ? {} : { reasoningEffort: target.reasoningEffort }),\n maxTokens,\n temperature: GENERATION_TEMPERATURE,\n timeoutMs: base.timeoutMs,\n maxRetries: base.maxRetries,\n retryBaseDelayMs: base.retryBaseDelayMs,\n ...(base.limiter === undefined ? {} : { limiter: base.limiter }),\n }\n}\n\n/**\n * One best-of-N draft.\n *\n * A named seam over the plain-text path: generation has no A–T contract and no scoring channel, and\n * the name keeps it distinct from the judge calls at every call site and in the decision snapshot.\n *\n * Hitting the output ceiling is deliberately NOT an error here. The operator already paid for those\n * tokens, and the judge can see for itself that the text stops mid-sentence. That is exactly why the\n * judge's fail-closed max-tokens handling was split out of this path: before the split, one long\n * task made the whole tool return zero candidates.\n * @param base - any configured verifier client (the primary judge is the cheapest source).\n * @param target - the model that writes the draft (normally the session model).\n * @param prompt - the rendered drafting prompt.\n * @param signal - caller's abort signal.\n * @returns The draft text, token usage, and whether it ran into the ceiling.\n */\nexport async function generateCandidate(base: VerifierClientConfig, target: GenerationTarget, prompt: string, signal?: AbortSignal): Promise<GeneratedCandidate> {\n return callGeneratedText(generationClient(base, target), prompt, signal)\n}\n\n/** Generation transport: the judge's timeout/retry/limiter wrappers, with truncation as a result. */\nasync function callGeneratedText(config: VerifierClientConfig, prompt: string, signal: AbortSignal | undefined): Promise<GeneratedCandidate> {\n const invoke = () => retrying(config, signal, (attemptSignal, attempt) => callTextCompletion(config, prompt, attemptSignal, undefined, attempt, true))\n return config.limiter === undefined ? invoke() : config.limiter.run(invoke, signal)\n}\n\n/** Plain-text verifier call for conservative JSON routing; probability labels are intentionally bypassed. */\nexport async function callVerifierText(config: VerifierClientConfig, prompt: string, signal?: AbortSignal): Promise<VerifierCompletion> {\n const invoke = () => retrying(config, signal, (attemptSignal, attempt) => callExplicitTag(config, prompt, attemptSignal, undefined, attempt))\n return config.limiter === undefined ? invoke() : config.limiter.run(invoke, signal)\n}\nexport function addUsage(target: UsageStats, source: UsageStats): void { for (const key of ['calls', 'attempts', 'retries', 'inputTokens', 'cachedInputTokens', 'outputTokens', 'reasoningTokens'] as const) target[key] += source[key] ?? 0 }\nexport function emptyUsage(): UsageStats { return { calls: 0, attempts: 0, retries: 0, inputTokens: 0, cachedInputTokens: 0, outputTokens: 0, reasoningTokens: 0 } }\n"],"mappings":"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"}
|
package/lib/caller.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { GENERATION_MAX_TOKENS, GENERATION_TEMPERATURE, RequestLimiter, addUsage, callVerifier, callVerifierText, emptyUsage, generateCandidate, generationClient, predictScoringChannel };
|
|
1
|
+
import { a as attachUsage, c as emptyUsage, d as generationClient, f as partialUsage, i as addUsage, l as fallbackDeepFreeze, m as requestAttempts, n as GENERATION_TEMPERATURE, o as callVerifier, p as predictScoringChannel, r as RequestLimiter, s as callVerifierText, t as GENERATION_MAX_TOKENS, u as generateCandidate } from "./caller-BUK7OgUs.js";
|
|
2
|
+
export { GENERATION_MAX_TOKENS, GENERATION_TEMPERATURE, RequestLimiter, addUsage, attachUsage, callVerifier, callVerifierText, emptyUsage, fallbackDeepFreeze, generateCandidate, generationClient, partialUsage, predictScoringChannel, requestAttempts };
|