import type { LLMProvider, ProviderRuntimeMetadata } from './interface.js';
import { type ProviderCapability, type RequestProfile, type RouteExplanation } from './capabilities.js';
import type { DiscoveredServer } from '@pellux/goodvibes-sdk/platform/discovery/scanner';
import type { RuntimeEventBus } from '../runtime/events/index.js';
import { type CatalogModel, type MinimalModelDefinition } from './model-catalog.js';
import type { CanonicalModel } from './synthetic.js';
import type { ModelDefinition, ProviderRegistryOptions, RuntimeProviderRegistration, TokenLimits } from './registry-types.js';
export type { ContextWindowProvenance, ModelDefinition, ModelTier, ProviderRegistryOptions, RuntimeProviderRegistration, TokenLimits, } from './registry-types.js';
/**
 * ProviderRegistry — manages LLM provider instances and model selection.
 * Lazily instantiates providers on first use.
 */
export declare class ProviderRegistry {
    private providers;
    private currentModelId;
    private discoveredProviderNames;
    private runtimeProviderNames;
    private customModels;
    private runtimeModels;
    private discoveredModels;
    private readonly runtimeCatalogSuppressions;
    private _watcher;
    private _readyPromise;
    private readonly configManager;
    private readonly subscriptionManager;
    private readonly capabilityRegistry;
    private readonly cacheHitTracker;
    private readonly featureFlags;
    private readonly favoritesStore;
    private readonly benchmarkStore;
    private readonly modelLimitsService;
    private readonly runtimeMetadataDeps;
    private readonly runtimeBus;
    private readonly localContextIngestionService;
    private catalogModels;
    private pricingCatalog;
    private syntheticCanonicalModels;
    constructor(options: ProviderRegistryOptions);
    private registerBuiltins;
    private getPersistenceRoot;
    private getCustomProvidersDir;
    private getCatalogCachePaths;
    private getCatalogBuiltins;
    private getSyntheticBuiltins;
    private updateCatalogState;
    private getSuppressedCatalogModelIds;
    private getModelRegistry;
    /** Register a provider. Overwrites any existing entry with the same name. */
    register(provider: LLMProvider): void;
    /**
     * Register a runtime/plugin-owned provider and optional model definitions.
     * Returns an unregister callback so plugin cleanup can remove the provider and
     * its runtime model/catalog contributions.
     */
    registerRuntimeProvider(registration: RuntimeProviderRegistration): () => void;
    listProviders(): readonly LLMProvider[];
    /**
     * Register providers discovered by the local LLM scanner.
     * Clears previously discovered providers before re-registering.
     * Does not overwrite built-in or custom-loaded providers/models.
     */
    registerDiscoveredProviders(servers: DiscoveredServer[]): void;
    /** Retrieve a provider by name. Throws if not found. */
    get(name: string): LLMProvider;
    /** Retrieve the directly-registered provider without subscription route aliasing. */
    getRegistered(name: string): LLMProvider;
    describeRuntime(name: string): Promise<ProviderRuntimeMetadata | null>;
    /** Return the provider responsible for a given model ID.
     * Accepts a registryKey (`provider:modelId`) OR a plain modelId.
     * - If input contains `:`, treats as registryKey — exact match on `m.registryKey`
     * - If no `:`, treats as plain modelId — exact match on `m.id`
     * When `provider` is supplied alongside a plain modelId, it disambiguates.
     * Explicit provider constraints do not fall through to other providers.
     */
    getForModel(modelId: string, provider?: string): LLMProvider;
    /** All registered model definitions. */
    listModels(): ModelDefinition[];
    getCostFromCatalog(modelId: string): {
        input: number;
        output: number;
    };
    getContextWindowForModel(modelDef: ModelDefinition): number;
    getTokenLimitsForModel(modelDef: ModelDefinition): Required<TokenLimits>;
    getPricingForModel(modelId: string, provider: string): {
        prompt: number;
        completion: number;
    } | null;
    getToolResultMaxCharsForModel(model: ModelDefinition | null | undefined): number;
    initModelLimits(): void;
    refreshModelLimits(): Promise<number>;
    getRawCatalogModels(): readonly CatalogModel[];
    getCatalogModelDefinitions(): readonly MinimalModelDefinition[];
    getSyntheticModelDefinitions(): readonly MinimalModelDefinition[];
    getSyntheticCanonicalModels(): readonly CanonicalModel[];
    getSyntheticBackendModelIds(): Set<string>;
    getSyntheticModelInfoFromCatalog(modelId: string): import("./model-catalog-synthetic.js").SyntheticModelInfo | null;
    getConfiguredProviderIds(): string[];
    /** Only the models the user can switch to. */
    getSelectableModels(): ModelDefinition[];
    /** Currently active model definition. */
    getCurrentModel(): ModelDefinition;
    /**
     * Override the context window cap for a custom or discovered (local) model.
     * Mutates the live model entry in customModels or discoveredModels so the change
     * is reflected immediately without requiring a full provider reload.
     *
     * @param registryKey - The model's registryKey (`provider:id`).
     * @param cap         - New context window value in tokens.
     * @remarks Context cap is session-only. Not persisted to config — lost on restart.
     */
    setModelContextCap(registryKey: string, cap: number): void;
    /** Switch to a different model. Accepts registryKey or plain modelId. Throws if not selectable. */
    setCurrentModel(modelId: string): void;
    /**
     * Load custom providers from ~/.goodvibes/goodvibes/providers/ and merge them
     * into the live model registry. Returns any warnings collected during loading.
     * Call this after construction to populate custom providers.
     */
    loadCustomProviders(): Promise<{
        warnings: string[];
        added: string[];
        removed: string[];
        updated: string[];
    }>;
    /**
     * Start watching ~/.goodvibes/goodvibes/providers/ for file changes.
     * On change, reloads custom providers and emits typed provider runtime events.
     * Safe to call multiple times — stops the previous watcher first.
     */
    startWatching(runtimeBus?: RuntimeEventBus | null): void;
    /** Stop the file watcher started by startWatching(). */
    stopWatching(): void;
    /**
     * Returns a promise that resolves when the initial custom provider load
     * completes. Callers can await this before calling getForModel() with a
     * custom model ID to avoid a "model not found" race window.
     */
    ready(): Promise<void>;
    /**
     * Find an alternative model when the current provider fails non-transiently.
     * Prefers a synthetic failover wrapper; falls back to same-tier model on a different provider.
     */
    findAlternativeModel(currentModelId: string): ModelDefinition | null;
    /**
     * Resolve the full capability record for a model.
     * Accepts a plain model ID or a `provider:modelId` registryKey.
     *
     * @param modelId - Plain model ID or registryKey (`provider:modelId`).
     * @returns A fully-resolved, immutable `ProviderCapability`.
     */
    getCapabilityForModel(modelId: string): ProviderCapability;
    /**
     * Check whether a model can handle a request described by `profile`.
     * Fails early with a typed explanation when unsupported — avoids mid-stream errors.
     *
     * @param modelId - Plain model ID or registryKey.
     * @param profile - The capability requirements for this request.
     * @returns A `RouteExplanation` with `accepted` flag, rejections, and capability.
     */
    explainRoute(modelId: string, profile: RequestProfile): RouteExplanation;
    /**
     * Resolve the provider identity and instance for a plain model ID or registryKey.
     * Shared by `getCapabilityForModel` and `explainRoute` to avoid duplication.
     *
     * @param modelId - Plain model ID or registryKey (`provider:modelId`).
     */
    private _resolveModelContext;
    /** Kick off async custom provider loading. Called once from bootstrap-owned construction. */
    initCustomProviders(): void;
    initCatalog(): void;
    refreshCatalog(): Promise<void>;
}
//# sourceMappingURL=registry.d.ts.map