UNPKG

overmind-mcp

Version:

Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mémoire (Private Memory Context) et le support pour

147 lines • 7.62 kB
import { z } from 'zod'; import path from 'path'; import { fileURLToPath } from 'url'; import { AgentManager } from '../services/AgentManager.js'; /** * MCP servers injectés par défaut lors de la création d'un agent Hermes. * 'memory' = 3 tools restreint (memory_search/store/runs, --memory-only sur :3099). * Pour un accès complet 14 tools, utiliser 'overmind' au lieu de 'memory'. */ const DEFAULT_MCP_SERVERS = ['memory']; export const createAgentSchema = z.object({ name: z .string() .regex(/^[a-zA-Z0-9_-]+$/, 'Agent name must only contain alphanumeric, underscores, and hyphens (no path separators)') .describe("Nom unique de l'agent (ex: 'sniper_analyst'). Ce nom servira d'identifiant pour sa mémoire sémantique isolée."), prompt: z .string() .describe("Le prompt système OBLIGATOIRE. Tu DOIS y définir le persona de l'agent, ses missions, les outils MCP qu'il est autorisé à utiliser, et lui ordonner de consulter/enrichir systématiquement sa mémoire Overmind."), runner: z .enum(['claude', 'gemini', 'kilo', 'qwencli', 'openclaw', 'cline', 'opencode', 'hermes']) .optional() .default('claude') .describe('Type de runner pour cet agent (défaut: claude)'), model: z .string() .optional() .describe("Surnom original ou Modèle technique (ex: 'The Chaos Prophet', 'claude-sonnet-4-6'). Le protocole 'Custom-Nickname' d'Overmind permet d'assigner n'importe quel nom ici pour personnaliser votre Cortex. Le runner se chargera automatiquement de mapper ce surnom vers un modèle valide pour l'API."), copyEnvFrom: z .string() .optional() .describe("Chemin vers un settings.json existant pour copier les variables d'environnement (ex: .claude/settingsM.json)"), // Options spécifiques à certains runners mode: z .enum(['code', 'architect', 'ask', 'debug', 'orchestrator', 'plan', 'act']) .optional() .describe('Mode spécifique pour Kilo (code, architect, ask, debug, orchestrator) ou Cline (plan, act)'), cliPath: z .string() .refine((val) => { // Allow simple basenames (no path separators) or absolute paths // Reject relative paths with .. or . components if (val.includes('..')) return false; if (path.isAbsolute(val)) return true; // Simple command name (no separators) return /^[a-zA-Z0-9_-]+$/.test(val); }, 'cliPath must be a simple command name or absolute path (no ".." or relative paths)') .optional() .describe('Chemin vers l\'exécutable CLI (ex: "cline", "opencode")'), }); export async function createAgent(args) { const manager = new AgentManager(); const { name, prompt, runner, model, copyEnvFrom, mode, cliPath } = args; const currentFileUrl = import.meta.url; const currentFilePath = fileURLToPath(currentFileUrl); const projectRoot = path.resolve(path.dirname(currentFilePath), '../../'); const defaultModel = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-6'; const result = await manager.createAgent(name, prompt, model || defaultModel, copyEnvFrom, projectRoot, runner, mode, cliPath); // Pour les agents Hermes, s'assurer que le MCP memory est configuré // et injecter les instructions memory dans SOUL.md if (runner === 'hermes') { try { const { HermesProfileManager } = await import('../services/HermesProfileManager.js'); const profilePath = await HermesProfileManager.getProfilePath(name); if (profilePath) { // 1. Configurer les MCP servers (overmind :3099) await HermesProfileManager.setMcpServers(name, DEFAULT_MCP_SERVERS, profilePath); // 2. Injecter le bloc instructions memory dans SOUL.md const fs = await import('fs'); const soulPath = `${profilePath}/SOUL.md`; const existingSoul = fs.readFileSync(soulPath, 'utf-8'); // Ne pas dupliquer si déjà présent if (!existingSoul.includes('## Mémoire Overmind')) { const memoryBlock = [ '', '---', '', '## Mémoire Overmind', '', `Tu es l'agent **${name}**. Ta mémoire est isolée dans une DB dédiée.`, '', '### Outils mémoire disponibles (via MCP overmind :3099):', '- **memory_search**: Recherche sémantique dans ta mémoire', '- **memory_store**: Mémorise une connaissance/décision', "- **memory_runs**: Consulte l'historique de tes runs", '', '### Utilisation:', "Quand tu apprends quelque chose d'important, utilise memory_store.", 'Quand tu as besoin de contexte passé, utilise memory_search.', '', 'Ton agent_name est automatiquement détecté (OVERMIND_AGENT_NAME).', "Tu n'as pas besoin de le préciser dans les appels.", '', ].join('\n'); fs.writeFileSync(soulPath, existingSoul.trimEnd() + '\n' + memoryBlock, 'utf-8'); } } } catch { // silent fail — l'agent est créé, les MCP servers sont optionnels } } if (result.error === 'INVALID_NAME') { return { content: [ { type: 'text', text: `❌ **Nom d'agent invalide**\n\nLe nom '${name}' contient des caractères interdits.`, }, ], isError: true, }; } if (result.error?.startsWith('MISSING_AUTH_TOKEN')) { return { content: [ { type: 'text', text: `❌ **Authentification impossible**\n\n${result.error}\n\n**Fix :** ajoutez dans le .env du service OverMind (ex. \`/home/<user>/.overmind/.env\`) :\n\n\`\`\`\nANTHROPIC_AUTH_TOKEN=sk-...\n\`\`\`\n\nPuis \`sudo systemctl restart overmind-mcp.service\`.`, }, ], isError: true, }; } // Message de succès adapté selon le runner const runnerInfo = { claude: 'Claude Code', gemini: 'Gemini', kilo: 'Kilocode', qwencli: 'Qwen CLI', openclaw: 'OpenClaw', cline: 'Cline', opencode: 'OpenCode', hermes: 'Nous Hermes', }; const runnerName = runnerInfo[runner] || 'Claude Code'; return { content: [ { type: 'text', text: `[OK] Agent '${name}' créé avec succès pour ${runnerName} !\n\n[FILES] Fichiers créés :\n- Prompt : ${result.promptPath}\n- Config : ${result.settingsPath}\n\n[RUN] Pour lancer cet agent avec le runner ${runner} :\n\`\`\`bash\n# Via l'outil MCP run_agent:\nrun_agent(runner: "${runner}", agentName: "${name}", prompt: "votre prompt")\n\`\`\`\n\n[INFO] **Runners disponibles:**\n- claude: Claude Code (défaut)\n- gemini: Gemini\n- kilo: Kilocode${mode ? ` (mode: ${mode})` : ''}\n- qwencli: Qwen CLI\n- openclaw: OpenClaw\n- cline: Cline${mode ? ` (mode: ${mode})` : ''}\n- opencode: OpenCode\n- hermes: Nous Hermes`, }, ], }; } //# sourceMappingURL=create_agent.js.map