/**
 * RL corpus — the durable, append-only accumulation of graded RunRecords that
 * every eval run deposits BY DEFAULT.
 *
 * The dataset is the free exhaust of the normal eval process: we run evals
 * constantly to get an agent production-ready, and those runs already produce
 * graded trajectories. Instead of writing them to an ephemeral run dir and
 * throwing them away, `appendToCorpus` accumulates them into a durable corpus;
 * `buildDatasetFromCorpus` later harvests the whole corpus into a publishable
 * bundle. No separate data-collection campaign — the data accrues from work we
 * do anyway. This is the "best things for free by our process" layer.
 *
 * Trajectory text rides on the record as top-level `prompt` / `completion`
 * (what the eval harnesses capture; the RunRecord validator ignores the extra
 * keys). The harvest reads them directly — no trace store round-trip needed.
 */
import type { RunRecord } from '../run-record';
import { type RlDatasetBundle, type RlDatasetConfig } from './dataset';
/** A corpus record is a RunRecord carrying the trajectory text the harness
 *  captured. `prompt`/`completion` are top-level (the validator ignores extras). */
export type CorpusRecord = RunRecord & {
    prompt?: string;
    completion?: string;
};
export interface CorpusAppendResult {
    appended: number;
    /** Skipped because a record with the same runId was already in the corpus
     *  (idempotent appends — NOT re-run collapsing; re-runs get fresh runIds). */
    skipped: number;
    total: number;
}
/**
 * Append graded records to the corpus (append-only JSONL). Deduplicates by
 * `runId` against what's already on disk so re-running the same harness is
 * idempotent. Creates the file and parent dir. This is the call every eval
 * harness makes by default after producing its records.
 */
export declare function appendToCorpus(records: CorpusRecord[], corpusPath: string): CorpusAppendResult;
/** Read the full corpus. Returns [] if the corpus does not exist yet. */
export declare function readCorpus(corpusPath: string): CorpusRecord[];
export interface HarvestOptions {
    /** Keep only records scoring >= this (rejection-sampling for SFT). */
    minScore?: number;
    /** Keep only these splits (e.g. ['holdout'] for an eval-only dataset). */
    splits?: RunRecord['splitTag'][];
}
/**
 * Harvest the accumulated corpus into a publishable RL dataset bundle. Reads
 * trajectory text from each record's top-level `prompt`/`completion`; records
 * missing either are excluded (a graded score with no trajectory can't train).
 * Optionally filters by score / split. Throws (via buildRlDataset) if nothing
 * survives — an empty dataset must never be published.
 */
export declare function buildDatasetFromCorpus(corpusPath: string, config: RlDatasetConfig, opts?: HarvestOptions): Promise<RlDatasetBundle>;
//# sourceMappingURL=corpus.d.ts.map