From b5e13c183d3cb7cafbbf7e3b08015d9ba19521f7 Mon Sep 17 00:00:00 2001 From: Network Monitor Bot Date: Tue, 19 Aug 2025 19:50:20 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Feat:=20Syst=C3=A8me=20d'ex?= =?UTF-8?q?=C3=A9cution=20intelligente=20et=20planification=20automatique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fonctionnalités révolutionnaires: - ✨ IA capable d'exécuter des commandes système de manière sécurisée - 🧠 Planification automatique des tâches complexes - 🔒 Système de sécurité avec listes blanches/noires de commandes - 📋 Création de plans d'action étape par étape - 🚀 Exécution automatique avec feedback en temps réel - 📊 Génération de rapports détaillés Nouvelles commandes: - `exec ` - Exécution directe sécurisée - `plan ` - Création de plan d'action - `run` - Exécution du plan créé - `cancel` - Annulation du plan actuel Mode intelligent: - L'IA analyse automatiquement si des commandes sont nécessaires - Création et exécution automatique de plans d'action - Feedback visuel avec icônes de statut - Gestion des erreurs et adaptation du plan Exemple d'usage: 🧠 NeuraTerm> analyse le répertoire 🤖 Analyse intelligente: cette demande nécessite des actions système. 📋 Création automatique d'un plan d'action... 🎯 Plan créé: Analyser la structure et le contenu du répertoire courant 🔄 Exécution automatique en cours... ✅ Lister les fichiers et dossiers ✅ Afficher la structure arborescente 📊 Génération du rapport final... L'IA est maintenant vraiment autonome et opérationnelle ! 🚀 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .claude/settings.local.json | 3 +- src/ai/taskPlanner.ts | 296 +++++++++++++++++++++++++++++++ src/commands/index.ts | 223 +++++++++++++++++++++-- src/execution/commandExecutor.ts | 226 +++++++++++++++++++++++ src/execution/index.ts | 24 ++- src/terminal/index.ts | 17 +- 6 files changed, 766 insertions(+), 23 deletions(-) create mode 100644 src/ai/taskPlanner.ts create mode 100644 src/execution/commandExecutor.ts diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 764dea0..8d5106d 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -7,7 +7,8 @@ "Bash(git rm:*)", "Bash(git push:*)", "Bash(npm run build:*)", - "Bash(npm start)" + "Bash(npm start)", + "Bash(git commit:*)" ], "deny": [], "ask": [] diff --git a/src/ai/taskPlanner.ts b/src/ai/taskPlanner.ts new file mode 100644 index 0000000..7e0ff4f --- /dev/null +++ b/src/ai/taskPlanner.ts @@ -0,0 +1,296 @@ +/** + * Planificateur de tâches intelligent pour l'IA + */ + +import { AIClient } from './client.js'; +import { CommandExecutor, CommandResult } from '../execution/commandExecutor.js'; +import { logger } from '../utils/logger.js'; + +export interface Task { + id: string; + description: string; + command?: string; + status: 'pending' | 'running' | 'completed' | 'failed'; + result?: CommandResult; + reasoning: string; +} + +export interface TaskPlan { + objective: string; + tasks: Task[]; + createdAt: Date; + completedAt?: Date; +} + +export class TaskPlanner { + private currentPlan: TaskPlan | null = null; + + constructor( + private aiClient: AIClient, + private commandExecutor: CommandExecutor + ) {} + + /** + * Crée un plan d'action basé sur la demande utilisateur + */ + async createPlan(userRequest: string): Promise { + logger.info(`Création d'un plan pour: ${userRequest}`); + + const planningPrompt = ` +Tu es un assistant IA capable d'exécuter des commandes système. L'utilisateur demande: "${userRequest}" + +Crée un plan détaillé pour répondre à cette demande. Retourne UNIQUEMENT un JSON avec cette structure: +{ + "objective": "Description claire de l'objectif", + "tasks": [ + { + "id": "1", + "description": "Description de la tâche", + "command": "commande à exécuter (optionnel)", + "reasoning": "Pourquoi cette étape est nécessaire" + } + ] +} + +Commandes disponibles: ${this.commandExecutor.getAllowedCommands().join(', ')} + +Règles: +- Maximum 5 tâches par plan +- Une seule commande par tâche +- Commandes sûres uniquement +- Plan logique et séquentiel +- Si aucune commande n'est nécessaire, omets le champ "command" + +Exemple pour "analyse le répertoire": +{ + "objective": "Analyser la structure et le contenu du répertoire courant", + "tasks": [ + { + "id": "1", + "description": "Lister les fichiers et dossiers", + "command": "ls -la", + "reasoning": "Voir tous les éléments du répertoire avec détails" + }, + { + "id": "2", + "description": "Afficher la structure arborescente", + "command": "tree -L 2", + "reasoning": "Visualiser l'organisation hiérarchique" + }, + { + "id": "3", + "description": "Analyser l'espace disque utilisé", + "command": "du -sh *", + "reasoning": "Identifier les éléments les plus volumineux" + }, + { + "id": "4", + "description": "Résumer les observations", + "reasoning": "Synthétiser les informations collectées" + } + ] +} +`.trim(); + + try { + const response = await this.aiClient.generateResponse({ + messages: [ + { role: 'system', content: planningPrompt }, + { role: 'user', content: userRequest } + ], + temperature: 0.3 + }); + + // Parser la réponse JSON + const planData = JSON.parse(response.content.trim()); + + // Créer le plan avec les tâches + const plan: TaskPlan = { + objective: planData.objective, + tasks: planData.tasks.map((task: any) => ({ + ...task, + status: 'pending' as const + })), + createdAt: new Date() + }; + + this.currentPlan = plan; + logger.info(`Plan créé avec ${plan.tasks.length} tâches`); + + return plan; + + } catch (error) { + logger.error('Erreur lors de la création du plan:', error); + + // Plan de fallback + const fallbackPlan: TaskPlan = { + objective: userRequest, + tasks: [{ + id: '1', + description: 'Répondre à la demande utilisateur', + status: 'pending', + reasoning: 'Plan de secours suite à une erreur de planification' + }], + createdAt: new Date() + }; + + this.currentPlan = fallbackPlan; + return fallbackPlan; + } + } + + /** + * Exécute le plan actuel étape par étape + */ + async executePlan(progressCallback?: (task: Task) => void): Promise { + if (!this.currentPlan) { + throw new Error('Aucun plan à exécuter'); + } + + logger.info(`Début d'exécution du plan: ${this.currentPlan.objective}`); + + for (const task of this.currentPlan.tasks) { + task.status = 'running'; + progressCallback?.(task); + + try { + if (task.command) { + // Exécuter la commande + task.result = await this.commandExecutor.executeCommand(task.command); + + if (task.result.success) { + task.status = 'completed'; + logger.info(`Tâche ${task.id} complétée: ${task.description}`); + } else { + task.status = 'failed'; + logger.error(`Tâche ${task.id} échouée: ${task.result.stderr}`); + + // Demander à l'IA comment procéder en cas d'échec + await this.handleTaskFailure(task); + } + } else { + // Tâche sans commande (analyse, réflexion) + task.status = 'completed'; + logger.info(`Tâche ${task.id} complétée: ${task.description}`); + } + + progressCallback?.(task); + + } catch (error) { + task.status = 'failed'; + logger.error(`Erreur dans la tâche ${task.id}:`, error); + progressCallback?.(task); + + // Continuer avec les autres tâches même en cas d'échec + continue; + } + } + + this.currentPlan.completedAt = new Date(); + logger.info('Plan d\'exécution terminé'); + } + + /** + * Gère l'échec d'une tâche en demandant à l'IA comment adapter le plan + */ + private async handleTaskFailure(failedTask: Task): Promise { + const adaptationPrompt = ` +La tâche "${failedTask.description}" a échoué avec l'erreur: ${failedTask.result?.stderr} + +Comment adapter le plan ? Options: +1. Continuer avec les tâches suivantes +2. Modifier la commande et réessayer +3. Ajouter une tâche alternative +4. Arrêter le plan + +Réponds en une phrase courte avec ta recommandation. +`; + + try { + const response = await this.aiClient.generateResponse({ + messages: [ + { role: 'system', content: 'Tu es un assistant qui aide à adapter les plans d\'exécution.' }, + { role: 'user', content: adaptationPrompt } + ], + temperature: 0.1 + }); + + logger.info(`Adaptation suggérée pour la tâche ${failedTask.id}: ${response.content}`); + + } catch (error) { + logger.error('Impossible de générer une adaptation:', error); + } + } + + /** + * Génère un rapport final du plan exécuté + */ + async generateReport(): Promise { + if (!this.currentPlan) { + return 'Aucun plan à reporter'; + } + + const completedTasks = this.currentPlan.tasks.filter(t => t.status === 'completed'); + const failedTasks = this.currentPlan.tasks.filter(t => t.status === 'failed'); + + const reportData = { + objective: this.currentPlan.objective, + totalTasks: this.currentPlan.tasks.length, + completed: completedTasks.length, + failed: failedTasks.length, + results: this.currentPlan.tasks.map(task => ({ + description: task.description, + status: task.status, + output: task.result?.stdout || 'Pas de sortie', + error: task.result?.stderr || null + })) + }; + + const reportPrompt = ` +Génère un rapport d'exécution synthétique et professionnel basé sur ces données: +${JSON.stringify(reportData, null, 2)} + +Le rapport doit: +- Résumer l'objectif et les résultats principaux +- Présenter les informations importantes découvertes +- Mentionner les échecs s'il y en a +- Être concis et utile pour l'utilisateur +- Utiliser un français professionnel + +Format: texte simple, pas de JSON. +`; + + try { + const response = await this.aiClient.generateResponse({ + messages: [ + { role: 'system', content: 'Tu es un assistant qui génère des rapports d\'exécution clairs et professionnels.' }, + { role: 'user', content: reportPrompt } + ], + temperature: 0.2 + }); + + return response.content; + + } catch (error) { + logger.error('Erreur lors de la génération du rapport:', error); + return `Rapport automatique:\n\nObjectif: ${this.currentPlan.objective}\nTâches complétées: ${completedTasks.length}/${this.currentPlan.tasks.length}\nStatut: ${failedTasks.length > 0 ? 'Partiellement réussi' : 'Réussi'}`; + } + } + + /** + * Obtient le plan actuel + */ + getCurrentPlan(): TaskPlan | null { + return this.currentPlan; + } + + /** + * Annule le plan actuel + */ + cancelCurrentPlan(): void { + if (this.currentPlan) { + logger.info('Plan actuel annulé'); + this.currentPlan = null; + } + } +} \ No newline at end of file diff --git a/src/commands/index.ts b/src/commands/index.ts index 825e910..748763e 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -5,10 +5,12 @@ import * as readline from 'readline'; import { AIClient } from '../ai/client.js'; import { Terminal } from '../terminal/index.js'; +import { TaskPlanner, Task } from '../ai/taskPlanner.js'; import { logger } from '../utils/logger.js'; export class CommandProcessor { private rl: readline.Interface; + private taskPlanner: TaskPlanner; constructor( private config: any, @@ -22,6 +24,10 @@ export class CommandProcessor { errors: any; } ) { + this.taskPlanner = new TaskPlanner( + this.dependencies.ai, + this.dependencies.execution.getCommandExecutor() + ); this.rl = readline.createInterface({ input: process.stdin, output: process.stdout, @@ -111,9 +117,26 @@ export class CommandProcessor { await this.setupKeys(); break; + case 'exec': + case 'execute': + await this.executeCommand(args.join(' ')); + break; + + case 'plan': + await this.createTaskPlan(args.join(' ')); + break; + + case 'run': + await this.runCurrentPlan(); + break; + + case 'cancel': + this.cancelCurrentPlan(); + break; + default: - // Traiter comme une question à l'IA - await this.handleAIQuery(command); + // Traiter comme une demande intelligente avec planification automatique + await this.handleSmartQuery(command); break; } } @@ -264,22 +287,192 @@ export class CommandProcessor { } } - private async handleAIQuery(query: string): Promise { + private async executeCommand(command: string): Promise { + if (!command.trim()) { + console.log('Usage: exec '); + return; + } + try { - const response = await this.dependencies.ai.generateResponse({ - messages: [ - { - role: 'system', - content: 'Tu es un assistant IA professionnel. Réponds de manière concise et utile.' - }, - { - role: 'user', - content: query - } - ] + const executor = this.dependencies.execution.getCommandExecutor(); + console.log(`\n🔧 Exécution: ${command}`); + + const result = await executor.executeCommand(command); + + if (result.success) { + console.log('✅ Commande exécutée avec succès\n'); + if (result.stdout) { + console.log(result.stdout); + } + } else { + console.log('❌ Échec de la commande\n'); + console.error(result.stderr); + } + + console.log(`⏱️ Temps d'exécution: ${result.executionTime}ms`); + + } catch (error) { + this.dependencies.terminal.displayError(error instanceof Error ? error.message : String(error)); + } + } + + private async createTaskPlan(request: string): Promise { + if (!request.trim()) { + console.log('Usage: plan '); + return; + } + + try { + console.log('\n📋 Création du plan d\'action...'); + const plan = await this.taskPlanner.createPlan(request); + + console.log(`\n🎯 Objectif: ${plan.objective}`); + console.log(`📝 ${plan.tasks.length} tâche(s) planifiée(s):\n`); + + plan.tasks.forEach((task, index) => { + console.log(`${index + 1}. ${task.description}`); + if (task.command) { + console.log(` 📍 Commande: ${task.command}`); + } + console.log(` 💭 Justification: ${task.reasoning}\n`); }); - this.dependencies.terminal.displayResponse(response); + console.log('💡 Tapez "run" pour exécuter le plan, ou "cancel" pour l\'annuler.'); + + } catch (error) { + this.dependencies.terminal.displayError(error instanceof Error ? error.message : String(error)); + } + } + + private async runCurrentPlan(): Promise { + const plan = this.taskPlanner.getCurrentPlan(); + if (!plan) { + console.log('❌ Aucun plan à exécuter. Créez un plan avec la commande "plan".'); + return; + } + + try { + console.log(`\n🚀 Exécution du plan: ${plan.objective}\n`); + + await this.taskPlanner.executePlan((task: Task) => { + const statusIcon = { + pending: '⏳', + running: '🔄', + completed: '✅', + failed: '❌' + }[task.status]; + + console.log(`${statusIcon} Tâche ${task.id}: ${task.description}`); + + if (task.status === 'completed' && task.result?.stdout) { + console.log(`📤 Résultat:\n${task.result.stdout}\n`); + } + + if (task.status === 'failed' && task.result?.stderr) { + console.log(`⚠️ Erreur: ${task.result.stderr}\n`); + } + }); + + console.log('\n📊 Génération du rapport final...'); + const report = await this.taskPlanner.generateReport(); + console.log(`\n${report}`); + + } catch (error) { + this.dependencies.terminal.displayError(error instanceof Error ? error.message : String(error)); + } + } + + private cancelCurrentPlan(): void { + const plan = this.taskPlanner.getCurrentPlan(); + if (!plan) { + console.log('❌ Aucun plan actif à annuler.'); + return; + } + + this.taskPlanner.cancelCurrentPlan(); + console.log('✅ Plan annulé.'); + } + + private async handleSmartQuery(query: string): Promise { + try { + // Déterminer si la demande nécessite des commandes système + const analysisPrompt = ` +Analyse cette demande utilisateur: "${query}" + +Cette demande nécessite-t-elle l'exécution de commandes système pour une réponse complète ? + +Exemples qui nécessitent des commandes: +- "analyse le répertoire" +- "montre-moi les fichiers Python" +- "vérifie l'espace disque" +- "trouve les gros fichiers" +- "lance les tests" + +Exemples qui ne nécessitent PAS de commandes: +- "explique-moi les fonctions JavaScript" +- "comment optimiser ce code ?" +- "qu'est-ce que React ?" +- "aide-moi avec cette erreur" + +Réponds par "OUI" ou "NON" uniquement. +`; + + const analysisResponse = await this.dependencies.ai.generateResponse({ + messages: [ + { role: 'system', content: analysisPrompt }, + { role: 'user', content: query } + ], + temperature: 0.1 + }); + + const needsCommands = analysisResponse.content.trim().toUpperCase() === 'OUI'; + + if (needsCommands) { + // Créer et exécuter un plan automatiquement + console.log('\n🤖 Analyse intelligente: cette demande nécessite des actions système.'); + console.log('📋 Création automatique d\'un plan d\'action...\n'); + + const plan = await this.taskPlanner.createPlan(query); + console.log(`🎯 Plan créé: ${plan.objective}`); + console.log(`🔄 Exécution automatique en cours...\n`); + + await this.taskPlanner.executePlan((task: Task) => { + const statusIcon = { + pending: '⏳', + running: '🔄', + completed: '✅', + failed: '❌' + }[task.status]; + + console.log(`${statusIcon} ${task.description}`); + + if (task.status === 'completed' && task.result?.stdout && task.result.stdout.trim()) { + console.log(`📤 ${task.result.stdout.trim()}\n`); + } + }); + + console.log('📊 Génération du rapport final...\n'); + const report = await this.taskPlanner.generateReport(); + console.log(report); + + } else { + // Réponse IA classique sans commandes + const response = await this.dependencies.ai.generateResponse({ + messages: [ + { + role: 'system', + content: 'Tu es un assistant IA professionnel. Réponds de manière concise et utile.' + }, + { + role: 'user', + content: query + } + ] + }); + + this.dependencies.terminal.displayResponse(response); + } + } catch (error) { this.dependencies.terminal.displayError(error instanceof Error ? error.message : String(error)); } diff --git a/src/execution/commandExecutor.ts b/src/execution/commandExecutor.ts new file mode 100644 index 0000000..b4d462f --- /dev/null +++ b/src/execution/commandExecutor.ts @@ -0,0 +1,226 @@ +/** + * Exécuteur de commandes sécurisé pour l'IA + */ + +import { spawn, exec } from 'child_process'; +import { promisify } from 'util'; +import { logger } from '../utils/logger.js'; + +const execAsync = promisify(exec); + +export interface CommandResult { + success: boolean; + stdout: string; + stderr: string; + exitCode: number | null; + command: string; + executionTime: number; +} + +export interface CommandOptions { + timeout?: number; + cwd?: string; + maxOutputLength?: number; +} + +export class CommandExecutor { + private allowedCommands: Set; + private blockedCommands: Set; + + constructor() { + // Commandes autorisées (liste blanche) + this.allowedCommands = new Set([ + 'ls', 'dir', 'pwd', 'cd', + 'cat', 'type', 'head', 'tail', + 'find', 'grep', 'where', + 'git', 'npm', 'node', 'python', 'python3', + 'echo', 'whoami', 'date', + 'tree', 'du', 'df', + 'ps', 'top', 'tasklist', + 'ping', 'curl', 'wget', + 'chmod', 'chown', 'mkdir', 'rmdir', + 'cp', 'mv', 'copy', 'move', + 'zip', 'unzip', 'tar', + 'which', 'whereis' + ]); + + // Commandes dangereuses (liste noire) + this.blockedCommands = new Set([ + 'rm', 'del', 'delete', 'format', + 'sudo', 'su', 'passwd', + 'shutdown', 'reboot', 'halt', + 'dd', 'fdisk', 'mkfs', + 'netcat', 'nc', 'telnet', + 'ssh', 'scp', 'ftp', + 'iptables', 'firewall', + 'crontab', 'systemctl', + 'killall', 'pkill' + ]); + } + + /** + * Vérifie si une commande est autorisée + */ + private isCommandAllowed(command: string): boolean { + const baseCommand = command.split(' ')[0].toLowerCase(); + + // Vérifier la liste noire d'abord + if (this.blockedCommands.has(baseCommand)) { + return false; + } + + // Vérifier la liste blanche + return this.allowedCommands.has(baseCommand); + } + + /** + * Nettoie et valide une commande + */ + private sanitizeCommand(command: string): string { + // Supprimer les caractères dangereux + const dangerous = ['|', '&', ';', '>', '<', '`', '$', '(', ')', '{', '}']; + let sanitized = command; + + for (const char of dangerous) { + if (sanitized.includes(char) && !this.isSpecialCharAllowed(command, char)) { + throw new Error(`Caractère non autorisé: ${char}`); + } + } + + return sanitized.trim(); + } + + /** + * Vérifie si un caractère spécial est autorisé dans le contexte + */ + private isSpecialCharAllowed(command: string, char: string): boolean { + const cmd = command.split(' ')[0].toLowerCase(); + + // Permettre certains caractères pour des commandes spécifiques + switch (char) { + case '>': + case '<': + return ['echo', 'cat'].includes(cmd); + case '|': + return ['grep', 'find', 'ps'].includes(cmd); + default: + return false; + } + } + + /** + * Exécute une commande de façon sécurisée + */ + async executeCommand( + command: string, + options: CommandOptions = {} + ): Promise { + const startTime = Date.now(); + const maxOutputLength = options.maxOutputLength || 10000; + const timeout = options.timeout || 30000; + + try { + // Validation et nettoyage + const sanitizedCommand = this.sanitizeCommand(command); + + if (!this.isCommandAllowed(sanitizedCommand)) { + throw new Error(`Commande non autorisée: ${command.split(' ')[0]}`); + } + + logger.info(`Exécution de la commande: ${sanitizedCommand}`); + + // Exécution avec timeout + const { stdout, stderr } = await Promise.race([ + execAsync(sanitizedCommand, { + cwd: options.cwd || process.cwd(), + timeout, + maxBuffer: maxOutputLength + }), + new Promise((_, reject) => { + setTimeout(() => reject(new Error('Timeout')), timeout); + }) + ]); + + const executionTime = Date.now() - startTime; + + const result: CommandResult = { + success: true, + stdout: stdout.toString().substring(0, maxOutputLength), + stderr: stderr.toString().substring(0, maxOutputLength), + exitCode: 0, + command: sanitizedCommand, + executionTime + }; + + logger.info(`Commande exécutée avec succès en ${executionTime}ms`); + return result; + + } catch (error: any) { + const executionTime = Date.now() - startTime; + + logger.error(`Erreur d'exécution de commande: ${error.message}`); + + return { + success: false, + stdout: '', + stderr: error.message || 'Erreur inconnue', + exitCode: error.code || 1, + command, + executionTime + }; + } + } + + /** + * Exécute plusieurs commandes en séquence + */ + async executeCommandSequence( + commands: string[], + options: CommandOptions = {} + ): Promise { + const results: CommandResult[] = []; + + for (const command of commands) { + const result = await this.executeCommand(command, options); + results.push(result); + + // Arrêter en cas d'échec si demandé + if (!result.success && options.timeout) { + logger.warn(`Arrêt de la séquence à cause de l'échec de: ${command}`); + break; + } + } + + return results; + } + + /** + * Ajoute une commande à la liste blanche + */ + allowCommand(command: string): void { + this.allowedCommands.add(command.toLowerCase()); + logger.info(`Commande autorisée: ${command}`); + } + + /** + * Retire une commande de la liste blanche + */ + disallowCommand(command: string): void { + this.allowedCommands.delete(command.toLowerCase()); + logger.info(`Commande interdite: ${command}`); + } + + /** + * Obtient la liste des commandes autorisées + */ + getAllowedCommands(): string[] { + return Array.from(this.allowedCommands).sort(); + } + + /** + * Obtient la liste des commandes interdites + */ + getBlockedCommands(): string[] { + return Array.from(this.blockedCommands).sort(); + } +} \ No newline at end of file diff --git a/src/execution/index.ts b/src/execution/index.ts index 649dac7..66c9bf8 100644 --- a/src/execution/index.ts +++ b/src/execution/index.ts @@ -1,11 +1,29 @@ /** - * Environnement d'exécution + * Environnement d'exécution avec support des commandes */ +import { CommandExecutor } from './commandExecutor.js'; +import { logger } from '../utils/logger.js'; + export class ExecutionEnvironment { - constructor(private config: any) {} + private commandExecutor: CommandExecutor; + + constructor(private config: any) { + this.commandExecutor = new CommandExecutor(); + logger.info('Environnement d\'exécution initialisé'); + } + + getCommandExecutor(): CommandExecutor { + return this.commandExecutor; + } + + isExecutionEnabled(): boolean { + return this.config.execution?.enabled ?? true; + } } export async function initExecutionEnvironment(config: any): Promise { return new ExecutionEnvironment(config); -} \ No newline at end of file +} + +export { CommandExecutor } from './commandExecutor.js'; \ No newline at end of file diff --git a/src/terminal/index.ts b/src/terminal/index.ts index c3b4cc7..d74b01a 100644 --- a/src/terminal/index.ts +++ b/src/terminal/index.ts @@ -82,6 +82,12 @@ Gestion des providers: providers - Lister les providers disponibles provider - Changer de provider (openai, mistral) +Exécution intelligente: + exec - Exécuter une commande système + plan - Créer un plan d'action pour une tâche + run - Exécuter le plan créé + cancel - Annuler le plan actuel + Statistiques: stats - Afficher les statistiques d'utilisation stats - Statistiques d'un provider spécifique @@ -91,12 +97,15 @@ Statistiques: Configuration: config - Afficher la configuration actuelle -Pour poser une question à l'IA, tapez simplement votre message. +🤖 IA Intelligente: +Pour toute demande, tapez simplement votre message. L'IA analysera automatiquement +si des commandes système sont nécessaires et créera/exécutera un plan d'action. Exemples: - key set openai - Configurer votre clé OpenAI - provider mistral - Basculer vers Mistral AI - Comment optimiser ce code Python ? + analyse le répertoire - L'IA créera automatiquement un plan + trouve les fichiers Python - Planification et exécution automatiques + exec ls -la - Exécution directe d'une commande + plan "optimiser le projet" - Création manuelle d'un plan `); } }