/** * Model Recommendation Command * * Uses the ModelSupervisor to recommend optimal models for different tasks */ import chalk from 'chalk'; import inquirer from 'inquirer'; import { OllamaClient, ModelSupervisor, TaskType, TaskContext } from '@fsfalmansour/neohub-core'; import { ConfigManager } from '../config'; export async function recommendCommand(): Promise { console.log(chalk.bold.cyan('\nšŸŽÆ Model Recommendation\n')); const config = new ConfigManager(); const client = new OllamaClient(config.getOllamaConfig()); const supervisor = new ModelSupervisor(client); try { // Initialize supervisor console.log(chalk.gray('Analyzing available models...')); await supervisor.initialize(); const flagshipModels = supervisor.getAvailableFlagshipModels(); if (flagshipModels.length === 0) { console.log( chalk.yellow('\nāš ļø No flagship models detected. Please install at least one:\n') ); console.log(chalk.gray(' ollama pull deepseek-coder:33b')); console.log(chalk.gray(' ollama pull codellama:34b\n')); return; } console.log( chalk.green( `\nāœ“ Found ${flagshipModels.length} flagship model(s): ${flagshipModels.join(', ')}\n` ) ); // Prompt for task type const { taskType } = await inquirer.prompt<{ taskType: TaskType }>([ { type: 'list', name: 'taskType', message: 'What type of task do you need help with?', choices: [ { name: 'šŸ“ Code Generation', value: 'code-generation' }, { name: 'šŸ” Code Review', value: 'code-review' }, { name: 'ā™»ļø Refactoring', value: 'refactoring' }, { name: 'šŸ› Debugging', value: 'debugging' }, { name: 'šŸ“– Code Explanation', value: 'explanation' }, { name: 'šŸ—ļø Architecture Design', value: 'architecture' }, { name: 'āœļø Quick Edit', value: 'quick-edit' }, { name: 'šŸ”¬ Code Analysis', value: 'analysis' }, ], }, ]); // Prompt for complexity const { complexity } = await inquirer.prompt<{ complexity: 'low' | 'medium' | 'high'; }>([ { type: 'list', name: 'complexity', message: 'How complex is the task?', choices: [ { name: 'Low - Simple, straightforward task', value: 'low' }, { name: 'Medium - Moderate complexity', value: 'medium' }, { name: 'High - Complex, requires deep understanding', value: 'high' }, ], }, ]); // Optional: file size context const { hasFileContext } = await inquirer.prompt<{ hasFileContext: boolean }>([ { type: 'confirm', name: 'hasFileContext', message: 'Are you working with a large file (>500 lines)?', default: false, }, ]); const lineCount = hasFileContext ? 1000 : 100; // Build context and get recommendation const context: TaskContext = { type: taskType, complexity, lineCount, }; const recommendation = await supervisor.recommendModel(context); // Display recommendation console.log(chalk.bold.green('\nšŸŽÆ Recommended Model\n')); console.log(chalk.cyan('Model: ') + chalk.bold(recommendation.model)); console.log( chalk.cyan('Confidence: ') + chalk.bold((recommendation.confidence * 100).toFixed(0) + '%') ); console.log(chalk.cyan('Reasoning: ') + recommendation.reasoning); if (recommendation.alternatives && recommendation.alternatives.length > 0) { console.log( chalk.cyan('\nAlternatives: ') + chalk.gray(recommendation.alternatives.join(', ')) ); } // Display model stats const stats = supervisor.getModelStats(); if (stats.performanceMetrics.size > 0) { console.log(chalk.bold('\nšŸ“Š Performance History\n')); for (const [model, metrics] of stats.performanceMetrics.entries()) { console.log( chalk.gray(` ${model}: `) + chalk.white(`${metrics.avgResponseTime.toFixed(0)}ms avg `) + chalk.gray(`(${metrics.sampleSize} samples)`) ); } } // Suggest command to use console.log(chalk.bold.cyan('\nšŸ’” Suggested Usage\n')); console.log( chalk.gray(' To use this model, run:\n ') + chalk.white(`neohub chat --model ${recommendation.model}`) ); console.log( chalk.gray(' Or set it as default:\n ') + chalk.white(`neohub config set ollama.model ${recommendation.model}\n`) ); } catch (error) { console.log(chalk.red('\nāœ— Error: ' + (error as Error).message + '\n')); } }