maia-cli
Version:
Command-line interface for MAIA (Modern AI Assistant)
154 lines (131 loc) ⢠5.47 kB
JavaScript
/**
* 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);
}
});