// @generated — DO NOT EDIT. Source: packages/ai/provider.ts /** * Provider registry — manages AI provider instances. * * Supports multiple instances of the same provider type (e.g., two Claude * Agent SDK providers with different configs) keyed by instance ID. * * Each server (plan review, code review, annotate) should create its own * ProviderRegistry or share one — no module-level global state. */ import type { AIProvider, AIProviderConfig } from "./types.ts"; // --------------------------------------------------------------------------- // Factory registry (global — factories are stateless type→constructor maps) // --------------------------------------------------------------------------- type ProviderFactory = (config: AIProviderConfig) => Promise; const factories = new Map(); /** Register a factory function for a provider type. */ export function registerProviderFactory( type: string, factory: ProviderFactory ): void { factories.set(type, factory); } /** Create a provider from config using a registered factory. Does NOT auto-register. */ export async function createProvider( config: AIProviderConfig ): Promise { const factory = factories.get(config.type); if (!factory) { throw new Error( `No AI provider factory registered for type "${config.type}". ` + `Available: ${[...factories.keys()].join(", ") || "(none)"}` ); } return factory(config); } // --------------------------------------------------------------------------- // Registry // --------------------------------------------------------------------------- export class ProviderRegistry { private instances = new Map(); /** * Register a provider instance under an ID. * If no instanceId is provided, uses `provider.name`. * Returns the instanceId used. */ register(provider: AIProvider, instanceId?: string): string { const id = instanceId ?? provider.name; this.instances.set(id, provider); return id; } /** Get a provider by instance ID. */ get(instanceId: string): AIProvider | undefined { return this.instances.get(instanceId); } /** Get the first registered provider (convenience for single-provider setups). */ getDefault(): { id: string; provider: AIProvider } | undefined { const first = this.instances.entries().next(); if (first.done) return undefined; return { id: first.value[0], provider: first.value[1] }; } /** Get all instances of a given provider type (by provider.name). */ getByType(typeName: string): AIProvider[] { return [...this.instances.values()].filter((p) => p.name === typeName); } /** List all instance IDs. */ list(): string[] { return [...this.instances.keys()]; } /** Dispose and remove a single instance. No-op if not found. */ dispose(instanceId: string): void { const provider = this.instances.get(instanceId); if (provider) { provider.dispose(); this.instances.delete(instanceId); } } /** Dispose all providers and clear the registry. */ disposeAll(): void { for (const provider of this.instances.values()) { provider.dispose(); } this.instances.clear(); } /** Number of registered instances. */ get size(): number { return this.instances.size; } }