UNPKG

maia-cli

Version:

Command-line interface for MAIA (Modern AI Assistant)

154 lines (131 loc) • 5.47 kB
/** * MAIA Chat Command - Interactive chat session */ import { Command } from 'commander'; import inquirer from 'inquirer'; import chalk from 'chalk'; import ora from 'ora'; import { MAIAEngine, ConfigManager, getBuiltinTools } from 'maia-core'; export const chatCommand = new Command('chat') .description('Start interactive chat session') .option('-c, --conversation <id>', 'continue existing conversation') .option('--stream', 'enable streaming responses') .action(async (options) => { console.log(chalk.cyan('šŸ’¬ Starting MAIA chat session...\n')); try { // Load configuration const configManager = new ConfigManager(); if (!configManager.exists()) { console.log(chalk.red('āŒ MAIA not initialized. Run "maia init" first.')); return; } const config = configManager.load(); // Validate API key if (!config.ai[config.ai.provider]?.apiKey) { console.log(chalk.red('āŒ API key not configured. Run "maia config" to set up.')); return; } // Initialize MAIA engine const spinner = ora('Initializing MAIA engine...').start(); const engine = new MAIAEngine({ config }); // Wait for engine initialization (loads built-in and external tools) await new Promise(resolve => setTimeout(resolve, 100)); // Give time for async initialization // Count all available tools const builtinToolsCount = config.tools.enabled.length; const externalTools = engine.externalTools.listTools(); const externalToolsCount = externalTools.length; const externalMethodsCount = externalTools.reduce((count, tool) => count + tool.tools.length, 0); const totalTools = builtinToolsCount + externalToolsCount; if (externalToolsCount > 0) { spinner.succeed(`MAIA ready with ${totalTools} tools (${builtinToolsCount} built-in, ${externalToolsCount} external with ${externalMethodsCount} methods)`); } else { spinner.succeed(`MAIA ready with ${totalTools} tools`); } // Get or create conversation let conversation; if (options.conversation) { conversation = engine.getConversation(options.conversation); if (!conversation) { console.log(chalk.yellow(`āš ļø Conversation ${options.conversation} not found. Creating new one.`)); conversation = engine.createConversation(); } else { console.log(chalk.green(`šŸ“– Continuing conversation: ${conversation.title || conversation.id}`)); } } else { conversation = engine.createConversation(); } console.log(chalk.gray(`Conversation ID: ${conversation.id}`)); console.log(chalk.gray('Type "exit" or "quit" to end the session\n')); // Chat loop while (true) { const { message } = await inquirer.prompt([ { type: 'input', name: 'message', message: chalk.blue('You:'), validate: (input) => { if (!input || input.trim().length === 0) { return 'Please enter a message'; } return true; }, }, ]); // Check for exit commands if (['exit', 'quit', 'bye'].includes(message.toLowerCase().trim())) { console.log(chalk.cyan('šŸ‘‹ Goodbye!')); break; } // Show typing indicator const thinkingSpinner = ora('MAIA is thinking...').start(); try { if (options.stream) { // Streaming response thinkingSpinner.stop(); process.stdout.write(chalk.green('MAIA: ')); const responseStream = await engine.chat( message, conversation.id, { stream: true } ); let fullResponse = ''; for await (const chunk of responseStream) { if (chunk.content) { const newContent = chunk.content.slice(fullResponse.length); process.stdout.write(newContent); fullResponse = chunk.content; } } console.log('\n'); } else { // Regular response const response = await engine.chat(message, conversation.id); thinkingSpinner.succeed(); console.log(chalk.green('MAIA:'), response.content); // Show tool calls if any if (response.toolCalls && response.toolCalls.length > 0) { console.log(chalk.gray('\nšŸ”§ Tools used:')); response.toolCalls.forEach(tool => { if (tool.error) { console.log(chalk.red(` āŒ ${tool.name}: ${tool.error}`)); } else { console.log(chalk.green(` āœ… ${tool.name}`)); } }); } } console.log(); // Empty line for spacing } catch (error) { thinkingSpinner.fail('Error occurred'); console.error(chalk.red('āŒ Error:'), error.message); console.log(); // Empty line for spacing } } // Show conversation stats const stats = engine.getStats(); console.log(chalk.gray(`\nšŸ“Š Session stats: ${stats.messages} messages, ${stats.tools} tools available`)); } catch (error) { console.error(chalk.red('āŒ Chat session failed:'), error.message); process.exit(1); } });