/**
 * IntelligenceRouter — routes each LLM call to a framework-specific provider
 * based on the calling component's category/name, so different Instar components
 * can run on different agentic frameworks (e.g. sentinels on Codex while the
 * agent's conversation stays on Claude). Implements docs/specs/
 * per-component-framework-routing.md (B1).
 *
 * KEY DESIGN (corrected by convergence):
 *  - Routing is resolved at CALL TIME, at the single funnel every `.evaluate()`
 *    already passes through — NOT at construction. The component name only
 *    exists at call time (`attribution.component`), and ~half the LLM callers
 *    never receive a constructor-injected provider, so construction-time routing
 *    is unworkable. The router IS the injected provider; it dispatches per call.
 *  - Config is read LIVE on each call, so a `componentFrameworks` change takes
 *    effect on the next call with no restart (no session-start staleness trap).
 *  - Each non-default framework gets its OWN circuit breaker (built by the
 *    injected `buildProvider`), so a Claude rate-limit trip does NOT pause Codex.
 *    The default framework keeps using the existing shared (global-breaker)
 *    provider, so unconfigured behavior is byte-identical to today.
 *  - Fallback is circuit-aware: a framework whose binary is MISSING degrades to
 *    the default framework (config/install problem, low volume) and reports it; a
 *    framework that is merely RATE-LIMITED surfaces LlmCircuitOpenError, which
 *    callers already swallow into their heuristic — so we never herd a Codex
 *    outage's worth of calls onto Claude all at once.
 */
import type { IntelligenceProvider, IntelligenceOptions } from './types.js';
import type { IntelligenceFramework } from './intelligenceProviderFactory.js';
import { type ComponentCategory } from './componentCategories.js';
export interface ComponentFrameworksConfig {
    /** Framework for anything not otherwise specified. Defaults to the router's defaultFramework. */
    default?: IntelligenceFramework;
    /** Per-category framework, e.g. { sentinel: 'codex-cli' }. */
    categories?: Partial<Record<ComponentCategory, IntelligenceFramework>>;
    /** Per-component-name override, highest precedence. */
    overrides?: Record<string, IntelligenceFramework>;
    /** When a routed framework's provider is unavailable (binary missing): 'default' degrades, 'none' errors. */
    fallback?: 'default' | 'none';
    /**
     * Ordered fallback frameworks to try when a SAFETY-GATING call's primary
     * provider FAILS at runtime (rate-limit / circuit-open / error), BEFORE the
     * caller falls closed. Each target has its OWN circuit breaker, so a target
     * whose circuit is already open throws fast and is skipped — no herd onto a
     * stressed provider. Only calls flagged `attribution.gating` swap, keeping the
     * herd tiny. If every target is also down, the original error re-throws so the
     * caller fails closed. Default: undefined ⇒ no swap (exactly today's behavior).
     * This implements the "No Silent Degradation to Brittle Fallback" standard:
     * swap-provider before fail-closed, never silently degrade to a brittle heuristic.
     */
    failureSwap?: IntelligenceFramework[];
}
export interface RouterDegradeInfo {
    component: string;
    category: ComponentCategory;
    from: IntelligenceFramework;
    to: IntelligenceFramework;
    reason: string;
}
export interface IntelligenceRouterOptions {
    /** The existing shared provider for the default framework (global breaker). Used unconfigured + for default-routed calls. */
    defaultProvider: IntelligenceProvider;
    /** Which framework defaultProvider speaks. */
    defaultFramework: IntelligenceFramework;
    /** Live config getter — read on EVERY call so changes are hot. Returns undefined ⇒ routing disabled (all default). */
    resolveConfig: () => ComponentFrameworksConfig | undefined;
    /**
     * Per-attempt swap timeout in ms (provider-fallback-default-policy.md §4.5). Each
     * failure-swap attempt races this cap; a slow-but-not-erroring provider is abandoned
     * at the cap and the loop advances. The cap is ALSO passed through to the provider as
     * its `timeoutMs` so the CLI subprocess SIGTERMs itself at the same bound (the cap and
     * the subprocess kill are the same bound). Inline-defaulted to 5000ms by the caller
     * (no ConfigDefaults entry — codexExecJson precedent). Omitted ⇒ no per-attempt cap
     * (legacy unbounded behavior, for callers that build the router without the policy).
     */
    swapAttemptTimeoutMs?: number;
    /**
     * Build a provider for a non-default framework, with its OWN circuit breaker.
     * Returns null when that framework's binary isn't available. Called at most
     * once per framework (result cached). MUST NOT throw (catch internally).
     */
    buildProvider: (framework: IntelligenceFramework) => IntelligenceProvider | null;
    /** Optional: invoked when a routed call degrades to the default framework (for DegradationReporter). */
    onDegrade?: (info: RouterDegradeInfo) => void;
}
export declare class IntelligenceRouter implements IntelligenceProvider {
    private readonly opts;
    private readonly cache;
    constructor(opts: IntelligenceRouterOptions);
    /**
     * The framework the default (shared, global-breaker) provider speaks — i.e. the
     * framework a component routes to when nothing routes it elsewhere. The
     * CartographerSweep off-Claude probe compares `for(...).framework` against this
     * to detect a silent resolve-to-default (Claude) and refuse to author there.
     */
    get defaultFramework(): IntelligenceFramework;
    /** Resolve the framework for a component+category against a config (pure). */
    resolveFramework(component: string | undefined, category: ComponentCategory, cfg: ComponentFrameworksConfig | undefined): IntelligenceFramework;
    /**
     * Diagnostic resolver for the GET /intelligence/routing surface: what framework
     * a component WOULD route to right now, and whether that framework is available.
     */
    for(component: string, categoryOverride?: ComponentCategory): {
        component: string;
        category: ComponentCategory;
        framework: IntelligenceFramework;
        available: boolean;
    };
    /** Get-or-build the provider for a framework (cached). Default framework → shared provider. */
    private providerFor;
    /** Default framework → shared provider; else the cached per-framework provider (null if binary missing). */
    private resolveProvider;
    evaluate(prompt: string, options?: IntelligenceOptions): Promise<string>;
}
//# sourceMappingURL=IntelligenceRouter.d.ts.map