@tangle-network/agent-eval 0.86.0 → 0.90.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/adapters/http.d.ts +3 -3
  3. package/dist/adapters/langchain.d.ts +3 -3
  4. package/dist/adapters/otel.d.ts +6 -6
  5. package/dist/adversarial-DIVcDoI_.d.ts +88 -0
  6. package/dist/analyst/index.d.ts +11 -10
  7. package/dist/analyst/index.js +13 -8
  8. package/dist/analyst/index.js.map +1 -1
  9. package/dist/analyze-runs-DwCEkpO_.d.ts +81 -0
  10. package/dist/belief-state/index.d.ts +4 -4
  11. package/dist/belief-state/index.js +1 -1
  12. package/dist/benchmarks/index.d.ts +3 -3
  13. package/dist/campaign/index.d.ts +165 -18
  14. package/dist/campaign/index.js +289 -14
  15. package/dist/campaign/index.js.map +1 -1
  16. package/dist/chunk-45EEMHTC.js +35 -0
  17. package/dist/chunk-45EEMHTC.js.map +1 -0
  18. package/dist/{chunk-FZWAFVAA.js → chunk-4FBZZIYD.js} +2 -2
  19. package/dist/{chunk-YV7J7X5N.js → chunk-5HRORJQY.js} +22 -12
  20. package/dist/chunk-5HRORJQY.js.map +1 -0
  21. package/dist/{chunk-OTYQPHPL.js → chunk-6SOJM3VR.js} +5 -5
  22. package/dist/chunk-BOD4O7OF.js +40 -0
  23. package/dist/chunk-BOD4O7OF.js.map +1 -0
  24. package/dist/{chunk-Z7VFTS2J.js → chunk-CY6U5S3X.js} +2 -2
  25. package/dist/{chunk-VIDQF3F5.js → chunk-D3V5B42D.js} +5 -34
  26. package/dist/chunk-D3V5B42D.js.map +1 -0
  27. package/dist/{chunk-YGYXHNAQ.js → chunk-FIUKOSWI.js} +21 -8
  28. package/dist/chunk-FIUKOSWI.js.map +1 -0
  29. package/dist/{chunk-WJL2NJXN.js → chunk-GSH6QNNS.js} +2 -2
  30. package/dist/{chunk-RBNA5AZT.js → chunk-L3JOU6XM.js} +2 -2
  31. package/dist/{chunk-IDVBLYCY.js → chunk-LMZQ2Z4U.js} +56 -2
  32. package/dist/{chunk-IDVBLYCY.js.map → chunk-LMZQ2Z4U.js.map} +1 -1
  33. package/dist/{chunk-VUINJM5M.js → chunk-QAY5UIJO.js} +2 -193
  34. package/dist/chunk-QAY5UIJO.js.map +1 -0
  35. package/dist/{chunk-P2J6SOXT.js → chunk-QG2OVF2D.js} +5 -3
  36. package/dist/{chunk-P2J6SOXT.js.map → chunk-QG2OVF2D.js.map} +1 -1
  37. package/dist/chunk-REVYNR6C.js +100 -0
  38. package/dist/chunk-REVYNR6C.js.map +1 -0
  39. package/dist/chunk-STGVSCDH.js +202 -0
  40. package/dist/chunk-STGVSCDH.js.map +1 -0
  41. package/dist/{chunk-ZZ2HOPME.js → chunk-TWS7AZEY.js} +2 -2
  42. package/dist/chunk-UHMJT4T7.js +200 -0
  43. package/dist/chunk-UHMJT4T7.js.map +1 -0
  44. package/dist/chunk-UMMZHCPB.js +190 -0
  45. package/dist/chunk-UMMZHCPB.js.map +1 -0
  46. package/dist/chunk-VZSRQ272.js +149 -0
  47. package/dist/chunk-VZSRQ272.js.map +1 -0
  48. package/dist/{chunk-L5G7OUKD.js → chunk-XY4DDNEG.js} +8 -190
  49. package/dist/chunk-XY4DDNEG.js.map +1 -0
  50. package/dist/chunk-Y47J2LJ3.js +859 -0
  51. package/dist/chunk-Y47J2LJ3.js.map +1 -0
  52. package/dist/{chunk-BABOZOSN.js → chunk-ZFIBGEOL.js} +3 -3
  53. package/dist/chunk-ZFIBGEOL.js.map +1 -0
  54. package/dist/{code-agent-session-BRXmavYv.d.ts → code-agent-session-BO8nCnv3.d.ts} +1 -1
  55. package/dist/contract/index.d.ts +24 -95
  56. package/dist/contract/index.js +25 -764
  57. package/dist/contract/index.js.map +1 -1
  58. package/dist/{control-GeE8OhpN.d.ts → control-_Qb7skHX.d.ts} +2 -2
  59. package/dist/control.d.ts +5 -5
  60. package/dist/corpus-BoR-041R.d.ts +560 -0
  61. package/dist/cost-ledger-DuSqlw5B.d.ts +113 -0
  62. package/dist/counterfactual-Dwibr5IW.d.ts +85 -0
  63. package/dist/{dataset-B2kL-fSM.d.ts → dataset-BbGkaN2I.d.ts} +1 -1
  64. package/dist/{registry-DrEQ3Luj.d.ts → default-registry-zoGHUQEH.d.ts} +29 -2
  65. package/dist/diagnose.d.ts +251 -0
  66. package/dist/diagnose.js +381 -0
  67. package/dist/diagnose.js.map +1 -0
  68. package/dist/{errors-Dwqw-T_m.d.ts → errors-CzMUYo7b.d.ts} +1 -1
  69. package/dist/{feedback-trajectory-B3rErRsh.d.ts → feedback-trajectory-D9OVLrg9.d.ts} +1 -1
  70. package/dist/fuzz.d.ts +484 -0
  71. package/dist/fuzz.js +613 -0
  72. package/dist/fuzz.js.map +1 -0
  73. package/dist/governance/index.d.ts +4 -4
  74. package/dist/hosted/index.d.ts +6 -6
  75. package/dist/{index-DE3RXAXD.d.ts → index-Bx3gZ8xl.d.ts} +1 -1
  76. package/dist/index.d.ts +718 -455
  77. package/dist/index.js +1604 -793
  78. package/dist/index.js.map +1 -1
  79. package/dist/{insight-report-3ADTfClO.d.ts → insight-report-BBwvOh6x.d.ts} +2 -2
  80. package/dist/{integrity-CJzrpUua.d.ts → integrity-VJ9A7aST.d.ts} +1 -1
  81. package/dist/{judge-calibration-DilmB3Ml.d.ts → judge-calibration-0p2QcWNE.d.ts} +1 -1
  82. package/dist/{kind-factory-CVecZZG_.d.ts → kind-factory-5b7xXXOr.d.ts} +2 -2
  83. package/dist/{llm-client-CuUg2Mn3.d.ts → llm-client-BeEcAokY.d.ts} +1 -1
  84. package/dist/matrix/index.d.ts +2 -2
  85. package/dist/meta-eval/index.d.ts +177 -3
  86. package/dist/meta-eval/index.js +260 -1
  87. package/dist/meta-eval/index.js.map +1 -1
  88. package/dist/{multi-layer-verifier-DlWCXuxL.d.ts → multi-layer-verifier-DUZXrPDA.d.ts} +7 -1
  89. package/dist/multishot/index.d.ts +25 -11
  90. package/dist/multishot/index.js +36 -7
  91. package/dist/multishot/index.js.map +1 -1
  92. package/dist/openapi.json +1 -1
  93. package/dist/perf/index.d.ts +123 -0
  94. package/dist/perf/index.js +18 -0
  95. package/dist/pipelines/index.js +2 -2
  96. package/dist/{agent-profile-D0PBIWlV.d.ts → pre-registration-DELOEJ8v.d.ts} +144 -4
  97. package/dist/{provenance-DPpNIOJD.d.ts → provenance-LnqRT0sS.d.ts} +5 -5
  98. package/dist/{red-team-DW9Ca_tj.d.ts → red-team-BXHil6c8.d.ts} +1 -1
  99. package/dist/{release-report-hlNtD12q.d.ts → release-report-euXIV_Sk.d.ts} +3 -3
  100. package/dist/reporting.d.ts +8 -8
  101. package/dist/reporting.js +3 -3
  102. package/dist/{researcher-BLPHBbNV.d.ts → researcher-DE6Gpnb4.d.ts} +4 -4
  103. package/dist/rl.d.ts +194 -656
  104. package/dist/rl.js +231 -149
  105. package/dist/rl.js.map +1 -1
  106. package/dist/{rubric-predictive-validity-CnEl9Jc8.d.ts → rubric-predictive-validity-Cy_W-hWZ.d.ts} +1 -1
  107. package/dist/{run-campaign-4Y5V5CN3.js → run-campaign-RDGAM5KJ.js} +3 -3
  108. package/dist/run-campaign-RDGAM5KJ.js.map +1 -0
  109. package/dist/{run-improvement-loop-CNqQckTj.d.ts → run-improvement-loop-5z_l5zDz.d.ts} +2 -2
  110. package/dist/{run-record-De9VarXR.d.ts → run-record-e7vj1uZQ.d.ts} +1 -1
  111. package/dist/{runtime-trajectory-BLRiaifm.d.ts → runtime-trajectory-BDgfGZSr.d.ts} +1 -1
  112. package/dist/{semantic-concept-judge-DIEgr_6v.d.ts → semantic-concept-judge-Dn8Z6KEG.d.ts} +5 -31
  113. package/dist/series-convergence-D5OWMBg6.d.ts +33 -0
  114. package/dist/{statistics-CnC1FMbx.d.ts → statistics-C7PozGrZ.d.ts} +71 -2
  115. package/dist/{summary-report-Db0dDSWP.d.ts → summary-report-DGmUucwQ.d.ts} +1 -1
  116. package/dist/traces.d.ts +3 -3
  117. package/dist/traces.js +8 -6
  118. package/dist/{types-Cu3u_x59.d.ts → types-2VVIL04s.d.ts} +2 -2
  119. package/dist/{types-D7lLRYe9.d.ts → types-BU-7W85F.d.ts} +21 -1
  120. package/dist/{types-CqPax19X.d.ts → types-mn5Aqk7x.d.ts} +1 -1
  121. package/dist/{verdict-CeEgtjyI.d.ts → verdict-C9MlYujm.d.ts} +3 -0
  122. package/dist/wire/index.d.ts +3 -3
  123. package/dist/workflow/index.d.ts +12 -11
  124. package/dist/workflow/index.js +1 -1
  125. package/package.json +16 -1
  126. package/dist/chunk-BABOZOSN.js.map +0 -1
  127. package/dist/chunk-L5G7OUKD.js.map +0 -1
  128. package/dist/chunk-SHTXZ4O2.js +0 -113
  129. package/dist/chunk-SHTXZ4O2.js.map +0 -1
  130. package/dist/chunk-VIDQF3F5.js.map +0 -1
  131. package/dist/chunk-VUINJM5M.js.map +0 -1
  132. package/dist/chunk-YGYXHNAQ.js.map +0 -1
  133. package/dist/chunk-YV7J7X5N.js.map +0 -1
  134. /package/dist/{chunk-FZWAFVAA.js.map → chunk-4FBZZIYD.js.map} +0 -0
  135. /package/dist/{chunk-OTYQPHPL.js.map → chunk-6SOJM3VR.js.map} +0 -0
  136. /package/dist/{chunk-Z7VFTS2J.js.map → chunk-CY6U5S3X.js.map} +0 -0
  137. /package/dist/{chunk-WJL2NJXN.js.map → chunk-GSH6QNNS.js.map} +0 -0
  138. /package/dist/{chunk-RBNA5AZT.js.map → chunk-L3JOU6XM.js.map} +0 -0
  139. /package/dist/{chunk-ZZ2HOPME.js.map → chunk-TWS7AZEY.js.map} +0 -0
  140. /package/dist/{run-campaign-4Y5V5CN3.js.map → perf/index.js.map} +0 -0
package/dist/rl.d.ts CHANGED
@@ -1,22 +1,26 @@
1
1
  export { O as OffPolicyEstimate, a as OffPolicyOptions, b as OffPolicyTrajectory, d as doublyRobust, i as inverseProbabilityWeighting, o as offPolicyEstimateAll, s as selfNormalizedImportanceWeighting } from './off-policy-DiwuKKg7.js';
2
- import { R as RunRecord, a as RunSplitTag } from './run-record-De9VarXR.js';
3
- import { g as CampaignResult } from './types-D7lLRYe9.js';
4
- import { a as VerificationReport } from './multi-layer-verifier-DlWCXuxL.js';
5
- import { S as Span } from './schema-m0gsnbt3.js';
6
- import { T as TraceStore } from './store-CKUAgsJz.js';
2
+ import { P as PreferenceExtractionReport, D as DpoExportRow, G as GrpoExportRow, S as SftExportRow, E as ExtractPreferencesOptions, a as DpoLookups, b as GrpoLookups, c as SftLookups } from './corpus-BoR-041R.js';
3
+ export { d as CorpusAppendResult, C as CorpusRecord, e as DatasetFormat, f as ExtractStepRewardsOptions, H as HarvestOptions, g as PreferenceStrategy, h as PreferenceTriple, i as PrmExportRow, j as PrmLookups, k as PrmTrainingTriple, R as RewardKind, l as RewardStats, m as RlDatasetBundle, n as RlDatasetConfig, o as RlDatasetManifest, p as RlDatasetStats, q as RunwiseStepSummary, r as StepReward, s as StepRewardJsonlRow, t as StepScorer, u as appendToCorpus, v as buildDatasetFromCorpus, w as buildRlDataset, x as datasheetToMarkdown, y as extractPreferences, z as extractStepRewards, A as prmTrainingPairs, B as readCorpus, F as runwiseStepRewardSummary, I as stepRewardsToJsonl, J as toAnthropicFormat, K as toDpoJsonl, L as toDpoRows, M as toGrpoJsonl, N as toGrpoRows, O as toPrmJsonl, Q as toPrmRows, T as toSftJsonl, U as toSftRows, V as toTRLFormat } from './corpus-BoR-041R.js';
4
+ import { g as CampaignResult } from './types-BU-7W85F.js';
5
+ import { a as RunSplitTag, R as RunRecord } from './run-record-e7vj1uZQ.js';
6
+ import { a as VerificationReport } from './multi-layer-verifier-DUZXrPDA.js';
7
+ export { A as AdversarialMutation, a as AdversarialScenario, b as AdversarialSearchOptions, c as AdversarialSearchReport, d as adversarialScenarioSearch } from './adversarial-DIVcDoI_.js';
7
8
  import { b as OutcomeStore } from './outcome-store-rnXLEqSn.js';
8
9
  export { D as DeploymentOutcome, F as FileSystemOutcomeStore, a as FileSystemOutcomeStoreOptions, I as InMemoryOutcomeStore } from './outcome-store-rnXLEqSn.js';
9
- import { b as RubricPredictiveValidityReport } from './rubric-predictive-validity-CnEl9Jc8.js';
10
- import { R as Researcher, F as FailureMode, S as SteeringChange, E as ExperimentPlan, a as ExperimentResult, b as EvalCampaignResult, c as EvalCampaignOptions } from './researcher-BLPHBbNV.js';
11
- export { r as runEvalCampaign } from './researcher-BLPHBbNV.js';
10
+ import { b as RubricPredictiveValidityReport } from './rubric-predictive-validity-Cy_W-hWZ.js';
11
+ import { R as Researcher, F as FailureMode, S as SteeringChange, E as ExperimentPlan, a as ExperimentResult, b as EvalCampaignResult, c as EvalCampaignOptions } from './researcher-DE6Gpnb4.js';
12
+ export { r as runEvalCampaign } from './researcher-DE6Gpnb4.js';
12
13
  import { I as InterimReleaseConfidence } from './sequential-5iSVfzl2.js';
13
- import './errors-Dwqw-T_m.js';
14
- import './llm-client-CuUg2Mn3.js';
14
+ import './schema-m0gsnbt3.js';
15
+ import './store-CKUAgsJz.js';
16
+ import './errors-CzMUYo7b.js';
17
+ import './verdict-C9MlYujm.js';
18
+ import './llm-client-BeEcAokY.js';
15
19
  import './raw-provider-sink-C46HDghv.js';
16
- import './summary-report-Db0dDSWP.js';
20
+ import './summary-report-DGmUucwQ.js';
17
21
  import './failure-cluster-CL7IVgkJ.js';
18
22
  import './emitter-DEZwY14K.js';
19
- import './integrity-CJzrpUua.js';
23
+ import './integrity-VJ9A7aST.js';
20
24
 
21
25
  /**
22
26
  * Test-time compute scaling curves.
@@ -262,147 +266,6 @@ declare function injectIrrelevantClause<S extends {
262
266
  prompt: string;
263
267
  }>(clause: string, position?: 'prefix' | 'suffix'): ScenarioPerturbation<S>;
264
268
 
265
- /**
266
- * Preference dataset extraction — bridge from `RunRecord[]` to RL training.
267
- *
268
- * Production RLHF / DPO / KTO / SimPO pipelines need preference triples:
269
- * `(prompt, chosen, rejected)`. The campaign artifact already contains the
270
- * ingredients — every (variantId, scenarioId, seed) cell is a candidate
271
- * that ran the same prompt against the same scenario, scored by the same
272
- * judge — but turning that into a clean preference dataset requires
273
- * deciding *what counts as a preference*.
274
- *
275
- * This module ships three preference-extraction strategies with explicit
276
- * tradeoffs, plus a unified output type compatible with HuggingFace TRL,
277
- * Anthropic finetuning JSONL, and OpenAI fine-tuning APIs. The strategies
278
- * are deliberately not auto-magical — picking the wrong one corrupts the
279
- * gradient.
280
- *
281
- * Strategies:
282
- *
283
- * 1. **`paired-by-scenario-and-seed`** — exact-match comparisons. For
284
- * each scenario × seed pair, compare every (variantA, variantB) on
285
- * that exact (scenario, seed). Matches scenarios so the comparison
286
- * isolates variant effects. Highest signal-to-noise; smallest
287
- * dataset (only matched pairs count).
288
- *
289
- * 2. **`paired-by-scenario`** — looser matching. For each scenario,
290
- * compare every (variantA, variantB) where both have ≥ 1 run on the
291
- * same scenario. Aggregates across seeds to compute mean scores per
292
- * (variant, scenario), then forms preferences from the means. More
293
- * data, lower per-pair signal.
294
- *
295
- * 3. **`top-vs-bottom`** — coarsest. Within each scenario, the highest-
296
- * scoring run is `chosen`, the lowest is `rejected`. Smallest dataset
297
- * per scenario but biggest score gap per pair. Useful for early
298
- * bootstrapping when you have few variants.
299
- *
300
- * The output `PreferenceTriple` is *agent-eval-canonical* but trivially
301
- * mappable to TRL's `DPODataset` shape (`prompt`, `chosen`, `rejected`)
302
- * via the `toTRLFormat` helper.
303
- */
304
-
305
- type PreferenceStrategy = 'paired-by-scenario-and-seed' | 'paired-by-scenario' | 'top-vs-bottom';
306
- interface PreferenceTriple {
307
- /** The scenario (input) the variants were run against. */
308
- scenarioId: string;
309
- /** RunRecord ids on each side, for traceability. */
310
- chosenRunId: string;
311
- rejectedRunId: string;
312
- /** Variant ids — load-bearing for the RL update. */
313
- chosenVariantId: string;
314
- rejectedVariantId: string;
315
- /** The score gap between chosen and rejected. Larger = stronger signal. */
316
- marginScore: number;
317
- /**
318
- * Optional `(chosen_score, rejected_score)` pair for soft-margin DPO
319
- * variants. Omitted for `top-vs-bottom` runs that don't carry meaningful
320
- * scalar gaps.
321
- */
322
- scores?: {
323
- chosen: number;
324
- rejected: number;
325
- };
326
- /** Tie-breaker — when multiple seeds match this scenario, the one used. */
327
- seed?: number;
328
- /**
329
- * Free-form metadata propagated from the run records — e.g. original
330
- * prompt-hash, model, etc. Lets the RL trainer reconstruct the prompt.
331
- */
332
- meta: {
333
- chosenPromptHash: string;
334
- rejectedPromptHash: string;
335
- chosenConfigHash: string;
336
- rejectedConfigHash: string;
337
- chosenModel: string;
338
- rejectedModel: string;
339
- };
340
- }
341
- interface ExtractPreferencesOptions {
342
- strategy?: PreferenceStrategy;
343
- /**
344
- * Minimum score gap required to admit a pair. Pairs below this are
345
- * dropped — they're noise, not signal. Default 0.05 (5% of [0,1]).
346
- */
347
- minMargin?: number;
348
- /**
349
- * Optional split tag filter — restrict to runs from one split. Default
350
- * `'holdout'` (the canonical "real" signal).
351
- */
352
- splitTag?: RunRecord['splitTag'];
353
- /**
354
- * Optional reward extractor that overrides `outcome.holdoutScore` /
355
- * `outcome.searchScore`. Use to drive preferences off a verifiable
356
- * reward instead of the headline score.
357
- */
358
- rewardOf?: (run: RunRecord) => number | null;
359
- }
360
- interface PreferenceExtractionReport {
361
- pairs: PreferenceTriple[];
362
- /** Number of (scenario, seed) cells inspected. */
363
- cellsInspected: number;
364
- /** Number of pairs filtered by `minMargin`. */
365
- pairsBelowMargin: number;
366
- /** Number of cells with only one variant (no comparison possible). */
367
- cellsSingleton: number;
368
- /** Strategy used. */
369
- strategy: PreferenceStrategy;
370
- }
371
- /**
372
- * Convert `RunRecord[]` to preference triples for RL training.
373
- *
374
- * Returns a structured report so callers can see how much data was
375
- * dropped and why (low-margin pairs, singleton cells). For production
376
- * pipelines, you usually want to:
377
- *
378
- * 1. Run a campaign producing 5–10 variants × 50–200 scenarios × 3 seeds
379
- * 2. Call this with `strategy: 'paired-by-scenario-and-seed'` and a
380
- * verifiable-reward extractor as `rewardOf`
381
- * 3. Pass `report.pairs` to `toTRLFormat` and pipe to your DPO trainer
382
- */
383
- declare function extractPreferences(runs: RunRecord[], opts?: ExtractPreferencesOptions): PreferenceExtractionReport;
384
- /**
385
- * TRL-compatible export. TRL's `DPODataset` is `{ prompt, chosen, rejected }`
386
- * but the prompt isn't stored on the RunRecord — only its hash. The caller
387
- * passes a `promptOf(promptHash)` lookup that the TRL trainer can use.
388
- */
389
- declare function toTRLFormat(triples: PreferenceTriple[], promptOf: (hash: string) => string): Array<{
390
- prompt: string;
391
- chosen: string;
392
- rejected: string;
393
- }>;
394
- /**
395
- * Anthropic finetuning JSONL export — `{ system, user, assistant_chosen, assistant_rejected }`
396
- * shape. Same caveat as TRL: prompt + outputs are content the caller has
397
- * to map back from the run record / raw event log.
398
- */
399
- declare function toAnthropicFormat(triples: PreferenceTriple[]): Array<{
400
- scenarioId: string;
401
- chosenRunId: string;
402
- rejectedRunId: string;
403
- margin: number;
404
- }>;
405
-
406
269
  /**
407
270
  * Adapters: convert measurement outputs into the canonical `RunRecord[]`
408
271
  * artifact that `replayCache`, `pairedEvalueSequence`, and
@@ -624,7 +487,17 @@ interface VerifiableReward {
624
487
  /** The layer / judge id that produced the signal, for provenance. */
625
488
  origin: string;
626
489
  /**
627
- * Any per-source breakdown the consumer might want e.g. `{ tests_passed: 7, tests_total: 10 }`.
490
+ * Per-source contribution to `value`, keyed by layer/judge id. Single-source
491
+ * rewards carry one entry (`{ [origin]: value }`); composite rewards carry
492
+ * every contributing layer's score — the anti-scalar-collapse surface RL
493
+ * consumers weight per-source instead of trusting one blended number.
494
+ */
495
+ components: Record<string, number>;
496
+ /**
497
+ * @deprecated Read `components` for per-source reward values. Kept for
498
+ * published-API compatibility: single-source rewards carry the layer's
499
+ * diagnostics here (e.g. `{ tests_passed: 7 }`); composite rewards carry
500
+ * the same per-layer scores `components` now holds.
628
501
  */
629
502
  breakdown?: Record<string, number>;
630
503
  }
@@ -904,507 +777,6 @@ declare function compareAdaptationCurves(a: AdaptationCurve, b: AdaptationCurve,
904
777
  /** First k at which the curve's per-scenario pass rate reliably hits the threshold. */
905
778
  declare function firstPassK(curve: AdaptationCurve, threshold?: number): number | null;
906
779
 
907
- /**
908
- * Adversarial scenario search.
909
- *
910
- * Capability evaluation on a fixed scenario set measures performance on
911
- * the distribution someone curated. Production failure modes live in the
912
- * tail — inputs the curator didn't think of, or actively avoided. The
913
- * adversarial-search primitive actively looks for them: starting from a
914
- * pool of scenarios where the policy already passes, it mutates them
915
- * (paraphrase, edge-case substitution, compositional combination) and
916
- * keeps the mutations that *break* the policy.
917
- *
918
- * This is not magic. It's the simplest version of the loop that AdA
919
- * (Open-Ended Adaptation, DeepMind 2023), POET, and Anthropic's
920
- * auto-jailbreak rigs all run: hill-climb against a failure indicator,
921
- * keep the survivors, repeat. We ship the harness; consumers supply the
922
- * mutation strategies and the failure detector.
923
- *
924
- * Why ship this in agent-eval and not as a separate red-team tool: every
925
- * piece of the standard adversarial loop is already in this package
926
- * (`runEvalCampaign` for the matrix run, `RawProviderSink` for capture,
927
- * `assertRunCaptured` for integrity, `pairedEvalueSequence` for stop
928
- * criteria). The adversarial primitive is just the *scenario-mutation
929
- * meta-loop* on top of that machinery.
930
- */
931
- interface AdversarialScenario<S> {
932
- /** Stable id — used for deduplication and lineage tracking. */
933
- id: string;
934
- /** Generation index — 0 for seeds, 1 for first round of mutations, etc. */
935
- generation: number;
936
- /** Lineage — id of the parent scenario this was mutated from, if any. */
937
- parentId: string | null;
938
- scenario: S;
939
- /** Score on the policy under test. Lower = adversarial signal. */
940
- score: number | null;
941
- /** Strategy that produced this mutation, for diagnostics. */
942
- mutationStrategy: string | null;
943
- }
944
- interface AdversarialMutation<S> {
945
- id: string;
946
- /**
947
- * Mutate one scenario. Return null to skip; return one or more new
948
- * scenarios. The harness deduplicates by `mutateScenarioId(scenario)`.
949
- */
950
- mutate(parent: S, rng: () => number): Promise<S[]> | S[];
951
- }
952
- interface AdversarialSearchOptions<S> {
953
- /** Initial scenarios — typically those the policy currently passes. */
954
- seeds: S[];
955
- /** Stable identifier extraction. */
956
- mutateScenarioId: (s: S) => string;
957
- /** Mutation strategies. */
958
- mutations: AdversarialMutation<S>[];
959
- /**
960
- * Run the policy under test against one scenario, return a scalar score
961
- * in [0, 1]. Lower = adversarial signal.
962
- */
963
- scoreFn: (s: S) => Promise<number>;
964
- /**
965
- * Threshold below which a scenario counts as a "failure" worth keeping.
966
- * Default 0.5.
967
- */
968
- failureThreshold?: number;
969
- /** Number of mutation rounds. Default 3. */
970
- rounds?: number;
971
- /** Children per parent per round. Default 4. */
972
- childrenPerParent?: number;
973
- /** Maximum total scenarios examined. Default Infinity. */
974
- budget?: number;
975
- /** Seed for the deterministic RNG. Default 1. */
976
- seed?: number;
977
- }
978
- interface AdversarialSearchReport<S> {
979
- scenarios: AdversarialScenario<S>[];
980
- /** Discovered failures sorted by score ascending. */
981
- failures: AdversarialScenario<S>[];
982
- /** Round-by-round counts. */
983
- byGeneration: Array<{
984
- generation: number;
985
- total: number;
986
- failures: number;
987
- meanScore: number;
988
- }>;
989
- /** Total scoreFn invocations consumed. */
990
- scoreCalls: number;
991
- }
992
- declare function adversarialScenarioSearch<S>(opts: AdversarialSearchOptions<S>): Promise<AdversarialSearchReport<S>>;
993
-
994
- /**
995
- * Process reward extraction — step-level credit assignment from trace spans.
996
- *
997
- * RL on long-horizon agents needs *step-level* rewards, not run-level
998
- * ones. The classic credit-assignment problem (Sutton & Barto) requires
999
- * knowing which sub-decisions in a trajectory contributed to the
1000
- * outcome. Modern systems (DeepSeek-R1, OpenAI o-series, Lightman et al.
1001
- * "Let's Verify Step by Step" 2023) train *process reward models* (PRMs)
1002
- * that score every step, then do RL with the PRM as the reward signal.
1003
- *
1004
- * This module extracts `StepReward[]` from trace spans — one per
1005
- * meaningful step — and ships:
1006
- *
1007
- * 1. `extractStepRewards(store, runId, opts)` — span → step-reward
1008
- * conversion using configurable per-span scorers (LLM judge over the
1009
- * span output, deterministic checkers, or a learned PRM).
1010
- * 2. `runwiseStepRewardSummary(stepRewards)` — aggregate the per-step
1011
- * signal into a credit-assignment-aware run-level score.
1012
- * 3. `prmTrainingPairs(stepRewards, options)` — produce the
1013
- * `(prefix, suffix_chosen, suffix_rejected)` triples that PRM
1014
- * training pipelines consume.
1015
- *
1016
- * What we ship: the *extraction* and *aggregation* infrastructure plus
1017
- * the data shape PRM training expects. We do NOT ship the actual PRM
1018
- * training (gradient descent over a transformer is out of scope for a
1019
- * TS package). The interface is the contract; downstream consumers wire
1020
- * their preferred trainer.
1021
- *
1022
- * Caveat the panel will land: this is descriptive credit assignment
1023
- * (which steps correlate with outcome), not causal credit assignment
1024
- * (which steps caused outcome). For causal claims you need
1025
- * counterfactual rollouts or a learned dynamics model. Future work; the
1026
- * descriptive version is what production PRM training actually uses.
1027
- */
1028
-
1029
- interface StepReward {
1030
- /** Trace span this reward attaches to. */
1031
- spanId: string;
1032
- runId: string;
1033
- /** Index in the trajectory (0-based, in started-at order). */
1034
- stepIndex: number;
1035
- /** Span kind (typically 'tool', 'llm', 'judge'). */
1036
- kind: Span['kind'];
1037
- /** Span name — for the consumer's downstream filtering. */
1038
- name: string;
1039
- /** Step-level reward in [0, 1]. */
1040
- reward: number;
1041
- /**
1042
- * Determinism class. Mirrors the verifiable-reward distinction:
1043
- * deterministic = test/compile/schema check; probabilistic = LLM judge.
1044
- */
1045
- determinism: 'deterministic' | 'probabilistic';
1046
- /** Optional rationale / evidence — the trainer typically discards. */
1047
- rationale?: string;
1048
- /** Optional weight — how much this step contributes to credit assignment. */
1049
- weight?: number;
1050
- }
1051
- interface StepScorer {
1052
- /** Span kinds this scorer applies to. */
1053
- appliesTo: Span['kind'][];
1054
- /** Returns null to skip the span; returns a `StepReward` shape (without index/runId/spanId, which are filled in). */
1055
- score(span: Span): Promise<Omit<StepReward, 'spanId' | 'runId' | 'stepIndex'>> | null | undefined;
1056
- }
1057
- interface ExtractStepRewardsOptions {
1058
- /**
1059
- * Ordered list of scorers. Each span runs through scorers in order;
1060
- * the first non-null result wins. If no scorer applies, the span is
1061
- * skipped (not all spans are training-worthy).
1062
- */
1063
- scorers: StepScorer[];
1064
- /** Optional filter — return null to drop the span entirely before scoring. */
1065
- preFilter?: (span: Span) => boolean;
1066
- }
1067
- declare function extractStepRewards(store: TraceStore, runId: string, opts: ExtractStepRewardsOptions): Promise<StepReward[]>;
1068
- interface RunwiseStepSummary {
1069
- runId: string;
1070
- totalSteps: number;
1071
- meanReward: number;
1072
- /** Sum-of-rewards (weighted by `weight ?? 1`). Use as the run-level proxy. */
1073
- sumWeightedReward: number;
1074
- /** Fraction of steps where reward < 0.5 — proxy for "where the policy was wrong." */
1075
- failureFraction: number;
1076
- /** Maximum drop in reward between consecutive steps — diagnoses a step where things went sideways. */
1077
- worstStepDelta: number;
1078
- worstStepIndex: number | null;
1079
- }
1080
- declare function runwiseStepRewardSummary(stepRewards: StepReward[]): RunwiseStepSummary;
1081
- interface PrmTrainingTriple {
1082
- /** Prefix run-id (or composite key) — the trajectory up to step k-1. */
1083
- prefixRunId: string;
1084
- prefixStepIndex: number;
1085
- /** The step that came next on a high-reward trajectory. */
1086
- chosenSpanId: string;
1087
- chosenReward: number;
1088
- /** A step from a divergent low-reward trajectory at the same prefix length. */
1089
- rejectedSpanId: string;
1090
- rejectedReward: number;
1091
- /** The prefix run came from this run; the rejected step came from `rejectedRunId`. */
1092
- rejectedRunId: string;
1093
- marginScore: number;
1094
- }
1095
- /**
1096
- * Build PRM training triples. The shape: pair runs that share an early
1097
- * prefix (same scenario, same first N steps) and diverge later — at the
1098
- * point of divergence, the high-reward run's next step is `chosen`, the
1099
- * low-reward run's next step is `rejected`. This is the canonical PRM
1100
- * training data shape from Lightman et al. and DeepSeek-R1 process
1101
- * supervision.
1102
- *
1103
- * Implementation note: we don't have a way to detect "same prefix" in
1104
- * the general agent setting (token-level prefixes require hashing model
1105
- * outputs). The current heuristic groups by `(scenarioId, prefixSpanName
1106
- * sequence)` — runs are paired when their first K span names match. For
1107
- * production use this should be replaced with a proper trajectory-prefix
1108
- * hash; the heuristic is good enough for early-stage scaffolding.
1109
- */
1110
- declare function prmTrainingPairs(stepRewardsByRun: Map<string, StepReward[]>, opts?: {
1111
- minMargin?: number;
1112
- minPrefixLength?: number;
1113
- }): PrmTrainingTriple[];
1114
-
1115
- /**
1116
- * Trainer-format exporters.
1117
- *
1118
- * agent-eval produces canonical artifacts (`RunRecord[]`, `PreferenceTriple[]`,
1119
- * `StepReward[]`, `PrmTrainingTriple[]`). RL training pipelines consume
1120
- * different shapes — Hugging Face TRL, Prime Intellect's prime-rl, OpenAI
1121
- * fine-tuning, Anthropic finetuning, OpenRLHF, verl. Each has its own
1122
- * JSONL conventions. Rather than ship N adapters, this module ships the
1123
- * canonical formats most production pipelines accept and ergonomic helpers
1124
- * for the rest.
1125
- *
1126
- * Shapes:
1127
- * - **DPO / IPO / KTO** — `{prompt, chosen, rejected}` JSONL. Consumed
1128
- * by HuggingFace TRL, prime-rl's offline DPO, OpenRLHF.
1129
- * - **GRPO offline** — `{prompt, completions[], rewards[]}` JSONL.
1130
- * Consumed by prime-rl GRPO, verl, OpenRLHF.
1131
- * - **SFT** — `{messages[]}` JSONL with chosen completion as the final
1132
- * assistant turn. Consumed by HF SFT trainers, OpenAI fine-tuning,
1133
- * Anthropic finetuning.
1134
- * - **PRM** — `{prompt, prefix_steps[], chosen_step, rejected_step}` JSONL.
1135
- * Consumed by Lightman-style PRM trainers and prime-rl's PRM mode.
1136
- *
1137
- * Why ship this in agent-eval rather than a separate adapter package: the
1138
- * canonical artifacts (`RunRecord[]`, `PreferenceTriple[]`, etc.) are
1139
- * agent-eval's contract; without first-party exporters consumers reverse-
1140
- * engineer the mapping every release. The exporters codify it.
1141
- *
1142
- * The exporters take callbacks for any field that isn't on the canonical
1143
- * artifact (specifically: prompt + completion text, since the package
1144
- * stores only their hashes by design — full text is the consumer's
1145
- * trace store / raw event log).
1146
- */
1147
-
1148
- interface DpoLookups {
1149
- /** Resolve the prompt text for a run (typically from a trace store / raw event sink). */
1150
- promptOf: (runId: string) => string | Promise<string>;
1151
- /** Resolve the assistant completion text for a run. */
1152
- completionOf: (runId: string) => string | Promise<string>;
1153
- }
1154
- interface DpoExportRow {
1155
- prompt: string;
1156
- chosen: string;
1157
- rejected: string;
1158
- /** Carried-through margin. Some KTO / IPO variants use this. */
1159
- margin?: number;
1160
- /** Free-form metadata for downstream filtering / sharding. */
1161
- meta?: Record<string, unknown>;
1162
- }
1163
- /**
1164
- * Convert preference triples to TRL-compatible DPO rows. The shape
1165
- * `{prompt, chosen, rejected}` is the canonical HuggingFace DPODataset
1166
- * entry; every major DPO trainer accepts it.
1167
- */
1168
- declare function toDpoRows(triples: PreferenceTriple[], lookups: DpoLookups): Promise<DpoExportRow[]>;
1169
- /** Serialize DPO rows as JSONL. One line per row. */
1170
- declare function toDpoJsonl(rows: DpoExportRow[]): string;
1171
- interface GrpoLookups {
1172
- promptOf: (runId: string) => string | Promise<string>;
1173
- completionOf: (runId: string) => string | Promise<string>;
1174
- /** Optional: derive a custom reward from the run. Defaults to score. */
1175
- rewardOf?: (run: RunRecord) => number | null;
1176
- }
1177
- interface GrpoExportRow {
1178
- prompt: string;
1179
- completions: string[];
1180
- rewards: number[];
1181
- /** runIds in the same order as `completions[]` for traceability. */
1182
- runIds: string[];
1183
- meta?: Record<string, unknown>;
1184
- }
1185
- /**
1186
- * Convert RunRecord[] grouped by `(scenarioId)` into GRPO offline rows —
1187
- * one row per scenario, with one completion per run on that scenario.
1188
- *
1189
- * GRPO (Shao et al. 2024 / DeepSeek-R1) trains on relative advantages
1190
- * within a group of completions for the same prompt; this is the
1191
- * canonical input format.
1192
- */
1193
- declare function toGrpoRows(runs: RunRecord[], lookups: GrpoLookups): Promise<GrpoExportRow[]>;
1194
- declare function toGrpoJsonl(rows: GrpoExportRow[]): string;
1195
- interface SftLookups {
1196
- promptOf: (runId: string) => string | Promise<string>;
1197
- completionOf: (runId: string) => string | Promise<string>;
1198
- /** Optional system message. Default omits. */
1199
- systemOf?: (run: RunRecord) => string | null | undefined;
1200
- /** Filter — return false to skip the run (e.g., low score, failed cases). */
1201
- include?: (run: RunRecord) => boolean;
1202
- }
1203
- interface SftExportRow {
1204
- messages: Array<{
1205
- role: 'system' | 'user' | 'assistant';
1206
- content: string;
1207
- }>;
1208
- meta?: Record<string, unknown>;
1209
- }
1210
- /**
1211
- * Convert RunRecord[] into Hugging Face / OpenAI / Anthropic-style
1212
- * conversational SFT rows. By default every record becomes one row;
1213
- * pass `include` to filter (e.g., keep only `score >= 0.8` for
1214
- * rejection-sampling SFT).
1215
- */
1216
- declare function toSftRows(runs: RunRecord[], lookups: SftLookups): Promise<SftExportRow[]>;
1217
- declare function toSftJsonl(rows: SftExportRow[]): string;
1218
- interface PrmLookups {
1219
- /** Resolve the prompt text for a run. */
1220
- promptOf: (runId: string) => string | Promise<string>;
1221
- /** Resolve the trajectory step text for a (runId, spanId) pair. */
1222
- stepTextOf: (runId: string, spanId: string) => string | Promise<string>;
1223
- /** Optional: sequence of prefix span ids leading up to the divergence. */
1224
- prefixOf?: (runId: string, prefixStepIndex: number) => string[] | Promise<string[]>;
1225
- }
1226
- interface PrmExportRow {
1227
- prompt: string;
1228
- /** Span ids for the steps before divergence — caller resolves text via `stepTextOf`. */
1229
- prefixSpanIds: string[];
1230
- prefixStepText: string[];
1231
- chosenStep: string;
1232
- rejectedStep: string;
1233
- chosenReward: number;
1234
- rejectedReward: number;
1235
- marginScore: number;
1236
- meta?: Record<string, unknown>;
1237
- }
1238
- /**
1239
- * Convert PRM training triples to JSONL rows. Caller's `stepTextOf`
1240
- * callback resolves span text from the consumer's trace store.
1241
- */
1242
- declare function toPrmRows(triples: PrmTrainingTriple[], lookups: PrmLookups): Promise<PrmExportRow[]>;
1243
- declare function toPrmJsonl(rows: PrmExportRow[]): string;
1244
- interface StepRewardJsonlRow {
1245
- runId: string;
1246
- spanId: string;
1247
- stepIndex: number;
1248
- reward: number;
1249
- determinism: 'deterministic' | 'probabilistic';
1250
- weight: number;
1251
- }
1252
- declare function stepRewardsToJsonl(stepRewards: StepReward[]): string;
1253
-
1254
- /**
1255
- * RL dataset packaging + datasheet — the publishable, sellable bundle.
1256
- *
1257
- * The format exporters (`toGrpoRows` / `toSftRows` / `toDpoRows`) already
1258
- * produce trainer-ready shapes (prime-rl GRPO, TRL DPO, conversational SFT).
1259
- * What turns that into a dataset someone can PUBLISH or BUY is the provenance
1260
- * + a datasheet: which models produced it, which prompt/agent versions, how the
1261
- * reward was derived (deterministic verifiable vs probabilistic judge — the
1262
- * credibility axis a buyer checks first), the split discipline, the reward
1263
- * distribution, the quality gates, the license, and the intended/out-of-scope
1264
- * uses. This module computes those facts from the `RunRecord[]` and renders a
1265
- * "Datasheet for Datasets" (Gebru et al. 2018) card alongside the format files.
1266
- *
1267
- * It composes the existing `rl/exporters` — it does not reimplement any trainer
1268
- * format. The renderers token-identity step (DeepSeek/Kimi/Qwen tokenization
1269
- * with per-token loss masks) is a downstream Python stage that consumes the
1270
- * `messages`/`completions` this bundle emits.
1271
- */
1272
-
1273
- type RewardKind = 'deterministic' | 'probabilistic' | 'mixed';
1274
- type DatasetFormat = 'grpo' | 'sft' | 'dpo';
1275
- /** Caller-declared context — the qualitative half of the datasheet that can't
1276
- * be computed from records. */
1277
- interface RlDatasetConfig {
1278
- name: string;
1279
- version: string;
1280
- /** Product/task domain, e.g. 'legal-m&a', 'tax-1040'. */
1281
- domain: string;
1282
- /** SPDX id or a named commercial license. Required — an unlicensed dataset
1283
- * cannot be published or sold. */
1284
- license: string;
1285
- /** How the reward was produced. `kind: 'deterministic'` (a test/schema/XPath
1286
- * decided it) is the credibility signal; 'probabilistic' = LLM-judge. */
1287
- reward: {
1288
- kind: RewardKind;
1289
- source: string;
1290
- description: string;
1291
- };
1292
- intendedUse: string;
1293
- outOfScope: string;
1294
- limitations: string;
1295
- /** ISO timestamp — passed in (the substrate forbids Date.now()). */
1296
- createdAtIso: string;
1297
- /** Default: ['grpo', 'sft']. */
1298
- formats?: DatasetFormat[];
1299
- /** Quality gates already run, recorded on the card for the buyer. */
1300
- qualityGates?: {
1301
- contaminationProbe?: 'passed' | 'failed' | 'not-run';
1302
- dedup?: boolean;
1303
- verifiableRewardFilter?: boolean;
1304
- };
1305
- }
1306
- interface RewardStats {
1307
- n: number;
1308
- mean: number;
1309
- median: number;
1310
- min: number;
1311
- max: number;
1312
- std: number;
1313
- }
1314
- interface RlDatasetStats {
1315
- records: number;
1316
- /** Record count per split — a publishable dataset must declare its holdout. */
1317
- splits: Record<RunSplitTag, number>;
1318
- reward: RewardStats;
1319
- /** Distinct snapshot-pinned models that produced the trajectories. */
1320
- models: string[];
1321
- /** Distinct effective-prompt hashes (the agent profile/prompt versions). */
1322
- promptHashes: string[];
1323
- commitShas: string[];
1324
- totalTokens: {
1325
- input: number;
1326
- output: number;
1327
- };
1328
- totalCostUsd: number;
1329
- }
1330
- interface RlDatasetManifest extends RlDatasetConfig {
1331
- formats: DatasetFormat[];
1332
- rowCounts: Partial<Record<DatasetFormat, number>>;
1333
- stats: RlDatasetStats;
1334
- }
1335
- interface RlDatasetBundle {
1336
- manifest: RlDatasetManifest;
1337
- /** Relative filename -> contents. Write these to a directory to publish. */
1338
- files: Record<string, string>;
1339
- }
1340
- /**
1341
- * Package graded `RunRecord[]` into a publishable RL dataset bundle: the
1342
- * trainer-format JSONL files + a manifest + a datasheet. DPO requires
1343
- * pre-extracted preference triples (pass `preferences`); GRPO/SFT derive from
1344
- * the records directly via the supplied lookups. Throws on an empty corpus —
1345
- * an empty dataset must never be published.
1346
- */
1347
- declare function buildRlDataset(records: RunRecord[], lookups: GrpoLookups & SftLookups, config: RlDatasetConfig, preferences?: {
1348
- triples: PreferenceTriple[];
1349
- lookups: DpoLookups;
1350
- }): Promise<RlDatasetBundle>;
1351
- /** Render the "Datasheet for Datasets" card — the artifact a buyer reads. */
1352
- declare function datasheetToMarkdown(m: RlDatasetManifest): string;
1353
-
1354
- /**
1355
- * RL corpus — the durable, append-only accumulation of graded RunRecords that
1356
- * every eval run deposits BY DEFAULT.
1357
- *
1358
- * The dataset is the free exhaust of the normal eval process: we run evals
1359
- * constantly to get an agent production-ready, and those runs already produce
1360
- * graded trajectories. Instead of writing them to an ephemeral run dir and
1361
- * throwing them away, `appendToCorpus` accumulates them into a durable corpus;
1362
- * `buildDatasetFromCorpus` later harvests the whole corpus into a publishable
1363
- * bundle. No separate data-collection campaign — the data accrues from work we
1364
- * do anyway. This is the "best things for free by our process" layer.
1365
- *
1366
- * Trajectory text rides on the record as top-level `prompt` / `completion`
1367
- * (what the eval harnesses capture; the RunRecord validator ignores the extra
1368
- * keys). The harvest reads them directly — no trace store round-trip needed.
1369
- */
1370
-
1371
- /** A corpus record is a RunRecord carrying the trajectory text the harness
1372
- * captured. `prompt`/`completion` are top-level (the validator ignores extras). */
1373
- type CorpusRecord = RunRecord & {
1374
- prompt?: string;
1375
- completion?: string;
1376
- };
1377
- interface CorpusAppendResult {
1378
- appended: number;
1379
- /** Skipped because a record with the same runId was already in the corpus
1380
- * (idempotent appends — NOT re-run collapsing; re-runs get fresh runIds). */
1381
- skipped: number;
1382
- total: number;
1383
- }
1384
- /**
1385
- * Append graded records to the corpus (append-only JSONL). Deduplicates by
1386
- * `runId` against what's already on disk so re-running the same harness is
1387
- * idempotent. Creates the file and parent dir. This is the call every eval
1388
- * harness makes by default after producing its records.
1389
- */
1390
- declare function appendToCorpus(records: CorpusRecord[], corpusPath: string): CorpusAppendResult;
1391
- /** Read the full corpus. Returns [] if the corpus does not exist yet. */
1392
- declare function readCorpus(corpusPath: string): CorpusRecord[];
1393
- interface HarvestOptions {
1394
- /** Keep only records scoring >= this (rejection-sampling for SFT). */
1395
- minScore?: number;
1396
- /** Keep only these splits (e.g. ['holdout'] for an eval-only dataset). */
1397
- splits?: RunRecord['splitTag'][];
1398
- }
1399
- /**
1400
- * Harvest the accumulated corpus into a publishable RL dataset bundle. Reads
1401
- * trajectory text from each record's top-level `prompt`/`completion`; records
1402
- * missing either are excluded (a graded score with no trajectory can't train).
1403
- * Optionally filters by score / split. Throws (via buildRlDataset) if nothing
1404
- * survives — an empty dataset must never be published.
1405
- */
1406
- declare function buildDatasetFromCorpus(corpusPath: string, config: RlDatasetConfig, opts?: HarvestOptions): Promise<RlDatasetBundle>;
1407
-
1408
780
  /**
1409
781
  * `PredictiveValidityResearcher` — concrete `Researcher` implementation
1410
782
  * that drives selection from outcome-anchored predictive validity.
@@ -1651,4 +1023,170 @@ interface RLCampaignResult<V> {
1651
1023
  }
1652
1024
  declare function runRLCampaign<V>(opts: RunRLCampaignOptions<V>): Promise<RLCampaignResult<V>>;
1653
1025
 
1654
- export { type AdaptationCurve, type AdaptationPoint, type AdaptationRunner, type AdapterContext, type AdversarialMutation, type AdversarialScenario, type AdversarialSearchOptions, type AdversarialSearchReport, type BradleyTerryFit, type BradleyTerryRating, type BuildPairwiseFromCampaignInput, type CellObservation, type CompareCurvesResult, type ComputeBestOfNOptions, type ComputeBestOfNResult, type ComputeCurve, type ComputeCurveBudget, type ComputeCurvePoint, type ContaminationProbeInput, type ContaminationProbeOptions, type ContaminationProbeReport, type CorpusAppendResult, type CorpusRecord, type CurriculumAllocation, type DatasetFormat, type DetectRewardHackingInput, type DpoExportRow, type DpoLookups, type EloOptions, type ExtractPreferencesOptions, type ExtractStepRewardsOptions, type GrpoExportRow, type GrpoLookups, type HarvestOptions, OutcomeStore, type PairwiseOutcome, type ParetoPointInput, PredictiveValidityResearcher, type PredictiveValidityResearcherOptions, type PreferenceExtractionReport, type PreferenceStrategy, type PreferenceTriple, type PrmExportRow, type PrmLookups, type PrmTrainingTriple, type RLCampaignResult, type RewardHackingFinding, type RewardHackingReport, type RewardHackingSignal, type RewardKind, type RewardStats, type RlDatasetBundle, type RlDatasetConfig, type RlDatasetManifest, type RlDatasetStats, type RunAdaptationCurveOptions, type RunComputeCurveOptions, type RunRLCampaignOptions, type RunwiseStepSummary, type ScenarioPerturbation, type ScenarioPerturbationKind, type SelfConsistencyOptions, type SelfConsistencyResult, type SftExportRow, type SftLookups, type StepReward, type StepRewardJsonlRow, type StepScorer, type ThompsonCurriculumOptions, type VarianceCurriculumOptions, type VerifiableReward, type VerifiableRewardExtractionOptions, type VerifiableRewardSource, adversarialScenarioSearch, appendToCorpus, applyEloUpdate, bestOfN, buildDatasetFromCorpus, buildPairwiseFromCampaign, buildRlDataset, campaignToRunRecords, compareAdaptationCurves, datasheetToMarkdown, detectRewardHacking, extractPreferences, extractStepRewards, extractVerifiableReward, extractVerifiableRewardsFromRecords, filterDeterministicallyRewarded, firstPassK, fitBradleyTerry, injectIrrelevantClause, observationsFromRunRecords, paretoFrontier, prmTrainingPairs, readCorpus, renameVariables, runAdaptationCurve, runComputeCurve, runContaminationProbe, runRLCampaign, runwiseStepRewardSummary, selfConsistency, shuffleOrder, stepRewardsToJsonl, thompsonCurriculum, toAnthropicFormat, toDpoJsonl, toDpoRows, toGrpoJsonl, toGrpoRows, toPrmJsonl, toPrmRows, toSftJsonl, toSftRows, toTRLFormat, varianceBasedCurriculum, verificationReportToRunRecord };
1026
+ /**
1027
+ * Simulator fidelity — score a user SIMULATOR's realism against real-user
1028
+ * trace distributions.
1029
+ *
1030
+ * Synthetic-persona evals (`PersonaConfig`-driven canonical evals, fuzz
1031
+ * user-simulator objectives) stand in for real users in most of the numbers
1032
+ * we publish. The standing threat is the Sim2Real gap: a simulator that is
1033
+ * distributionally unlike production creates "easy mode" and silently
1034
+ * inflates every score built on it. This module measures that gap from the
1035
+ * SAME artifact both sides already produce — `RunRecord`s — so no new
1036
+ * capture pipeline is needed:
1037
+ *
1038
+ * - `simFidelityReport` — per-feature Jensen-Shannon divergence between
1039
+ * simulated and production record distributions, collapsed into a
1040
+ * fidelity coefficient in [0,1].
1041
+ * - `easyModeCheck` — the headline academic failure mode (sim inflates
1042
+ * pass-rate over production) as its own named artifact.
1043
+ *
1044
+ * Every synthetic-persona eval result should publish its fidelity
1045
+ * coefficient alongside the score — a number from an unrepresentative
1046
+ * simulator is an unlabeled estimate. Wire-in points:
1047
+ *
1048
+ * - canonical persona evals: pass the campaign's `RunRecord`s as
1049
+ * `simulated` and intake-adapter output (`contract/intake`: OTel spans,
1050
+ * feedback tables, coding-agent sessions) as `production`
1051
+ * - the fuzz user-sim objective: use `1 - report.fidelity` as a realism
1052
+ * penalty when searching over generated personas
1053
+ * - the durable corpus (`./corpus`): both sides read straight from
1054
+ * `readCorpus` — tag sim vs production by `experimentId`
1055
+ */
1056
+
1057
+ /** Extracts a flat behavioral feature map from one record. `string` values
1058
+ * are categorical, `number` values are quantile-bucketed over the union of
1059
+ * both sides, `null` means the feature is absent on this record and is
1060
+ * counted explicitly as its own category (never silently dropped). */
1061
+ type BehaviorFeatures = (record: RunRecord) => Record<string, string | number | null>;
1062
+ /** Reserved histogram category for `null` feature values. A capture-rate
1063
+ * difference (one side instruments a signal, the other does not) registers
1064
+ * as divergence by design: a simulator that produces no tool traces is not
1065
+ * representative of production that does. */
1066
+ declare const ABSENT_CATEGORY = "(absent)";
1067
+ /** Minimum non-null observations PER SIDE for a feature to enter the
1068
+ * fidelity mean. Below this the JSD estimate is sampling noise. */
1069
+ declare const DEFAULT_MIN_N_PER_FEATURE = 20;
1070
+ /** Quantile buckets used to discretize numeric features. Quartiles balance
1071
+ * resolution against per-bucket sample size at the default minN. */
1072
+ declare const DEFAULT_QUANTILE_BUCKETS = 4;
1073
+ /** Fidelity at or above this → 'representative'; below → 'skewed'.
1074
+ * 1 − 0.8 = mean JSD 0.2 ≈ distributions that mostly overlap with one
1075
+ * clearly shifted mode — the point where per-feature shifts start changing
1076
+ * which failure classes an eval can even observe. */
1077
+ declare const REPRESENTATIVE_MIN_FIDELITY = 0.8;
1078
+ /**
1079
+ * Default feature set — ONLY fields verified present on both simulated and
1080
+ * production records:
1081
+ *
1082
+ * - `score`, `wall_ms`, `output_tokens` — mandatory per the `RunRecord`
1083
+ * validator (non-finite values read as absent rather than poisoning a
1084
+ * bucket).
1085
+ * - `failure_class` — optional taxonomy field; absent counted explicitly.
1086
+ * - `turn_count`, `tool_errors`, `tool_error_recovery` — derived from the
1087
+ * `outcome.raw` counters the intake adapters and eval harnesses write
1088
+ * (`turns_completed`, `assistant_messages`, `tool_errors`,
1089
+ * `turns_aborted`); absent on records whose producer did not capture
1090
+ * them, counted explicitly.
1091
+ * - `completion_length` — from the optional `CorpusRecord` trajectory
1092
+ * text; the message-length proxy when records come from the corpus.
1093
+ *
1094
+ * `RunRecord` carries event COUNTS, not event ordering, so
1095
+ * `tool_error_recovery` is a counts-only derivation: errors occurred and the
1096
+ * run still completed cleanly ('recovered') vs aborted or classified as a
1097
+ * failure ('unrecovered') — not a literal error→retry sequence check.
1098
+ */
1099
+ declare const defaultBehaviorFeatures: BehaviorFeatures;
1100
+ /**
1101
+ * Jensen-Shannon divergence between two categorical histograms (raw counts;
1102
+ * normalized internally). Log base 2 → bounded [0,1]: 0 = identical
1103
+ * distributions, 1 = disjoint support. Symmetric, defined even where the
1104
+ * supports differ — exactly the regime sim-vs-production comparison lives in.
1105
+ * Throws on zero-mass or negative/non-finite counts: an empty histogram has
1106
+ * no distribution and a silent 0 would read as "perfectly representative".
1107
+ */
1108
+ declare function jsDivergence(p: Record<string, number>, q: Record<string, number>): number;
1109
+ /**
1110
+ * Deterministic quantile edges over a value set (the UNION of both sides, so
1111
+ * sim and production land in the same buckets). Linear interpolation between
1112
+ * order statistics; duplicate edges from heavy ties collapse into fewer,
1113
+ * wider buckets. Returns `bucketCount - 1` edges before deduplication.
1114
+ */
1115
+ declare function quantileEdges(values: number[], bucketCount?: number): number[];
1116
+ /** Stable half-open bucket label for a value against quantile edges:
1117
+ * `[-inf,e0)`, `[e0,e1)`, …, `[eLast,+inf)`. */
1118
+ declare function bucketLabel(value: number, edges: number[]): string;
1119
+ interface FeatureShift {
1120
+ /** Category label (a string value, a numeric bucket, or `ABSENT_CATEGORY`). */
1121
+ value: string;
1122
+ /** Probability of this category among ALL simulated records (nulls included
1123
+ * via `ABSENT_CATEGORY`, so each side's shifts sum to 1). */
1124
+ pSim: number;
1125
+ /** Probability among ALL production records. */
1126
+ pProd: number;
1127
+ }
1128
+ interface FeatureDivergence {
1129
+ feature: string;
1130
+ /** Jensen-Shannon divergence in [0,1] for this feature. */
1131
+ divergence: number;
1132
+ /** Largest |pSim − pProd| categories, descending — where the sim deviates. */
1133
+ topShifts: FeatureShift[];
1134
+ /** Non-null observations on the simulated side. */
1135
+ nSim: number;
1136
+ /** Non-null observations on the production side. */
1137
+ nProd: number;
1138
+ }
1139
+ type FidelityVerdict = 'representative' | 'skewed' | 'insufficient-data';
1140
+ interface FidelityReport {
1141
+ perDimension: FeatureDivergence[];
1142
+ /** 1 − mean divergence over features with sufficient data. NaN when the
1143
+ * verdict is 'insufficient-data' — a 0 would read as "maximally skewed"
1144
+ * and silently poison downstream aggregation; check `verdict` first. */
1145
+ fidelity: number;
1146
+ /** Features excluded because either side had fewer than `minNPerFeature`
1147
+ * non-null observations. Named, never silently dropped. */
1148
+ insufficientData: string[];
1149
+ /** 'representative' when fidelity >= REPRESENTATIVE_MIN_FIDELITY (0.8),
1150
+ * 'skewed' below, 'insufficient-data' when no feature met minN. */
1151
+ verdict: FidelityVerdict;
1152
+ }
1153
+ interface SimFidelityOptions {
1154
+ /** Feature extractor. Defaults to `defaultBehaviorFeatures`. */
1155
+ features?: BehaviorFeatures;
1156
+ /** Minimum non-null observations per side per feature. Default 20. */
1157
+ minNPerFeature?: number;
1158
+ }
1159
+ /**
1160
+ * Compare a simulator's RunRecords against production RunRecords, feature by
1161
+ * feature. Numeric features are bucketed by deterministic quantiles of the
1162
+ * union; nulls count as an explicit `ABSENT_CATEGORY`. Throws on empty
1163
+ * inputs — "no records" is a wiring error, not a distribution.
1164
+ */
1165
+ declare function simFidelityReport(simulated: RunRecord[], production: RunRecord[], opts?: SimFidelityOptions): FidelityReport;
1166
+ interface EasyModeOptions {
1167
+ /** A run passes when its score (holdout, else search) >= this. Default 0.5
1168
+ * — matches the pass-threshold convention across the rl/ primitives. */
1169
+ passThreshold?: number;
1170
+ /** Pass-rate gap above which the sim is flagged inflated. Default 0.1 —
1171
+ * a 10-point inflation is enough to flip most promotion gates. */
1172
+ inflationTolerance?: number;
1173
+ }
1174
+ interface EasyModeReport {
1175
+ simPassRate: number;
1176
+ prodPassRate: number;
1177
+ /** simPassRate − prodPassRate. Positive = the simulator is easier than reality. */
1178
+ gap: number;
1179
+ /** True when gap > inflationTolerance: numbers measured against this
1180
+ * simulator overstate production performance. */
1181
+ inflated: boolean;
1182
+ }
1183
+ /**
1184
+ * The headline simulator failure mode as its own named artifact: a simulator
1185
+ * that creates "easy mode" inflates pass-rate relative to production, and
1186
+ * every score measured against it overstates reality. Throws on empty inputs
1187
+ * and on records carrying neither score — a silently-skipped record would
1188
+ * bias the very rate this check exists to keep honest.
1189
+ */
1190
+ declare function easyModeCheck(simulated: RunRecord[], production: RunRecord[], opts?: EasyModeOptions): EasyModeReport;
1191
+
1192
+ export { ABSENT_CATEGORY, type AdaptationCurve, type AdaptationPoint, type AdaptationRunner, type AdapterContext, type BehaviorFeatures, type BradleyTerryFit, type BradleyTerryRating, type BuildPairwiseFromCampaignInput, type CellObservation, type CompareCurvesResult, type ComputeBestOfNOptions, type ComputeBestOfNResult, type ComputeCurve, type ComputeCurveBudget, type ComputeCurvePoint, type ContaminationProbeInput, type ContaminationProbeOptions, type ContaminationProbeReport, type CurriculumAllocation, DEFAULT_MIN_N_PER_FEATURE, DEFAULT_QUANTILE_BUCKETS, type DetectRewardHackingInput, DpoExportRow, DpoLookups, type EasyModeOptions, type EasyModeReport, type EloOptions, ExtractPreferencesOptions, type FeatureDivergence, type FeatureShift, type FidelityReport, type FidelityVerdict, GrpoExportRow, GrpoLookups, OutcomeStore, type PairwiseOutcome, type ParetoPointInput, PredictiveValidityResearcher, type PredictiveValidityResearcherOptions, PreferenceExtractionReport, REPRESENTATIVE_MIN_FIDELITY, type RLCampaignResult, type RewardHackingFinding, type RewardHackingReport, type RewardHackingSignal, type RunAdaptationCurveOptions, type RunComputeCurveOptions, type RunRLCampaignOptions, type ScenarioPerturbation, type ScenarioPerturbationKind, type SelfConsistencyOptions, type SelfConsistencyResult, SftExportRow, SftLookups, type SimFidelityOptions, type ThompsonCurriculumOptions, type VarianceCurriculumOptions, type VerifiableReward, type VerifiableRewardExtractionOptions, type VerifiableRewardSource, applyEloUpdate, bestOfN, bucketLabel, buildPairwiseFromCampaign, campaignToRunRecords, compareAdaptationCurves, defaultBehaviorFeatures, detectRewardHacking, easyModeCheck, extractVerifiableReward, extractVerifiableRewardsFromRecords, filterDeterministicallyRewarded, firstPassK, fitBradleyTerry, injectIrrelevantClause, jsDivergence, observationsFromRunRecords, paretoFrontier, quantileEdges, renameVariables, runAdaptationCurve, runComputeCurve, runContaminationProbe, runRLCampaign, selfConsistency, shuffleOrder, simFidelityReport, thompsonCurriculum, varianceBasedCurriculum, verificationReportToRunRecord };