UNPKG

devibe

Version:

Intelligent repository cleanup with auto mode, AI learning, markdown consolidation, auto-consolidate workflow, context-aware classification, and cost optimization

228 lines (225 loc) 9.07 kB
/** * AI Model Configuration * * Supports multiple AI providers and models with automatic optimization * based on cost, context window, and quality requirements. */ export const AVAILABLE_MODELS = { // Anthropic Claude Models 'claude-3-5-sonnet': { id: 'claude-3-5-sonnet-20241022', name: 'Claude 3.5 Sonnet', provider: 'anthropic', contextWindow: 200000, inputPricePerMillion: 3.0, outputPricePerMillion: 15.0, recommendedBatchSize: 100, apiUrl: 'https://api.anthropic.com/v1/messages', quality: 'excellent', speed: 'fast', }, 'claude-3-haiku': { id: 'claude-3-haiku-20240307', name: 'Claude 3 Haiku', provider: 'anthropic', contextWindow: 200000, inputPricePerMillion: 0.25, outputPricePerMillion: 1.25, recommendedBatchSize: 120, apiUrl: 'https://api.anthropic.com/v1/messages', quality: 'good', speed: 'very-fast', }, 'claude-3-opus': { id: 'claude-3-opus-20240229', name: 'Claude 3 Opus', provider: 'anthropic', contextWindow: 200000, inputPricePerMillion: 15.0, outputPricePerMillion: 75.0, recommendedBatchSize: 100, apiUrl: 'https://api.anthropic.com/v1/messages', quality: 'best', speed: 'slow', }, // OpenAI Models 'gpt-4o': { id: 'gpt-4o', name: 'GPT-4o', provider: 'openai', contextWindow: 128000, inputPricePerMillion: 2.5, outputPricePerMillion: 10.0, recommendedBatchSize: 80, apiUrl: 'https://api.openai.com/v1/chat/completions', quality: 'excellent', speed: 'fast', }, 'gpt-4o-mini': { id: 'gpt-4o-mini', name: 'GPT-4o Mini', provider: 'openai', contextWindow: 128000, inputPricePerMillion: 0.15, outputPricePerMillion: 0.60, recommendedBatchSize: 80, apiUrl: 'https://api.openai.com/v1/chat/completions', quality: 'good', speed: 'very-fast', }, // Google Gemini Models 'gemini-1.5-pro': { id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro', provider: 'google', contextWindow: 2000000, inputPricePerMillion: 1.25, outputPricePerMillion: 5.0, recommendedBatchSize: 800, apiUrl: 'https://generativelanguage.googleapis.com/v1beta/models', quality: 'excellent', speed: 'fast', }, 'gemini-1.5-flash': { id: 'gemini-1.5-flash', name: 'Gemini 1.5 Flash', provider: 'google', contextWindow: 1000000, inputPricePerMillion: 0.075, outputPricePerMillion: 0.30, recommendedBatchSize: 600, apiUrl: 'https://generativelanguage.googleapis.com/v1beta/models', quality: 'good', speed: 'very-fast', }, }; /** * Select optimal model based on criteria */ export function selectModel(criteria = 'best-value') { // Direct model selection if (criteria in AVAILABLE_MODELS) { return AVAILABLE_MODELS[criteria]; } const models = Object.values(AVAILABLE_MODELS); switch (criteria) { case 'cheapest': // Lowest total cost (input + output) return models.reduce((cheapest, model) => { const currentCost = model.inputPricePerMillion + model.outputPricePerMillion; const cheapestCost = cheapest.inputPricePerMillion + cheapest.outputPricePerMillion; return currentCost < cheapestCost ? model : cheapest; }); case 'fastest': // Fastest processing return models.filter(m => m.speed === 'very-fast')[0] || AVAILABLE_MODELS['claude-3-haiku']; case 'largest-context': // Largest context window return models.reduce((largest, model) => model.contextWindow > largest.contextWindow ? model : largest); case 'best-quality': // Highest quality return models.filter(m => m.quality === 'best')[0] || AVAILABLE_MODELS['claude-3-5-sonnet']; case 'best-value': // Best balance of cost and quality (default) // Prefer good quality + cheap cost return AVAILABLE_MODELS['claude-3-haiku']; default: // Fallback to Sonnet return AVAILABLE_MODELS['claude-3-5-sonnet']; } } /** * Calculate estimated cost for a batch */ export function estimateCost(model, inputTokens, outputTokens) { const inputCost = (inputTokens / 1_000_000) * model.inputPricePerMillion; const outputCost = (outputTokens / 1_000_000) * model.outputPricePerMillion; return inputCost + outputCost; } /** * Get model configuration from environment or default */ export function getModelConfig() { const modelKey = process.env.AI_MODEL || 'claude-3-5-sonnet'; const selector = process.env.AI_MODEL_SELECTOR; if (selector) { return selectModel(selector); } return AVAILABLE_MODELS[modelKey] || AVAILABLE_MODELS['claude-3-5-sonnet']; } /** * Compare models side-by-side */ export function compareModels(fileCount, avgInputTokensPerFile = 400, avgOutputTokensPerFile = 100) { return Object.entries(AVAILABLE_MODELS).map(([key, config]) => { const filesPerBatch = config.recommendedBatchSize; const batchCount = Math.ceil(fileCount / filesPerBatch); const apiCalls = batchCount; const totalInputTokens = fileCount * avgInputTokensPerFile; const totalOutputTokens = fileCount * avgOutputTokensPerFile; const totalCost = estimateCost(config, totalInputTokens, totalOutputTokens); return { model: config.name, batchCount, totalCost: parseFloat(totalCost.toFixed(4)), costPerFile: parseFloat((totalCost / fileCount).toFixed(6)), apiCalls, }; }).sort((a, b) => a.totalCost - b.totalCost); // Sort by cost } /** * Get API key for a provider */ export function getApiKey(provider) { switch (provider) { case 'anthropic': return process.env.ANTHROPIC_API_KEY; case 'openai': return process.env.OPENAI_API_KEY; case 'google': return process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY; default: return undefined; } } /** * Check if a model is available (API key exists) */ export function isModelAvailable(modelKey) { const model = AVAILABLE_MODELS[modelKey]; if (!model) return false; const apiKey = getApiKey(model.provider); return !!apiKey; } /** * Get all available models (with API keys configured) */ export function getAvailableModels() { return Object.values(AVAILABLE_MODELS).filter(model => isModelAvailable(Object.keys(AVAILABLE_MODELS).find(k => AVAILABLE_MODELS[k] === model))); } // Example usage in CLI or config /* // Environment variable approach: export AI_MODEL_SELECTOR=cheapest export AI_MODEL=claude-3-haiku // Or specific model // Programmatic approach: const model = selectModel('cheapest'); console.log(`Using ${model.name} - $${model.inputPricePerMillion}/M input tokens`); // Cost comparison: const comparison = compareModels(1000); console.table(comparison); // Output: // ┌─────────┬────────────────────────┬────────────┬───────────┬───────────────┬───────────┐ // │ (index) │ model │ batchCount │ totalCost │ costPerFile │ apiCalls │ // ├─────────┼────────────────────────┼────────────┼───────────┼───────────────┼───────────┤ // │ 0 │ 'Gemini 1.5 Flash' │ 2 │ 0.012 │ 0.000012 │ 2 │ // │ 1 │ 'GPT-4o Mini' │ 13 │ 0.015 │ 0.000015 │ 13 │ // │ 2 │ 'Claude 3 Haiku' │ 9 │ 0.025 │ 0.000025 │ 9 │ // │ 3 │ 'Gemini 1.5 Pro' │ 2 │ 0.15 │ 0.00015 │ 2 │ // │ 4 │ 'GPT-4o' │ 13 │ 0.25 │ 0.00025 │ 13 │ // │ 5 │ 'Claude 3.5 Sonnet' │ 10 │ 0.30 │ 0.0003 │ 10 │ // │ 6 │ 'Claude 3 Opus' │ 10 │ 1.50 │ 0.0015 │ 10 │ // └─────────┴────────────────────────┴────────────┴───────────┴───────────────┴───────────┘ */ //# sourceMappingURL=ai-model-config.js.map