Architecture du protocole Agent Client
ACP standardise la relation entre une interface de codage et un agent de codage. Il leur donne une maniĂšre commune dâĂ©tablir des capacitĂ©s, dâouvrir une session de projet, dâĂ©changer des invites, de diffuser la progression en continu, de demander une autorisation, dâannuler le travail et de fermer ou reprendre la session.
Les deux rĂŽles
| RÎle | Responsabilités |
|---|---|
| Client / hĂŽte | DĂ©marre le processus de lâagent, prĂ©sente lâinterface humaine, sĂ©lectionne lâespace de travail, fournit des fichiers, des terminaux et des serveurs MCP facultatifs, applique la politique dâautorisation et affiche les mises Ă jour en direct |
| ACP agent | Accepte les sessions et les invites du projet, effectue le travail de codage, signale les messages et lâactivitĂ© des outils, demande une autorisation lorsque nĂ©cessaire et renvoie une raison dâarrĂȘt typĂ©e |
ADK-Rust peut occuper lâun ou lâautre rĂŽle. Ce sont deux directions de dĂ©ploiement, pas deux protocoles diffĂ©rents.
Lorsque ADK-Rust consomme un autre agent de codage, le cÎté gauche est ADK-Rust et le
cĂŽtĂ© droit est le processus externe. Lorsquâun Ă©diteur consomme un agent
ADK-Rust, lâĂ©diteur possĂšde le cĂŽtĂ© gauche et AcpServer possĂšde le cĂŽtĂ© droit.
Un tour de ACP
La connexion est bidirectionnelle. Un client doit continuer Ă lire pendant quâune invite sâexĂ©cute, car lâagent peut envoyer des notifications ou des demandes dâautorisation avant la rĂ©ponse finale de lâinvite.
Identité et état de la session
Une session ACP identifie une conversation en cours au sujet dâun projet. Elle
contient un cwd absolu, des répertoires supplémentaires facultatifs, plusieurs
invitations, des mises à jour diffusées en continu et un cycle de vie. Dans le
serveur ADK-Rust, une session ACP correspond Ă une session ADK-Rust afin que
lâhistorique du modĂšle et lâĂ©tat de la session restent attachĂ©s Ă la mĂȘme
conversation.
Fermer une connexion active est diffĂ©rent de supprimer lâhistorique persistant :
session/closelibĂšre la session active et ses processus ;session/resumese rattache Ă lâĂ©tat de session persistant ADK ;session/loadrĂ©active une session persistante et rejoue sa conversation stockĂ©e vers le client sous forme de notificationssession/updateordonnĂ©es avant que la requĂȘte ne se termine ;session/forkcrĂ©e une branche dâune session persistante vers un nouvel identifiant de session dont lâhistorique stockĂ© est une copie de celui de la source, en laissant la source intacte ;session/deletesupprime la session persistante ;session/listrenvoie les sessions visibles via leSessionServiceconfigurĂ©.
session/load valide le cwd fourni par rapport au répertoire de travail stocké de
la session de la mĂȘme maniĂšre que session/resume, et renvoie une erreur
de session introuvable pour un identifiant de session inconnu. La relecture mappe
chaque événement utilisateur, agent, réflexion et outil stocké vers son
variant SessionUpdate correspondant dans lâordre chronologique dâorigine, de sorte
quâun Ă©diteur qui se reconnecte restaure lâhistorique visible dans lâordre oĂč il
sâest produit.
ContrĂŽles de session interactive
Un agent peut exposer des contrĂŽles interactifs au client en fournissant un
fournisseur SessionControls. Lorsquâil le fait, le serveur les annonce dans les
réponses session/new, session/load, session/resume et session/fork :
- Modes â un ensemble de modes nommĂ©s (par exemple "ask" versus "code")
avec une sélection actuelle.
session/set_modevalide le mode demandĂ© par rapport Ă lâensemble annoncĂ©, lâenregistre et Ă©met unCurrentModeUpdate; un mode inconnu est rejetĂ© et le mode actuel reste inchangĂ©. - Options de configuration â des sĂ©lecteurs et des commutateurs que
le client peut lire et modifier.
session/set_config_optionvalide la valeur par rapport aux choix dĂ©clarĂ©s de lâoption, lâenregistre et Ă©met unConfigOptionUpdate; une option inconnue ou une valeur invalide est rejetĂ©e. - Commandes disponibles â des slash-commands ACP exposĂ©es comme un
AvailableCommandsUpdatelorsquâune session devient active.
Les sĂ©lections de mode et de configuration persistent dans lâĂ©tat de session
ADK (acp:mode, acp:config:<id>), elles survivent donc au chargement, Ă la reprise et Ă la
division. Un titre de session enregistrĂ© apparaĂźt comme un SessionInfoUpdate Ă
lâactivation et chaque fois quâil change. Une mapping de mise Ă jour Plan
existe mais reste dormante jusquâĂ ce quâune primitive de plan ADK fasse
remonter les entrĂ©es de plan. Un agent qui ne fournit aucun SessionControls nâannonce
aucun mode ni aucune option, ce qui maintient les capacités annoncées
exactement alignées sur ce que le serveur implémente.
Le contenu traverse la frontiĂšre via un seul mapping
Les invites qui arrivent dâun client et les mises Ă jour qui lui sont renvoyĂ©es
passent toutes deux par un seul module de contenu qui mappe des valeurs
ACP ContentBlock vers des valeurs adk_core::Part et inversement. Le fait de conserver un
seul mapping dans les deux sens signifie que le parseur dâinvite du serveur, le
diffuseur du serveur et le client sâaccordent tous sur la reprĂ©sentation de
chaque type de contenu.
Le mapping préserve fidÚlement les charges utiles. Les blocs de texte se
mappent vers Part::Text avec la chaßne intacte. Les blocs de ressource intégrée se
mappent vers Part::EmbeddedResource, en conservant la source URI, le type MIME facultatif
et le contenu. Une ressource textuelle circule verbatim dans les deux sens et
nâest jamais encodĂ©e en base64 ; une ressource binaire est encodĂ©e en base64 sur
le fil et décodée en octets bruts du cÎté ADK de la frontiÚre. Les blocs
dâimage et dâaudio se mappent vers Part::InlineData, en prĂ©servant le type MIME et les
octets dĂ©codĂ©s ; le serveur annonce et accepte ces mĂ©dias dâinvite, et le client
transmet le contenu non textuel ADK (ressource intégrée, image, audio) sous
forme du bloc ACP correspondant plutĂŽt que de lâabandonner.
Les mises à jour diffusées en continu transportent plus que du texte
Pendant quâune invite sâexĂ©cute, le serveur traduit les Ă©vĂ©nements ADK typĂ©s
en notifications ACP session/update. Le texte du modÚle et les réflexions
deviennent des fragments de message et de réflexion, et le contenu de
ressource intĂ©grĂ©e devient un fragment de message de ressource intĂ©grĂ©e. Au-delĂ
de cette surface, deux types de mise Ă jour donnent au client une vue plus
riche du tour :
- Mises Ă jour dâutilisation. Lorsquâun Ă©vĂ©nement ADK transporte des
mĂ©tadonnĂ©es dâutilisation, le serveur envoie un
UsageUpdatereflĂ©tant les dĂ©comptes de jetons signalĂ©s, ainsi que le coĂ»t en USD lorsque lâexĂ©cution lâindique. Les Ă©vĂ©nements sans mĂ©tadonnĂ©es dâutilisation ne produisent aucune mise Ă jour, et le serveur nâinvente jamais de dĂ©comptes. - Mises Ă jour enrichies des appels dâoutil. Un appel dâoutil commence comme
un
ToolCallavec unkinddâoutil dĂ©duit du comportement dĂ©clarĂ© de lâoutil. SonToolCallUpdateultĂ©rieur transporte le contenu du rĂ©sultat de lâoutil et les emplacements de fichiers que lâoutil indique avoir affectĂ©s, afin quâun Ă©diteur puisse afficher des diffs et des listes de fichiers affectĂ©s. La mise Ă jour conserve le mĂȘme identifiant que leToolCalldâorigine, prĂ©servant ainsi la corrĂ©lation tout au long du tour.
La direction du client a la fidĂ©litĂ© correspondante. Lorsquâune application ADK-Rust consomme un External_Agent, sa surface de diffusion en continu (OutputChunk) expose non seulement le texte et les pensĂ©es de lâagent, mais aussi le External_Agent ToolCallUpdate (sous la forme dâune mise Ă jour dâoutil corrĂ©lĂ©e Ă lâid, contenant le statut, le type, le titre, le texte du contenu et les emplacements de fichiers affectĂ©s) ainsi que son UsageUpdate (tokens utilisĂ©s et taille, plus le coĂ»t et la devise lorsquâils sont renseignĂ©s). Le texte des messages de lâagent est exposĂ© exactement comme auparavant, donc les consommateurs de texte existants ne sont pas affectĂ©s.
Les demandes dâautorisation font le pont avec les confirmations dâoutil
Un agent ADK-Rust peut suspendre un tour dans lâattente de lâapprobation humaine dâun appel dâoutil (ToolConfirmationRequest). CĂŽtĂ© serveur, cette suspension devient une demande native ACP session/request_permission dĂ©crivant lâoutil et ses arguments. Le rĂ©sultat du client reprend le tour : une approbation se mappe Ă allow, et un refus ou une annulation se mappent tous deux Ă deny, de sorte quâune demande annulĂ©e nâexĂ©cute jamais lâoutil. Chaque rĂ©sultat est corrĂ©lĂ© Ă lâappel exact par son identifiant dâappel de fonction et renvoyĂ© au runner via ses dĂ©cisions de confirmation dâoutil. La demande dâautorisation imbriquĂ©e est Ă©mise depuis la tĂąche de prompt gĂ©nĂ©rĂ©e, donc la rĂ©ponse externe session/prompt se termine toujours normalement.
Les capacités sont un contrat
Lâinitialisation nâest pas une poignĂ©e de main dĂ©corative. Chaque partie annonce uniquement les opĂ©rations et le contenu quâelle prend en charge. ADK-Rust utilise ces capacitĂ©s pour Ă©viter dâenvoyer une configuration facultative HTTP ou SSE MCP Ă un agent qui nâaccepte que stdio, et il nâannonce les opĂ©rations dâhĂŽte du systĂšme de fichiers ou du terminal que lorsque lâapplication fournit lâimplĂ©mentation correspondante.
Le serveur annonce exactement les types de contenu que son gestionnaire de prompt accepte. Il annonce les capacitĂ©s de prompt embedded_context, image et audio parce que le contenu de ressource intĂ©grĂ©e se mappe Ă adk_core::Part::EmbeddedResource et que le contenu dâimage et dâaudio se mappe Ă adk_core::Part::InlineData. Il annonce load_session parce quâil enregistre un gestionnaire session/load, et la capacitĂ© de session fork parce quâil enregistre un gestionnaire session/fork. Les modes de session et les options de configuration ne sont annoncĂ©s que lorsque lâagent fournit un fournisseur SessionControls, donc un agent qui nâen a pas nâannonce ni lâun ni lâautre. Les transports distants, les sĂ©lecteurs de modĂšle et les ajouts expĂ©rimentaux au protocole restent non annoncĂ©s. Un prompt portant un type de contenu que le serveur nâa pas annoncĂ© est rejetĂ© avec une erreur descriptive plutĂŽt que dâĂȘtre traitĂ© partiellement. Les appelants doivent concevoir en fonction de lâobjet de capacitĂ© nĂ©gociĂ© plutĂŽt que de supposer que chaque implĂ©mentation ACP a la mĂȘme surface.