/**
 * Make the trace-analyst's OWN prompt a GEPA-optimizable surface.
 *
 * The analyst that drives self-improvement is itself a prompt — and a
 * hand-tuned one (a hardcoded, hand-versioned `const`). This module lets the
 * loop optimize it: the analyst `actorDescription` becomes a `MutableSurface`
 * that `gepaProposer` / `haloProposer` / any `SurfaceProposer` can mutate inside
 * `runImprovementLoop` or `compareProposers`. That is the second-order loop —
 * optimizing the optimizer's eyes, not just the agent's prompt.
 *
 * Two pieces, both deliberately small (the loop engine already exists — this
 * only supplies the analyst-shaped dispatch + an objective scorer):
 *
 *  - `buildAnalystSurfaceDispatch` — `dispatchWithSurface(surface, scenario)`
 *    runs `analyzeTraces` with `surface` as the actorDescription over the
 *    scenario's fixed trace corpus, returning its findings.
 *  - `failureModeRecallJudge` — a DETERMINISTIC judge (no LLM, no opinion)
 *    that scores those findings against the scenario's GROUND-TRUTH failure
 *    modes. This is what keeps optimizing the analyst prompt ungameable: the
 *    labels come from objective signal (e.g. AppWorld `world.evaluate()` tells
 *    us which task failed and which API calls were wrong), so we reward an
 *    analyst for surfacing the failures that really happened — not for
 *    pleasing a judge that could be talked into anything (Goodhart).
 *
 * Wiring (the loop is unchanged; you only pass these in):
 *
 *   const dispatchWithSurface = buildAnalystSurfaceDispatch({ analystOptions: { ai } })
 *   await runImprovementLoop({
 *     baselineSurface: TRACE_ANALYST_ACTOR_DESCRIPTION,  // the prompt under optimization
 *     scenarios: trainScenarios,                          // labeled trace corpora
 *     holdoutScenarios: heldOutScenarios,
 *     dispatchWithSurface,
 *     judges: [failureModeRecallJudge()],
 *     proposer: gepaProposer({ baseUrl, apiKey }),
 *     gate: heldOutGate({ minDelta: 0.02 }),
 *     autoOnPromote: 'none',
 *   })
 */
import type { AnalyzeTracesInput, AnalyzeTracesOptions, AnalyzeTracesResult } from '../trace-analyst/analyst';
import type { DispatchContext, JudgeConfig, MutableSurface, Scenario } from './types';
/**
 * A labeled trace scenario: a FIXED trace corpus plus the failure modes a
 * competent analyst MUST surface from it. The labels are ground truth — the
 * objective failures that actually occurred — which is what makes optimizing
 * the analyst prompt against them meaningful rather than circular.
 */
export interface AnalystScenario extends Scenario {
    kind: 'analyst-surface';
    /** OTLP-JSONL path or an in-memory store of the traces to analyze. */
    source: AnalyzeTracesOptions['source'];
    /** The domain question handed to the analyst (framing lives here, not in
     *  the surface under optimization). */
    question: string;
    /**
     * Ground-truth failure modes a good analyst must identify. A finding "hits"
     * a mode when it contains ANY of the mode's case-insensitive cues. Derive
     * these from objective signal (failed task + which step broke), never from
     * the analyst's own prior output.
     */
    expectedFailureModes: Array<{
        id: string;
        cues: string[];
    }>;
    /**
     * Cues that mark a finding as HALLUCINATED / out-of-scope for this corpus —
     * naming a tool, error, or failure that did not occur. Presence penalizes
     * precision. Optional; omit to score recall only.
     */
    forbiddenCues?: string[];
}
/** The analyst's output for one scenario — the artifact the judge scores. */
export interface AnalystArtifact {
    answer: string;
    findings: string[];
    /** The hardcoded-prompt version the analyst reported (provenance only; the
     *  optimized surface overrides the actual prompt text used). */
    actorPromptVersion: string;
}
export interface BuildAnalystSurfaceDispatchOptions {
    /**
     * Everything `analyzeTraces` needs EXCEPT `actorDescription` (supplied by the
     * surface under optimization) and `source` (supplied by the scenario). `ai`
     * (the AxAIService) is required for a live run.
     */
    analystOptions: Omit<AnalyzeTracesOptions, 'actorDescription' | 'source'>;
    /** Test seam: defaults to the real `analyzeTraces`. */
    analyze?: (input: AnalyzeTracesInput, options: AnalyzeTracesOptions) => Promise<AnalyzeTracesResult>;
}
/**
 * Build the `dispatchWithSurface(surface, scenario, ctx)` the improvement loop
 * calls: run the analyst with `surface` as its actorDescription over the
 * scenario's trace corpus and return its findings.
 */
export declare function buildAnalystSurfaceDispatch(opts: BuildAnalystSurfaceDispatchOptions): (surface: MutableSurface, scenario: AnalystScenario, ctx: DispatchContext) => Promise<AnalystArtifact>;
export interface FailureModeRecallJudgeOptions {
    /** Weight on recall when precision is also scored (forbiddenCues present).
     *  Default 0.5 (equal). Recall-only when no forbiddenCues exist. */
    recallWeight?: number;
}
/**
 * Deterministic, ground-truth judge for analyst findings. Composite =
 * recall of the scenario's `expectedFailureModes` (optionally blended with a
 * precision term that penalizes findings tripping `forbiddenCues`). No LLM —
 * the score is a function of the labels, so the analyst prompt is optimized
 * toward surfacing real failures, not toward a judge it can flatter.
 */
export declare function failureModeRecallJudge(opts?: FailureModeRecallJudgeOptions): JudgeConfig<AnalystArtifact, AnalystScenario>;
//# sourceMappingURL=analyst-surface.d.ts.map