UNPKG

@hivetechs/hive-ai

Version:

Real-time streaming AI consensus platform with HTTP+SSE MCP integration for Claude Code, VS Code, Cursor, and Windsurf - powered by OpenRouter's unified API

767 lines 39.1 kB
/** * Expert Profile Templates System * * Sophisticated pre-built consensus profiles for different use cases, * with advanced configuration options and intelligent model selection. * * Features: * - 10+ expert-crafted templates * - Dynamic model selection based on current rankings * - Budget-aware configurations * - Performance optimization settings * - Scope-specific templates (minimal/basic/production) * - Advanced routing variant control */ import { getDatabase, createPipelineProfileWithInternalIds, getAllPipelineProfiles } from '../storage/unified-database.js'; import { OpenRouterRankings } from './openrouter-rankings.js'; import { DynamicModelSelector } from './dynamic-model-selector.js'; import { TemplateMaintenanceManager } from './hiveai/template-maintenance.js'; // ===== EXPERT TEMPLATE CATALOG ===== export const EXPERT_TEMPLATES = [ { id: 'lightning-fast', name: 'Lightning Fast', description: 'Ultra-high-speed consensus optimized for rapid prototyping and quick answers', category: 'speed', scope: 'minimal', expertLevel: 'beginner', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-5', costRange: 'low', fallback: { type: 'speed-optimized', tier: 'standard', providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-10', costRange: 'ultra-low', fallback: { type: 'cost-efficient', tier: 'budget' } }, validator: { rankingPosition: 'cost-efficient', fallback: { type: 'cost-efficient', tier: 'budget', providers: ['google'] } }, curator: { rankingPosition: 'top-5', costRange: 'low', fallback: { type: 'speed-optimized', tier: 'standard', providers: ['anthropic'] } } }, temperatures: { generator: 0.3, refiner: 0.2, validator: 0.1, curator: 0.3 }, routingPreferences: { generator: ':nitro', refiner: ':floor', validator: ':floor', curator: ':nitro' }, budgetProfile: { priority: 'cost', preferredCostRange: 'ultra-low', maxCostPerConversation: 0.05 }, performanceProfile: { priority: 'speed', maxLatencyMs: 2000, qualityThreshold: 0.7 }, useCases: ['Quick prototyping', 'Simple questions', 'Learning', 'Debugging small issues'], tags: ['speed', 'budget-friendly', 'beginner', 'rapid'] }, { id: 'precision-architect', name: 'Precision Architect', description: 'Maximum quality consensus for complex architectural decisions and critical code', category: 'quality', scope: 'production', expertLevel: 'expert', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-5', contextWindow: 'xl', fallback: { type: 'premium-quality', tier: 'flagship', contextWindow: 'xl', providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-5', contextWindow: 'large', fallback: { type: 'premium-quality', tier: 'flagship', contextWindow: 'large', providers: ['openai'] } }, validator: { rankingPosition: 'top-10', capabilities: ['reasoning'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['reasoning'], providers: ['google'] } }, curator: { rankingPosition: 'top-5', contextWindow: 'xl', fallback: { type: 'premium-quality', tier: 'flagship', contextWindow: 'xl', providers: ['anthropic'] } } }, temperatures: { generator: 0.7, refiner: 0.5, validator: 0.3, curator: 0.6 }, routingPreferences: { generator: ':nitro', refiner: ':nitro', validator: ':default', curator: ':nitro' }, budgetProfile: { priority: 'performance', preferredCostRange: 'premium', maxCostPerConversation: 1.00 }, performanceProfile: { priority: 'quality', qualityThreshold: 0.95 }, useCases: ['System architecture', 'Complex algorithms', 'Production code review', 'Security analysis'], tags: ['quality', 'expert', 'architecture', 'premium', 'production'] }, { id: 'budget-optimizer', name: 'Budget Optimizer', description: 'Cost-efficient consensus that maximizes value while minimizing expenses', category: 'cost', scope: 'basic', expertLevel: 'intermediate', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'cost-efficient', costRange: 'low', fallback: { type: 'cost-efficient', tier: 'standard', providers: ['meta-llama'] } }, refiner: { rankingPosition: 'cost-efficient', costRange: 'ultra-low', fallback: { type: 'cost-efficient', tier: 'budget', providers: ['google'] } }, validator: { rankingPosition: 'cost-efficient', costRange: 'ultra-low', fallback: { type: 'cost-efficient', tier: 'budget', providers: ['anthropic'] } }, curator: { rankingPosition: 'cost-efficient', costRange: 'low', fallback: { type: 'cost-efficient', tier: 'standard', providers: ['mistral', 'mistralai'] } } }, temperatures: { generator: 0.4, refiner: 0.3, validator: 0.2, curator: 0.4 }, routingPreferences: { generator: ':floor', refiner: ':floor', validator: ':floor', curator: ':floor' }, budgetProfile: { priority: 'cost', preferredCostRange: 'low', maxCostPerConversation: 0.10 }, performanceProfile: { priority: 'balanced', qualityThreshold: 0.8 }, useCases: ['Learning projects', 'Personal development', 'Small team projects', 'Budget-conscious development'], tags: ['cost-effective', 'budget', 'efficient', 'balanced'] }, { id: 'research-deep-dive', name: 'Research Deep Dive', description: 'Comprehensive analysis for research, documentation, and knowledge discovery', category: 'specialized', scope: 'production', expertLevel: 'advanced', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-10', contextWindow: 'xl', capabilities: ['research'], fallback: { type: 'premium-quality', tier: 'premium', contextWindow: 'xl', capabilities: ['research'], providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-10', contextWindow: 'large', fallback: { type: 'premium-quality', tier: 'premium', contextWindow: 'large', providers: ['openai'] } }, validator: { rankingPosition: 'top-15', capabilities: ['analysis'], fallback: { type: 'premium-quality', tier: 'standard', capabilities: ['analysis'], providers: ['google'] } }, curator: { rankingPosition: 'top-5', contextWindow: 'xl', fallback: { type: 'premium-quality', tier: 'flagship', contextWindow: 'xl', providers: ['anthropic'] } } }, temperatures: { generator: 0.8, refiner: 0.6, validator: 0.4, curator: 0.7 }, routingPreferences: { generator: ':online', refiner: ':default', validator: ':default', curator: ':online' }, budgetProfile: { priority: 'performance', preferredCostRange: 'high' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.9 }, useCases: ['Technical research', 'Market analysis', 'Academic writing', 'Documentation'], tags: ['research', 'analysis', 'comprehensive', 'web-enabled'] }, { id: 'startup-mvp', name: 'Startup MVP', description: 'Balanced consensus for MVP development with good quality and reasonable cost', category: 'production', scope: 'basic', expertLevel: 'intermediate', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-10', costRange: 'medium', fallback: { type: 'balanced', tier: 'premium', providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-15', costRange: 'low', fallback: { type: 'balanced', tier: 'standard', providers: ['openai'] } }, validator: { rankingPosition: 'cost-efficient', fallback: { type: 'balanced', tier: 'standard', providers: ['google'] } }, curator: { rankingPosition: 'top-10', costRange: 'medium', fallback: { type: 'balanced', tier: 'premium', providers: ['anthropic'] } } }, temperatures: { generator: 0.6, refiner: 0.4, validator: 0.3, curator: 0.5 }, routingPreferences: { generator: ':default', refiner: ':floor', validator: ':floor', curator: ':default' }, budgetProfile: { priority: 'balanced', preferredCostRange: 'medium', maxCostPerConversation: 0.25 }, performanceProfile: { priority: 'balanced', qualityThreshold: 0.85 }, useCases: ['MVP development', 'Startup projects', 'Feature prototyping', 'Small team development'], tags: ['startup', 'mvp', 'balanced', 'practical'] }, { id: 'enterprise-grade', name: 'Enterprise Grade', description: 'Production-ready consensus with enterprise security, reliability, and compliance', category: 'production', scope: 'production', expertLevel: 'expert', selectionStrategy: 'hybrid', fixedModels: { generator: 1, // anthropic/claude-3.5-sonnet refiner: 2, // openai/gpt-4o validator: 5, // google/gemini-pro-1.5 curator: 6 // anthropic/claude-3-opus }, temperatures: { generator: 0.5, refiner: 0.3, validator: 0.2, curator: 0.4 }, routingPreferences: { generator: ':nitro', refiner: ':nitro', validator: ':default', curator: ':nitro' }, budgetProfile: { priority: 'performance', preferredCostRange: 'premium' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.95 }, useCases: ['Enterprise applications', 'Mission-critical systems', 'Financial services', 'Healthcare systems'], tags: ['enterprise', 'production', 'reliable', 'premium', 'compliance'] }, { id: 'creative-innovator', name: 'Creative Innovator', description: 'High-creativity consensus for innovative solutions and creative problem solving', category: 'specialized', scope: 'basic', expertLevel: 'advanced', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-5', capabilities: ['creative'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['creative'], providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-10', fallback: { type: 'premium-quality', tier: 'premium', providers: ['openai'] } }, validator: { rankingPosition: 'top-15', fallback: { type: 'premium-quality', tier: 'standard', providers: ['google'] } }, curator: { rankingPosition: 'top-5', capabilities: ['creative'], fallback: { type: 'premium-quality', tier: 'flagship', capabilities: ['creative'], providers: ['anthropic'] } } }, temperatures: { generator: 0.9, refiner: 0.7, validator: 0.5, curator: 0.8 }, budgetProfile: { priority: 'performance', preferredCostRange: 'high' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.85 }, useCases: ['Creative coding', 'Innovative solutions', 'Brainstorming', 'Novel algorithms'], tags: ['creative', 'innovative', 'experimental', 'high-temperature'] }, { id: 'security-focused', name: 'Security Focused', description: 'Security-first consensus optimized for secure coding and vulnerability analysis', category: 'specialized', scope: 'production', expertLevel: 'expert', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-5', capabilities: ['security'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['security'], providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-10', capabilities: ['security'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['security'], providers: ['openai'] } }, validator: { rankingPosition: 'top-10', capabilities: ['analysis'], fallback: { type: 'premium-quality', tier: 'standard', capabilities: ['analysis'], providers: ['google'] } }, curator: { rankingPosition: 'top-5', capabilities: ['security'], fallback: { type: 'premium-quality', tier: 'flagship', capabilities: ['security'], providers: ['anthropic'] } } }, temperatures: { generator: 0.4, refiner: 0.3, validator: 0.2, curator: 0.3 }, routingPreferences: { generator: ':nitro', refiner: ':nitro', validator: ':default', curator: ':nitro' }, budgetProfile: { priority: 'performance', preferredCostRange: 'high' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.95 }, useCases: ['Security audits', 'Vulnerability analysis', 'Secure coding', 'Compliance reviews'], tags: ['security', 'analysis', 'compliance', 'expert', 'careful'] }, { id: 'ml-ai-specialist', name: 'ML/AI Specialist', description: 'Specialized consensus for machine learning and AI development projects', category: 'specialized', scope: 'production', expertLevel: 'expert', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-5', capabilities: ['ml', 'ai'], contextWindow: 'xl', fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['ml', 'ai'], contextWindow: 'xl', providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-10', capabilities: ['ml'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['ml'], providers: ['openai'] } }, validator: { rankingPosition: 'top-10', capabilities: ['analysis'], fallback: { type: 'premium-quality', tier: 'standard', capabilities: ['analysis'], providers: ['google'] } }, curator: { rankingPosition: 'top-5', capabilities: ['ml', 'ai'], fallback: { type: 'premium-quality', tier: 'flagship', capabilities: ['ml', 'ai'], providers: ['anthropic'] } } }, temperatures: { generator: 0.6, refiner: 0.4, validator: 0.3, curator: 0.5 }, budgetProfile: { priority: 'performance', preferredCostRange: 'high' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.9 }, useCases: ['ML model development', 'AI system design', 'Data science', 'Neural networks'], tags: ['ml', 'ai', 'data-science', 'specialist', 'advanced'] }, { id: 'debugging-detective', name: 'Debugging Detective', description: 'Methodical consensus optimized for debugging, troubleshooting, and error analysis', category: 'specialized', scope: 'basic', expertLevel: 'intermediate', selectionStrategy: 'dynamic', selectionCriteria: { generator: { rankingPosition: 'top-10', capabilities: ['debugging'], fallback: { type: 'premium-quality', tier: 'premium', capabilities: ['debugging'], providers: ['anthropic'] } }, refiner: { rankingPosition: 'top-15', capabilities: ['analysis'], fallback: { type: 'balanced', tier: 'standard', capabilities: ['analysis'], providers: ['openai'] } }, validator: { rankingPosition: 'top-10', capabilities: ['reasoning'], fallback: { type: 'premium-quality', tier: 'standard', capabilities: ['reasoning'], providers: ['google'] } }, curator: { rankingPosition: 'top-10', fallback: { type: 'premium-quality', tier: 'premium', providers: ['anthropic'] } } }, temperatures: { generator: 0.3, refiner: 0.2, validator: 0.1, curator: 0.3 }, budgetProfile: { priority: 'balanced', preferredCostRange: 'medium' }, performanceProfile: { priority: 'quality', qualityThreshold: 0.9 }, useCases: ['Bug debugging', 'Error analysis', 'Code troubleshooting', 'System diagnostics'], tags: ['debugging', 'troubleshooting', 'methodical', 'precise'] } ]; // ===== EXPERT TEMPLATE MANAGER ===== export class ExpertTemplateManager { rankings; selector; maintenance; constructor() { this.rankings = new OpenRouterRankings(); this.selector = new DynamicModelSelector(); this.maintenance = new TemplateMaintenanceManager(); } /** * Get all available templates, optionally filtered */ getTemplates(filter) { let templates = [...EXPERT_TEMPLATES]; if (filter) { if (filter.category) { templates = templates.filter(t => t.category === filter.category); } if (filter.scope) { templates = templates.filter(t => t.scope === filter.scope); } if (filter.expertLevel) { templates = templates.filter(t => t.expertLevel === filter.expertLevel); } if (filter.useCases?.length) { templates = templates.filter(t => filter.useCases.some(useCase => t.useCases.some(tUseCase => tUseCase.toLowerCase().includes(useCase.toLowerCase())))); } if (filter.tags?.length) { templates = templates.filter(t => filter.tags.some(tag => t.tags.includes(tag))); } } return templates; } /** * Find the best template for a specific question or use case */ async findBestTemplate(question, preferences) { const questionLower = question.toLowerCase(); const scores = new Map(); // Analyze question content for relevant templates for (const template of EXPERT_TEMPLATES) { let score = 0; // Use case matching for (const useCase of template.useCases) { if (questionLower.includes(useCase.toLowerCase())) { score += 10; } } // Tag matching for (const tag of template.tags) { if (questionLower.includes(tag)) { score += 5; } } // Category matching if (questionLower.includes('debug') && template.category === 'specialized' && template.id === 'debugging-detective') score += 15; if (questionLower.includes('security') && template.id === 'security-focused') score += 15; if (questionLower.includes('ml') || questionLower.includes('ai') && template.id === 'ml-ai-specialist') score += 15; if (questionLower.includes('fast') || questionLower.includes('quick') && template.category === 'speed') score += 10; if (questionLower.includes('budget') || questionLower.includes('cheap') && template.category === 'cost') score += 10; if (questionLower.includes('enterprise') || questionLower.includes('production') && template.id === 'enterprise-grade') score += 15; // Preference matching if (preferences) { if (preferences.budget === 'low' && template.budgetProfile?.priority === 'cost') score += 8; if (preferences.budget === 'high' && template.budgetProfile?.priority === 'performance') score += 8; if (preferences.speed === 'fast' && template.category === 'speed') score += 8; if (preferences.speed === 'quality' && template.category === 'quality') score += 8; if (preferences.expertLevel && template.expertLevel === preferences.expertLevel) score += 5; } scores.set(template.id, score); } // Return top 3 templates, sorted by score return EXPERT_TEMPLATES .filter(t => scores.get(t.id) > 0) .sort((a, b) => scores.get(b.id) - scores.get(a.id)) .slice(0, 3); } /** * Create a profile from an expert template */ async createProfileFromTemplate(templateId, profileName, userId) { const template = EXPERT_TEMPLATES.find(t => t.id === templateId); if (!template) { throw new Error(`Template not found: ${templateId}`); } const name = profileName || `${template.name} Profile`; let modelInternalIds; try { if (template.selectionStrategy === 'fixed' && template.fixedModels) { // Use fixed models - resolve any that aren't already internal IDs modelInternalIds = { generator: typeof template.fixedModels.generator === 'number' ? template.fixedModels.generator : await this.resolveModelToInternalId(template.fixedModels.generator) || await this.findFallbackModelFromDatabase('generator'), refiner: typeof template.fixedModels.refiner === 'number' ? template.fixedModels.refiner : await this.resolveModelToInternalId(template.fixedModels.refiner) || await this.findFallbackModelFromDatabase('refiner'), validator: typeof template.fixedModels.validator === 'number' ? template.fixedModels.validator : await this.resolveModelToInternalId(template.fixedModels.validator) || await this.findFallbackModelFromDatabase('validator'), curator: typeof template.fixedModels.curator === 'number' ? template.fixedModels.curator : await this.resolveModelToInternalId(template.fixedModels.curator) || await this.findFallbackModelFromDatabase('curator') }; } else if (template.selectionStrategy === 'hybrid' && template.fixedModels) { // Hybrid strategy with fixed models - use fixed models as fallback modelInternalIds = { generator: typeof template.fixedModels.generator === 'number' ? template.fixedModels.generator : await this.resolveModelToInternalId(template.fixedModels.generator) || await this.findFallbackModelFromDatabase('generator'), refiner: typeof template.fixedModels.refiner === 'number' ? template.fixedModels.refiner : await this.resolveModelToInternalId(template.fixedModels.refiner) || await this.findFallbackModelFromDatabase('refiner'), validator: typeof template.fixedModels.validator === 'number' ? template.fixedModels.validator : await this.resolveModelToInternalId(template.fixedModels.validator) || await this.findFallbackModelFromDatabase('validator'), curator: typeof template.fixedModels.curator === 'number' ? template.fixedModels.curator : await this.resolveModelToInternalId(template.fixedModels.curator) || await this.findFallbackModelFromDatabase('curator') }; } else if (template.selectionStrategy === 'dynamic' || (template.selectionStrategy === 'hybrid' && template.selectionCriteria)) { // Use dynamic selection - this now always returns internal IDs modelInternalIds = await this.selectModelsFromCriteria(template.selectionCriteria); } else { throw new Error(`Invalid selection strategy: ${template.selectionStrategy}`); } // Verify all models have valid internal IDs for (const [stage, internalId] of Object.entries(modelInternalIds)) { if (!internalId || internalId <= 0) { throw new Error(`Invalid internal ID ${internalId} for ${stage} model - run 'hive sync' to update models`); } } } catch (modelSelectionError) { throw modelSelectionError; } try { // Check for duplicate profile names to prevent duplicates const existingProfiles = await getAllPipelineProfiles(); const nameExists = existingProfiles.some(p => p.name.toLowerCase() === name.toLowerCase()); if (nameExists) { throw new Error(`Profile "${name}" already exists. Please choose a different name or delete the existing profile first.`); } // Create the profile using internal IDs const profile = await createPipelineProfileWithInternalIds(name, modelInternalIds.generator, template.temperatures.generator, modelInternalIds.refiner, template.temperatures.refiner, modelInternalIds.validator, template.temperatures.validator, modelInternalIds.curator, template.temperatures.curator, userId); console.log(`✅ Created expert profile: ${name}`); console.log(`📋 Template: ${template.name} (${template.category})`); console.log(`🎯 Internal IDs: ${modelInternalIds.generator}${modelInternalIds.refiner}${modelInternalIds.validator}${modelInternalIds.curator}`); return { profile, template, selectedModels: modelInternalIds }; } catch (dbError) { if (process.platform === 'win32' && dbError instanceof Error) { if (dbError.message.includes('lock')) { console.log(`💡 Windows database lock issue - try closing other Hive instances`); } if (dbError.message.includes('permission')) { console.log(`💡 Windows permission issue - try running as Administrator`); } } throw dbError; } } /** * Select models based on criteria - ONLY returns internal IDs from unified database */ async selectModelsFromCriteria(criteria) { const analysis = await this.rankings.getRankingAnalysis(); const models = { generator: 0, refiner: 0, validator: 0, curator: 0 }; for (const [stage, stageCriteria] of Object.entries(criteria)) { let selectedModelId = ''; let internalId = null; // Try to get model from rankings first if (stageCriteria.rankingPosition) { switch (stageCriteria.rankingPosition) { case 'top-5': selectedModelId = analysis.topModelsOverall[0]?.modelId || ''; break; case 'top-10': selectedModelId = analysis.topModelsOverall[2]?.modelId || ''; break; case 'top-15': selectedModelId = analysis.topModelsOverall[4]?.modelId || ''; break; case 'top-20': selectedModelId = analysis.topModelsOverall[5]?.modelId || ''; break; case 'cost-efficient': selectedModelId = analysis.costEfficient[0]?.modelId || ''; break; case 'rising-stars': selectedModelId = analysis.risingStars[0]?.modelId || ''; break; } } // Try to resolve the selected model to internal ID if (selectedModelId) { internalId = await this.resolveModelToInternalId(selectedModelId); } // If still no internal ID, try to resolve fallback if (!internalId && stageCriteria.fallback) { internalId = await this.resolveModelToInternalId(stageCriteria.fallback); } // If still no internal ID, query database for best available model for this stage if (!internalId) { console.warn(`⚠️ Could not resolve model for ${stage}, querying database for fallback`); internalId = await this.findFallbackModelFromDatabase(stage); } models[stage] = internalId; } return models; } /** * Find fallback model from database for a specific stage */ async findFallbackModelFromDatabase(stage) { try { const db = await getDatabase(); let query = ''; const params = []; // Stage-specific fallback queries - optimized for each role switch (stage) { case 'generator': // For generator: prefer top-ranked models with good context query = ` SELECT om.internal_id FROM openrouter_models om LEFT JOIN model_rankings mr ON om.internal_id = mr.model_internal_id AND mr.ranking_source = 'openrouter_programming_weekly' WHERE om.is_active = 1 ORDER BY COALESCE(mr.rank_position, 999) ASC, om.context_window DESC LIMIT 1 `; break; case 'refiner': // For refiner: prefer cost-efficient models with decent ranking query = ` SELECT om.internal_id FROM openrouter_models om LEFT JOIN model_rankings mr ON om.internal_id = mr.model_internal_id AND mr.ranking_source = 'openrouter_programming_weekly' WHERE om.is_active = 1 ORDER BY (COALESCE(mr.rank_position, 999) + COALESCE(om.pricing_input * 100000, 999)) ASC LIMIT 1 `; break; case 'validator': // For validator: prefer very cost-efficient models query = ` SELECT om.internal_id FROM openrouter_models om WHERE om.is_active = 1 ORDER BY COALESCE(om.pricing_input, 999) ASC, om.internal_id ASC LIMIT 1 `; break; case 'curator': // For curator: prefer top-ranked models for final polish query = ` SELECT om.internal_id FROM openrouter_models om LEFT JOIN model_rankings mr ON om.internal_id = mr.model_internal_id AND mr.ranking_source = 'openrouter_programming_weekly' WHERE om.is_active = 1 ORDER BY COALESCE(mr.rank_position, 999) ASC, om.context_window DESC LIMIT 1 `; break; default: // Generic fallback: any active model query = ` SELECT om.internal_id FROM openrouter_models om WHERE om.is_active = 1 ORDER BY om.internal_id ASC LIMIT 1 `; } const result = await db.get(query, params); if (!result) { throw new Error(`No active models found in database for ${stage} - run 'hive sync' to populate models`); } console.log(`✅ Found database fallback for ${stage}: internal_id ${result.internal_id}`); return result.internal_id; } catch (error) { console.error(`❌ Error finding fallback model for ${stage}:`, error); throw new Error(`Could not find fallback model for ${stage} - run 'hive sync' to populate models`); } } /** * Resolve semantic model descriptor to internal ID using existing AI evolution architecture */ async resolveSemanticModel(descriptor) { try { const db = await getDatabase(); const analysis = await this.rankings.getRankingAnalysis(); // Build query based on semantic descriptor let query = ` SELECT om.internal_id, om.openrouter_id, om.provider_name, COALESCE(mr.rank_position, 999) as rank_position FROM openrouter_models om LEFT JOIN model_rankings mr ON om.internal_id = mr.model_internal_id AND mr.ranking_source = 'openrouter_programming_weekly' WHERE om.is_active = 1 `; const params = []; // Apply provider filter if (descriptor.providers?.length) { query += ` AND om.provider_name IN (${descriptor.providers.map(() => '?').join(',')})`; params.push(...descriptor.providers); } // Apply context window filter if (descriptor.contextWindow) { const contextLimits = { 'small': [0, 8000], 'medium': [8000, 32000], 'large': [32000, 128000], 'xl': [128000, Infinity] }; const [min, max] = contextLimits[descriptor.contextWindow]; query += ` AND om.context_window >= ? AND om.context_window < ?`; params.push(min, max === Infinity ? 999999999 : max); } // Order by semantic type switch (descriptor.type) { case 'speed-optimized': query += ` ORDER BY rank_position ASC, om.context_window ASC`; break; case 'cost-efficient': query += ` ORDER BY om.pricing_input ASC, rank_position ASC`; break; case 'premium-quality': query += ` ORDER BY rank_position ASC, om.context_window DESC`; break; case 'balanced': query += ` ORDER BY (rank_position + COALESCE(om.pricing_input * 1000000, 0)) ASC`; break; case 'latest-from-provider': query += ` ORDER BY om.last_updated DESC, rank_position ASC`; break; } query += ` LIMIT 5`; const models = await db.all(query, params); if (models.length === 0) { console.warn(`⚠️ No models found matching semantic descriptor:`, descriptor); return null; } // Return the best match const selectedModel = models[0]; console.log(`✅ Resolved semantic model ${descriptor.type} to: ${selectedModel.openrouter_id} (internal_id: ${selectedModel.internal_id})`); return selectedModel.internal_id; } catch (error) { console.error(`❌ Error resolving semantic model:`, error); return null; } } /** * Resolve any model reference (string, number, or semantic descriptor) to internal ID */ async resolveModelToInternalId(modelRef) { if (typeof modelRef === 'number') { return modelRef; // Already an internal ID } if (typeof modelRef === 'string') { return await this.getModelInternalId(modelRef); // OpenRouter ID } if (typeof modelRef === 'object' && modelRef.type) { return await this.resolveSemanticModel(modelRef); // Semantic descriptor } console.error('❌ Invalid model reference type:', typeof modelRef); return null; } /** * Get internal ID for a model by OpenRouter ID, with automatic fallback resolution */ async getModelInternalId(openrouterId) { try { const db = await getDatabase(); const result = await db.get('SELECT internal_id FROM openrouter_models WHERE openrouter_id = ? AND is_active = 1', [openrouterId]); if (!result) { console.warn(`⚠️ Model ${openrouterId} not found in database or inactive - attempting automatic replacement...`); // Use existing template maintenance system to find replacement const replacement = await this.maintenance.findModelReplacement(openrouterId); if (replacement) { console.log(`🔄 Found automatic replacement: ${openrouterId}${replacement}`); return await this.getModelInternalId(replacement); } return null; } return result.internal_id; } catch (error) { console.error(`❌ Error getting internal ID for model ${openrouterId}:`, error); return null; } } /** * Get template recommendations for a user */ getRecommendations(userLevel = 'intermediate') { const recommendations = []; // Always recommend speed and cost templates for beginners if (userLevel === 'beginner') { recommendations.push(EXPERT_TEMPLATES.find(t => t.id === 'lightning-fast'), EXPERT_TEMPLATES.find(t => t.id === 'budget-optimizer'), EXPERT_TEMPLATES.find(t => t.id === 'startup-mvp')); } else if (userLevel === 'intermediate') { recommendations.push(EXPERT_TEMPLATES.find(t => t.id === 'startup-mvp'), EXPERT_TEMPLATES.find(t => t.id === 'debugging-detective'), EXPERT_TEMPLATES.find(t => t.id === 'research-deep-dive')); } else if (userLevel === 'advanced') { recommendations.push(EXPERT_TEMPLATES.find(t => t.id === 'precision-architect'), EXPERT_TEMPLATES.find(t => t.id === 'creative-innovator'), EXPERT_TEMPLATES.find(t => t.id === 'ml-ai-specialist')); } else { // expert recommendations.push(EXPERT_TEMPLATES.find(t => t.id === 'enterprise-grade'), EXPERT_TEMPLATES.find(t => t.id === 'security-focused'), EXPERT_TEMPLATES.find(t => t.id === 'precision-architect')); } return recommendations.filter(Boolean); } } // ===== CONVENIENCE FUNCTIONS ===== export async function createExpertProfile(templateId, profileName, userId) { const manager = new ExpertTemplateManager(); return await manager.createProfileFromTemplate(templateId, profileName, userId); } export function getAvailableTemplates() { return EXPERT_TEMPLATES; } export async function findTemplateForQuestion(question, preferences) { const manager = new ExpertTemplateManager(); return await manager.findBestTemplate(question, preferences); } export function getTemplateRecommendations(userLevel) { const manager = new ExpertTemplateManager(); return manager.getRecommendations(userLevel); } export default ExpertTemplateManager; //# sourceMappingURL=expert-profile-templates.js.map