/**
 * `otlpToRunRecords` — fold an OTLP traces.jsonl (one OTLP span per line;
 * the form AppWorld / HALO emit via their OpenInference OTLP exporter, the
 * same shape `flattenOtlpExportToNdjson` produces) into validated
 * `RunRecord[]` — one record per `trace_id` (one trace == one task).
 *
 * This is the offline ingestion primitive the AppWorld proposer bench and the
 * hosted Intelligence product both stand on: traces in, paper-grade rows
 * out, ready for `compareProposers` / `analyzeRuns` / the promotion gate.
 *
 * Aggregation per trace:
 *   - tokenUsage: sum LLM-span `input` / `output` (+ `cached` when present)
 *     across every LLM span in the trace.
 *   - costUsd: sum per-span LLM cost when present; else priced via
 *     `opts.priceUsdPerToken` from the aggregated tokens; else 0 with a
 *     loud `raw.cost_unpriced = 1` marker so a missing price is visible, not
 *     a silent zero folded into a gate.
 *   - failureMode: the first `STATUS_CODE_ERROR` span's normalized status
 *     message (carries the real failure signature, not a generic class).
 *   - model: the dominant LLM model in the trace (snapshot-padded to satisfy
 *     `validateRunRecord` when the trace's model is a bare alias).
 *   - outcome score: `opts.scoreForTrace` (AppWorld `world.evaluate()` →
 *     TGC/SGC) when supplied; else 1 when the trace had no error span, 0
 *     when it did — a defensible default the caller can override.
 *   - prompt / completion: carried into `raw` as token-count signals and,
 *     when the first/last LLM span exposes `input.value` / `output.value`,
 *     the verbatim text is preserved on the optional `promptText` /
 *     `completionText` of the returned `OtlpTraceRunRecord`.
 *
 * Fail-loud: an OTLP file with zero valid spans throws. A trace with no
 * spans is impossible (a trace exists only because a span referenced it).
 * `validateRunRecord` runs on every row — a malformed projection throws
 * rather than silently producing a half-record.
 */
import { type RunRecord, type RunSplitTag, type RunTokenUsage } from '../run-record';
export interface OtlpToRunRecordsOptions {
    /** Logical experiment grouping for every produced record. */
    experimentId: string;
    /** Candidate (variant) id — the surface these traces exercised. The
     *  bench passes the proposer label here so `compareProposers` can pair rows. */
    candidateId: string;
    /** Split assignment for every produced record. Default `'holdout'` —
     *  ingested traces are evidence, not the optimizer's training pool. */
    splitTag?: RunSplitTag;
    /** Git SHA the traces were produced from. Default `'unknown'`. */
    commitSha?: string;
    /** sha256 of the effective prompt surface. Default `'unknown'`. */
    promptHash?: string;
    /** sha256 of the effective config. Default `'unknown'`. */
    configHash?: string;
    /** RNG seed recorded on every row. Default 0. */
    seed?: number;
    /**
     * Fallback model snapshot when the trace exposes no LLM model attribute
     * OR exposes a bare alias `validateRunRecord` would reject. The trace's
     * own model wins when it already carries a snapshot. Default
     * `'unknown@otlp'` (opaque-snapshot form the validator accepts).
     */
    fallbackModel?: string;
    /**
     * USD per total token (input+output) used to price a trace when no
     * per-span cost attribute is present. When unset, an unpriced trace
     * records `costUsd: 0` AND `raw.cost_unpriced = 1` — the zero is flagged,
     * never silent.
     */
    priceUsdPerToken?: number;
    /**
     * Score for a trace's outcome (AppWorld `world.evaluate()` → TGC/SGC, or
     * any [0,1] task-success signal). Keyed by `trace_id`; falls through to
     * the error-derived default (1 = no error span, 0 = had one) when the map
     * has no entry or the function returns undefined.
     */
    scoreForTrace?: (traceId: string, span: TraceAggregate) => number | undefined;
    /**
     * Per-record judge metadata when an external judge produced the score.
     * Keyed by `trace_id`.
     */
    judgeMetadataForTrace?: (traceId: string) => RunRecord['judgeMetadata'] | undefined;
}
/** A `RunRecord` plus the verbatim prompt/completion text when the trace's
 *  LLM spans exposed it. The text is NOT on the validated `RunRecord`
 *  (`outcome.raw` is numeric-only) but consumers ingesting full traces want
 *  it — so it rides alongside. */
export interface OtlpTraceRunRecord {
    record: RunRecord;
    /** Verbatim first-LLM-span `input.value`, when present. */
    promptText?: string;
    /** Verbatim last-LLM-span `output.value`, when present. */
    completionText?: string;
}
/** Per-trace rollup the score callback can inspect. */
export interface TraceAggregate {
    traceId: string;
    spanCount: number;
    llmSpanCount: number;
    toolSpanCount: number;
    agentSpanCount: number;
    errorSpanCount: number;
    tokenUsage: RunTokenUsage;
    /** First error span's normalized status message, if any. */
    firstErrorMessage?: string;
    model: string;
    startTime: string;
    endTime: string;
    wallMs: number;
}
/**
 * Parse + aggregate an OTLP traces.jsonl string into validated
 * `RunRecord[]` (one per trace). Use {@link otlpToTraceRunRecords} when you
 * also want the verbatim prompt/completion text alongside each record.
 */
export declare function otlpToRunRecords(otlpJsonl: string, opts: OtlpToRunRecordsOptions): RunRecord[];
/** As {@link otlpToRunRecords} but returns the prompt/completion text too. */
export declare function otlpToTraceRunRecords(otlpJsonl: string, opts: OtlpToRunRecordsOptions): OtlpTraceRunRecord[];
//# sourceMappingURL=otlp-to-run-records.d.ts.map