capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
129 lines • 4.9 kB
JavaScript
import { providerRegistry } from '../../providers/base.js';
import { OpenAIProvider } from '../../providers/openai.js';
import { configManager } from '../../core/config.js';
export class LocalModelRouter {
providers = new Map();
initialized = false;
constructor() {
}
async initializeProviders() {
const providers = [
{ name: 'openai', class: OpenAIProvider },
];
for (const provider of providers) {
const apiKey = await configManager.getApiKey(provider.name);
if (apiKey) {
const instance = new provider.class(apiKey);
this.providers.set(provider.name, instance);
providerRegistry.register(instance);
}
}
}
async route(request) {
if (!this.initialized) {
await this.initializeProviders();
this.initialized = true;
}
const provider = this.getProviderForModel(request.model);
if (!provider) {
throw new Error(`No provider available for model: ${request.model}`);
}
if (request.useCloud) {
}
const response = await provider.complete(request.messages, {
model: request.model,
temperature: request.temperature,
maxTokens: request.maxTokens
});
return {
content: response.content,
model: request.model,
usage: response.usage,
provider: provider.name
};
}
async listAvailableModels() {
const models = [];
if (this.providers.has('openai')) {
models.push({
id: 'gpt-3.5-turbo',
name: 'GPT-3.5 Turbo',
provider: 'openai',
contextWindow: 16385,
supportsStreaming: true,
supportsTools: true,
pricing: { prompt: 0.0005, completion: 0.0015 }
}, {
id: 'gpt-4o',
name: 'GPT-4o',
provider: 'openai',
contextWindow: 128000,
supportsStreaming: true,
supportsTools: true,
pricing: { prompt: 0.005, completion: 0.015 }
}, {
id: 'gpt-4o-mini',
name: 'GPT-4o Mini',
provider: 'openai',
contextWindow: 128000,
supportsStreaming: true,
supportsTools: true,
pricing: { prompt: 0.00015, completion: 0.0006 }
}, {
id: 'gpt-4-turbo',
name: 'GPT-4 Turbo',
provider: 'openai',
contextWindow: 128000,
supportsStreaming: true,
supportsTools: true,
pricing: { prompt: 0.01, completion: 0.03 }
});
}
return models;
}
async estimateCost(request) {
const modelInfo = (await this.listAvailableModels()).find(m => m.id === request.model);
if (!modelInfo || !modelInfo.pricing) {
throw new Error(`No pricing info for model: ${request.model}`);
}
const messageLength = request.messages.reduce((sum, msg) => sum + msg.content.length, 0);
const estimatedPromptTokens = Math.ceil(messageLength / 4);
const estimatedCompletionTokens = request.maxTokens || 1000;
const estimatedTotalTokens = estimatedPromptTokens + estimatedCompletionTokens;
const promptCost = (estimatedPromptTokens / 1000) * modelInfo.pricing.prompt;
const completionCost = (estimatedCompletionTokens / 1000) * modelInfo.pricing.completion;
const totalCost = promptCost + completionCost;
return {
estimatedTokens: estimatedTotalTokens,
estimatedCost: totalCost,
model: request.model,
provider: modelInfo.provider
};
}
getProviderForModel(model) {
const modelProviderMap = {
'gpt-3.5-turbo': 'openai',
'gpt-4o': 'openai',
'gpt-4o-mini': 'openai',
'gpt-4-turbo': 'openai',
'gpt-4': 'openai',
'claude-3-opus': 'anthropic',
'claude-3-sonnet': 'anthropic',
'claude-3-haiku': 'anthropic',
'claude-3.5-sonnet': 'anthropic',
'gemini-pro': 'google',
'gemini-ultra': 'google',
};
const providerName = modelProviderMap[model];
if (!providerName) {
throw new Error(`Unknown model: ${model}`);
}
const provider = this.providers.get(providerName);
if (!provider) {
throw new Error(`Provider ${providerName} not configured. ` +
`Set ${providerName.toUpperCase()}_API_KEY environment variable.`);
}
return provider;
}
}
//# sourceMappingURL=model-router.js.map