Exposer un agent ADK-Rust via ACP

Utilisez l’orientation serveur lorsqu’un Ă©diteur ou un autre client ACP doit dĂ©marrer votre binaire ADK-Rust et utiliser son agent dans une interface de codage. Votre processus Rust gĂšre l’agent, le modĂšle, les outils, les flux de travail, les sessions, la mĂ©moire et la politique d’exploitation. Le client ne voit que les capacitĂ©s et le cycle de vie des sessions publiĂ©s via ACP.

Installer la fonctionnalité serveur

[dependencies]
adk-acp = { version = "2.1.0", features = ["server"] }

Construire et servir un agent

use adk_acp::server::{AcpServer, AcpServerConfigBuilder};
use adk_session::InMemorySessionService;
use std::sync::Arc;

let config = AcpServerConfigBuilder::new()
    .agent(Arc::new(repository_agent))
    .session_service(Arc::new(InMemorySessionService::new()))
    .agent_name("repository-guide")
    .agent_description("Explains and improves this Rust workspace")
    .max_sessions(16)
    .build()?;

let handle = AcpServer::run(config).await?;
handle.wait().await?;

Le serveur utilise le générateur officiel Agent de SDK et le transport stdio. Le trafic du protocole est la seule donnée écrite sur stdout ; configurez la journalisation et les diagnostics pour utiliser stderr.

Correspondance d’exĂ©cution

Rendering architecture


Le gestionnaire valide un cwd absolu, rĂ©serve la capacitĂ© de session, crĂ©e ou reprend la session ADK et exĂ©cute l’agent configurĂ©. Les Ă©vĂ©nements ADK typĂ©s sont traduits en notifications session/update ACP pendant que l’invite est active.

Cycle de vie implémenté

Opération ACPComportement ADK-Rust
initializeNĂ©gocie le protocole v1 et renvoie les mĂ©tadonnĂ©es exactes de l’implĂ©mentation et des capacitĂ©s
session/newValide les chemins de l’espace de travail et crĂ©e une session ADK persistante
session/promptConvertit les blocs de contenu pris en charge (text, resource-link, embedded-resource, image, audio) et diffuse le Runner
session/loadRéactive une session persistée (en validant cwd) et rejoue sa conversation enregistrée sous forme de notifications session/update ordonnées avant de terminer
session/cancelAnnule l’invocation active du Runner et renvoie une raison d’arrĂȘt indiquant l’annulation
$/cancel_requestAnnule la requĂȘte JSON-RPC correspondante sans corrompre la session
session/closeAnnule le travail actif et libĂšre les processus appartenant Ă  la session
session/listRépertorie les sessions persistées visibles par ACP
session/resumeSe rattache à la session et à l’espace de travail d’origine
session/forkCrĂ©e une branche d’une session persistĂ©e dans une nouvelle session, en copiant son historique et l’état pertinent, tout en laissant la source inchangĂ©e
session/set_modeValide et enregistre un mode de session dĂ©clarĂ© par le SessionControls de l’agent, en Ă©mettant un CurrentModeUpdate
session/set_config_optionValide et enregistre une valeur de configuration dĂ©clarĂ©e par le SessionControls de l’agent, en Ă©mettant un ConfigOptionUpdate
session/deleteSupprime l’historique persistant et libùre les ressources actives

Une seule invite peut s’exĂ©cuter Ă  la fois dans une session. DiffĂ©rentes sessions peuvent s’exĂ©cuter simultanĂ©ment jusqu’à max_sessions.

Mappage des événements

  • le texte du modĂšle devient agent_message_chunk ;
  • le contenu de rĂ©flexion du modĂšle devient agent_thought_chunk ;
  • le contenu de la ressource intĂ©grĂ©e devient une ressource intĂ©grĂ©e agent_message_chunk de ACP ;
  • les appels de fonction ADK deviennent des mises Ă  jour de dĂ©marrage d’outil ACP avec un outil kind dĂ©duit ;
  • les rĂ©ponses de fonction deviennent des mises Ă  jour d’achĂšvement de l’outil enrichies du contenu du rĂ©sultat et de tout emplacement de fichier affectĂ©, associĂ©es Ă  l’appel d’outil d’origine ;
  • les Ă©vĂ©nements contenant des mĂ©tadonnĂ©es d’utilisation deviennent des notifications UsageUpdate (nombre de jetons, ainsi que le coĂ»t en USD lorsqu’il est communiquĂ©) ;
  • les commandes dĂ©clarĂ©es par l’agent deviennent un AvailableCommandsUpdate lorsqu’une session devient active, et un titre de session enregistrĂ© devient un SessionInfoUpdate ;
  • les entrĂ©es du plan deviendraient une mise Ă  jour Plan — ce mappage existe, mais reste inactif jusqu’à ce qu’une primitive de plan ADK expose les entrĂ©es du plan ;
  • l’annulation devient StopReason::Cancelled ;
  • l’achĂšvement normal devient StopReason::EndTurn.

Un module de contenu partagĂ© gĂšre la correspondance ContentBlock ↔ adk_core::Part dans les deux sens. Le contenu d’invite d’une ressource intĂ©grĂ©e est converti en Part::EmbeddedResource, en prĂ©servant la source URI, le type MIME facultatif et le contenu ; les ressources textuelles sont prĂ©servĂ©es Ă  l’identique, tandis que les ressources binaires sont encodĂ©es en base64 sur le rĂ©seau, puis dĂ©codĂ©es en octets bruts en interne. Le contenu d’invite d’image et audio est converti en Part::InlineData, en prĂ©servant le type MIME, les octets dĂ©codĂ©s, les annotations et la source URI facultative d’une image. Ces champs restent dans la JSON de session et sont restaurĂ©s par session/load. Comme le gestionnaire d’invites accepte le contenu de ressources intĂ©grĂ©es, d’images et audio, le serveur annonce les capacitĂ©s d’invite embedded_context, image et audio. Une invite contenant un type de contenu que le serveur n’a pas annoncĂ© est rejetĂ©e avec une erreur explicite au lieu d’ĂȘtre traitĂ©e partiellement.

Chargement et relecture de l’historique

session/load restaure l’historique visible d’une session persistante lorsqu’un client se reconnecte. Le gestionnaire rĂ©active la session de la mĂȘme maniĂšre que session/resume — en vĂ©rifiant que l’appelant a fourni le cwd d’origine et en renvoyant une erreur indiquant que la session est introuvable pour un identifiant inconnu — puis effectue une passe de relecture. Il lit les Ă©vĂ©nements persistants via le service de session et convertit chaque Ă©vĂ©nement stockĂ© d’utilisateur, d’agent, de rĂ©flexion et d’outil en sa notification session/update correspondante, dans l’ordre chronologique d’origine, avant la fin de la requĂȘte de chargement. Le serveur annonce la capacitĂ© load_session afin qu’un client sache qu’il peut se reconnecter et reconstruire la vue de la conversation.

Modes de session, options de configuration et bifurcation

Un agent active les contrĂŽles de session interactive en fournissant un fournisseur SessionControls via AcpServerConfigBuilder::session_controls. Le fournisseur dĂ©clare les modes disponibles (un SessionModeState), les options de configuration (sĂ©lections et boutons bascule), ainsi que les commandes slash ACP. Le serveur annonce exactement ce que le fournisseur dĂ©clare — un agent sans fournisseur n’annonce aucun mode ni aucune option — et les expose dans les rĂ©ponses session/new, session/load, session/resume et session/fork.

session/set_mode valide l’identifiant du mode demandĂ© par rapport Ă  l’ensemble annoncĂ©, l’enregistre et Ă©met un CurrentModeUpdate ; un identifiant inconnu est rejetĂ© et le mode actuel reste inchangĂ©. session/set_config_option valide la valeur par rapport aux choix dĂ©clarĂ©s pour l’option, l’enregistre et Ă©met un ConfigOptionUpdate ; une option inconnue ou une valeur non valide est rejetĂ©e. Les deux sĂ©lections sont conservĂ©es dans l’état de session ADK sous acp:mode et acp:config:<id>, et persistent donc lors du chargement, de la reprise et de la crĂ©ation d’une branche.

session/fork crĂ©e une branche d’une session persistante : il lit la session source, crĂ©e un nouvel identifiant de session, y copie les Ă©vĂ©nements enregistrĂ©s et l’état pertinent (cwd, les rĂ©pertoires supplĂ©mentaires, le mode et la configuration), puis renvoie le nouvel identifiant. L’historique persistant de la session source reste inchangĂ© octet par octet. La crĂ©ation d’une branche pour un identifiant de session inconnu renvoie une erreur indiquant que la session est introuvable. Le serveur annonce la capacitĂ© de session fork, car le gestionnaire est enregistrĂ©.

Lors de l’activation d’une session, le serveur Ă©met Ă©galement un AvailableCommandsUpdate pour toutes les commandes dĂ©clarĂ©es par le fournisseur (et aucun lorsqu’il n’en dĂ©clare aucune), ainsi qu’un SessionInfoUpdate contenant le titre de la session lorsqu’un titre est enregistrĂ© sous acp:title (dĂ©fini via set_session_title). Un mappage de mise Ă  jour Plan existe, mais reste inactif jusqu’à ce qu’une primitive de plan ADK expose des entrĂ©es de plan.

Serveurs MCP fournis par le client

Le client peut inclure des serveurs stdio MCP dans session/new ou session/resume. Le serveur valide les noms, les commandes, les arguments et les entrĂ©es d’environnement avant de dĂ©marrer un processus. Il :

  1. dĂ©marre chaque processus enfant dans l’espace de travail de la session ;
  2. applique une négociation de démarrage limitée ;
  3. encapsule la connexion en tant que ADK McpToolset ;
  4. injecte l’ensemble d’outils dans cette invocation de Runner ;
  5. annule les services MCP lors de la fermeture, de la suppression, d’un Ă©chec du dĂ©marrage ou de l’arrĂȘt du serveur.

Les ensembles d’outils associĂ©s Ă  une invocation sont actuellement rĂ©solus par LlmAgent et CodeActAgent. Les transports HTTP et SSE MCP facultatifs ne sont pas annoncĂ©s par le serveur.

Décisions de persistance

InMemorySessionService convient Ă  un processus d’éditeur local et aux tests. Utilisez un service durable lorsque les sessions doivent survivre aux redĂ©marrages du processus. La reprise valide que l’appelant fournit le cwd d’origine ; une session ne peut pas ĂȘtre rattachĂ©e silencieusement Ă  un autre projet.

Limite d’approbation des outils

Le serveur fait le lien entre les confirmations d’outils ADK et les demandes d’autorisation natives ACP. Lorsque l’agent configurĂ© se met en pause sur un ToolConfirmationRequest pendant un tour de requĂȘte — signalĂ© sur event.actions.tool_confirmation lorsqu’un agent attend l’approbation humaine d’un appel d’outil — le serveur envoie une requĂȘte session/request_permission dĂ©crivant l’outil et ses arguments, attend le rĂ©sultat du client, puis reprend l’exĂ©cution avec la dĂ©cision correspondante. Une approbation est mappĂ©e vers l’autorisation, et un refus ou une annulation sont tous deux mappĂ©s vers le refus, de sorte qu’une requĂȘte annulĂ©e n’exĂ©cute jamais l’outil. Chaque rĂ©sultat est associĂ© Ă  l’appel exact au moyen de son identifiant d’appel de fonction et renvoyĂ© au Runner via RunConfig::tool_confirmation_decisions.

Le session/request_permission imbriquĂ© est Ă©mis depuis la tĂąche qui gĂšre dĂ©jĂ  le session/prompt externe, gĂ©nĂ©rĂ© via ConnectionTo::spawn ; il ne bloque donc pas la boucle de distribution de la connexion, et la rĂ©ponse Ă  l’invite externe s’achĂšve tout de mĂȘme. Une inquiĂ©tude prĂ©cĂ©dente selon laquelle le SDK Rust officiel perdrait la rĂ©ponse Ă  l’invite externe aprĂšs une requĂȘte bidirectionnelle imbriquĂ©e ne se reproduit pas avec ce flux de suspension/reprise ; ce cas est couvert par les tests d’interopĂ©rabilitĂ© en mĂ©moire.

L’autorisation des outils gĂ©rĂ©e par le serveur, les outils en lecture seule, RBAC, les garde-fous et les interruptions de workflow restent disponibles lorsque l’approbation doit avoir lieu entiĂšrement au sein du processus ADK-Rust. Le chemin d’autorisation cĂŽtĂ© client pour les agents ACP externes est Ă©galement entiĂšrement implĂ©mentĂ©.

Déployer en toute sécurité

  • DĂ©marrez le binaire avec l’espace de travail du projet prĂ©vu.
  • ConsidĂ©rez cwd et les racines supplĂ©mentaires comme un contexte, et non comme un mĂ©canisme d’isolation du systĂšme d’exploitation.
  • Appliquez adk-sandbox, un conteneur ou une autre limite de processus pour les invites et commandes non fiables.
  • Conservez les identifiants du modĂšle et de MCP dans un magasin de secrets client ou dans l’environnement du processus.
  • N’écrivez jamais de banniĂšres, d’objets de dĂ©bogage ou de journaux sur la sortie standard du protocole.
  • Utilisez un SessionService durable lorsque la reprise doit survivre au redĂ©marrage du processus.
  • DĂ©finissez une limite de session finie et fermez les sessions inactives.

Le crate acp_server exĂ©cutable inclut un agent basĂ© sur Gemini, des outils de lecture limitĂ©s Ă  l’espace de travail, la journalisation de suivi vers la sortie d’erreur et la configuration du processus de l’éditeur.

Ensuite

Exposer un agent ADK-Rust via ACP - Documentation ADK-Rust | ADK-Rust