@localmode/bench 0.1.0 → 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/dist/index.d.cts CHANGED
@@ -5,9 +5,9 @@
5
5
  * published statistics can be recomputed and audited server-side.
6
6
  */
7
7
  /** Protocol identifier embedded in every result. Bump only with a spec change. */
8
- declare const BENCH_PROTOCOL_VERSION = "localmode-bench/1";
8
+ declare const BENCH_PROTOCOL_VERSION = "localmode-bench/2";
9
9
  /** Result JSON schema version (independent of the protocol semantics version). */
10
- declare const BENCH_SCHEMA_VERSION = 1;
10
+ declare const BENCH_SCHEMA_VERSION = 2;
11
11
  /** Benchmark suite presets. `custom` = user-picked cells. */
12
12
  type BenchSuiteId = 'quick' | 'standard' | 'thorough' | 'custom';
13
13
  /**
@@ -69,6 +69,12 @@ interface BenchModelRef {
69
69
  /** Direct model URL when applicable (wllama GGUF, litert). */
70
70
  url?: string;
71
71
  requiresWebGPU?: boolean;
72
+ /**
73
+ * Appended to the quality-lane instruction line for every runtime of this
74
+ * pairing (e.g. " /no_think" to hold Qwen3 in non-thinking mode). Uniform
75
+ * across runtimes by construction, so fidelity comparisons stay valid.
76
+ */
77
+ qualityPromptSuffix?: string;
72
78
  }
73
79
  /** One recorded stream chunk: wall-clock timestamp + delta length in chars. */
74
80
  interface BenchChunk {
@@ -131,6 +137,8 @@ interface MemorySample {
131
137
  baseline?: number;
132
138
  postLoad?: number;
133
139
  postRun?: number;
140
+ /** Bytes at the moment a cell errored (load or workload failure). */
141
+ atError?: number;
134
142
  api: 'uaSpecific' | 'legacyHeap' | 'none';
135
143
  }
136
144
  /** Quality lane outcome attached to a cell. */
@@ -141,6 +149,13 @@ interface QualityResult {
141
149
  n: number;
142
150
  /** Per-item correctness or per-pair cosine, for auditability. */
143
151
  details?: number[];
152
+ /**
153
+ * Raw model outputs per item (MMLU lanes; capped at 400 chars each) so the
154
+ * score is recomputable server-side and parse failures are auditable.
155
+ */
156
+ outputs?: string[];
157
+ /** Fraction of items whose answer was parseable (MMLU lanes). */
158
+ parseRate?: number;
144
159
  }
145
160
  type BenchCellStatus = 'ok' | 'invalid' | 'error' | 'skipped';
146
161
  /** One benchmark cell: (runtime x model x workload) with its raw iterations. */
@@ -162,9 +177,11 @@ interface BenchCellResult {
162
177
  quality?: QualityResult;
163
178
  status: BenchCellStatus;
164
179
  invalidReasons?: string[];
180
+ /** Error that ended the cell; `cause` carries the wrapped provider error's message when present. */
165
181
  error?: {
166
182
  name: string;
167
183
  message: string;
184
+ cause?: string;
168
185
  };
169
186
  }
170
187
  /** Trace events global to the suite run (validity accounting). */
@@ -281,6 +298,16 @@ interface CellSummary {
281
298
  decodeChunksPerSec?: MetricSummary;
282
299
  prefillTokPerSecApprox?: MetricSummary;
283
300
  generatedChars?: MetricSummary;
301
+ /** Request wall time (startT → endT), all LLM lanes. */
302
+ totalMs?: MetricSummary;
303
+ /** End-to-end chars/s over the whole request (prefill + decode conflated). */
304
+ overallCharsPerSec?: MetricSummary;
305
+ /**
306
+ * False when the chunk trace is not genuinely incremental (single chunk, or
307
+ * the visible stream spans <20% of the request) — TTFT and decode metrics
308
+ * are then omitted because they would be timing artifacts, not measurements.
309
+ */
310
+ streamIncremental?: boolean;
284
311
  /** Embedding lanes. */
285
312
  singleLatencyMs?: MetricSummary;
286
313
  batchTextsPerSec?: MetricSummary;
@@ -288,6 +315,8 @@ interface CellSummary {
288
315
  loadMs?: number;
289
316
  loadCached?: boolean;
290
317
  qualityScore?: number;
318
+ /** Fraction of MMLU items whose answer parsed; a low value marks a format failure, not a fidelity one. */
319
+ qualityParseRate?: number;
291
320
  highVariance: boolean;
292
321
  }
293
322
  /** The unit of submission: one full suite run on one device. */
@@ -340,6 +369,14 @@ interface ValidationReport {
340
369
 
341
370
  /** Fixed generation budget for timed lanes (tg128, MLPerf-Client-sized). */
342
371
  declare const GENERATION_BUDGET = 128;
372
+ /**
373
+ * Minimum generated characters for a timed iteration to count as a decode
374
+ * measurement (part of the versioned protocol). An instruct model that emits
375
+ * EOS after a handful of characters - typically an untemplated prompt or a
376
+ * tokenizer mismatch - produces no decode phase to time; such iterations are
377
+ * gated `degenerate-output` and the cell is marked invalid rather than scored.
378
+ */
379
+ declare const MIN_GENERATED_CHARS = 16;
343
380
  /** LLM performance workloads. */
344
381
  declare const LLM_WORKLOADS: readonly LLMWorkloadSpec[];
345
382
  /** Embedding performance workloads. */
@@ -348,6 +385,25 @@ declare const EMBED_WORKLOADS: readonly EmbedWorkloadSpec[];
348
385
  declare const QUALITY_WORKLOADS: readonly QualityWorkloadSpec[];
349
386
  /** All workloads indexed by id. */
350
387
  declare const WORKLOADS_BY_ID: ReadonlyMap<string, LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec>;
388
+ /**
389
+ * Fixed runtime execution order (part of the versioned protocol). This makes
390
+ * the order deterministic so runtime interleaving is not a confounder across
391
+ * runs; it is a reproducibility measure, not a correctness fix. (The
392
+ * Transformers.js ORT-web lanes fail during session creation regardless of
393
+ * where they run in the order - a separate open runtime/adapter issue.) The
394
+ * order runs the WASM-arena runtimes first and the multi-GB-heap runtimes last.
395
+ * Within a runtime, catalog order is preserved.
396
+ */
397
+ declare const RUNTIME_EXECUTION_ORDER: readonly BenchRuntimeId[];
398
+ /**
399
+ * Sort planned cells into the protocol execution order (stable within a
400
+ * runtime). The runner applies this itself; exported for hosts and tests.
401
+ */
402
+ declare function orderCells<T extends {
403
+ model: {
404
+ runtimeId: BenchRuntimeId;
405
+ };
406
+ }>(cells: readonly T[]): T[];
351
407
  /** Run policy for a suite (part of the versioned protocol). */
352
408
  interface RunPolicy {
353
409
  /** Untimed warmup generations per cell (absorbs shader compile/JIT). */
@@ -704,19 +760,40 @@ declare function spearman(a: readonly number[], b: readonly number[]): number;
704
760
  */
705
761
 
706
762
  /** Version of the plausibility rule set (recorded alongside moderation). */
707
- declare const PLAUSIBILITY_RULES_VERSION = 1;
763
+ declare const PLAUSIBILITY_RULES_VERSION = 2;
764
+ /**
765
+ * Minimum fraction of the request that the visible chunk stream must span for
766
+ * the trace to count as incremental. LiteRT-LM's web surface delivers every
767
+ * chunk in a terminal burst (~0.8ms of a 30s request), so TTFT/decode derived
768
+ * from such a trace are timing artifacts; a real token stream spans most of
769
+ * the request by construction.
770
+ */
771
+ declare const STREAM_COHERENCE_MIN_SPAN_RATIO = 0.2;
708
772
  /**
709
773
  * Structural validation of a submitted result. Returns human-readable errors
710
774
  * (empty array = shape ok). Deliberately hand-rolled: this package is
711
775
  * zero-dependency and the checks double as executable schema documentation.
712
776
  */
713
777
  declare function validateRunShape(value: unknown): string[];
778
+ /**
779
+ * True when an iteration's chunk trace is genuinely incremental: at least two
780
+ * chunks, and the visible stream spans at least
781
+ * `STREAM_COHERENCE_MIN_SPAN_RATIO` of the request wall time. Anything else
782
+ * (a doGenerate fallback's single chunk, or a runtime that computes the whole
783
+ * generation and flushes it in a terminal burst) carries no usable TTFT or
784
+ * decode timing.
785
+ */
786
+ declare function isIncrementalStream(it: LLMIteration): boolean;
714
787
  /**
715
788
  * Recompute a cell's summary purely from its raw iteration traces.
716
789
  * This function IS the metric definition:
717
790
  * - TTFT = first non-empty chunk timestamp − startT
718
791
  * - decode rate = (chars after first chunk) / (endT_lastChunk − t_firstChunk)
719
792
  * - prefill tok/s ≈ approxPromptTokens / TTFT (approximate by construction)
793
+ * - overall rate = total chars / (endT − startT), always derivable
794
+ * TTFT/decode/prefill are derived only when EVERY iteration passes the
795
+ * stream-coherence test (`streamIncremental`); overall rate and total wall
796
+ * time are reported for all LLM lanes.
720
797
  */
721
798
  declare function summarizeCell(cell: BenchCellResult, highVarianceCv?: number, approxPromptTokens?: number): CellSummary;
722
799
  /** Recompute all cell summaries for a run (workload prompt sizes looked up). */
@@ -784,11 +861,15 @@ interface LeaderboardRow {
784
861
  /** Median-of-medians metrics (only those applicable to the workload). */
785
862
  ttftMs?: number;
786
863
  decodeCharsPerSec?: number;
864
+ /** End-to-end chars/s (prefill + decode); the only rate for lanes whose stream is not incremental. */
865
+ overallCharsPerSec?: number;
787
866
  singleLatencyMs?: number;
788
867
  batchTextsPerSec?: number;
789
868
  loadColdMs?: number;
790
869
  loadWarmMs?: number;
791
870
  qualityScore?: number;
871
+ /** Median MMLU parse rate; below 1 the quality score is format-limited. */
872
+ qualityParseRate?: number;
792
873
  resolvedBackends: string[];
793
874
  browsers: string[];
794
875
  /** True when any contributing submission had a high-variance metric. */
@@ -843,26 +924,44 @@ declare const TINY_MMLU: readonly MMLUItem[];
843
924
  * model's training data. Always run at temperature 0, outside timed regions.
844
925
  */
845
926
 
846
- /** Fixed MCQ prompt template (part of the versioned protocol). */
847
- declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number]): string;
848
927
  /**
849
- * Parse the answer letter from a model response. Accepts "B", "B.", "(B)",
850
- * "Answer: B", or a response beginning with the exact choice text.
928
+ * Generation budget for MMLU items (part of the versioned protocol). Large
929
+ * enough to absorb an empty Qwen3-style `<think></think>` block plus a
930
+ * verbose "The answer is B." — the v1 budget of 8 truncated before any
931
+ * parseable letter on thinking-mode builds, scoring fidelity as 0.
932
+ */
933
+ declare const MMLU_MAX_TOKENS = 48;
934
+ /** Cap on each stored raw output (auditability without payload bloat). */
935
+ declare const MMLU_OUTPUT_CAP = 400;
936
+ /** Fixed MCQ prompt template (part of the versioned protocol). */
937
+ declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number], promptSuffix?: string): string;
938
+ /**
939
+ * Parse the answer letter from a model response. Reasoning blocks are
940
+ * stripped first; markdown emphasis around the letter is ignored. Accepts
941
+ * "B", "B.", "(B)", "**B**", "Answer: B", "Option C", "choice (B)", or a
942
+ * response beginning with the exact choice text. Letters are matched
943
+ * case-sensitively after a keyword so the article "a" ("the answer is a
944
+ * bit unclear") is never read as answer A; a lowercase letter counts only
945
+ * when it is the whole reply or leads it as "b." / "b)".
851
946
  *
852
947
  * @returns 0-3, or null when no unambiguous answer is present.
853
948
  */
854
949
  declare function parseMMLUAnswer(response: string, choices: readonly string[]): number | null;
855
950
  /**
856
951
  * Run the tinyMMLU fidelity task on a language model (temperature 0,
857
- * `maxTokens` 8, greedy answer parsing). Unparseable answers count as wrong.
952
+ * `MMLU_MAX_TOKENS` budget, greedy answer parsing). Unparseable answers count
953
+ * as wrong; raw outputs and the parse rate are recorded so the score is
954
+ * auditable and recomputable server-side.
858
955
  *
859
956
  * @param model - Any structurally-compatible LanguageModel.
860
- * @param items - Number of items from the 100-item set (25 or 100 in v1).
861
- * @returns Accuracy in [0,1] with per-item correctness details.
957
+ * @param items - Number of items from the 100-item set (25 or 100).
958
+ * @returns Accuracy in [0,1] with per-item correctness details and outputs.
862
959
  */
863
960
  declare function runMMLUFidelity(model: BenchLanguageModel, items: number, options?: {
864
961
  abortSignal?: AbortSignal;
865
962
  onProgress?: (done: number, total: number) => void;
963
+ /** Appended to the instruction line of every item (from the model catalog). */
964
+ promptSuffix?: string;
866
965
  }): Promise<QualityResult>;
867
966
  /**
868
967
  * Run the STS-B embedding-quality task: Spearman correlation of cosine
@@ -898,4 +997,4 @@ interface STSPair {
898
997
  /** 100-pair STS-B test subset (order preserved from the source dataset). */
899
998
  declare const STSB_SUBSET: readonly STSPair[];
900
999
 
901
- export { type AdapterAvailability, type AdapterLoadProgress, BENCH_PROTOCOL_VERSION, BENCH_SCHEMA_VERSION, type BenchCellResult, type BenchCellStatus, type BenchChunk, type BenchEmbeddingModel, type BenchLanguageModel, type BenchModelRef, type BenchRunResult, type BenchRuntimeId, type BenchStreamChunk, type BenchSuiteId, type BenchWorkloadKind, type BenchWorkloadSpec, type BrowserInfo, type CellSummary, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, type MMLUItem, type MemorySample, type MetricSummary, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, mean, median, memoryApiAvailable, parseMMLUAnswer, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };
1000
+ export { type AdapterAvailability, type AdapterLoadProgress, BENCH_PROTOCOL_VERSION, BENCH_SCHEMA_VERSION, type BenchCellResult, type BenchCellStatus, type BenchChunk, type BenchEmbeddingModel, type BenchLanguageModel, type BenchModelRef, type BenchRunResult, type BenchRuntimeId, type BenchStreamChunk, type BenchSuiteId, type BenchWorkloadKind, type BenchWorkloadSpec, type BrowserInfo, type CellSummary, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, MIN_GENERATED_CHARS, type MMLUItem, MMLU_MAX_TOKENS, MMLU_OUTPUT_CAP, type MemorySample, type MetricSummary, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUNTIME_EXECUTION_ORDER, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STREAM_COHERENCE_MIN_SPAN_RATIO, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, isIncrementalStream, mean, median, memoryApiAvailable, orderCells, parseMMLUAnswer, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };
package/dist/index.d.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  * published statistics can be recomputed and audited server-side.
6
6
  */
7
7
  /** Protocol identifier embedded in every result. Bump only with a spec change. */
8
- declare const BENCH_PROTOCOL_VERSION = "localmode-bench/1";
8
+ declare const BENCH_PROTOCOL_VERSION = "localmode-bench/2";
9
9
  /** Result JSON schema version (independent of the protocol semantics version). */
10
- declare const BENCH_SCHEMA_VERSION = 1;
10
+ declare const BENCH_SCHEMA_VERSION = 2;
11
11
  /** Benchmark suite presets. `custom` = user-picked cells. */
12
12
  type BenchSuiteId = 'quick' | 'standard' | 'thorough' | 'custom';
13
13
  /**
@@ -69,6 +69,12 @@ interface BenchModelRef {
69
69
  /** Direct model URL when applicable (wllama GGUF, litert). */
70
70
  url?: string;
71
71
  requiresWebGPU?: boolean;
72
+ /**
73
+ * Appended to the quality-lane instruction line for every runtime of this
74
+ * pairing (e.g. " /no_think" to hold Qwen3 in non-thinking mode). Uniform
75
+ * across runtimes by construction, so fidelity comparisons stay valid.
76
+ */
77
+ qualityPromptSuffix?: string;
72
78
  }
73
79
  /** One recorded stream chunk: wall-clock timestamp + delta length in chars. */
74
80
  interface BenchChunk {
@@ -131,6 +137,8 @@ interface MemorySample {
131
137
  baseline?: number;
132
138
  postLoad?: number;
133
139
  postRun?: number;
140
+ /** Bytes at the moment a cell errored (load or workload failure). */
141
+ atError?: number;
134
142
  api: 'uaSpecific' | 'legacyHeap' | 'none';
135
143
  }
136
144
  /** Quality lane outcome attached to a cell. */
@@ -141,6 +149,13 @@ interface QualityResult {
141
149
  n: number;
142
150
  /** Per-item correctness or per-pair cosine, for auditability. */
143
151
  details?: number[];
152
+ /**
153
+ * Raw model outputs per item (MMLU lanes; capped at 400 chars each) so the
154
+ * score is recomputable server-side and parse failures are auditable.
155
+ */
156
+ outputs?: string[];
157
+ /** Fraction of items whose answer was parseable (MMLU lanes). */
158
+ parseRate?: number;
144
159
  }
145
160
  type BenchCellStatus = 'ok' | 'invalid' | 'error' | 'skipped';
146
161
  /** One benchmark cell: (runtime x model x workload) with its raw iterations. */
@@ -162,9 +177,11 @@ interface BenchCellResult {
162
177
  quality?: QualityResult;
163
178
  status: BenchCellStatus;
164
179
  invalidReasons?: string[];
180
+ /** Error that ended the cell; `cause` carries the wrapped provider error's message when present. */
165
181
  error?: {
166
182
  name: string;
167
183
  message: string;
184
+ cause?: string;
168
185
  };
169
186
  }
170
187
  /** Trace events global to the suite run (validity accounting). */
@@ -281,6 +298,16 @@ interface CellSummary {
281
298
  decodeChunksPerSec?: MetricSummary;
282
299
  prefillTokPerSecApprox?: MetricSummary;
283
300
  generatedChars?: MetricSummary;
301
+ /** Request wall time (startT → endT), all LLM lanes. */
302
+ totalMs?: MetricSummary;
303
+ /** End-to-end chars/s over the whole request (prefill + decode conflated). */
304
+ overallCharsPerSec?: MetricSummary;
305
+ /**
306
+ * False when the chunk trace is not genuinely incremental (single chunk, or
307
+ * the visible stream spans <20% of the request) — TTFT and decode metrics
308
+ * are then omitted because they would be timing artifacts, not measurements.
309
+ */
310
+ streamIncremental?: boolean;
284
311
  /** Embedding lanes. */
285
312
  singleLatencyMs?: MetricSummary;
286
313
  batchTextsPerSec?: MetricSummary;
@@ -288,6 +315,8 @@ interface CellSummary {
288
315
  loadMs?: number;
289
316
  loadCached?: boolean;
290
317
  qualityScore?: number;
318
+ /** Fraction of MMLU items whose answer parsed; a low value marks a format failure, not a fidelity one. */
319
+ qualityParseRate?: number;
291
320
  highVariance: boolean;
292
321
  }
293
322
  /** The unit of submission: one full suite run on one device. */
@@ -340,6 +369,14 @@ interface ValidationReport {
340
369
 
341
370
  /** Fixed generation budget for timed lanes (tg128, MLPerf-Client-sized). */
342
371
  declare const GENERATION_BUDGET = 128;
372
+ /**
373
+ * Minimum generated characters for a timed iteration to count as a decode
374
+ * measurement (part of the versioned protocol). An instruct model that emits
375
+ * EOS after a handful of characters - typically an untemplated prompt or a
376
+ * tokenizer mismatch - produces no decode phase to time; such iterations are
377
+ * gated `degenerate-output` and the cell is marked invalid rather than scored.
378
+ */
379
+ declare const MIN_GENERATED_CHARS = 16;
343
380
  /** LLM performance workloads. */
344
381
  declare const LLM_WORKLOADS: readonly LLMWorkloadSpec[];
345
382
  /** Embedding performance workloads. */
@@ -348,6 +385,25 @@ declare const EMBED_WORKLOADS: readonly EmbedWorkloadSpec[];
348
385
  declare const QUALITY_WORKLOADS: readonly QualityWorkloadSpec[];
349
386
  /** All workloads indexed by id. */
350
387
  declare const WORKLOADS_BY_ID: ReadonlyMap<string, LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec>;
388
+ /**
389
+ * Fixed runtime execution order (part of the versioned protocol). This makes
390
+ * the order deterministic so runtime interleaving is not a confounder across
391
+ * runs; it is a reproducibility measure, not a correctness fix. (The
392
+ * Transformers.js ORT-web lanes fail during session creation regardless of
393
+ * where they run in the order - a separate open runtime/adapter issue.) The
394
+ * order runs the WASM-arena runtimes first and the multi-GB-heap runtimes last.
395
+ * Within a runtime, catalog order is preserved.
396
+ */
397
+ declare const RUNTIME_EXECUTION_ORDER: readonly BenchRuntimeId[];
398
+ /**
399
+ * Sort planned cells into the protocol execution order (stable within a
400
+ * runtime). The runner applies this itself; exported for hosts and tests.
401
+ */
402
+ declare function orderCells<T extends {
403
+ model: {
404
+ runtimeId: BenchRuntimeId;
405
+ };
406
+ }>(cells: readonly T[]): T[];
351
407
  /** Run policy for a suite (part of the versioned protocol). */
352
408
  interface RunPolicy {
353
409
  /** Untimed warmup generations per cell (absorbs shader compile/JIT). */
@@ -704,19 +760,40 @@ declare function spearman(a: readonly number[], b: readonly number[]): number;
704
760
  */
705
761
 
706
762
  /** Version of the plausibility rule set (recorded alongside moderation). */
707
- declare const PLAUSIBILITY_RULES_VERSION = 1;
763
+ declare const PLAUSIBILITY_RULES_VERSION = 2;
764
+ /**
765
+ * Minimum fraction of the request that the visible chunk stream must span for
766
+ * the trace to count as incremental. LiteRT-LM's web surface delivers every
767
+ * chunk in a terminal burst (~0.8ms of a 30s request), so TTFT/decode derived
768
+ * from such a trace are timing artifacts; a real token stream spans most of
769
+ * the request by construction.
770
+ */
771
+ declare const STREAM_COHERENCE_MIN_SPAN_RATIO = 0.2;
708
772
  /**
709
773
  * Structural validation of a submitted result. Returns human-readable errors
710
774
  * (empty array = shape ok). Deliberately hand-rolled: this package is
711
775
  * zero-dependency and the checks double as executable schema documentation.
712
776
  */
713
777
  declare function validateRunShape(value: unknown): string[];
778
+ /**
779
+ * True when an iteration's chunk trace is genuinely incremental: at least two
780
+ * chunks, and the visible stream spans at least
781
+ * `STREAM_COHERENCE_MIN_SPAN_RATIO` of the request wall time. Anything else
782
+ * (a doGenerate fallback's single chunk, or a runtime that computes the whole
783
+ * generation and flushes it in a terminal burst) carries no usable TTFT or
784
+ * decode timing.
785
+ */
786
+ declare function isIncrementalStream(it: LLMIteration): boolean;
714
787
  /**
715
788
  * Recompute a cell's summary purely from its raw iteration traces.
716
789
  * This function IS the metric definition:
717
790
  * - TTFT = first non-empty chunk timestamp − startT
718
791
  * - decode rate = (chars after first chunk) / (endT_lastChunk − t_firstChunk)
719
792
  * - prefill tok/s ≈ approxPromptTokens / TTFT (approximate by construction)
793
+ * - overall rate = total chars / (endT − startT), always derivable
794
+ * TTFT/decode/prefill are derived only when EVERY iteration passes the
795
+ * stream-coherence test (`streamIncremental`); overall rate and total wall
796
+ * time are reported for all LLM lanes.
720
797
  */
721
798
  declare function summarizeCell(cell: BenchCellResult, highVarianceCv?: number, approxPromptTokens?: number): CellSummary;
722
799
  /** Recompute all cell summaries for a run (workload prompt sizes looked up). */
@@ -784,11 +861,15 @@ interface LeaderboardRow {
784
861
  /** Median-of-medians metrics (only those applicable to the workload). */
785
862
  ttftMs?: number;
786
863
  decodeCharsPerSec?: number;
864
+ /** End-to-end chars/s (prefill + decode); the only rate for lanes whose stream is not incremental. */
865
+ overallCharsPerSec?: number;
787
866
  singleLatencyMs?: number;
788
867
  batchTextsPerSec?: number;
789
868
  loadColdMs?: number;
790
869
  loadWarmMs?: number;
791
870
  qualityScore?: number;
871
+ /** Median MMLU parse rate; below 1 the quality score is format-limited. */
872
+ qualityParseRate?: number;
792
873
  resolvedBackends: string[];
793
874
  browsers: string[];
794
875
  /** True when any contributing submission had a high-variance metric. */
@@ -843,26 +924,44 @@ declare const TINY_MMLU: readonly MMLUItem[];
843
924
  * model's training data. Always run at temperature 0, outside timed regions.
844
925
  */
845
926
 
846
- /** Fixed MCQ prompt template (part of the versioned protocol). */
847
- declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number]): string;
848
927
  /**
849
- * Parse the answer letter from a model response. Accepts "B", "B.", "(B)",
850
- * "Answer: B", or a response beginning with the exact choice text.
928
+ * Generation budget for MMLU items (part of the versioned protocol). Large
929
+ * enough to absorb an empty Qwen3-style `<think></think>` block plus a
930
+ * verbose "The answer is B." — the v1 budget of 8 truncated before any
931
+ * parseable letter on thinking-mode builds, scoring fidelity as 0.
932
+ */
933
+ declare const MMLU_MAX_TOKENS = 48;
934
+ /** Cap on each stored raw output (auditability without payload bloat). */
935
+ declare const MMLU_OUTPUT_CAP = 400;
936
+ /** Fixed MCQ prompt template (part of the versioned protocol). */
937
+ declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number], promptSuffix?: string): string;
938
+ /**
939
+ * Parse the answer letter from a model response. Reasoning blocks are
940
+ * stripped first; markdown emphasis around the letter is ignored. Accepts
941
+ * "B", "B.", "(B)", "**B**", "Answer: B", "Option C", "choice (B)", or a
942
+ * response beginning with the exact choice text. Letters are matched
943
+ * case-sensitively after a keyword so the article "a" ("the answer is a
944
+ * bit unclear") is never read as answer A; a lowercase letter counts only
945
+ * when it is the whole reply or leads it as "b." / "b)".
851
946
  *
852
947
  * @returns 0-3, or null when no unambiguous answer is present.
853
948
  */
854
949
  declare function parseMMLUAnswer(response: string, choices: readonly string[]): number | null;
855
950
  /**
856
951
  * Run the tinyMMLU fidelity task on a language model (temperature 0,
857
- * `maxTokens` 8, greedy answer parsing). Unparseable answers count as wrong.
952
+ * `MMLU_MAX_TOKENS` budget, greedy answer parsing). Unparseable answers count
953
+ * as wrong; raw outputs and the parse rate are recorded so the score is
954
+ * auditable and recomputable server-side.
858
955
  *
859
956
  * @param model - Any structurally-compatible LanguageModel.
860
- * @param items - Number of items from the 100-item set (25 or 100 in v1).
861
- * @returns Accuracy in [0,1] with per-item correctness details.
957
+ * @param items - Number of items from the 100-item set (25 or 100).
958
+ * @returns Accuracy in [0,1] with per-item correctness details and outputs.
862
959
  */
863
960
  declare function runMMLUFidelity(model: BenchLanguageModel, items: number, options?: {
864
961
  abortSignal?: AbortSignal;
865
962
  onProgress?: (done: number, total: number) => void;
963
+ /** Appended to the instruction line of every item (from the model catalog). */
964
+ promptSuffix?: string;
866
965
  }): Promise<QualityResult>;
867
966
  /**
868
967
  * Run the STS-B embedding-quality task: Spearman correlation of cosine
@@ -898,4 +997,4 @@ interface STSPair {
898
997
  /** 100-pair STS-B test subset (order preserved from the source dataset). */
899
998
  declare const STSB_SUBSET: readonly STSPair[];
900
999
 
901
- export { type AdapterAvailability, type AdapterLoadProgress, BENCH_PROTOCOL_VERSION, BENCH_SCHEMA_VERSION, type BenchCellResult, type BenchCellStatus, type BenchChunk, type BenchEmbeddingModel, type BenchLanguageModel, type BenchModelRef, type BenchRunResult, type BenchRuntimeId, type BenchStreamChunk, type BenchSuiteId, type BenchWorkloadKind, type BenchWorkloadSpec, type BrowserInfo, type CellSummary, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, type MMLUItem, type MemorySample, type MetricSummary, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, mean, median, memoryApiAvailable, parseMMLUAnswer, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };
1000
+ export { type AdapterAvailability, type AdapterLoadProgress, BENCH_PROTOCOL_VERSION, BENCH_SCHEMA_VERSION, type BenchCellResult, type BenchCellStatus, type BenchChunk, type BenchEmbeddingModel, type BenchLanguageModel, type BenchModelRef, type BenchRunResult, type BenchRuntimeId, type BenchStreamChunk, type BenchSuiteId, type BenchWorkloadKind, type BenchWorkloadSpec, type BrowserInfo, type CellSummary, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, MIN_GENERATED_CHARS, type MMLUItem, MMLU_MAX_TOKENS, MMLU_OUTPUT_CAP, type MemorySample, type MetricSummary, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUNTIME_EXECUTION_ORDER, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STREAM_COHERENCE_MIN_SPAN_RATIO, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, isIncrementalStream, mean, median, memoryApiAvailable, orderCells, parseMMLUAnswer, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };