contextual-agent-sdk
Version:
SDK for building AI agents with seamless voice-text context switching
217 lines • 7.59 kB
JavaScript
"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