@flowlab/all
Version:
A cool library focusing on handling various flows
63 lines (50 loc) • 2.65 kB
text/typescript
import { IAIProvider, AIProviderConfig } from './types';
import { ConfigurationError } from '@flowlab/core'; // Assuming core exports errors
type AIProviderConstructor = new (config: AIProviderConfig) => IAIProvider;
export class AIProviderRegistry {
private providers: Map<string, IAIProvider> = new Map();
private constructors: Map<string, AIProviderConstructor> = new Map();
private globalConfigs: Map<string, AIProviderConfig> = new Map();
// Load global configurations (e.g., from env vars or a config file at startup)
public loadGlobalConfigs(configs: Record<string, AIProviderConfig>): void {
for (const name in configs) {
this.globalConfigs.set(name.toLowerCase(), configs[name]);
}
}
// Register a provider's constructor
public registerProvider(name: string, constructor: AIProviderConstructor): void {
this.constructors.set(name.toLowerCase(), constructor);
}
// Get or create a provider instance
public getProvider(name: string, nodeSpecificConfig?: AIProviderConfig): IAIProvider {
const lowerName = name.toLowerCase();
// Use cached instance if config matches (simple check, might need deeper comparison)
if (this.providers.has(lowerName) && !nodeSpecificConfig) {
// TODO: Improve caching if config needs to be considered per instance
// For now, assume global config instance is sufficient if no override
return this.providers.get(lowerName)!;
}
const constructor = this.constructors.get(lowerName);
if (!constructor) {
throw new ConfigurationError(`AI provider "${name}" is not registered.`);
}
const globalConfig = this.globalConfigs.get(lowerName) || {};
// Merge global config with node-specific config (node takes precedence)
const effectiveConfig = { ...globalConfig, ...nodeSpecificConfig };
if (!effectiveConfig.apiKey && !process.env[`${lowerName.toUpperCase()}_API_KEY`]) {
// Attempt to load from common env var pattern if not provided
// Consider more robust secret management in production
console.warn(`API key for provider "${name}" not found in config or env var (${lowerName.toUpperCase()}_API_KEY).`);
} else if (!effectiveConfig.apiKey) {
effectiveConfig.apiKey = process.env[`${lowerName.toUpperCase()}_API_KEY`];
}
const instance = new constructor(effectiveConfig);
// Cache instance only if using global config for simplicity now
if (!nodeSpecificConfig) {
this.providers.set(lowerName, instance);
}
return instance;
}
}
// Default export for easy access
export const aiProviderRegistry = new AIProviderRegistry();