UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with external MCP server integration, multi-provider support, and professional CLI. Connect to 65+ MCP servers for filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major pr

324 lines (323 loc) 12.7 kB
import { execSync } from 'child_process'; import chalk from 'chalk'; import ora from 'ora'; import inquirer from 'inquirer'; export const ollamaCommand = { command: 'ollama <command>', describe: 'Manage Ollama local AI models', builder: (yargs) => { return yargs .command('list-models', 'List installed Ollama models', {}, listModelsHandler) .command('pull <model>', 'Download an Ollama model', { model: { describe: 'Model name to download', type: 'string', demandOption: true } }, pullModelHandler) .command('remove <model>', 'Remove an Ollama model', { model: { describe: 'Model name to remove', type: 'string', demandOption: true } }, removeModelHandler) .command('status', 'Check Ollama service status', {}, statusHandler) .command('start', 'Start Ollama service', {}, startHandler) .command('stop', 'Stop Ollama service', {}, stopHandler) .command('setup', 'Interactive Ollama setup', {}, setupHandler) .demandCommand(1, 'Please specify a command'); }, handler: () => { } // No-op handler as subcommands handle everything }; async function listModelsHandler() { const spinner = ora('Fetching installed models...').start(); try { const output = execSync('ollama list', { encoding: 'utf8' }); spinner.succeed('Installed models:'); if (output.trim()) { console.log(output); } else { console.log(chalk.yellow('No models installed. Use "neurolink ollama pull <model>" to download a model.')); } } catch (error) { spinner.fail('Failed to list models. Is Ollama installed?'); console.error(chalk.red('Error:', error.message)); console.log(chalk.blue('\nTip: Install Ollama from https://ollama.ai')); process.exit(1); } } async function pullModelHandler(argv) { const { model } = argv; console.log(chalk.blue(`Downloading model: ${model}`)); console.log(chalk.gray('This may take several minutes...')); try { execSync(`ollama pull ${model}`, { stdio: 'inherit' }); console.log(chalk.green(`\n✅ Successfully downloaded ${model}`)); console.log(chalk.blue(`\nTest it with: npx @juspay/neurolink generate-text "Hello!" --provider ollama --model ${model}`)); } catch (error) { console.error(chalk.red(`\n❌ Failed to download ${model}`)); console.error(chalk.red('Error:', error.message)); process.exit(1); } } async function removeModelHandler(argv) { const { model } = argv; // Confirm removal const { confirm } = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: `Are you sure you want to remove model "${model}"?`, default: false } ]); if (!confirm) { console.log(chalk.yellow('Removal cancelled.')); return; } const spinner = ora(`Removing model ${model}...`).start(); try { execSync(`ollama rm ${model}`, { encoding: 'utf8' }); spinner.succeed(`Successfully removed ${model}`); } catch (error) { spinner.fail(`Failed to remove ${model}`); console.error(chalk.red('Error:', error.message)); process.exit(1); } } async function statusHandler() { const spinner = ora('Checking Ollama service status...').start(); try { // Try to run a simple command execSync('ollama list', { encoding: 'utf8' }); spinner.succeed('Ollama service is running'); // Get additional info try { const response = execSync('curl -s http://localhost:11434/api/tags', { encoding: 'utf8' }); const data = JSON.parse(response); if (data.models && data.models.length > 0) { console.log(chalk.green(`\n${data.models.length} models available`)); } } catch { // Curl might not be available, that's ok } } catch (error) { spinner.fail('Ollama service is not running'); console.log(chalk.yellow('\nStart Ollama with: ollama serve')); console.log(chalk.blue('Or restart the Ollama app if using the desktop version')); process.exit(1); } } async function startHandler() { console.log(chalk.blue('Starting Ollama service...')); try { // Check if already running try { execSync('ollama list', { encoding: 'utf8' }); console.log(chalk.yellow('Ollama service is already running!')); return; } catch { // Not running, continue to start } // Different approaches for different platforms if (process.platform === 'darwin') { // macOS console.log(chalk.gray('Starting Ollama on macOS...')); try { execSync('open -a Ollama'); console.log(chalk.green('✅ Ollama app started')); } catch { // Try service command execSync('ollama serve > /dev/null 2>&1 &', { stdio: 'ignore' }); console.log(chalk.green('✅ Ollama service started')); } } else if (process.platform === 'linux') { // Linux console.log(chalk.gray('Starting Ollama service on Linux...')); try { execSync('systemctl start ollama', { encoding: 'utf8' }); console.log(chalk.green('✅ Ollama service started')); } catch { // Try direct command execSync('ollama serve > /dev/null 2>&1 &', { stdio: 'ignore' }); console.log(chalk.green('✅ Ollama service started')); } } else { // Windows console.log(chalk.gray('Starting Ollama on Windows...')); execSync('start ollama serve', { stdio: 'ignore' }); console.log(chalk.green('✅ Ollama service started')); } console.log(chalk.blue('\nWait a few seconds for the service to initialize...')); } catch (error) { console.error(chalk.red('Failed to start Ollama service')); console.error(chalk.red('Error:', error.message)); console.log(chalk.blue('\nTry starting Ollama manually or check installation')); process.exit(1); } } async function stopHandler() { const spinner = ora('Stopping Ollama service...').start(); try { if (process.platform === 'darwin') { // macOS try { execSync('pkill ollama', { encoding: 'utf8' }); } catch { execSync('killall Ollama', { encoding: 'utf8' }); } } else if (process.platform === 'linux') { // Linux try { execSync('systemctl stop ollama', { encoding: 'utf8' }); } catch { execSync('pkill ollama', { encoding: 'utf8' }); } } else { // Windows execSync('taskkill /F /IM ollama.exe', { encoding: 'utf8' }); } spinner.succeed('Ollama service stopped'); } catch (error) { spinner.fail('Failed to stop Ollama service'); console.error(chalk.red('It may not be running or requires manual stop')); } } async function setupHandler() { console.log(chalk.blue('🦙 Welcome to Ollama Setup!\n')); // Check if Ollama is installed const checkSpinner = ora('Checking Ollama installation...').start(); let isInstalled = false; try { execSync('ollama --version', { encoding: 'utf8' }); isInstalled = true; checkSpinner.succeed('Ollama is installed'); } catch { checkSpinner.fail('Ollama is not installed'); } if (!isInstalled) { console.log(chalk.yellow('\nOllama needs to be installed first.')); console.log(chalk.blue('\nInstallation instructions:')); if (process.platform === 'darwin') { console.log('\nFor macOS:'); console.log(chalk.gray(' brew install ollama')); console.log(chalk.gray(' # or download from https://ollama.ai')); } else if (process.platform === 'linux') { console.log('\nFor Linux:'); console.log(chalk.gray(' curl -fsSL https://ollama.ai/install.sh | sh')); } else { console.log('\nFor Windows:'); console.log(chalk.gray(' Download from https://ollama.ai')); } const { proceedAnyway } = await inquirer.prompt([ { type: 'confirm', name: 'proceedAnyway', message: 'Would you like to continue with setup anyway?', default: false } ]); if (!proceedAnyway) { console.log(chalk.blue('\nInstall Ollama and run setup again!')); return; } } // Check if service is running let serviceRunning = false; try { execSync('ollama list', { encoding: 'utf8' }); serviceRunning = true; console.log(chalk.green('\n✅ Ollama service is running')); } catch { console.log(chalk.yellow('\n⚠️ Ollama service is not running')); const { startService } = await inquirer.prompt([ { type: 'confirm', name: 'startService', message: 'Would you like to start the Ollama service?', default: true } ]); if (startService) { await startHandler(); serviceRunning = true; } } if (serviceRunning) { // List available models console.log(chalk.blue('\n📦 Popular Ollama models:')); console.log(' • llama2 (7B) - General purpose'); console.log(' • codellama (7B) - Code generation'); console.log(' • mistral (7B) - Fast and efficient'); console.log(' • tinyllama (1B) - Lightweight'); console.log(' • phi (2.7B) - Microsoft\'s compact model'); const { downloadModel } = await inquirer.prompt([ { type: 'confirm', name: 'downloadModel', message: 'Would you like to download a model?', default: true } ]); if (downloadModel) { const { selectedModel } = await inquirer.prompt([ { type: 'list', name: 'selectedModel', message: 'Select a model to download:', choices: [ { name: 'llama2 (7B) - Recommended for general use', value: 'llama2' }, { name: 'codellama (7B) - Best for code generation', value: 'codellama' }, { name: 'mistral (7B) - Fast and efficient', value: 'mistral' }, { name: 'tinyllama (1B) - Lightweight, fast', value: 'tinyllama' }, { name: 'phi (2.7B) - Microsoft\'s compact model', value: 'phi' }, { name: 'Other (enter manually)', value: 'other' } ] } ]); let modelToDownload = selectedModel; if (selectedModel === 'other') { const { customModel } = await inquirer.prompt([ { type: 'input', name: 'customModel', message: 'Enter the model name:', validate: (input) => input.trim().length > 0 || 'Model name is required' } ]); modelToDownload = customModel; } await pullModelHandler({ model: modelToDownload }); } } // Final instructions console.log(chalk.green('\n✅ Setup complete!\n')); console.log(chalk.blue('Next steps:')); console.log('1. List models: ' + chalk.gray('neurolink ollama list-models')); console.log('2. Generate text: ' + chalk.gray('neurolink generate-text "Hello!" --provider ollama')); console.log('3. Use specific model: ' + chalk.gray('neurolink generate-text "Hello!" --provider ollama --model codellama')); console.log(chalk.gray('\nFor more information, see: https://docs.neurolink.ai/providers/ollama')); } export default ollamaCommand;