Créer un client ou un hÎte ACP
Utilisez le mode client lorsquâune application ADK-Rust doit dĂ©lĂ©guer du travail de programmation Ă un processus ACP externe. Lâapplication reste lâhĂŽte : elle gĂšre la sĂ©lection du projet, lâexpĂ©rience utilisateur, les rĂšgles dâapprobation et tous les services locaux proposĂ©s Ă lâagent de programmation.
Installation
[dependencies]
adk-acp = "2.1.0"
Lâensemble de fonctionnalitĂ©s par dĂ©faut correspond Ă lâimplĂ©mentation client. La
fonctionnalitĂ© server est nĂ©cessaire uniquement lors de lâexposition dâun agent
ADK-Rust.
Choisir la forme du client
| Forme du produit | API |
|---|---|
| Une tùche isolée avec un nouveau processus | prompt_agent_with_policy |
| Une tùche isolée avec du contenu non textuel (image, audio, ressource) | prompt_agent_content_with_policy |
| Un spécialiste du codage disponible pour un agent LLM | AcpAgentTool |
| Plusieurs spécialistes du codage nommés | AcpToolset |
| Une conversation de projet continue | AcpSession |
| Progression du texte et des outils affichĂ©e pendant lâexĂ©cution du tour | stream_prompt |
Invite en une seule requĂȘte
use adk_acp::{
AcpAgentConfig, PermissionPolicy, prompt_agent_with_policy,
};
use std::sync::Arc;
let config = AcpAgentConfig::new("my-coding-agent --acp")
.working_dir("/absolute/path/to/project");
let answer = prompt_agent_with_policy(
&config,
"Inspect the failing test and explain the cause.",
Arc::new(PermissionPolicy::DenyAll),
).await?;
DenyAll est la valeur par dĂ©faut, car un agent de programmation lancĂ© peut demander des opĂ©rations ayant de vĂ©ritables effets secondaires. Utilisez AutoApprove uniquement dans le cadre dâun flux de travail local de confiance.
Envoyer un contenu de requĂȘte enrichi
prompt_agent_content_with_policy transmet une valeur adk_core::Content complĂšte â
et pas seulement une chaĂźne â afin quâune requĂȘte puisse transporter du contenu non textuel. Les parties intĂ©grĂ©es de ressource, dâimage et dâaudio sont mappĂ©es vers le bloc de contenu ACP correspondant par lâintermĂ©diaire du module de contenu partagĂ©, au lieu dâĂȘtre supprimĂ©es ; le texte est toujours conservĂ©. Les parties qui ne possĂšdent aucune reprĂ©sentation ACP transmissible sont ignorĂ©es, et une requĂȘte qui ne correspond Ă aucun bloc est rejetĂ©e.
use adk_acp::{AcpAgentConfig, PermissionPolicy};
use adk_acp::connection::prompt_agent_content_with_policy;
use adk_core::{Content, Part};
use std::sync::Arc;
let mut content = Content::new("user");
content.parts.push(Part::Text { text: "What is in this image?".into() });
content.parts.push(Part::InlineData { mime_type: "image/png".into(), data: png_bytes });
let config = AcpAgentConfig::new("my-coding-agent --acp")
.working_dir("/absolute/path/to/project");
let answer = prompt_agent_content_with_policy(
&config,
&content,
Arc::new(PermissionPolicy::DenyAll),
).await?;
Déléguer depuis un agent ADK
use adk_acp::{AcpAgentTool, PermissionDecision, PermissionPolicy};
use adk_agent::LlmAgentBuilder;
use std::sync::Arc;
let policy = PermissionPolicy::Custom(Box::new(|request| {
if request.title.to_ascii_lowercase().contains("delete") {
PermissionDecision::deny()
} else {
PermissionDecision::allow_once()
}
}));
let coding_agent = AcpAgentTool::new("my-coding-agent --acp")
.name("repository_specialist")
.description("Inspect and improve the current Rust repository")
.working_dir("/absolute/path/to/project")
.permission_policy(policy);
let coordinator = LlmAgentBuilder::new("coordinator")
.model(model)
.instruction("Delegate repository changes to repository_specialist.")
.tool(Arc::new(coding_agent))
.build()?;
Chaque appel Ă AcpAgentTool dĂ©marre un nouveau processus et une nouvelle session. Choisissez cette structure lorsque la tĂąche dĂ©lĂ©guĂ©e est autonome et que le coordinateur nâa besoin que du texte final comme rĂ©sultat de son outil.
Sessions persistantes et annulation
use adk_acp::{AcpAgentConfig, AcpSession, PermissionPolicy};
use std::sync::Arc;
let config = AcpAgentConfig::new("my-coding-agent --acp")
.working_dir("/absolute/path/to/project");
let mut session = AcpSession::start(
config,
Arc::new(PermissionPolicy::DenyAll),
).await?;
let first = session.prompt("Map the error-handling modules.").await?;
let second = session.prompt("Now inspect the most central one.").await?;
let cancel = session.cancellation_handle()?;
// Move `cancel` into a stop-button, timeout, or shutdown task while another
// task awaits `session.prompt(...)`.
session.close().await?;
Le handle dâannulation envoie la notification officielle session/cancel. La requĂȘte doit rester en attente jusquâĂ lâarrivĂ©e de la raison dâarrĂȘt indiquant lâannulation ; cela permet Ă la mĂȘme session dâaccepter une autre requĂȘte sans rĂ©ponse obsolĂšte dans sa file dâattente.
Diffuser un tour dans une interface utilisateur
stream_prompt produit des valeurs OutputChunk pour le texte de lâagent, ses rĂ©flexions, les dĂ©marrages dâoutils, les dĂ©cisions dâautorisation, lâachĂšvement et les erreurs. En plus de ces Ă©lĂ©ments, il expose deux vues plus riches du tour dâun External_Agent :
OutputChunk::ToolUpdateâ leToolCallUpdatede External_Agent, corrĂ©lĂ© pariddâappel dâoutil, contenant lâĂ©tat signalĂ©, le type, le titre mis Ă jour, le texte de contenu extrait et les emplacements de fichiers concernĂ©s. Cela permet Ă une interface dâafficher la progression de lâoutil, les diffĂ©rences et les listes de fichiers concernĂ©s, plutĂŽt que seulement le texte final.OutputChunk::Usageâ leUsageUpdatede External_Agent, contenant les jetonsusedet lasizede la fenĂȘtre de contexte, ainsi que lescostetcurrencycumulĂ©s lorsque lâagent les signale, afin quâune interface puisse afficher la consommation de la fenĂȘtre de contexte.
Le texte des messages de lâagent est exposĂ© exactement comme auparavant ; ainsi, une interface qui ne lit que les
fragments de texte nâest pas affectĂ©e. Lâapplication peut masquer les fragments de rĂ©flexion, afficher sĂ©parĂ©ment
lâactivitĂ© des outils et exposer le StatusTracker partagĂ© dans son interface.
Consultez le crate exécutable acp_client_host pour
la boucle complĂšte.
Laisser lâagent demander des fichiers
Implémentez AcpFileSystem et associez-le avec AcpAgentConfig::filesystem. Les capacités de lecture
et dâĂ©criture sont annoncĂ©es indĂ©pendamment par supports_read
et supports_write.
Le callback reçoit des chemins absolus. Un hÎte de production doit :
- canonicaliser lâespace de travail approuvĂ© et le chemin demandĂ© ;
- rejeter les chemins situés en dehors des racines approuvées, y compris les échappements via des liens symboliques ;
- dĂ©terminer si les tampons dâĂ©diteur non enregistrĂ©s remplacent le contenu du disque ;
- appliquer des limites de taille de fichier et de plage de lignes ;
- nâannoncer les Ă©critures que lorsque lâapplication les implĂ©mente et les autorise.
Le rĂ©pertoire de travail fournit un contexte, ce nâest pas une sandbox. La validation du systĂšme de fichiers et une frontiĂšre de processus du systĂšme dâexploitation rĂ©solvent des problĂšmes diffĂ©rents.
Laisser lâagent exĂ©cuter des commandes
Implémentez AcpTerminal et associez-le avec AcpAgentConfig::terminal. ACP
annonce le terminal comme une seule capacitĂ© ; lâhĂŽte doit donc implĂ©menter lâintĂ©gralitĂ© du cycle de vie :
crĂ©ation, sortie, attente, arrĂȘt et libĂ©ration.
LâhĂŽte choisit les listes dâautorisation des commandes, les rĂšgles de rĂ©pertoire de travail, les variables dâenvironnement, les limites de sortie, lâisolation des processus et le comportement de nettoyage. Les rappels du terminal sâexĂ©cutent en dehors de la boucle de distribution JSON-RPC afin quâune longue attente ne bloque pas le trafic dâautorisation ou dâannulation.
Fournir un serveur MCP Ă la session
use adk_acp::AcpAgentConfig;
use adk_acp::agent_client_protocol::schema::v1::{
McpServer, McpServerStdio,
};
let tools = McpServer::Stdio(
McpServerStdio::new("project-tools", "/absolute/path/to/mcp-server")
.args(vec!["--read-only".into()]),
);
let config = AcpAgentConfig::new("my-coding-agent --acp")
.working_dir("/absolute/path/to/project")
.mcp_server(tools);
La version stable ACP v1 exige que les agents acceptent la configuration stdio MCP. Les entrĂ©es HTTP et SSE ne sont envoyĂ©es que lorsque lâagent externe annonce la prise en charge de ces transports facultatifs. La sortie de dĂ©bogage AcpAgentConfig rĂ©pertorie les noms et les clĂ©s dâenvironnement sans afficher les valeurs secrĂštes.
Politiques dâautorisation
Chaque demande dâautorisation inclut lâID de session, lâID exact de lâappel dâoutil, le type dâoutil, lâentrĂ©e brute et toutes les options proposĂ©es par lâagent. Les ID dâoptions sont opaques. ADK-Rust applique la sĂ©mantique dâautorisation et de rejet, puis renvoie lâID dâorigine ; une sĂ©lection fabriquĂ©e devient une annulation.
PermissionPolicy::async_custom peut attendre une boĂźte de dialogue sur le bureau, une interface dâapprobation web ou un service de politiques de lâorganisation. Maintenez la boucle de distribution rĂ©active en attendant lâinteraction humaine via ce API au lieu de bloquer un thread.