/**
 * 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.
 */
export type RawProviderDirection = 'request' | 'response' | 'error';
export 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[];
}
export interface RawProviderSinkFilter {
    runId?: string;
    spanId?: string;
    direction?: RawProviderDirection;
    attemptIndex?: number;
}
export 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>;
}
export type ProviderRedactor = (event: RawProviderEvent) => RawProviderEvent;
/**
 * Default redactor — strips well-known auth headers and any body field whose
 * key matches the credential pattern. Records every redacted path on
 * `event.redactedFields` so a downstream reviewer can see what was removed.
 */
export declare function defaultProviderRedactor(event: RawProviderEvent): RawProviderEvent;
export interface InMemoryRawProviderSinkOptions {
    redactor?: ProviderRedactor;
}
export declare class InMemoryRawProviderSink implements RawProviderSink {
    private events;
    private redactor;
    constructor(opts?: InMemoryRawProviderSinkOptions);
    record(event: RawProviderEvent): Promise<void>;
    list(filter?: RawProviderSinkFilter): Promise<RawProviderEvent[]>;
    size(): number;
}
export declare class NoopRawProviderSink implements RawProviderSink {
    record(): Promise<void>;
    /**
     * Returns an empty array. Implemented so `assertRunCaptured` does not
     * trip the `no_raw_sink` issue when a caller explicitly opts out of
     * capture by passing this sink — opt-out is a deliberate choice, not a
     * misconfiguration.
     */
    list(): Promise<RawProviderEvent[]>;
}
export interface FileSystemRawProviderSinkOptions {
    /** Directory the NDJSON file is written into. Created if missing. */
    dir: string;
    /** File name; default `'raw-provider-events.ndjson'`. */
    fileName?: string;
    /** Bytes after which the writer rolls over to a new file (default 32 MiB). */
    rollAtBytes?: number;
    redactor?: ProviderRedactor;
}
export declare class FileSystemRawProviderSink implements RawProviderSink {
    private dir;
    private fileName;
    private rollAtBytes;
    private redactor;
    private bytesWritten;
    private rollIndex;
    private initPromise;
    constructor(opts: FileSystemRawProviderSinkOptions);
    private ensureInit;
    private currentPath;
    record(event: RawProviderEvent): Promise<void>;
    list(filter?: RawProviderSinkFilter): Promise<RawProviderEvent[]>;
}
/**
 * Best-effort provider id from a base URL. Falls back to the URL host when
 * none of the well-known patterns match.
 */
export declare function providerFromBaseUrl(baseUrl: string): string;
//# sourceMappingURL=raw-provider-sink.d.ts.map