import type { ConfiguredModel, LocalRuntimeProtocol, ResponseModelStyle } from './model-registry.js';
import type { OperatingMode } from './native/modes.js';
export { normalizeModel } from './model-registry.js';
export type { ConfiguredModel, LocalRuntimeProtocol, ResponseModelStyle, ResolvedModel, ModelRoute } from './model-registry.js';
export { LocalRuntimeProtocolUnresolvedError, resolveConfiguredModel, getDefaultConfiguredModel, getPreferredInteractiveConfiguredModel, isInteractiveChatModel, isInteractiveChatModelName, hasResolvedLocalRuntimeProtocol, listConfiguredModels, probeRouterModels, overlayAvailability, resolveModelContextCapability, resolveModelContextWindow, responseModelName, requiresResolvedLocalRuntimeProtocol, resolveModelRoute, resolveModel, reverseModel, } from './model-registry.js';
export interface MiddlewareConfig {
    rateLimitRpm?: number;
    retryMaxAttempts?: number;
    retryBaseDelayMs?: number;
    fallbackEnabled?: boolean;
    circuitBreakerThreshold?: number;
    circuitBreakerCooldownMs?: number;
    sloTargetPercent?: number;
    requestTimeoutMs?: number;
    /** 0.13.97: streaming-only first-token watchdog. setTimeout starts when
     *  /v1/messages?stream=true reaches the SSE loop; clears on first
     *  content_block_delta / content_block_start. If it fires before any
     *  visible chunk arrives, the stream is aborted with kind
     *  `stream_first_token_timeout` (frontend: pre_first_token_stream_close).
     *  Does NOT apply to non-streaming. Default 90_000 — matches OwlCC
     *  upstream watchdog convention; lower for impatient setups, higher
     *  (e.g. 180_000) for cold-start cloud models with large context. */
    streamFirstTokenTimeoutMs?: number;
    /** 0.13.97: streaming idle-between-chunks deadline. Each call to
     *  readStreamChunkWithDeadline already sets a fresh per-read timer; this
     *  field overrides the per-route default that timer uses. When unset,
     *  falls back to per-route `timeoutMs` and then `routerTimeoutMs`
     *  (default 600_000). Only useful when you want streaming idle to
     *  diverge from the route's overall HTTP timeout. */
    streamIdleTimeoutMs?: number;
    /** 0.13.98 Batch B: model used by auto-compact's LLM-summary path.
     *  Defaults to the conversation's current model. Set to a cheap-and-fast
     *  model id (e.g. an aliased local 7B) to decouple compaction cost from
     *  main turn cost. The compactor is run with hard limits — 15s timeout,
     *  max_tokens=1500, temperature=0, no tools, no stream. */
    compactionModel?: string;
    /** 0.13.98 Batch B: bounded compactor input cap in tokens. Default
     *  8000. Must be smaller than the smallest model context window in
     *  use; the bounded input shape is composed of 7 segments
     *  (system / latest_user_goal / recent_turns_verbatim /
     *  tool_call_summary / error_evidence / file_paths_touched / scaffold)
     *  and overflow drops sections in priority order. system and
     *  latest_user_goal are load-bearing and are NEVER dropped — only
     *  truncated with a hash marker. */
    compactionInputMaxTokens?: number;
    maxRequestBodyBytes?: number;
    intentRouting?: boolean;
    /** 0.14.1: input-size-aware timeout extension. When true (default),
     *  /v1/messages non-streaming wall-clock (requestTimeoutMs) and
     *  streaming first-token watchdog (streamFirstTokenTimeoutMs) get
     *  a linear extension per 10K estimated input tokens. Disable to
     *  restore 0.14.0 flat behavior. See `src/middleware/adaptive-timeout.ts`. */
    adaptiveTimeoutEnabled?: boolean;
    /** 0.14.1: ms added per 10K estimated input tokens above 0. Default
     *  60_000 (60s). Set to 0 to effectively disable scaling without
     *  flipping `adaptiveTimeoutEnabled` off (preserves estimator telemetry). */
    adaptiveTimeoutExtensionPer10kMs?: number;
    /** 0.14.1: absolute cap on the adaptive budget. Default 600_000
     *  (10 min). Stops accidental 100K-token inputs from creating
     *  multi-hour budgets. */
    adaptiveTimeoutCapMs?: number;
    /** 0.14.2: on streaming first-token watchdog fire (no chunks
     *  arrived), retry the same body on non-streaming once before
     *  surfacing recovery wording. On success, the non-streaming JSON
     *  is synthesized into Anthropic SSE events and written through
     *  the already-open response. Default true. Disable to restore the
     *  0.14.1 wording-only behavior. */
    streamFallbackToNonStreamingEnabled?: boolean;
    /** 0.14.4: mirror of streamFallbackToNonStreamingEnabled in the
     *  reverse direction. When the non-streaming wall-clock fires,
     *  retry the same body with stream:true, consume the SSE event
     *  stream, and assemble back into a JSON response. Default true.
     *  Disable for routes whose streaming path is known to misbehave
     *  on large contexts (e.g. some kimi/deepseek long-context OOM
     *  reports). See `src/middleware/non-stream-fallback.ts`. */
    nonStreamFallbackToStreamingEnabled?: boolean;
}
export interface OwlCodaConfig {
    port: number;
    host: string;
    routerUrl: string;
    localRuntimeProtocol: LocalRuntimeProtocol;
    routerTimeoutMs: number;
    models: ConfiguredModel[];
    responseModelStyle: ResponseModelStyle;
    logLevel: 'debug' | 'info' | 'warn' | 'error';
    logFilePath?: string;
    logFileMaxBytes?: number;
    logFileKeep?: number;
    adminToken?: string;
    catalogLoaded: boolean;
    middleware: MiddlewareConfig;
    backends?: import('./backends/types.js').BackendConfig[];
    skillInjection?: boolean;
    skillTopK?: number;
    skillThreshold?: number;
    /** L3 training-data collection master switch. Default: false (opt-in).
     *  When true, sessions with quality >= minQuality (default 60) are saved
     *  to ~/.owlcoda/training/collected.jsonl after PII sanitization.
     *  Override at runtime: OWLCODA_TRAINING_COLLECTION=1 (or =0). */
    trainingCollection?: boolean;
    /** Default interactive/headless operating mode unless OWLCODA_MODES=0. */
    mode?: OperatingMode;
    modelMap: Record<string, string>;
    defaultModel: string;
    reverseMapInResponse: boolean;
}
export declare function appendBuiltinEndpointModels(config: OwlCodaConfig): void;
export declare function estimateContextWindow(id: string): number;
export declare function loadConfig(configPath?: string): OwlCodaConfig;
/**
 * Merge discovered backend models into an existing config.
 * Discovered models are added if not already present (by ID).
 * Each discovered model gets its own endpoint URL so it routes directly
 * to its backend without going through the Router.
 */
export declare function mergeDiscoveredModels(config: OwlCodaConfig, discovered: import('./backends/types.js').DiscoveredModel[]): OwlCodaConfig;
