import type { AuthContext } from '../../auth/AuthContext'; import type { GatewayDeployment } from '../auth/InvocationTokenCodec'; import type { ConnectCredentialRecord, PodCredentialRepository } from '../connect'; import type { CredentialVault } from '../credentials/CredentialVault'; import { EmbeddingModelPolicy } from '../../../ai/service/EmbeddingModelPolicy'; import { type ProviderRegistry } from '../providers/ProviderRegistry'; import { type DiscoveredProviderModel, type ProviderModelDiscoveryAdapter } from './ProviderModelDiscoveryAdapters'; import type { PodModelSelection, PodSelectedModelInput, PodModelSelectionRepository } from './PodModelSelectionRepository'; export interface ProviderModelDiscoveryServiceLike { /** * Discover with the caller-selected credential. This is deliberately the * caller-owned path: the delegate must not resolve another credential or * fall back to process configuration. */ listFromSecret(input: { webId: string; provider: string; offeringId?: string; credentialId: string; authMode?: ConnectCredentialRecord['authMode']; secret?: Record; apiKey?: string; baseUrl?: string; proxyUrl?: string; compatibility?: 'auto' | 'openai' | 'anthropic'; signal?: AbortSignal; }): Promise<{ models: ReadonlyArray<{ id: string; displayName?: string; modelType?: DiscoveredProviderModel['modelType']; }>; }>; } export type ProviderModelCatalogModel = DiscoveredProviderModel & { selected: boolean; availability: 'available' | 'unavailable' | 'statusUnknown'; }; export type ProviderModelCatalog = { provider: string; fetchedAt?: string; version: string; status: 'ready' | 'notFetched' | 'statusUnknown'; models: ProviderModelCatalogModel[]; }; export interface DiscoverProviderModelInput { webId: string; provider: string; /** Resolve a specific active credential in the caller's Pod scope. */ credentialId?: string; deployment?: GatewayDeployment; auth?: AuthContext; signal?: AbortSignal; /** Bypass a fresh catalog cache while preserving in-flight de-duplication. */ forceRefresh?: boolean; } export interface GetProviderModelCatalogInput extends DiscoverProviderModelInput { } export interface ReplaceProviderModelSelectionInput { webId: string; provider: string; modelIds: readonly string[]; defaultModel?: string; expectedVersion?: string; deployment?: GatewayDeployment; auth?: AuthContext; } export interface ProviderModelSelectionRepositoryLike { listSelection(input: { webId: string; provider: string; auth?: AuthContext; }): Promise; reconcileAvailability(input: { webId: string; provider: string; discoveredModels: readonly DiscoveredProviderModel[]; auth?: AuthContext; }): Promise; replaceSelection(input: { webId: string; provider: string; models: readonly PodSelectedModelInput[]; defaultModel?: string; expectedVersion?: string; auth?: AuthContext; }): Promise; } export interface ProviderModelDiscoveryRegistryLike { get(provider: string): ProviderModelDiscoveryAdapter; } export interface ProviderModelSelectionServiceOptions { credentialRepository?: PodCredentialRepository; selectionRepository?: ProviderModelSelectionRepositoryLike | Pick; /** Alias matching the repository option used by other Gateway services. */ repository?: ProviderModelSelectionRepositoryLike; discoveryRegistry?: ProviderModelDiscoveryRegistryLike; /** Backwards-compatible alias for callers that name the registry adapters. */ discoveryAdapters?: ProviderModelDiscoveryRegistryLike; adapters?: readonly ProviderModelDiscoveryAdapter[]; providerRegistry?: ProviderRegistry; baseUrlForProvider?: (provider: string) => string; /** Optional provider-model service for offering-aware caller-owned discovery. */ modelsService?: ProviderModelDiscoveryServiceLike; /** * Deployment policy for embedding models. Discovery can surface any model a * BYOK endpoint advertises; a cloud deployment may still only select embedding * models its gateway catalog provides. */ embeddingModelPolicy?: EmbeddingModelPolicy; /** Opens the selected caller credential when the Pod stores a secret cell. */ credentialVault?: CredentialVault; now?: () => Date; cacheTtlMs?: number; } /** * Coordinates short-lived provider discovery with durable Pod selections. * Provider secrets are decoded only inside discoverAndCache and are never put * in a cache entry, result DTO, or error message. */ export declare class ProviderModelSelectionService { private readonly credentialRepository; private readonly selectionRepository; private readonly discoveryRegistry; private readonly providerRegistry; private readonly baseUrlForProvider?; private readonly modelsService?; private readonly credentialVault?; private readonly embeddingModelPolicy; private readonly now; private readonly cacheTtlMs; private readonly cache; private readonly inFlight; constructor(options: ProviderModelSelectionServiceOptions); discover(input: DiscoverProviderModelInput): Promise; getCatalog(input: GetProviderModelCatalogInput): Promise; listCatalog(input: GetProviderModelCatalogInput): Promise; replaceSelection(input: ReplaceProviderModelSelectionInput): Promise; private discoverAndCache; private openCredentialSecret; private discoverProviderModels; /** Cloud settings only manage providers this deployment provides. */ private requireProvidedProvider; private resolveCredential; private resolveOptionalCredential; private discoveryContext; private resolveBaseUrl; private cacheCatalog; private freshCacheEntry; private timestamp; }