// --------------------------------------------------------------------------- // ProviderRegistry — routes task types to provider adapters // Spec reference: §3.4 // --------------------------------------------------------------------------- import type { Provider, TaskTypeName } from '../task/task-state.js'; import type { BaseProviderAdapter } from './base-adapter.js'; /** * Central registry for provider adapters. * * Supports: * - Registration by provider ID * - Default fallback provider * - Per-task-type routing overrides * - Bulk shutdown */ export class ProviderRegistry { private readonly adapters = new Map(); private defaultProvider: Provider | undefined; private readonly taskTypeRoutes = new Map(); /** Register an adapter. Keyed by its `id` property. */ register(adapter: BaseProviderAdapter): void { this.adapters.set(adapter.id, adapter); } /** Set the fallback provider used when no task-type route matches. */ setDefault(provider: Provider): void { this.defaultProvider = provider; } /** Override routing for a specific task type. */ setTaskTypeRoute(taskType: TaskTypeName, provider: Provider): void { this.taskTypeRoutes.set(taskType, provider); } /** Look up an adapter by provider ID. */ getAdapter(provider: Provider): BaseProviderAdapter | undefined { return this.adapters.get(provider); } /** * Select the best adapter for a given task type. * * Resolution order: * 1. Explicit task-type route * 2. Default provider * 3. First registered adapter (arbitrary but deterministic) */ selectForTaskType(taskType: TaskTypeName): BaseProviderAdapter | undefined { // 1. Check explicit route const routed = this.taskTypeRoutes.get(taskType); if (routed !== undefined) { const adapter = this.adapters.get(routed); if (adapter) return adapter; } // 2. Check default if (this.defaultProvider !== undefined) { const adapter = this.adapters.get(this.defaultProvider); if (adapter) return adapter; } // 3. Fall back to first registered const all = Array.from(this.adapters.values()); return all.length > 0 ? all[0] : undefined; } /** Return all registered adapters. */ getAllAdapters(): BaseProviderAdapter[] { return Array.from(this.adapters.values()); } /** Shut down all registered adapters in parallel. */ async shutdownAll(): Promise { await Promise.all( Array.from(this.adapters.values()).map((a) => a.shutdown()), ); } }