ACP (Agent Client Protocol) (Français)
Qu’est-ce qu’ACP ?
Section intitulée « Qu’est-ce qu’ACP ? »ACP (Agent Client Protocol) est un transport « CLI comme backend » pour OmniRoute. Au lieu d’intercepter les appels aux API HTTP des fournisseurs d’IA, ACP lance des agents CLI en tant que processus enfants et leur transmet les prompts via leur interface native.
Pourquoi utiliser ACP ?
Section intitulée « Pourquoi utiliser ACP ? »| Avantage | Description |
|---|---|
| Aucune clé API requise | Utilise l’authentification existante de votre CLI |
| Protocole natif | Utilise le format d’entrée/sortie natif de chaque CLI |
| Détection automatique | Détecte les CLI installées sur votre système |
| 15 agents intégrés | Préconfiguré pour les outils CLI populaires |
| Agents personnalisés | Ajoutez vos propres outils CLI via les paramètres |
| Gestion des processus | Gère le cycle de vie (lancement, envoi, arrêt) |
Agents CLI pris en charge
Section intitulée « Agents CLI pris en charge »ACP prend en charge 15 agents CLI intégrés prêts à l’emploi :
| ID de l’agent | Nom d’affichage | Binaire | Protocole |
|---|---|---|---|
codex |
OpenAI Codex CLI | codex |
stdio |
claude |
Claude Code CLI | claude |
stdio |
goose |
Goose CLI | goose |
stdio |
openclaw |
OpenClaw | openclaw |
stdio |
aider |
Aider | aider |
stdio |
opencode |
OpenCode | opencode |
stdio |
cline |
Cline | cline |
stdio |
qwen |
Qwen Code | qwen --acp |
stdio |
forge |
ForgeCode | forge |
stdio |
amazon-q |
Amazon Q Developer | q |
stdio |
interpreter |
Open Interpreter | interpreter |
stdio |
cursor-cli |
Cursor CLI | cursor |
stdio |
warp |
Warp AI | warp |
stdio |
gemini |
Gemini CLI | gemini |
stdio |
zcode |
ZCode | zcode |
stdio |
Agents personnalisés
Section intitulée « Agents personnalisés »Vous pouvez ajouter vos propres agents CLI via les paramètres. Les agents personnalisés prennent en charge les mêmes fonctionnalités que les agents intégrés.
Démarrage rapide
Section intitulée « Démarrage rapide »Étape 1 : Installer un agent CLI
Section intitulée « Étape 1 : Installer un agent CLI »# Exemple : installer Claude Code CLInpm install -g @anthropic-ai/claude-code
# Vérifier l’installationclaude --versionÉtape 2 : Détection automatique par ACP
Section intitulée « Étape 2 : Détection automatique par ACP »ACP détecte automatiquement les agents CLI installés sur votre système. Aucune configuration n’est nécessaire !
Étape 3 : Utiliser le transport ACP
Section intitulée « Étape 3 : Utiliser le transport ACP »Une fois détecté, ACP peut être utilisé comme transport pour tout fournisseur pris en charge. OmniRoute utilisera automatiquement ACP lorsque la CLI sera disponible.
Fonctionnement d’ACP
Section intitulée « Fonctionnement d’ACP »Architecture
Section intitulée « Architecture »┌─────────────────┐│ OmniRoute ││ (Proxy HTTP) │└────────┬────────┘ │ │ spawn() ▼┌─────────────────┐│ Processus enfant││ (Agent CLI) ││ ││ stdin ◄──────┤ Envoyer le prompt│ stdout ──────►│ Recevoir la réponse│ stderr ──────►│ Recevoir les erreurs└─────────────────┘Cycle de vie du processus
Section intitulée « Cycle de vie du processus »- Lancement — ACP crée un processus enfant pour l’agent CLI
- Envoi — ACP écrit les prompts dans le flux stdin du processus
- Réception — ACP lit les réponses depuis stdout/stderr
- Détection de l’inactivité — ACP attend 2 secondes d’inactivité avant de considérer la réponse comme terminée
- Arrêt — ACP met fin au processus (SIGTERM, puis SIGKILL après 5 s)
Protocole de communication
Section intitulée « Protocole de communication »ACP utilise stdio (entrée/sortie standard) pour communiquer avec les agents CLI. Le protocole est le suivant :
- Envoyer le prompt — Écrire dans stdin avec un saut de ligne
- Attendre la réponse — Lire depuis stdout jusqu’à détection d’une période d’inactivité (aucune sortie pendant 2 s)
- Délai d’expiration — 120 secondes par défaut (configurable)
Référence de l’API
Section intitulée « Référence de l’API »Fonctions du registre
Section intitulée « Fonctions du registre »detectInstalledAgents()
Section intitulée « detectInstalledAgents() »Détecte tous les agents CLI installés sur le système. Les résultats sont mis en cache pendant 60 secondes.
import { detectInstalledAgents } from "@/lib/acp";
const agents = detectInstalledAgents();// Renvoie : CliAgentInfo[]
interface CliAgentInfo { id: string; // p. ex. « codex », « claude » name: string; // Nom d’affichage binary: string; // Nom du binaire à lancer versionCommand: string; // Commande de détection de la version version: string | null; // Version détectée (null si non installé) installed: boolean; // Indique si l’agent est installé providerAlias: string; // ID du fournisseur dans OmniRoute spawnArgs: string[]; // Arguments à transmettre lors du lancement protocol: "stdio" | "http"; // Protocole de communication isCustom?: boolean; // Indique s’il s’agit d’un agent personnalisé défini par l’utilisateur}getAvailableAgents()
Section intitulée « getAvailableAgents() »Obtient uniquement les agents installés et disponibles pour ACP.
import { getAvailableAgents } from "@/lib/acp";
const available = getAvailableAgents();// Renvoie : CliAgentInfo[] (uniquement les agents installés)getAgentById(id)
Section intitulée « getAgentById(id) »Obtient un agent spécifique à partir de son ID.
import { getAgentById } from "@/lib/acp";
const agent = getAgentById("claude");// Renvoie : CliAgentInfo | undefinedsetCustomAgents(agents)
Section intitulée « setCustomAgents(agents) »Définit les agents personnalisés à partir des paramètres.
import { setCustomAgents } from "@/lib/acp";
setCustomAgents([ { id: "my-custom-cli", name: "My Custom CLI", binary: "mycli", versionCommand: "mycli --version", providerAlias: "my-provider", spawnArgs: [], protocol: "stdio", },]);Fonctions du gestionnaire
Section intitulée « Fonctions du gestionnaire »acpManager.spawn(agentId, binary, args, env)
Section intitulée « acpManager.spawn(agentId, binary, args, env) »Lance un nouveau processus d’agent CLI.
import { acpManager } from "@/lib/acp";
const session = acpManager.spawn("claude", "claude", ["--print", "--output-format", "json"], { /* variables d’environnement personnalisées */});// Renvoie : AcpSessionID d’agents autorisés : ["claude", "codex", "gemini", "qwen"]
acpManager.sendPrompt(sessionId, prompt, timeoutMs)
Section intitulée « acpManager.sendPrompt(sessionId, prompt, timeoutMs) »Envoie une invite à un agent CLI et collecte la réponse.
import { acpManager } from "@/lib/acp";
const response = await acpManager.sendPrompt( "acp-claude-1234567890-abc123", "What is 2+2?", 120000 // délai d’expiration de 2 minutes);// Renvoie : Promise<string>acpManager.kill(sessionId)
Section intitulée « acpManager.kill(sessionId) »Arrête une session et effectue le nettoyage.
import { acpManager } from "@/lib/acp";
const killed = acpManager.kill("acp-claude-1234567890-abc123");// Renvoie : booleanacpManager.getActiveSessions()
Section intitulée « acpManager.getActiveSessions() »Obtient toutes les sessions actives.
import { acpManager } from "@/lib/acp";
const sessions = acpManager.getActiveSessions();// Renvoie : AcpSession[]acpManager.killAll()
Section intitulée « acpManager.killAll() »Arrête toutes les sessions.
import { acpManager } from "@/lib/acp";
acpManager.killAll();Interface de session
Section intitulée « Interface de session »interface AcpSession { id: string; // ID de session unique agentId: string; // ID de l’agent (p. ex. « claude ») process: ChildProcess; // Référence au processus enfant alive: boolean; // Indique si le processus est actif stdoutBuffer: string; // Tampon stdout accumulé stderrBuffer: string; // Tampon stderr accumulé createdAt: Date; // Horodatage de création}Événements
Section intitulée « Événements »AcpManager étend EventEmitter et émet les événements suivants :
Émis lorsque l’agent CLI écrit dans stdout.
acpManager.on("stdout", ({ sessionId, data }) => { console.log(`[${sessionId}] stdout: ${data}`);});Émis lorsque l’agent CLI écrit dans stderr.
acpManager.on("stderr", ({ sessionId, data }) => { console.error(`[${sessionId}] stderr: ${data}`);});Émis lorsque le processus de l’agent CLI se termine.
acpManager.on("exit", ({ sessionId, code, signal }) => { console.log(`[${sessionId}] exited with code ${code}, signal ${signal}`);});Émis lorsqu’une erreur survient dans le processus de l’agent CLI.
acpManager.on("error", ({ sessionId, error }) => { console.error(`[${sessionId}] error: ${error}`);});Configuration
Section intitulée « Configuration »Variables d’environnement
Section intitulée « Variables d’environnement »ACP hérite de toutes les variables d’environnement du processus parent et peut être étendu avec des variables d’environnement personnalisées :
acpManager.spawn("claude", "claude", [], { ANTHROPIC_API_KEY: "sk-...", DEBUG: "true",});Arguments de lancement
Section intitulée « Arguments de lancement »Chaque agent possède des arguments de lancement par défaut définis dans le registre. Vous pouvez les remplacer :
acpManager.spawn("claude", "claude", ["--print", "--verbose"], {});Délais d’expiration
Section intitulée « Délais d’expiration »Le délai d’expiration par défaut d’une requête est de 120 secondes (2 minutes). Vous pouvez le remplacer :
await acpManager.sendPrompt(sessionId, prompt, 300000); // 5 minutesCache de détection
Section intitulée « Cache de détection »La détection des agents est mise en cache pendant 60 secondes afin d’éviter des analyses coûteuses du système de fichiers. Pour forcer l’actualisation :
import { refreshAgentCache } from "@/lib/acp";
refreshAgentCache();Sécurité
Section intitulée « Sécurité »Prévention des injections de commandes
Section intitulée « Prévention des injections de commandes »ACP valide les commandes de version afin d’empêcher les attaques par injection de commandes :
const DISALLOWED_VERSION_COMMAND_CHARS = /[;&|<>`$\r\n]/;Les commandes de version contenant ces caractères sont rejetées :
;— Séparateur de commandes&— Processus en arrière-plan|— Tube<,>— Redirection`— Substitution de commande$— Expansion de variable\r,\n— Sauts de ligne
Validation du nom du binaire
Section intitulée « Validation du nom du binaire »ACP vérifie que le binaire de la commande de version correspond au nom de binaire attendu (sauf s’il s’agit d’un agent personnalisé).
Isolation des processus
Section intitulée « Isolation des processus »Chaque session ACP s’exécute dans son propre processus enfant. Le processus est arrêté lorsque la session se termine ou atteint son délai d’expiration.
Performances
Section intitulée « Performances »Performances de la détection
Section intitulée « Performances de la détection »- Premier appel : ~50-200ms (exécute la commande
versionpour chaque agent) - Appels mis en cache : <1ms (retour depuis le cache)
- Durée de vie du cache : 60 secondes
Performances des requêtes
Section intitulée « Performances des requêtes »- Lancement : ~50-100ms
- Envoi de la requête : ~10-50ms
- Attente de la réponse : dépend de l’agent CLI (généralement 1 à 30 secondes)
- Arrêt : ~5 secondes (SIGTERM) + immédiat (SIGKILL)
Utilisation des ressources
Section intitulée « Utilisation des ressources »- Mémoire par session : ~10-50MB (dépend de l’agent CLI)
- CPU : minimale (limitée par les E/S)
- Disque : aucune
Dépannage
Section intitulée « Dépannage »Erreur « Unknown agent »
Section intitulée « Erreur « Unknown agent » »Problème : acpManager.spawn() lève l’erreur Unknown agent: <id>
Solution : seuls les agents suivants sont autorisés dans spawn() :
claudecodexgeminiqwen
Les autres agents doivent être lancés manuellement ou à l’aide de définitions d’agents personnalisés.
Erreur « Session not alive »
Section intitulée « Erreur « Session not alive » »Problème : acpManager.sendPrompt() lève l’erreur Session ${sessionId} is not alive
Solution : la session peut s’être terminée ou avoir été arrêtée. Vérifiez son état :
const session = acpManager.getSession(sessionId);if (!session?.alive) { // Relancer la session acpManager.spawn("claude", "claude", [], {});}Erreur « ACP timeout »
Section intitulée « Erreur « ACP timeout » »Problème : acpManager.sendPrompt() lève l’erreur ACP timeout after 120000ms
Solution : augmentez le délai d’expiration :
await acpManager.sendPrompt(sessionId, prompt, 300000); // 5 minutesCLI non détectée
Section intitulée « CLI non détectée »Problème : detectInstalledAgents() ne trouve pas votre CLI
Solutions :
- Vérifiez PATH : assurez-vous que la CLI figure dans le PATH de votre système
- Vérifiez la commande de version : exécutez manuellement
claude --version - Vérifiez les autorisations : assurez-vous que la CLI est exécutable
- Agent personnalisé : ajoutez une définition d’agent personnalisé pour les CLI non standard
Permission refusée
Section intitulée « Permission refusée »Problème : ACP ne peut pas exécuter la CLI
Solutions :
- Vérifiez les autorisations du fichier :
chmod +x /usr/local/bin/claude - Vérifiez le propriétaire : assurez-vous qu’OmniRoute dispose des autorisations de lecture et d’exécution
- Vérifiez SELinux/AppArmor : ces systèmes peuvent bloquer le lancement de processus
Exemples
Section intitulée « Exemples »Exemple 1 : Lancer et utiliser Claude Code
Section intitulée « Exemple 1 : Lancer et utiliser Claude Code »import { acpManager, detectInstalledAgents } from "@/lib/acp";
// Détecter les agents installésconst agents = detectInstalledAgents();const claude = agents.find((a) => a.id === "claude");
if (claude?.installed) { // Lancer une nouvelle session const session = acpManager.spawn("claude", claude.binary, ["--print", "--output-format", "json"]);
// Envoyer une requête const response = await acpManager.sendPrompt( session.id, "Explain quantum computing in 100 words" );
console.log("Claude's response:", response);
// Nettoyer les ressources acpManager.kill(session.id);}Exemple 2 : Découverte automatique avec solution de repli
Section intitulée « Exemple 2 : Découverte automatique avec solution de repli »import { acpManager, getAvailableAgents } from "@/lib/acp";
const available = getAvailableAgents();
// Essayer d'abord Claude, puis utiliser Codex comme solution de replilet agentId = "claude";if (!available.find((a) => a.id === "claude")) { if (available.find((a) => a.id === "codex")) { agentId = "codex"; } else { throw new Error("No ACP-compatible CLI agent found"); }}
const agent = available.find((a) => a.id === agentId)!;const session = acpManager.spawn(agentId, agent.binary, agent.spawnArgs);
const response = await acpManager.sendPrompt(session.id, "Hello!");
acpManager.kill(session.id);Exemple 3 : Agent personnalisé
Section intitulée « Exemple 3 : Agent personnalisé »import { setCustomAgents, detectInstalledAgents } from "@/lib/acp";
// Enregistrer un agent CLI personnalisésetCustomAgents([ { id: "my-llm-cli", name: "My LLM CLI", binary: "myllm", versionCommand: "myllm --version", providerAlias: "my-llm-provider", spawnArgs: ["--format", "json"], protocol: "stdio", },]);
// Désormais, detectInstalledAgents() inclura "my-llm-cli"const agents = detectInstalledAgents();Et ensuite ?
Section intitulée « Et ensuite ? »- Référence de l’API — Points de terminaison de l’API REST
- Référence des fournisseurs — Les 352 fournisseurs
- Serveur MCP — Intégration du Model Context Protocol
- Serveur A2A — Protocole Agent-to-Agent
- Agent cloud — Agents basés dans le cloud
Références
Section intitulée « Références »- Projet AionUi — Source d’inspiration pour la détection automatique ACP
- Code source ACP — Détails de l’implémentation
manager.ts— Gestion du cycle de vie des processusregistry.ts— Découverte et enregistrement des agentsindex.ts— Exportations de l’API publique
HagiCode
HagiCode est un espace de développement agentique qui associe workflows structurés, exécution multi-agent et vues Hero Dungeon.
Transformez vos idées en logiciels utiles grâce à un workflow agentique plus intelligent, rapide et agréable.

- SmartDes workflows structurés transforment une intention en parcours exécutable, de l’idée à la livraison.
- EfficientLes workflows multi-agents font avancer recherche, réalisation et revue en parallèle.
- FunHero Dungeon rend les longues sessions de code plus visuelles et collaboratives.