// Model configuration - centralized place to manage AI models export interface ModelConfig { id: string; name: string; provider: string; openRouterModel: string; supportsTools: boolean; tier: 'smart' | 'fast'; // New: classification for usage tracking description?: string; badge?: 'nsfw' | 'experimental' | 'beta'; // New: special badges for certain models } // Available models configuration export const MODELS: ModelConfig[] = [ { id: 'gemini-2-5-flash', name: 'Gemini 2.5 Flash', provider: 'google', openRouterModel: 'google/gemini-2.5-flash', supportsTools: true, tier: 'fast', description: '⚡ Ultra fast responses\n🎯 Precise answers\n📝 Concise writing\n💪 High throughput' }, { id: 'kimi-k2', name: 'Kimi K2', provider: 'moonshotai', openRouterModel: 'moonshotai/kimi-k2', supportsTools: true, tier: 'smart', description: '🧠 Strong reasoning\n📖 Long context (128K)\n💻 Excellent coding\n🎯 Plot analysis\n⚠️ May fabricate details' }, { id: 'gemini-2-5-pro', name: 'Gemini 2.5 Pro', provider: 'google', openRouterModel: 'google/gemini-2.5-pro', supportsTools: true, tier: 'smart', description: '💡 Creative ideas\n🔄 Multiple perspectives\n🎨 Versatile writing\n📝 Can be verbose' }, { id: 'gpt-4o-mini', name: 'GPT-4o Mini', provider: 'openai', openRouterModel: 'openai/gpt-4o-mini', supportsTools: true, tier: 'fast', description: '⚡ Fast & efficient\n📝 Clear writing\n🎯 Structured tasks\n⚠️ Less creative' }, { id: 'claude-sonnet-4', name: 'Claude Sonnet 4', provider: 'anthropic', openRouterModel: 'anthropic/claude-sonnet-4', supportsTools: true, tier: 'smart', description: '🎭 Character depth\n📚 Detailed analysis\n🌟 Creative writing\n⏱️ Slower response' }, { id: 'claude-3-7-sonnet', name: 'Claude 3.7 Sonnet', provider: 'anthropic', openRouterModel: 'anthropic/claude-3.7-sonnet', supportsTools: true, tier: 'smart', description: '✨ Premium quality\n🎭 Deep insights\n📚 Sophisticated prose\n⏱️ Most thorough' }, { id: 'mistral-nemo', name: 'Mistral Nemo', provider: 'mistralai', openRouterModel: 'mistralai/mistral-nemo', supportsTools: false, tier: 'smart', badge: 'nsfw', description: '🔥 NSFW content\n🎭 Adult themes\n💋 Mature writing\n⚠️ 18+ only' } ]; // Default model (first model in the list) export const DEFAULT_MODEL = MODELS[0]; // Helper functions export function getModelByName(name: string): ModelConfig | undefined { return MODELS.find(model => model.name === name); } export function getModelById(id: string): ModelConfig | undefined { return MODELS.find(model => model.id === id); } export function getOpenRouterModel(modelName: string): string { const model = getModelByName(modelName); return model?.openRouterModel || DEFAULT_MODEL.openRouterModel; } // New: Get model tier for usage tracking export function getModelTier(modelName: string): 'smart' | 'fast' { const model = getModelByName(modelName); // Handle image generation models explicitly as smart if (modelName.includes('gpt-image') || modelName.includes('dall-e') || modelName.includes('image')) { return 'smart'; } return model?.tier || 'fast'; } // New: Get models by tier export function getModelsByTier(tier: 'smart' | 'fast'): ModelConfig[] { return MODELS.filter(model => model.tier === tier); } // New: Check if a model is smart export function isSmartModel(modelName: string): boolean { return getModelTier(modelName) === 'smart'; } export function getToolCompatibleModels(): ModelConfig[] { return MODELS.filter(model => model.supportsTools); } // Create mapping object for backwards compatibility export const MODEL_MAPPING: Record = MODELS.reduce((acc, model) => { acc[model.name] = model.openRouterModel; return acc; }, {} as Record); // List of tool-compatible model OpenRouter IDs export const TOOL_COMPATIBLE_MODELS = MODELS .filter(model => model.supportsTools) .map(model => model.openRouterModel); // Get models for standalone chat (includes NSFW models) export function getStandaloneChatModels(): ModelConfig[] { return MODELS; // All models including NSFW ones } // Get models for book chat (excludes NSFW models) export function getBookChatModels(): ModelConfig[] { return MODELS.filter(model => !model.badge || model.badge !== 'nsfw'); }