UNPKG

contextual-agent-sdk

Version:

SDK for building AI agents with seamless voice-text context switching

217 lines 7.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LLMManager = void 0; class LLMManager { providers = new Map(); defaultProvider; fallbackProvider; retryAttempts; constructor(config) { this.defaultProvider = config.defaultProvider; this.fallbackProvider = config.fallbackProvider; this.retryAttempts = config.retryAttempts || 3; Object.entries(config.providers).forEach(([name, providerConfig]) => { const provider = this.createProvider(name, providerConfig); if (provider) { this.providers.set(name, provider); } }); } createProvider(name, config) { try { const providerType = config.type.charAt(0).toUpperCase() + config.type.slice(1); const providerModule = require(`./llm-providers/${providerType}Provider`); const ProviderClass = providerModule[`${providerType}Provider`]; const providerConfig = config.config || config; return new ProviderClass(providerConfig); } catch (error) { console.error(`Failed to create provider ${name}:`, error); return null; } } async generateResponse(options) { const provider = this.getCurrentProvider(); if (!provider) { throw new Error('No LLM provider available'); } try { return await provider.generateResponse(options); } catch (error) { if (this.fallbackProvider && this.fallbackProvider !== this.defaultProvider) { const fallback = this.providers.get(this.fallbackProvider); if (fallback) { return await fallback.generateResponse(options); } } throw error; } } async generateWithTools(options, tools) { const provider = this.getCurrentProvider(); if (!provider) { throw new Error('No LLM provider available'); } if (!provider.supportsTools()) { console.log('⚠️ Provider does not support tools, falling back to basic generation'); const response = await this.generateResponse(options); return { ...response, toolCalls: [], stopReason: 'stop' }; } try { if (provider.generateWithTools) { const toolDefinitions = tools.map(tool => ({ type: 'function', function: { name: tool.id, description: tool.description, parameters: { type: 'object', properties: this.inferToolParameters(tool), required: [] } } })); return await provider.generateWithTools({ ...options, tools: toolDefinitions }); } else { const response = await provider.generateResponse(options); return { ...response, toolCalls: [], stopReason: 'stop' }; } } catch (error) { if (this.fallbackProvider && this.fallbackProvider !== this.defaultProvider) { const fallback = this.providers.get(this.fallbackProvider); if (fallback && fallback.supportsTools() && fallback.generateWithTools) { const toolDefinitions = tools.map(tool => ({ type: 'function', function: { name: tool.id, description: tool.description, parameters: { type: 'object', properties: this.inferToolParameters(tool), required: [] } } })); return await fallback.generateWithTools({ ...options, tools: toolDefinitions }); } } throw error; } } supportsTools() { const provider = this.getCurrentProvider(); return provider ? provider.supportsTools() : false; } inferToolParameters(tool) { if (tool.id.includes('sms') || tool.id.includes('twilio')) { return { to: { type: 'string', description: 'Phone number to send SMS to (E.164 format, e.g., +1234567890)' }, message: { type: 'string', description: 'The message content to send' } }; } if (tool.id.includes('email')) { return { to: { type: 'string', description: 'Email address to send to' }, subject: { type: 'string', description: 'Email subject line' }, body: { type: 'string', description: 'Email body content' } }; } return { input: { type: 'string', description: 'Input parameter for the tool' } }; } getCurrentProvider() { if (!this.defaultProvider) return undefined; return this.providers.get(this.defaultProvider); } addProvider(name, config) { const provider = this.createProvider(name, config); if (provider) { this.providers.set(name, provider); if (!this.defaultProvider) { this.defaultProvider = name; } } } setDefaultProvider(name) { if (this.providers.has(name)) { this.defaultProvider = name; } } async getProviderStatus() { const entries = Array.from(this.providers.entries()); const statusPromises = entries.map(async ([name, provider]) => ({ name, available: provider.isAvailable ? await provider.isAvailable() : true, isDefault: name === this.defaultProvider, isFallback: name === this.fallbackProvider })); return Promise.all(statusPromises); } async testProvider(name) { const provider = this.providers.get(name); if (!provider) { return { success: false, responseTime: 0, error: 'Provider not found' }; } const start = Date.now(); try { await provider.test?.(); return { success: true, responseTime: Date.now() - start }; } catch (error) { return { success: false, responseTime: Date.now() - start, error: error instanceof Error ? error.message : 'Unknown error' }; } } getAvailableProviders() { return Array.from(this.providers.keys()); } } exports.LLMManager = LLMManager; //# sourceMappingURL=LLMManager.js.map