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
198 lines • 7.93 kB
JavaScript
import { z } from 'zod';
import path from 'path';
import { AgentManager } from '../services/AgentManager.js';
// --- Schemas ---
export const listAgentsSchema = z.object({
details: z
.boolean()
.optional()
.default(false)
.describe('Si true, affiche les détails complets (modèle, config) de chaque agent.'),
});
export const deleteAgentSchema = z.object({
name: z
.string()
.regex(/^[a-zA-Z0-9_-]+$/, 'Agent name must only contain alphanumeric, underscores, and hyphens')
.describe("Nom de l'agent à supprimer (ex: agent_finance)"),
});
export const updateAgentConfigSchema = z.object({
name: z
.string()
.regex(/^[a-zA-Z0-9_-]+$/, 'Agent name must only contain alphanumeric, underscores, and hyphens')
.describe("Nom de l'agent à modifier"),
model: z
.string()
.optional()
.describe('Modèle à utiliser (ex: z.ai/glm-4.7, MiniMax-Text-01, deepseek-reasoner, moonshot-v1-32k)'),
mcpServers: z
.array(z.string())
.optional()
.describe("Liste complète des serveurs MCP à activer (remplace la liste existante). Ex: ['overmind']"),
env: z
.record(z.string(), z.string())
.optional()
.describe("Variables d'environnement supplémentaires à définir ou écraser (ex: { 'API_KEY': '123' })"),
runner: z
.enum(['claude', 'gemini', 'kilo', 'qwencli', 'openclaw', 'cline', 'opencode', 'hermes'])
.optional()
.describe('Type de runner pour cet agent'),
mode: z
.enum(['code', 'architect', 'ask', 'debug', 'orchestrator', 'plan', 'act'])
.optional()
.describe('Mode spécifique pour Kilo ou Cline'),
cliPath: z
.string()
.refine((val) => !val.includes('..') && (path.isAbsolute(val) || /^[a-zA-Z0-9_-]+$/.test(val)), 'cliPath must be a simple command name or absolute path')
.optional()
.describe("Chemin vers l'exécutable CLI (pour runners spécifiques)"),
file: z
.enum(['prompt.md', 'settings.json', '.mcp.json', 'skill.md'])
.optional()
.describe('Fichier spécifique à réécrire ENTIÈREMENT'),
content: z
.string()
.optional()
.describe('Nouveau contenu complet du fichier (si "file" est spécifié)'),
});
// --- Tools ---
export async function listAgents(args) {
const manager = new AgentManager();
try {
const agentsList = await manager.listAgents(args.details);
if (agentsList.length === 0) {
return {
content: [{ type: 'text', text: '📂 Aucun agent trouvé.' }],
};
}
return {
content: [
{
type: 'text',
text: `📋 **Liste des Agents Disponibles (${agentsList.length})** :\n\n${agentsList.join('\n\n')}`,
},
],
};
}
catch (e) {
return {
isError: true,
content: [
{
type: 'text',
text: `❌ Erreur lors du listing des agents : ${e instanceof Error ? e.message : String(e)}`,
},
],
};
}
}
export async function deleteAgent(args) {
const manager = new AgentManager();
const { name } = args;
const result = await manager.deleteAgent(name);
if (result.deletedFiles.length === 0 && result.errors.length === 0) {
return {
isError: true,
content: [
{ type: 'text', text: `⚠️ Agent '${name}' introuvable (ni prompt, ni settings).` },
],
};
}
let response = `🗑️ **Suppression de l'agent '${name}'**\n`;
if (result.deletedFiles.length > 0) {
response += `\n✅ Fichiers supprimés :\n${result.deletedFiles.map((f) => `- ${path.basename(f)}`).join('\n')}`;
}
if (result.errors.length > 0) {
response += `\n\n❌ Erreurs :\n${result.errors.join('\n')}`;
}
return {
content: [{ type: 'text', text: response }],
};
}
export async function updateAgentConfig(args) {
const manager = new AgentManager();
const { name, model, mcpServers, env, runner, mode, cliPath, file, content } = args;
// (a) Avertissement explicite quand 'runner' est omis alors qu'une mise à jour unitaire
// est demandée : sans runner explicite, run_agent ne peut pas dispatcher de façon fiable.
const isUnitUpdate = !!(model || mcpServers || env || mode || cliPath);
const isFileRewrite = !!(file && content);
if (isUnitUpdate && !isFileRewrite && !runner) {
const detected = await manager.peekRunner(name); // (b) lecture du runner déjà en place
const detectedTxt = detected
? `**${detected}**`
: '**non défini** (sera initialisé à `claude`)';
return {
content: [
{
type: 'text',
text: `⚠️ **Runner non spécifié** pour l'agent '${name}'.\n\n` +
`Le paramètre \`runner\` est omis : \`update_agent_config\` ne le modifiera pas, et ` +
`la valeur existante dans \`settings_${name}.json\` restera en place.\n\n` +
`🔎 Runner actuellement détecté : ${detectedTxt}\n\n` +
`💡 **Recommandation** : passer explicitement \`runner\` à l'appel pour éviter tout ` +
`dispatch ambigu vers run_agent. Valeurs valides : ` +
`claude | gemini | kilo | qwencli | openclaw | cline | opencode | hermes.\n\n` +
`➡️ Relance avec : \`update_agent_config(name: "${name}", runner: "le_bon_runner", ...)\``,
},
],
};
}
try {
const changes = await manager.updateAgentConfig(name, {
model,
mcpServers,
env,
runner: runner,
mode: mode,
cliPath,
file,
content,
});
// (b) Validation runtime : on confirme le runner effectif après update
const effectiveRunner = await manager.peekRunner(name);
const runnerNotice = effectiveRunner
? `\n\n🏃 Runner effectif : **${effectiveRunner}**`
: `\n\n⚠️ Aucun runner détectable — un futur run_agent risque d'échouer.`;
if (changes.length === 0) {
return {
content: [
{
type: 'text',
text: `⚠️ Aucune modification demandée pour l'agent '${name}'.${runnerNotice}`,
},
],
};
}
return {
content: [
{
type: 'text',
text: `✅ Configuration de l'agent '${name}' mise à jour :\n${changes.join('\n')}${runnerNotice}`,
},
],
};
}
catch (error) {
const e = error;
if (e && typeof e === 'object' && 'code' in e && e.code === 'ENOENT') {
return {
isError: true,
content: [
{
type: 'text',
text: `❌ **Agent Introuvable**\n\nImpossible de modifier la configuration pour '${name}' car le fichier settings est introuvable.\n\n💡 **Solution:** Vérifiez le nom de l'agent avec \`list_agents\`.`,
},
],
};
}
return {
isError: true,
content: [
{
type: 'text',
text: `❌ Erreur lors de la mise à jour de '${name}': ${e instanceof Error ? e.message : String(e)}`,
},
],
};
}
}
//# sourceMappingURL=manage_agents.js.map