/**
 * Proxy Request Tracer
 *
 * Creates and manages OTel spans for the proxy request lifecycle.
 * Provides a clean API for claudeProxyRoutes to trace each phase:
 *   receive -> account_selection -> upstream (per retry) -> stream -> end
 *
 * Uses the existing instrumentation infrastructure:
 * - getTracer() from instrumentation.ts for span creation
 * - setLangfuseContext() for Langfuse enrichment
 * - OtelBridge for context propagation to/from upstream
 * - SpanAttributes from spanTypes.ts for attribute naming
 * - calculateCost() from pricing.ts for cost tracking
 * - TelemetryService for metrics recording
 */
import { type Span } from "@opentelemetry/api";
import type { AccountSelectionContext, ProxyRequestContext, ProxyRequestOrigin, ResponseInfoContext, UpstreamAttemptContext, UsageContext, ProxyUsageAttributionOptions, RuntimeRequestMetadata, ProxyLogTraceContext } from "../types/index.js";
declare class ProxyTracer {
    private readonly rootSpan;
    private readonly proxyTracer;
    private readonly bridge;
    private readonly requestId;
    /**
     * Model used for costing. Starts as the model the client asked for and is
     * updated by setModelSubstitution(), so cost follows the model that actually
     * served the request rather than the one that was requested.
     */
    private model;
    /**
     * Provider used for costing. See ProxyRequestContext.provider. Mutable for
     * the same reason `model` is: a fallback can serve the request from a
     * different provider, and pricing has to follow it.
     */
    private billingProvider;
    private readonly startTime;
    private readonly isStream;
    private ended;
    private recordRequestMetrics;
    private recordUsageMetrics;
    private accountEmail?;
    private usage?;
    private mode;
    /** Where the Claude-shaped request originated, for cache/cost attribution. */
    private requestOrigin;
    private constructor();
    /**
     * Create a root span for a proxy request and set Langfuse context.
     *
     * If the incoming request carries a `traceparent` header, the root span
     * will be linked to the caller's trace via OtelBridge.extractContext().
     */
    static startRequest(ctx: ProxyRequestContext, incomingHeaders?: Record<string, string>): ProxyTracer;
    /** Span covering the initial request receive and parse phase. */
    startReceive(): Span;
    /** Span covering account selection logic (fill-first / round-robin). */
    startAccountSelection(): Span;
    /** Span covering a single upstream attempt. One per retry. */
    startUpstreamAttempt(ctx: UpstreamAttemptContext): Span;
    /** Span covering the SSE stream relay phase. */
    startStream(): Span;
    /** Record account selection outcome on the root span. */
    setAccountSelection(ctx: AccountSelectionContext): void;
    /** Attribute fallback metrics to the account that actually served them. */
    setServedAccount(account: string, accountType: string): void;
    /**
     * Record where the Claude-shaped request this span covers originated, so
     * the token/cost counters below can be broken down by origin (e.g. to
     * measure Codex-fallback cache-hit rate separately from native traffic).
     */
    setRequestOrigin(origin: ProxyRequestOrigin): void;
    /** Record token usage and cost on the root span. */
    setUsage(ctx: UsageContext, options?: ProxyUsageAttributionOptions): void;
    /**
     * Record response-side details parsed from the upstream reply: the model
     * that actually answered, the finish reason, and which tools the model
     * invoked (tool_use blocks). Uses gen_ai.* semantic-convention attributes.
     */
    setResponseInfo(ctx: ResponseInfoContext): void;
    /** Record an error on the root span. */
    setError(errorType: string, errorMessage: string): void;
    /** Record whether the request was handled in full or passthrough mode. */
    setMode(mode: "full" | "passthrough" | "passthrough-cli"): void;
    /**
     * Record that the proxy substituted a different model than was requested.
     * Sets span attributes and increments the substitution metric counter.
     */
    setModelSubstitution(requestedModel: string, actualModel: string, actualProvider?: string): void;
    setFallbackInfo(info: {
        triggered: boolean;
        provider?: string;
        model?: string;
        attemptCount: number;
        reason: string;
    }): void;
    /** Log the incoming client request body (redacted). */
    logRequestBody(body: string): void;
    /** Log the incoming client request headers (redacted). */
    logRequestHeaders(headers: Record<string, string>): void;
    /** Log the upstream request body (redacted, as sent to Anthropic). */
    logUpstreamRequestBody(body: string): void;
    /** Log the upstream request headers (redacted). */
    logUpstreamRequestHeaders(headers: Record<string, string>): void;
    /** Log the upstream response headers (redacted). */
    logUpstreamResponseHeaders(headers: Record<string, string>): void;
    /** Log the upstream response body (redacted). */
    logUpstreamResponseBody(body: string): void;
    /** Log SSE stream events (each event has type, timestamp, data). */
    logStreamEvents(events: Array<{
        type: string;
        timestamp: number;
        data: string;
    }>): void;
    /** Record an upstream retry attempt. */
    recordRetry(account: string, reason: string): void;
    /** Record request and/or response body sizes for bandwidth tracking. */
    recordBodySizes(requestBytes?: number, responseBytes?: number): void;
    /** Return the OTel trace/span IDs for this request (for log correlation). */
    getTraceContext(): ProxyLogTraceContext;
    /** Return the captured usage (set by setUsage). */
    getUsage(): UsageContext | undefined;
    /** End the root span with final HTTP status and duration, and emit OTEL metrics. */
    end(responseStatus: number, durationMs: number): void;
    /** Record metrics via TelemetryService (call after setUsage). */
    recordMetrics(): void;
    /**
     * Get trace context headers for propagation to the upstream Anthropic request.
     * Injects the current trace's `traceparent` / `tracestate` into a new header map.
     */
    getTraceHeaders(): Record<string, string>;
}
export declare function recordFallbackAttempt(attrs: {
    provider: string;
    model: string;
    status: "success" | "failure";
    errorMessage?: string;
    durationMs: number;
    /** Namespaces the leg-health key for a fallback direction other than the
     *  existing Claude-engine chain (e.g. `"codex-outbound"`), so a dead-leg
     *  alert for `anthropic/claude-...` reached via Codex-outbound fallback
     *  never merges its failure streak with the same provider/model reached
     *  through the Claude engine's own configured chain. Omitted entirely by
     *  every existing call site, which keeps their leg key exactly as before. */
    direction?: string;
}): void;
/**
 * Records one Codex-outbound tool-declaration schema degradation (a
 * `$ref`/`$defs` flatten that hit a circular reference, a dropped `strict`
 * flag, or a custom grammar tool wrapped into a one-string schema). `reason`
 * is a short, stable label — never the schema or tool-name text itself, so a
 * call site cannot accidentally leak request payload into a metric label.
 */
export declare function recordCodexOutboundSchemaDegraded(attrs: {
    toolName: string;
    reason: string;
}): void;
/**
 * Records one Codex-outbound request field dropped during translation
 * because this repo has no faithful Claude-request representation for it
 * (e.g. a malformed `function_call.arguments` string wrapped instead of
 * parsed). Mirrors `recordCodexOutboundSchemaDegraded`'s label discipline.
 */
export declare function recordCodexOutboundUnsupportedField(attrs: {
    field: string;
    reason: string;
}): void;
/** Reset leg-health state between tests. */
export declare const __fallbackLegHealthTestHooks: {
    threshold: number;
    maxTrackedLegs: number;
    trackedCount: () => number;
    reset: () => void;
    streakOf: (legKey: string) => number;
    isReported: (legKey: string) => boolean;
};
export { ProxyTracer };
/** Standard SERVER span covers every proxy door, including parsing and admission failures. */
export declare function startProxyHttpTrace(metadata: RuntimeRequestMetadata, headers: Record<string, string>): {
    run: <T>(fn: () => T) => T;
    end: (status: number, outcome: string, errorType?: string) => void;
};
