/**
 * Shared utilities for LLM provider adapters.
 *
 * These utilities live exactly once in this module. Each adapter
 * imports what it needs rather than reimplementing.
 *
 * Spec: P3-SUB-01 Section 9 (Shared Code to Extract)
 *
 * @connexum/ai-governance
 */
import type { LlmStreamChunk, LlmChatResponse, LlmToolDefinition, LlmToolCallResult, LlmMessage } from './index';
export type LlmAdapterAuditEventType = 'llm:api-version-mismatch' | 'llm:content-filter-triggered' | 'llm:model-substitution' | 'llm:rate-limit' | 'llm:auth-failure' | 'llm:retry-attempt' | 'llm:multimodal-input' | 'provider-unverified-baa-claim';
export interface LlmAdapterAuditEvent {
    type: LlmAdapterAuditEventType;
    severity: 'INFO' | 'WARN' | 'CRITICAL';
    adapterId: string;
    providerId: string;
    detail: string;
    timestamp: string;
    data?: Record<string, unknown>;
}
export type LlmAuditEmitter = (event: LlmAdapterAuditEvent) => void;
export interface BackoffRetryOptions {
    maxAttempts?: number;
    baseDelayMs?: number;
    maxDelayMs?: number;
    /** Factor for each retry (default: 2) */
    backoffFactor?: number;
    /** Jitter fraction 0-1 (default: 0.25) */
    jitterFraction?: number;
    /** If the error has retryAfterMs, honour it instead of computed delay */
    honourRetryAfter?: boolean;
    /** Only retry if this predicate returns true for the thrown error */
    retryIf?: (err: unknown) => boolean;
}
/**
 * Retry `fn` with exponential back-off, jitter, and Retry-After honour.
 * Throws the last error if all attempts are exhausted.
 */
export declare function exponentialBackoffRetry<T>(fn: () => Promise<T>, opts?: BackoffRetryOptions): Promise<T>;
/**
 * Consume an AsyncIterable<LlmStreamChunk> and collapse it into a final
 * LlmChatResponse.
 *
 * Throws if the iterable times out (default: 60s).
 */
export declare function accumulateStream(iterable: AsyncIterable<LlmStreamChunk>, modelId: string, timeoutMs?: number): Promise<LlmChatResponse>;
export type ToolWireFormat = 'openai' | 'azure' | 'google' | 'bedrock';
/**
 * Translate common LlmToolDefinition[] to a provider wire format.
 */
export declare function normalizeToolUseRequest(tools: LlmToolDefinition[], format: ToolWireFormat): unknown[];
/**
 * Translate a provider tool-call response into common LlmToolCallResult[].
 */
export declare function normalizeToolUseResponse(raw: unknown, format: ToolWireFormat): LlmToolCallResult[];
/**
 * Throws LlmProviderError with code UNEXPECTED_RESPONSE_SHAPE if any
 * required key is missing from obj.
 *
 * Partial-parse attempts are prohibited -- if the shape is wrong, throw.
 */
export declare function detectUnexpectedShape(obj: unknown, required: string[], providerId: string, adapterId: string): void;
/**
 * Emits `llm:api-version-mismatch` WARN event when the observed provider
 * API version header differs from the adapter's pinned version.
 * Does not throw -- version mismatch is a warning, not a fatal error.
 */
export declare function emitVersionMismatchIfNeeded(observed: string | null | undefined, pinned: string, adapterId: string, providerId: string, emit: LlmAuditEmitter): void;
/**
 * Parse a Retry-After header value (seconds as integer or HTTP-date)
 * into milliseconds.
 *
 * Returns 0 if unparseable.
 */
export declare function parseRetryAfterMs(headerValue: string | null | undefined): number;
/**
 * Coerce `LlmMessage.content` (string | LlmContentPart[]) into the
 * plain text string that text-only adapters need. Adapters that DO
 * NOT advertise `multimodal: true` in getCapabilities() MUST call
 * this on every message — silently dropping image parts on a vision
 * payload is a governance violation.
 *
 * Throws `LlmProviderError(UNSUPPORTED_MULTIMODAL)` when the message
 * carries any image_url part. Concatenates all `text` parts when the
 * content is array-shaped but text-only.
 *
 * F-NEW-GEMMA-VISION 2026-05-09. The widening of `LlmMessage.content`
 * to `string | LlmContentPart[]` is type-only; existing string-content
 * call sites keep working unchanged.
 */
export declare function coerceTextContent(message: LlmMessage, ctx: {
    providerId: string;
    adapterId: string;
}): string;
/**
 * Returns true if any message in the list carries an image_url part.
 * Adapters use this to decide whether to fail-fast at request entry
 * vs let the per-message coerce path handle it.
 *
 * F-NEW-GEMMA-VISION 2026-05-09.
 */
export declare function requestHasImageContent(messages: LlmMessage[]): boolean;
//# sourceMappingURL=shared.d.ts.map