import { Scenario, ScenarioGroup, SimulationDispatch, SimulationMode, SimulationRun, SimulationRun_Job } from '@livekit/protocol';
import type { JobContext } from './job.js';
export { Scenario, ScenarioGroup, SimulationDispatch, SimulationMode, SimulationRun, SimulationRun_Job, };
/** A pass/fail verdict for a scenario, with a human-readable reason. */
export interface SimulationVerdict {
    success: boolean;
    reason: string;
}
/** Decoded form of a Scenario's `userdata` (arbitrary JSON). On the wire it is
 * a JSON-encoded string; in a scenarios.yaml it is written as a nested mapping. */
export type ScenarioUserdata = {
    [key: string]: unknown;
};
/** Decode a protojson `SimulationDispatch`, ignoring unknown fields so newer
 * servers can add fields without breaking older SDKs. Throws on malformed
 * input. */
export declare function parseSimulationDispatch(raw: string): SimulationDispatch;
/**
 * Passed to the `onSimulationEnd` callback while running under a simulation.
 *
 * Carries two verdicts, both recorded for the run:
 * - {@link simulatorVerdict}: the simulator's verdict (its LLM judgment of the chat).
 * - {@link userVerdict}: your own veto, set via {@link fail} from richer checks
 *   (e.g. comparing mock backend state against the benchmark target in
 *   `scenario.userdata`). The effective result is the AND of the two: your
 *   check can fail a run the simulator passed, but it can never rescue one, so
 *   there is no `success()`; not calling {@link fail} leaves the simulator's
 *   verdict to stand.
 *
 * Use {@link jobContext} to reach the running session and the room.
 */
export declare class SimulationContext {
    #private;
    /** @internal */
    _dispatch: SimulationDispatch;
    constructor(dispatch: SimulationDispatch, jobCtx: JobContext);
    get scenario(): Scenario;
    /** How the simulated user interacts with the agent (text chat or audio).
     * Unspecified is treated as text, since simulations predating the field
     * were all text-only. */
    get simulationMode(): SimulationMode;
    /** The run this session belongs to. Available as soon as the entrypoint runs,
     * unlike {@link SimulationContext.simulationRun}, which the framework only fills in at the end. */
    get simulationRunId(): string;
    /** The run job (one scenario) behind this session, likewise available up front. */
    get simulationJobId(): string;
    /** The run, or `undefined` before the simulation ends.
     *
     * Carries only its `id` today, so every other field reads as its protobuf
     * default rather than the run's real state. Prefer {@link SimulationContext.simulationRunId},
     * which is the same ID and is available from the entrypoint. */
    get simulationRun(): SimulationRun | undefined;
    /** The simulator's verdict (its LLM judgment of the conversation). Read-only;
     * recorded alongside your {@link userVerdict}.
     *
     * Only available once the simulation has ended, i.e. inside
     * `onSimulationEnd`. Throws if accessed earlier (e.g. from the entrypoint). */
    get simulatorVerdict(): SimulationVerdict;
    /** The `JobContext` for this run; use it to reach the running session and
     * the room. */
    get jobContext(): JobContext;
    /** @internal Populate the simulator verdict / run before `onSimulationEnd`. */
    _beginFinalize(opts: {
        simulatorVerdict: SimulationVerdict;
        run?: SimulationRun;
    }): void;
    /** The scenario's `userdata` decoded from its JSON string (`{}` if empty). */
    userdata(): ScenarioUserdata;
    /** Veto this run from your own checks (e.g. final DB state diverged).
     *
     * The effective result is the AND of both verdicts, so this can only fail a
     * run the simulator passed, never rescue one. The simulator's verdict is
     * still reported. The last call wins if you call {@link fail} more than once. */
    fail(reason?: string): void;
    /** Your veto set via {@link fail}, or undefined if you didn't veto the run. */
    get userVerdict(): SimulationVerdict | undefined;
}
//# sourceMappingURL=simulation.d.ts.map