import { z } from 'zod';
import { OpenAPIObject } from 'openapi3-ts/oas31';
import * as hono_types from 'hono/types';
import { ServerType } from '@hono/node-server';
import { Hono } from 'hono';

type CostChannel = 'agent' | 'judge' | 'verifier' | 'analyst' | 'driver' | (string & {});
interface CostUsage {
    inputTokens: number;
    /** Includes reasoning tokens when the provider bills them as output. */
    outputTokens: number;
    /** Reasoning-token subset of outputTokens, when reported. */
    reasoningTokens?: number;
    /** Prompt tokens served from a provider cache. */
    cachedTokens?: number;
    /** Prompt tokens written into a provider cache. */
    cacheWriteTokens?: number;
}
interface CostCallBase {
    callId: string;
    channel: CostChannel;
    phase: string;
    actor: string;
    model: string;
    maximumCostUsd?: number;
    tags?: Record<string, string>;
    timestamp: number;
}
interface PendingCostCall extends CostCallBase {
    status: 'pending';
}
interface PendingCostCallView extends PendingCostCall {
    state: 'active' | 'late' | 'interrupted';
}
interface CostReceipt extends CostCallBase, CostUsage {
    status: 'settled';
    costUsd: number;
    costUnknown: boolean;
    usageUnknown?: boolean;
    /** Rates used to estimate cost locally. Absent when cost is provider-reported or unknown. */
    pricing?: {
        inputUsdPerThousand: number;
        cachedInputUsdPerThousand?: number;
        cacheWriteUsdPerThousand?: number;
        outputUsdPerThousand: number;
    };
    /** Cost reported by the provider, not a local token-price calculation. */
    actualCostUsd?: number;
    error?: string;
}
interface CostReceiptInput extends CostUsage {
    model: string;
    /** Caller-supplied rates for a local estimate when the provider does not report billed cost. */
    customTokenPricing?: CustomTokenPricing;
    actualCostUsd?: number;
    costUnknown?: boolean;
    usageUnknown?: boolean;
}
/** Per-million token rates for a model or endpoint not covered by package pricing. */
interface CustomTokenPricing {
    /** Non-cached input tokens. */
    inputUsdPerMillion: number;
    /** Cache-read tokens. Falls back to the normal input rate when omitted. */
    cachedInputUsdPerMillion?: number;
    /** Cache-creation or cache-write tokens. Falls back to the normal input rate when omitted. */
    cacheWriteUsdPerMillion?: number;
    outputUsdPerMillion: number;
}
type MaximumCharge = {
    externallyEnforcedMaximumUsd: number;
} | ({
    customTokenPricing: CustomTokenPricing;
} & Pick<CostUsage, 'inputTokens' | 'outputTokens' | 'cachedTokens' | 'cacheWriteTokens'>) | ({
    model: string;
} & CostUsage);
interface RunPaidCallInput<T> {
    callId?: string;
    channel: CostChannel;
    phase: string;
    actor: string;
    /** Used before a provider receipt exists and on failures without one. */
    model?: string;
    tags?: Record<string, string>;
    signal?: AbortSignal;
    /** Provider-enforced dollar maximum, or maximum token usage with known pricing. Required when capped. */
    maximumCharge?: MaximumCharge;
    /** `callId` can be forwarded as the provider's idempotency key. */
    execute(signal: AbortSignal, callId: string): Promise<T>;
    receipt(value: T): CostReceiptInput;
    receiptFromError?(error: Error): CostReceiptInput | undefined;
}
type PaidCallResult<T> = {
    succeeded: true;
    callId: string;
    value: T;
    receipt: CostReceipt;
} | {
    succeeded: false;
    callId?: string;
    error: Error;
    receipt?: CostReceipt;
};
interface ChannelRollup {
    channel: CostChannel;
    calls: number;
    inputTokens: number;
    outputTokens: number;
    reasoningTokens?: number;
    cachedTokens: number;
    cacheWriteTokens?: number;
    costUsd: number;
    unpricedCalls: number;
    unknownUsageCalls: number;
}
interface CostLedgerSummary {
    totalCalls: number;
    pendingCalls: number;
    unresolvedCalls: number;
    reservedCostUsd: number;
    inputTokens: number;
    outputTokens: number;
    reasoningTokens?: number;
    cachedTokens: number;
    cacheWriteTokens?: number;
    totalCostUsd: number;
    byChannel: ChannelRollup[];
    unpricedModels: string[];
    fullyPriced: boolean;
    usageComplete: boolean;
    accountingComplete: boolean;
    incompleteReasons: string[];
}
interface CostLedgerFilter {
    channel?: CostChannel;
    phase?: string;
    tags?: Record<string, string>;
}
interface CostLedgerWaitOptions {
    /** Maximum time to wait for active provider calls. Default 5 seconds. */
    timeoutMs?: number;
    /** Wait only for calls matching this attribution filter. */
    filter?: CostLedgerFilter;
}
/** Append-only storage. `append` must atomically reject stale revisions. */
interface CostLedgerPersistence {
    read(): {
        revision: string;
        events: string;
    };
    append(expectedRevision: string, event: string): string | undefined;
}
interface CostLedgerOptions {
    costCeilingUsd?: number;
    persistence?: CostLedgerPersistence;
    /** Import already-settled receipts without admitting new paid work. */
    receipts?: readonly CostReceipt[];
}
/** Run-wide paid-call admission, durable call state, receipts, and summaries. */
declare class CostLedger {
    private readonly records;
    private readonly activeCallIds;
    private readonly lateCallIds;
    private readonly idleWaiters;
    private completedTasks;
    private revision;
    private costLimitPersisted;
    readonly costCeilingUsd?: number;
    private readonly persistence?;
    constructor(input?: number | CostLedgerOptions);
    runPaidCall<T>(input: RunPaidCallInput<T>): Promise<PaidCallResult<T>>;
    /** Wait until every call started by this ledger has produced a durable outcome. */
    waitForIdle(options?: CostLedgerWaitOptions): Promise<boolean>;
    /** Settle a call left pending by a crashed process after reconciling with the provider. */
    reconcile(callId: string, observed: CostReceiptInput, options?: {
        error?: string;
    }): CostReceipt;
    list(filter?: CostLedgerFilter): CostReceipt[];
    /** Read pending calls without exposing mutable ledger state. */
    listPending(filter?: CostLedgerFilter): PendingCostCallView[];
    summary(filter?: CostLedgerFilter): CostLedgerSummary;
    markCompleted(count?: number): void;
    costPerCompletedTask(): number | null;
    private execute;
    private captureLateOutcome;
    private releaseActiveCall;
    private commitOutcome;
    private captureFailure;
    private commitReceipt;
    private resolveMaximum;
    private hasIncompleteSettledCall;
    private appendRecord;
    private ensureCostLimitPersisted;
    private appendEvent;
}
/** Public callback surface for a shared cost ledger.
 *
 * Declaration bundles may expose this type through multiple package subpaths.
 * Keeping callback contracts structural lets those subpaths compose while the
 * concrete {@link CostLedger} retains its private durable state.
 */
type CostLedgerHandle = Pick<CostLedger, Exclude<keyof CostLedger, 'listPending' | 'waitForIdle'>> & Partial<Pick<CostLedger, 'listPending' | 'waitForIdle'>>;

type RunStatus = 'running' | 'completed' | 'failed' | 'aborted';
interface BudgetSpec {
    tokens?: number;
    wallMs?: number;
    calls?: number;
    usd?: number;
}
interface RunOutcome {
    score?: number;
    pass?: boolean;
    failureClass?: FailureClass;
    notes?: string;
}
/**
 * Layer — optional classification in a nested build workflow.
 * `builder`: the meta-agent editing a project (e.g. agent-builder Forge chat).
 * `app-build`: sandbox harness that compiled + tested the generated scaffold.
 * `app-runtime`: a run of the generated agent against a domain scenario.
 * `meta`: any meta-eval (judge replay, correlation analysis).
 */
type RunLayer = 'builder' | 'app-build' | 'app-runtime' | 'meta' | 'custom';
interface Run {
    runId: string;
    /**
     * Stable identifier of the scenario being executed.
     *
     * Always populated on the persisted Run — but `TraceEmitter.startRun` accepts
     * input WITHOUT this field, substituting a sensible default
     * (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) when the caller has no
     * curated scenario to anchor to (runtime / operator / meta-eval runs). This
     * keeps the persisted shape unambiguous for downstream filters + aggregations
     * while removing the boilerplate of inventing placeholder ids at the call site.
     */
    scenarioId: string;
    variantId?: string;
    datasetVersion?: string;
    /** Git SHA of agent code at run time. */
    codeSha?: string;
    /** Hash of the prompt template + any system prompt. */
    promptSha?: string;
    /** Model id + date + system-prompt hash, concatenated. */
    modelFingerprint?: string;
    seed?: number;
    /** Arbitrary environment markers (shell, docker version, tz). */
    envFingerprint?: Record<string, string>;
    /** Version of the redaction rules applied to this run. */
    redactionVersion?: string;
    /** Parent run in a nested build workflow. A builder run's children are
     *  app-build runs; those children are app-runtime runs. */
    parentRunId?: string;
    /** Stable project identifier — groups runs across chats + sessions. */
    projectId?: string;
    /** Chat/conversation identifier within a project. */
    chatId?: string;
    /** Layer classification — hint for aggregation; not enforced. */
    layer?: RunLayer;
    startedAt: number;
    endedAt?: number;
    status: RunStatus;
    outcome?: RunOutcome;
    budget?: BudgetSpec;
    /** Free-form labels for downstream grouping. */
    tags?: Record<string, string>;
}
type SpanKind = 'agent' | 'llm' | 'tool' | 'retrieval' | 'judge' | 'sandbox' | 'custom';
type SpanStatus = 'ok' | 'error';
interface SpanBase {
    spanId: string;
    parentSpanId?: string;
    runId: string;
    kind: SpanKind;
    name: string;
    startedAt: number;
    endedAt?: number;
    status?: SpanStatus;
    error?: string;
    /** Anything not covered by typed fields. Kept deliberately free-form. */
    attributes?: Record<string, unknown>;
}
interface Message {
    role: 'system' | 'user' | 'assistant' | 'tool';
    content: string;
    tokens?: number;
    /** Multi-modal content descriptors; blobs themselves live in Artifacts. */
    images?: Array<{
        artifactId?: string;
        url?: string;
        mime?: string;
    }>;
}
interface LlmSpan extends SpanBase {
    kind: 'llm';
    model: string;
    messages: Message[];
    output?: string;
    inputTokens?: number;
    /** All generated tokens, including the reasoning subset when present. */
    outputTokens?: number;
    cachedTokens?: number;
    cacheWriteTokens?: number;
    /** Reasoning-token subset of `outputTokens`. */
    reasoningTokens?: number;
    costUsd?: number;
    finishReason?: string;
}
interface ToolSpan extends SpanBase {
    kind: 'tool';
    toolName: string;
    args: unknown;
    /** False when the source observed the call but did not capture its arguments. */
    argsCaptured?: boolean;
    result?: unknown;
    latencyMs?: number;
}
interface RetrievalSpan extends SpanBase {
    kind: 'retrieval';
    query: string;
    hits: Array<{
        docId: string;
        score: number;
        content?: string;
    }>;
}
interface JudgeSpan extends SpanBase {
    kind: 'judge';
    judgeId: string;
    /** Span this judgment applies to. */
    targetSpanId: string;
    dimension: string;
    /** Numeric score (free-range; interpretation up to the judge). */
    score: number;
    rationale?: string;
    evidence?: string;
}
interface SandboxSpan extends SpanBase {
    kind: 'sandbox';
    image?: string;
    command?: string;
    exitCode?: number;
    testsTotal?: number;
    testsPassed?: number;
    stdoutHash?: string;
    stderrHash?: string;
    /** Duration in ms; the harness fills this explicitly (endedAt - startedAt may miss setup). */
    wallMs?: number;
}
interface GenericSpan extends SpanBase {
    kind: 'agent' | 'custom';
}
type Span = LlmSpan | ToolSpan | RetrievalSpan | JudgeSpan | SandboxSpan | GenericSpan;
type EventKind = 'log' | 'error' | 'budget_decrement' | 'budget_breach' | 'state_mutation' | 'policy_violation' | 'redaction_applied' | 'custom';
interface TraceEvent$1 {
    eventId: string;
    runId: string;
    spanId?: string;
    kind: EventKind;
    timestamp: number;
    payload: Record<string, unknown>;
}
interface BudgetLedgerEntry {
    runId: string;
    dimension: keyof BudgetSpec;
    limit: number;
    consumed: number;
    remaining: number;
    timestamp: number;
    breached: boolean;
    /** Span that triggered this entry, if any. */
    spanId?: string;
}
interface Artifact {
    artifactId: string;
    runId: string;
    spanId?: string;
    contentType: string;
    sizeBytes: number;
    /** sha256 in hex. */
    hash: string;
    /** External storage URL (R2, S3, filesystem path). */
    storageUrl?: string;
    /** Inline content for small blobs — keep under ~64KB. */
    inlineContent?: string;
}
type FailureClass = 'success' | 'reasoning_error' | 'tool_selection_error' | 'tool_argument_error' | 'tool_recovery_failure' | 'hallucination' | 'instruction_following' | 'safety_refusal_miss' | 'policy_violation' | 'budget_exceeded' | 'format_drift' | 'permission_escalation' | 'pii_leak' | 'cost_overrun' | 'timeout' | 'sandbox_failure' | 'missing_user_data' | 'missing_domain_data' | 'missing_codebase_context' | 'missing_runtime_context' | 'missing_credentials' | 'missing_integration_connection' | 'missing_integration_scope' | 'integration_approval_required' | 'integration_auth_expired' | 'integration_provider_failure' | 'bad_integration_manifest' | 'unsafe_integration_write_denied' | 'stale_external_data' | 'bad_retrieval' | 'insufficient_evidence' | 'contradictory_evidence' | 'ambiguous_user_intent' | 'knowledge_readiness_blocked' | 'unknown';

interface RunFilter {
    scenarioId?: string;
    variantId?: string;
    status?: RunStatus;
    since?: number;
    until?: number;
    tag?: {
        key: string;
        value: string;
    };
    parentRunId?: string;
    projectId?: string;
    chatId?: string;
    layer?: RunLayer;
}
interface SpanFilter {
    runId?: string;
    parentSpanId?: string;
    kind?: SpanKind;
    name?: string;
    toolName?: string;
    judgeId?: string;
    since?: number;
    until?: number;
}
interface EventFilter {
    runId?: string;
    spanId?: string;
    kind?: EventKind;
    since?: number;
    until?: number;
}
interface TraceStore {
    appendRun(run: Run): Promise<void>;
    updateRun(runId: string, patch: Partial<Run>): Promise<void>;
    appendSpan(span: Span): Promise<void>;
    updateSpan(spanId: string, patch: Partial<Span>): Promise<void>;
    appendEvent(event: TraceEvent$1): Promise<void>;
    appendArtifact(artifact: Artifact): Promise<void>;
    appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void>;
    getRun(runId: string): Promise<Run | undefined>;
    listRuns(filter?: RunFilter): Promise<Run[]>;
    spans(filter?: SpanFilter): Promise<Span[]>;
    events(filter?: EventFilter): Promise<TraceEvent$1[]>;
    budget(runId: string): Promise<BudgetLedgerEntry[]>;
    artifacts(runId: string): Promise<Artifact[]>;
}

/**
 * Policy-based agent control runtime.
 *
 * This is the minimal reusable loop behind driver-agent patterns:
 *
 *   observe state -> validate -> decide next action -> act -> observe -> ...
 *
 * It deliberately does not model named "topologies". Direct execution,
 * critic/revise, driver intervention, specialist calls, and human escalation
 * are all just actions chosen by the control policy.
 */

type ControlSeverity = 'info' | 'warning' | 'error' | 'critical';
interface ControlEvalResult {
    /** Stable validator or judge id. */
    id: string;
    /** Whether this check passed. */
    passed: boolean;
    /** Optional normalized score. 1 = best, 0 = worst. */
    score?: number;
    /** Objective validators should usually be "error" or "critical" when failed. */
    severity?: ControlSeverity;
    /** Human-readable result. */
    detail?: string;
    /** Small evidence string or pointer. Avoid large payloads. */
    evidence?: string;
    /** True when the result came from deterministic state, not LLM judgment. */
    objective?: boolean;
    /** Structured details for downstream control policies and reports. */
    metadata?: Record<string, unknown>;
}

/**
 * Dataset — versioned, sliceable, content-hashed scenario collection.
 *
 * Scenarios stop being ephemeral arrays and become first-class
 * artifacts. Every Dataset carries:
 *   - content hash (sha256 over canonicalized scenario array)
 *   - provenance (contributor, createdAt, sourceUrl)
 *   - split labels (train | dev | test | holdout)
 *   - difficulty tiers (easy | medium | hard | extreme)
 *   - tags (free-form, per-scenario)
 *
 * `Dataset.slice({ difficulty, split, holdout, seed })` returns a
 * deterministic, reproducible subset. Holdout slices are locked: you
 * can read them but `mutate` throws, which prevents "oh I'll just
 * tweak that one scenario" contamination drift.
 */
type DatasetSplit = 'train' | 'dev' | 'test' | 'holdout';

type FeedbackArtifactType = 'text' | 'code' | 'plan' | 'research' | 'action' | 'ui' | 'decision' | 'data' | 'other';
type FeedbackLabelSource = 'user' | 'judge' | 'environment' | 'metric' | 'policy' | 'system';
type FeedbackLabelKind = 'approve' | 'reject' | 'select' | 'edit' | 'rank' | 'rate' | 'comment' | 'metric_outcome' | 'policy_block' | 'revision_request';
type FeedbackSeverity = 'info' | 'warning' | 'error' | 'critical';
interface FeedbackTask {
    intent: string;
    context?: unknown;
}
interface ProposedSideEffect {
    type: string;
    risk?: 'low' | 'medium' | 'high';
    costUsd?: number;
    externalSideEffect?: boolean;
    requiresApproval?: boolean;
    metadata?: Record<string, unknown>;
}
interface FeedbackLabel {
    id?: string;
    source: FeedbackLabelSource;
    kind: FeedbackLabelKind;
    value: unknown;
    reason?: string;
    severity?: FeedbackSeverity;
    createdAt: string;
    metadata?: Record<string, unknown>;
}
interface FeedbackAttempt {
    id: string;
    stepIndex: number;
    artifactType: FeedbackArtifactType;
    artifact: unknown;
    options?: unknown[];
    proposedAction?: ProposedSideEffect;
    evals?: ControlEvalResult[];
    feedback?: FeedbackLabel[];
    createdAt: string;
    metadata?: Record<string, unknown>;
}
interface FeedbackOutcome {
    success?: boolean;
    score?: number;
    metrics?: Record<string, number>;
    costUsd?: number;
    detail?: string;
    observedAt?: string;
    metadata?: Record<string, unknown>;
}
interface FeedbackTrajectory$1 {
    id: string;
    projectId?: string;
    scenarioId?: string;
    task: FeedbackTask;
    attempts: FeedbackAttempt[];
    labels: FeedbackLabel[];
    outcome?: FeedbackOutcome;
    split?: DatasetSplit;
    tags?: Record<string, string>;
    createdAt: string;
    updatedAt?: string;
    metadata?: Record<string, unknown>;
}
interface FeedbackTrajectoryStore {
    save(trajectory: FeedbackTrajectory$1): Promise<void>;
    get(id: string): Promise<FeedbackTrajectory$1 | null>;
    list(filter?: FeedbackTrajectoryFilter): Promise<FeedbackTrajectory$1[]>;
    appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory$1>;
    appendLabel(id: string, label: FeedbackLabel, attemptId?: string): Promise<FeedbackTrajectory$1>;
}
interface FeedbackTrajectoryFilter {
    projectId?: string;
    scenarioId?: string;
    split?: DatasetSplit;
    tag?: [string, string];
}

/**
 * RawProviderSink — first-class persistence for the actual HTTP-level
 * request/response bodies of every LLM provider call.
 *
 * Why this is a separate sink from the structured `LlmSpan`:
 *
 *   - `LlmSpan` records the *intent* — model name, messages, output text,
 *     usage. It's what dashboards read; it's NOT enough for forensics.
 *   - When a downstream consumer reports "the verifier used the wrong route"
 *     or "tokens look right but reasoning was missing," the only way to
 *     answer is the raw HTTP body. Span fields can lie (a proxy can echo
 *     a different `model` value than what actually answered); the raw
 *     response is ground truth.
 *
 * Default behaviour: opt-in. Pass `rawSink` to `LlmClientOptions` (or the
 * matrix runner / BuilderSession sets it up automatically) and every
 * request, response, and error is recorded — including retries, with the
 * attempt index attached so a flaky call's full event chain is recoverable.
 *
 * Redaction is enforced at sink time. The default redactor strips
 * `Authorization`, `X-Api-Key`, `X-Auth-Token`, `Cookie` headers and any
 * payload field whose key matches `apiKey | api_key | bearer | password |
 * secret | token` (case-insensitive). Override via the sink constructor or
 * the per-call `redactor`. The `redactedFields` array on the persisted
 * event lets a reviewer see what was stripped without exposing the values.
 */
type RawProviderDirection = 'request' | 'response' | 'error';
interface RawProviderEvent {
    /** Stable id. Generated by the sink if omitted. */
    eventId: string;
    /** Trace context populated by `LlmClient` when the call is wrapped in a span. */
    runId?: string;
    spanId?: string;
    /**
     * Logical provider name. Free-form so callers can use whatever id matches
     * their topology (`'openai'`, `'anthropic'`, `'tangle-router'`, …). When
     * omitted, derived from `baseUrl` in `LlmClientOptions`.
     */
    provider: string;
    model: string;
    /** Endpoint path, e.g. `'/v1/chat/completions'`. */
    endpoint: string;
    /** Base URL used for the call (already-normalised — no trailing slash). */
    baseUrl: string;
    /** 0-indexed retry attempt. The first attempt is 0; a retried call gets 1, 2, … */
    attemptIndex: number;
    direction: RawProviderDirection;
    /** Unix ms. */
    timestamp: number;
    /** Wall-clock duration of the call leg. Set on `response` and `error` events; null on `request`. */
    durationMs?: number;
    statusCode?: number;
    requestHeaders?: Record<string, string>;
    requestBody?: unknown;
    responseHeaders?: Record<string, string>;
    responseBody?: unknown;
    /** Set on `direction: 'error'` events. */
    errorMessage?: string;
    /** Field paths the redactor stripped from this event ('header:Authorization', 'body.apiKey', …). */
    redactedFields: string[];
}
interface RawProviderSinkFilter {
    runId?: string;
    spanId?: string;
    direction?: RawProviderDirection;
    attemptIndex?: number;
}
interface RawProviderSink {
    record(event: RawProviderEvent): Promise<void>;
    /** Optional listing — implementations that durably persist (file, db) should support this. */
    list?(filter?: RawProviderSinkFilter): Promise<RawProviderEvent[]>;
    /** Optional teardown for backed implementations. */
    close?(): Promise<void>;
}
type ProviderRedactor = (event: RawProviderEvent) => RawProviderEvent;

/**
 * LLM client with graceful degrade.
 *
 * OpenAI-compatible `/v1/chat/completions` client with:
 *   - Exponential-backoff retry on 429 + 5xx gateway errors (502/503/504).
 *   - Retry on transient network errors (fetch failed, AbortError, ECONNRESET).
 *   - Graceful json_schema → json_object degrade on 400 with schema-reject body.
 *   - Fenced-JSON stripping (```json ... ```) for models that wrap structured output.
 *   - Configurable base URL + api key / bearer, works with LiteLLM proxies, OpenAI
 *     directly, cli-bridge subscriptions, and any router that speaks the spec.
 *
 * Usage:
 *   const { value, result } = await callLlmJson<MyType>(
 *     { model: 'gpt-4o', messages: [...], jsonSchema: { name: 'x', schema: {...} } },
 *     { baseUrl: 'https://router.tangle.tools/v1', apiKey: process.env.KEY },
 *   )
 *
 * This is THE llm-calling seam for agent-eval primitives that need structured
 * output (semantic concept judge, reviewer directives, critic scores). Primitives
 * that need free-form text use `callLlm` and parse output themselves.
 */

type LlmThinkingMode = 'enabled' | 'disabled';
interface LlmClientOptions {
    /** Base URL (without trailing slash). Must end at the `/v1` prefix. */
    baseUrl?: string;
    /** Bearer token — either `apiKey` or `bearer` populates `Authorization: Bearer ...`. */
    apiKey?: string;
    bearer?: string;
    /** Override for the `Authorization` header (e.g. `X-Auth: ...`). Takes precedence over apiKey/bearer. */
    authHeader?: {
        name: string;
        value: string;
    };
    /** Stable provider idempotency key, reused across retries of this logical call. */
    idempotencyKey?: string;
    /** Default timeout in ms. Per-call can override. */
    defaultTimeoutMs?: number;
    /**
     * Caller-supplied abort signal — e.g. a campaign-wide cancel. Linked to
     * each attempt's per-attempt timeout controller, so aborting it cancels
     * the in-flight fetch. A caller abort is FATAL: it is not retried even
     * though an AbortError otherwise matches the transient patterns.
     */
    signal?: AbortSignal;
    /**
     * Cross-attempt wall-clock budget in ms, measured from the first attempt.
     * Before launching each attempt the loop checks the remaining budget and
     * stops retrying once it is exhausted, rather than waiting the full
     * per-attempt timeout on every retry. Bounds total time independent of
     * total attempts × `timeoutMs`.
     */
    deadlineMs?: number;
    /** Total provider attempts. Legacy option name; default 3 (1 initial + 2 retries). */
    maxRetries?: number;
    /** Token rates used when the provider omits cost or package pricing does not cover the model. */
    customTokenPricing?: CustomTokenPricing;
    /**
     * Transport for requests that declare `jsonSchema`. `native` sends
     * `response_format: json_schema`; `json-object` sends the broadly supported
     * JSON mode and relies on the caller to include the schema in model-visible
     * instructions. Default: `native`.
     */
    jsonSchemaTransport?: 'native' | 'json-object';
    /**
     * JSON payload parsing policy. `extract` accepts fenced or prose-prefixed JSON.
     * `exact` requires the complete response content to be one JSON value.
     * Default: `extract`.
     */
    jsonPayloadMode?: 'extract' | 'exact';
    /** Default provider reasoning mode. A per-call request value takes precedence. */
    thinking?: LlmThinkingMode;
    /** Fetch implementation — defaults to global `fetch`. Override for custom transport (e.g. tests). */
    fetch?: typeof fetch;
    /**
     * Optional raw HTTP capture sink. When provided, every request, response,
     * and error (across all retry attempts) is recorded to the sink, with auth
     * headers and credential-shaped body fields redacted by default. This is
     * the layer-1 forensics primitive: structured `LlmSpan`s record intent,
     * raw events record what actually crossed the wire.
     */
    rawSink?: RawProviderSink;
    /**
     * Logical provider id attached to raw events. When omitted, derived from
     * `baseUrl` via `providerFromBaseUrl`.
     */
    provider?: string;
    /** Trace context attached to raw events; populated by emitter-aware callers. */
    traceContext?: {
        runId?: string;
        spanId?: string;
    };
    /** Override the redaction strategy for this call. Defaults to `defaultProviderRedactor`. */
    redactor?: ProviderRedactor;
}
interface LlmRouteRequirements {
    /**
     * Throw if `opts.baseUrl` is undefined, i.e. the call would fall back to
     * `DEFAULT_BASE_URL`. Set this for evaluation runs where silently using
     * the public/free-tier router is a defect — the launch reviewer needs to
     * know exactly which provider answered.
     */
    requireExplicitBaseUrl?: boolean;
    /**
     * Allowlist of acceptable base URLs. Strings match by prefix
     * (case-insensitive); RegExps test against the full base URL.
     */
    allowedBaseUrls?: Array<string | RegExp>;
    /** Blocklist that takes precedence over `allowedBaseUrls`. */
    blockedBaseUrls?: Array<string | RegExp>;
    /** Throw if no auth header / api key is configured. */
    requireAuth?: boolean;
    /**
     * Logical provider id the configured `baseUrl` is expected to match (via
     * `providerFromBaseUrl`). Mainly useful when paired with `requireExplicitBaseUrl`.
     */
    expectedProvider?: string;
}

declare const RubricDimensionSchema: z.ZodObject<{
    id: z.ZodString;
    description: z.ZodString;
    weight: z.ZodDefault<z.ZodNumber>;
    min: z.ZodDefault<z.ZodNumber>;
    max: z.ZodDefault<z.ZodNumber>;
}, z.core.$strip>;
declare const FailureModeSchema: z.ZodObject<{
    id: z.ZodString;
    description: z.ZodString;
}, z.core.$strip>;
declare const RubricSchema: z.ZodObject<{
    name: z.ZodString;
    description: z.ZodString;
    systemPrompt: z.ZodString;
    dimensions: z.ZodArray<z.ZodObject<{
        id: z.ZodString;
        description: z.ZodString;
        weight: z.ZodDefault<z.ZodNumber>;
        min: z.ZodDefault<z.ZodNumber>;
        max: z.ZodDefault<z.ZodNumber>;
    }, z.core.$strip>>;
    failureModes: z.ZodDefault<z.ZodArray<z.ZodObject<{
        id: z.ZodString;
        description: z.ZodString;
    }, z.core.$strip>>>;
    wins: z.ZodDefault<z.ZodArray<z.ZodObject<{
        id: z.ZodString;
        description: z.ZodString;
    }, z.core.$strip>>>;
}, z.core.$strip>;
declare const JudgeRequestSchema: z.ZodObject<{
    rubricName: z.ZodOptional<z.ZodString>;
    rubric: z.ZodOptional<z.ZodObject<{
        name: z.ZodString;
        description: z.ZodString;
        systemPrompt: z.ZodString;
        dimensions: z.ZodArray<z.ZodObject<{
            id: z.ZodString;
            description: z.ZodString;
            weight: z.ZodDefault<z.ZodNumber>;
            min: z.ZodDefault<z.ZodNumber>;
            max: z.ZodDefault<z.ZodNumber>;
        }, z.core.$strip>>;
        failureModes: z.ZodDefault<z.ZodArray<z.ZodObject<{
            id: z.ZodString;
            description: z.ZodString;
        }, z.core.$strip>>>;
        wins: z.ZodDefault<z.ZodArray<z.ZodObject<{
            id: z.ZodString;
            description: z.ZodString;
        }, z.core.$strip>>>;
    }, z.core.$strip>>;
    content: z.ZodString;
    context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    model: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
declare const JudgeResultSchema: z.ZodObject<{
    composite: z.ZodNumber;
    dimensions: z.ZodRecord<z.ZodString, z.ZodNumber>;
    failureModes: z.ZodDefault<z.ZodArray<z.ZodString>>;
    wins: z.ZodDefault<z.ZodArray<z.ZodString>>;
    rationale: z.ZodString;
    rubricVersion: z.ZodString;
    model: z.ZodString;
    durationMs: z.ZodNumber;
}, z.core.$strip>;
declare const RubricInfoSchema: z.ZodObject<{
    name: z.ZodString;
    description: z.ZodString;
    dimensions: z.ZodArray<z.ZodObject<{
        id: z.ZodString;
        description: z.ZodString;
        weight: z.ZodNumber;
    }, z.core.$strip>>;
    failureModes: z.ZodDefault<z.ZodArray<z.ZodString>>;
    rubricVersion: z.ZodString;
}, z.core.$strip>;
declare const ListRubricsResponseSchema: z.ZodObject<{
    rubrics: z.ZodArray<z.ZodObject<{
        name: z.ZodString;
        description: z.ZodString;
        dimensions: z.ZodArray<z.ZodObject<{
            id: z.ZodString;
            description: z.ZodString;
            weight: z.ZodNumber;
        }, z.core.$strip>>;
        failureModes: z.ZodDefault<z.ZodArray<z.ZodString>>;
        rubricVersion: z.ZodString;
    }, z.core.$strip>>;
}, z.core.$strip>;
declare const VersionResponseSchema: z.ZodObject<{
    package: z.ZodString;
    version: z.ZodString;
    wireVersion: z.ZodString;
    apiSurface: z.ZodArray<z.ZodString>;
}, z.core.$strip>;
declare const HealthResponseSchema: z.ZodObject<{
    status: z.ZodLiteral<"ok">;
    uptimeSec: z.ZodNumber;
}, z.core.$strip>;
/**
 * Minimal `TraceEvent` shape that the production runtime emits.
 * Matches `trace/schema.ts` `TraceEvent` but is duplicated here as a
 * wire schema so non-TypeScript clients can validate without depending
 * on internal types.
 */
declare const TraceEventSchema: z.ZodObject<{
    eventId: z.ZodString;
    runId: z.ZodString;
    spanId: z.ZodOptional<z.ZodString>;
    kind: z.ZodEnum<{
        error: "error";
        custom: "custom";
        policy_violation: "policy_violation";
        log: "log";
        budget_decrement: "budget_decrement";
        budget_breach: "budget_breach";
        state_mutation: "state_mutation";
        redaction_applied: "redaction_applied";
    }>;
    timestamp: z.ZodNumber;
    payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
}, z.core.$strip>;
declare const TracesIngestRequestSchema: z.ZodObject<{
    events: z.ZodArray<z.ZodObject<{
        eventId: z.ZodString;
        runId: z.ZodString;
        spanId: z.ZodOptional<z.ZodString>;
        kind: z.ZodEnum<{
            error: "error";
            custom: "custom";
            policy_violation: "policy_violation";
            log: "log";
            budget_decrement: "budget_decrement";
            budget_breach: "budget_breach";
            state_mutation: "state_mutation";
            redaction_applied: "redaction_applied";
        }>;
        timestamp: z.ZodNumber;
        payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
    }, z.core.$strip>>;
}, z.core.$strip>;
declare const TracesIngestResponseSchema: z.ZodObject<{
    accepted: z.ZodNumber;
    rejected: z.ZodNumber;
    errors: z.ZodDefault<z.ZodArray<z.ZodObject<{
        eventId: z.ZodString;
        message: z.ZodString;
    }, z.core.$strip>>>;
}, z.core.$strip>;
declare const FeedbackLabelSchema: z.ZodObject<{
    id: z.ZodOptional<z.ZodString>;
    source: z.ZodEnum<{
        judge: "judge";
        user: "user";
        system: "system";
        policy: "policy";
        environment: "environment";
        metric: "metric";
    }>;
    kind: z.ZodEnum<{
        approve: "approve";
        reject: "reject";
        select: "select";
        edit: "edit";
        rank: "rank";
        rate: "rate";
        comment: "comment";
        metric_outcome: "metric_outcome";
        policy_block: "policy_block";
        revision_request: "revision_request";
    }>;
    value: z.ZodUnknown;
    reason: z.ZodOptional<z.ZodString>;
    severity: z.ZodOptional<z.ZodEnum<{
        error: "error";
        info: "info";
        critical: "critical";
        warning: "warning";
    }>>;
    createdAt: z.ZodString;
    metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, z.core.$strip>;
declare const FeedbackAttemptSchema: z.ZodObject<{
    id: z.ZodString;
    stepIndex: z.ZodNumber;
    artifactType: z.ZodEnum<{
        text: "text";
        code: "code";
        action: "action";
        decision: "decision";
        plan: "plan";
        research: "research";
        ui: "ui";
        data: "data";
        other: "other";
    }>;
    artifact: z.ZodUnknown;
    options: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
    proposedAction: z.ZodOptional<z.ZodObject<{
        type: z.ZodString;
        risk: z.ZodOptional<z.ZodEnum<{
            medium: "medium";
            low: "low";
            high: "high";
        }>>;
        costUsd: z.ZodOptional<z.ZodNumber>;
        externalSideEffect: z.ZodOptional<z.ZodBoolean>;
        requiresApproval: z.ZodOptional<z.ZodBoolean>;
        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    }, z.core.$strip>>;
    feedback: z.ZodOptional<z.ZodArray<z.ZodObject<{
        id: z.ZodOptional<z.ZodString>;
        source: z.ZodEnum<{
            judge: "judge";
            user: "user";
            system: "system";
            policy: "policy";
            environment: "environment";
            metric: "metric";
        }>;
        kind: z.ZodEnum<{
            approve: "approve";
            reject: "reject";
            select: "select";
            edit: "edit";
            rank: "rank";
            rate: "rate";
            comment: "comment";
            metric_outcome: "metric_outcome";
            policy_block: "policy_block";
            revision_request: "revision_request";
        }>;
        value: z.ZodUnknown;
        reason: z.ZodOptional<z.ZodString>;
        severity: z.ZodOptional<z.ZodEnum<{
            error: "error";
            info: "info";
            critical: "critical";
            warning: "warning";
        }>>;
        createdAt: z.ZodString;
        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    }, z.core.$strip>>>;
    createdAt: z.ZodString;
    metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, z.core.$strip>;
declare const FeedbackTrajectorySchema: z.ZodObject<{
    id: z.ZodString;
    projectId: z.ZodOptional<z.ZodString>;
    scenarioId: z.ZodOptional<z.ZodString>;
    task: z.ZodObject<{
        intent: z.ZodString;
        context: z.ZodOptional<z.ZodUnknown>;
    }, z.core.$strip>;
    attempts: z.ZodDefault<z.ZodArray<z.ZodObject<{
        id: z.ZodString;
        stepIndex: z.ZodNumber;
        artifactType: z.ZodEnum<{
            text: "text";
            code: "code";
            action: "action";
            decision: "decision";
            plan: "plan";
            research: "research";
            ui: "ui";
            data: "data";
            other: "other";
        }>;
        artifact: z.ZodUnknown;
        options: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
        proposedAction: z.ZodOptional<z.ZodObject<{
            type: z.ZodString;
            risk: z.ZodOptional<z.ZodEnum<{
                medium: "medium";
                low: "low";
                high: "high";
            }>>;
            costUsd: z.ZodOptional<z.ZodNumber>;
            externalSideEffect: z.ZodOptional<z.ZodBoolean>;
            requiresApproval: z.ZodOptional<z.ZodBoolean>;
            metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
        }, z.core.$strip>>;
        feedback: z.ZodOptional<z.ZodArray<z.ZodObject<{
            id: z.ZodOptional<z.ZodString>;
            source: z.ZodEnum<{
                judge: "judge";
                user: "user";
                system: "system";
                policy: "policy";
                environment: "environment";
                metric: "metric";
            }>;
            kind: z.ZodEnum<{
                approve: "approve";
                reject: "reject";
                select: "select";
                edit: "edit";
                rank: "rank";
                rate: "rate";
                comment: "comment";
                metric_outcome: "metric_outcome";
                policy_block: "policy_block";
                revision_request: "revision_request";
            }>;
            value: z.ZodUnknown;
            reason: z.ZodOptional<z.ZodString>;
            severity: z.ZodOptional<z.ZodEnum<{
                error: "error";
                info: "info";
                critical: "critical";
                warning: "warning";
            }>>;
            createdAt: z.ZodString;
            metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
        }, z.core.$strip>>>;
        createdAt: z.ZodString;
        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    }, z.core.$strip>>>;
    labels: z.ZodDefault<z.ZodArray<z.ZodObject<{
        id: z.ZodOptional<z.ZodString>;
        source: z.ZodEnum<{
            judge: "judge";
            user: "user";
            system: "system";
            policy: "policy";
            environment: "environment";
            metric: "metric";
        }>;
        kind: z.ZodEnum<{
            approve: "approve";
            reject: "reject";
            select: "select";
            edit: "edit";
            rank: "rank";
            rate: "rate";
            comment: "comment";
            metric_outcome: "metric_outcome";
            policy_block: "policy_block";
            revision_request: "revision_request";
        }>;
        value: z.ZodUnknown;
        reason: z.ZodOptional<z.ZodString>;
        severity: z.ZodOptional<z.ZodEnum<{
            error: "error";
            info: "info";
            critical: "critical";
            warning: "warning";
        }>>;
        createdAt: z.ZodString;
        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    }, z.core.$strip>>>;
    outcome: z.ZodOptional<z.ZodObject<{
        success: z.ZodOptional<z.ZodBoolean>;
        score: z.ZodOptional<z.ZodNumber>;
        metrics: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
        costUsd: z.ZodOptional<z.ZodNumber>;
        detail: z.ZodOptional<z.ZodString>;
        observedAt: z.ZodOptional<z.ZodString>;
        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
    }, z.core.$strip>>;
    split: z.ZodOptional<z.ZodEnum<{
        train: "train";
        dev: "dev";
        test: "test";
        holdout: "holdout";
    }>>;
    tags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
    createdAt: z.ZodString;
    updatedAt: z.ZodOptional<z.ZodString>;
    metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, z.core.$strip>;
declare const FeedbackIngestResponseSchema: z.ZodObject<{
    id: z.ZodString;
    persisted: z.ZodBoolean;
}, z.core.$strip>;
type TraceEvent = z.infer<typeof TraceEventSchema>;
type TracesIngestRequest = z.infer<typeof TracesIngestRequestSchema>;
type TracesIngestResponse = z.infer<typeof TracesIngestResponseSchema>;
type FeedbackTrajectory = z.infer<typeof FeedbackTrajectorySchema>;
type FeedbackIngestResponse = z.infer<typeof FeedbackIngestResponseSchema>;
declare const ErrorResponseSchema: z.ZodObject<{
    error: z.ZodObject<{
        code: z.ZodString;
        message: z.ZodString;
        details: z.ZodOptional<z.ZodUnknown>;
    }, z.core.$strip>;
}, z.core.$strip>;
type RubricDimension = z.infer<typeof RubricDimensionSchema>;
type FailureMode = z.infer<typeof FailureModeSchema>;
type Rubric = z.infer<typeof RubricSchema>;
type JudgeRequest = z.infer<typeof JudgeRequestSchema>;
type JudgeResult = z.infer<typeof JudgeResultSchema>;
type RubricInfo = z.infer<typeof RubricInfoSchema>;
type ListRubricsResponse = z.infer<typeof ListRubricsResponseSchema>;
type VersionResponse = z.infer<typeof VersionResponseSchema>;
type ErrorResponse = z.infer<typeof ErrorResponseSchema>;
/**
 * Bump on any breaking change to a request/response schema.
 * Non-breaking (additive) changes don't require a bump.
 */
declare const WIRE_VERSION = "1.0.0";
/**
 * Stable hash of a rubric. Used to make scores comparable across runs:
 * if the rubricVersion matches, the rubric was identical.
 */
declare function hashRubric(rubric: Rubric): string;

/**
 * Pure handler functions — the "business logic" behind every wire-protocol
 * method. The HTTP server (`server.ts`) and the stdio RPC (`rpc.ts`) both
 * call these. Tests call these directly without spinning a server.
 *
 * Each handler:
 *   - Takes a parsed request (already Zod-validated by the transport).
 *   - Returns a result that matches the response schema.
 *   - Throws `WireError` for caller-fixable errors (404, 400, 422).
 *   - Lets unexpected errors bubble — the transport maps them to 500.
 */

/** Caller-fixable error. The transport renders this to 4xx + ErrorResponse. */
declare class WireError extends Error {
    readonly code: string;
    readonly status: number;
    readonly details?: unknown | undefined;
    constructor(code: string, message: string, status?: number, details?: unknown | undefined);
}
interface HandleJudgeOptions {
    costLedger?: CostLedgerHandle;
    costPhase?: string;
    llm?: LlmClientOptions;
    defaultModel?: string;
    routeRequirements?: LlmRouteRequirements;
    signal?: AbortSignal;
}
declare function handleJudge(req: JudgeRequest, options?: HandleJudgeOptions): Promise<JudgeResult>;
declare function handleListRubrics(): ListRubricsResponse;
declare function handleVersion(): VersionResponse;
/**
 * Pluggable stores the wire layer routes ingestion writes into. Both
 * are optional — when omitted, the corresponding endpoint returns 503.
 *
 * Production deployments wire a `FileSystemTraceStore` and
 * `FileSystemFeedbackTrajectoryStore` here. Tests substitute in-memory
 * stores.
 */
interface IngestionStores {
    traceStore?: TraceStore;
    feedbackStore?: FeedbackTrajectoryStore;
}
/**
 * `POST /v1/traces/ingest` — accept a batch of `TraceEvent`s from the
 * production runtime. Best-effort: each event is appended independently;
 * one bad event does not poison the batch.
 *
 * Idempotency: the underlying store is append-only; consumers retrying
 * the same payload will get duplicate events. Consumers should
 * de-duplicate by `eventId` downstream — production traces frequently
 * land via at-least-once buses (Kafka, SQS) where dedup is unavoidable.
 */
declare function handleTracesIngest(req: TracesIngestRequest, stores: IngestionStores): Promise<TracesIngestResponse>;
/**
 * `POST /v1/feedback` — accept a single `FeedbackTrajectory` from the
 * production runtime. Idempotent on `id`: re-posting the same trajectory
 * replaces the prior record.
 */
declare function handleFeedbackIngest(req: FeedbackTrajectory, stores: IngestionStores): Promise<FeedbackIngestResponse>;

declare function buildOpenApi(packageVersion: string): OpenAPIObject;

/**
 * stdio RPC transport.
 *
 * For batch / cron use without a running server. The Python client falls
 * back to this when no server is reachable.
 *
 * Protocol (line-delimited JSON over stdin/stdout):
 *   IN:  one JSON object on stdin: {"method":"judge","params":{...}}
 *   OUT: one JSON object on stdout: {"result":{...}} or {"error":{...}}
 *
 * One request per process invocation. To pipeline many calls, the client
 * writes JSONL to stdin and reads JSONL from stdout — see batch mode below.
 */

interface RpcRequest {
    method: 'judge' | 'listRubrics' | 'version';
    params?: unknown;
}
interface RpcSuccess {
    result: unknown;
}
interface RpcError {
    error: {
        code: string;
        message: string;
        details?: unknown;
    };
}
interface RpcOptions {
    llm?: LlmClientOptions;
    judgeModel?: string;
    llmRouteRequirements?: LlmRouteRequirements;
}
declare function dispatchRpc(req: RpcRequest, options?: RpcOptions): Promise<RpcSuccess | RpcError>;
/** Read one JSON request from stdin, write one JSON response to stdout. */
declare function runRpcOnce(method?: string, options?: RpcOptions): Promise<number>;
/** Read JSONL requests from stdin, write JSONL responses to stdout. */
declare function runRpcBatch(method?: string, options?: RpcOptions): Promise<number>;

/**
 * Built-in rubrics shipped with agent-eval.
 *
 * A rubric is a set of scoring axes plus a system prompt that tells the
 * judging LLM how to grade against those axes. Built-in rubrics are
 * curated for use cases that recur across Tangle projects — call them
 * by name from any client.
 *
 * Adding a rubric:
 *   1. Define the Rubric object below with a clear `description` and
 *      named `dimensions`.
 *   2. Register it in `BUILTIN_RUBRICS` at the bottom.
 *   3. Add a test in `tests/wire/rubrics.test.ts`.
 *
 * Custom rubrics: callers pass `rubric` inline to /v1/judge instead of
 * `rubricName` — see schemas.ts.
 */

declare const BUILTIN_RUBRICS: Record<string, Rubric>;
/** Get a built-in rubric by name, or undefined. */
declare function getBuiltinRubric(name: string): Rubric | undefined;
/** List built-in rubrics with their stable versions. */
declare function listBuiltinRubrics(): {
    name: string;
    description: string;
    dimensions: {
        id: string;
        description: string;
        weight: number;
    }[];
    failureModes: string[];
    rubricVersion: string;
}[];

interface CreateAppOptions {
    /** Stores wired to the ingestion endpoints. */
    stores?: IngestionStores;
    /** Model provider used by `/v1/judge`. */
    llm?: LlmClientOptions;
    /** Default judge model when a request does not provide one. */
    judgeModel?: string;
    /** Model route checks applied before every judge call. */
    llmRouteRequirements?: LlmRouteRequirements;
    /**
     * Bearer-token auth. When provided, every endpoint EXCEPT `/healthz`
     * and `/v1/version` requires `Authorization: Bearer <token>`. The
     * token may be a static string OR a function for time-bounded /
     * rotating tokens.
     *
     * Recommended for any server that accepts ingestion writes from the
     * public internet. Read-only deployments may omit it.
     */
    auth?: {
        bearer: string | ((token: string) => boolean | Promise<boolean>);
    };
}
declare function createApp(opts?: CreateAppOptions): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
interface ServeOptions extends CreateAppOptions {
    /** Default 5005. */
    port?: number;
    /** Default '127.0.0.1'. Set to '0.0.0.0' to listen on all interfaces. */
    host?: string;
}
declare function startServer(opts?: ServeOptions): ServerType;
interface StartedServer {
    server: ServerType;
    /** The OS-assigned port. When opts.port was 0, this is the actual port the
     *  kernel bound — callers that need to dial back (smoke tests, sidecars
     *  registering with a parent) read this rather than guessing a free port. */
    port: number;
    /** Resolved host the server bound to (defaults to 127.0.0.1). */
    host: string;
    /** Close the server. Resolves once active connections have drained. */
    close(): Promise<void>;
}
/**
 * Promise-returning variant of `startServer` that resolves once the server is
 * listening and surfaces the resolved bound port. Use this from smoke tests
 * (`startServerAsync({ port: 0 })`) and any caller that needs to dial back.
 */
declare function startServerAsync(opts?: ServeOptions): Promise<StartedServer>;

export { BUILTIN_RUBRICS, type ErrorResponse, ErrorResponseSchema, type FailureMode, FailureModeSchema, FeedbackAttemptSchema, type FeedbackIngestResponse, FeedbackIngestResponseSchema, FeedbackLabelSchema, type FeedbackTrajectory, FeedbackTrajectorySchema, type HandleJudgeOptions, HealthResponseSchema, type IngestionStores, type JudgeRequest, JudgeRequestSchema, type JudgeResult, JudgeResultSchema, type ListRubricsResponse, ListRubricsResponseSchema, type RpcOptions, type Rubric, type RubricDimension, RubricDimensionSchema, type RubricInfo, RubricInfoSchema, RubricSchema, type ServeOptions, type StartedServer, type TraceEvent, TraceEventSchema, type TracesIngestRequest, TracesIngestRequestSchema, type TracesIngestResponse, TracesIngestResponseSchema, type VersionResponse, VersionResponseSchema, WIRE_VERSION, WireError, buildOpenApi, createApp, dispatchRpc, getBuiltinRubric, handleFeedbackIngest, handleJudge, handleListRubrics, handleTracesIngest, handleVersion, hashRubric, listBuiltinRubrics, runRpcBatch, runRpcOnce, startServer, startServerAsync };
