Einen ACP-Client oder Host erstellen
Verwenden Sie die Client-Richtung, wenn eine ADK-Rust-Anwendung Programmieraufgaben an einen externen ACP-Prozess delegieren muss. Die Anwendung bleibt der Host: Sie verwaltet die Projektauswahl, die Benutzererfahrung, Genehmigungsregeln und alle lokalen Dienste, die dem Programmieragenten angeboten werden.
Installation
[dependencies]
adk-acp = "2.1.0"
Der standardmäßige Funktionsumfang ist die Client-Implementierung. Das Feature server wird
nur benötigt, wenn ein ADK-Rust-Agent bereitgestellt wird.
Die Client-Form auswählen
| Produktform | API |
|---|---|
| Eine isolierte Aufgabe mit einem neuen Prozess | prompt_agent_with_policy |
| Eine isolierte Aufgabe mit nicht-textlichen (Bild-, Audio-, Ressourcen-)Inhalten | prompt_agent_content_with_policy |
| Ein für einen LLM-Agenten verfügbarer Programmier-Spezialist | AcpAgentTool |
| Mehrere benannte Programmier-Spezialisten | AcpToolset |
| Ein fortlaufendes Projektgespräch | AcpSession |
| Während des Ablaufs der Runde gerenderter Text- und Tool-Fortschritt | stream_prompt |
Einmaliger Prompt
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 ist die Standardeinstellung, da ein gestarteter Coding-Agent Operationen
mit realen Nebenwirkungen anfordern kann. Verwenden Sie AutoApprove nur innerhalb eines
vertrauenswürdigen lokalen Workflows.
Umfangreiche Prompt-Inhalte senden
prompt_agent_content_with_policy überträgt einen vollständigen Wert vom Typ adk_core::Content —
nicht nur eine Zeichenfolge —, sodass ein Prompt Inhalte enthalten kann, die nicht aus Text
bestehen. Eingebettete Ressourcen sowie Bild- und Audioteile werden über das gemeinsame
Content-Modul dem passenden Inhaltsblock ACP zugeordnet, anstatt verworfen zu werden;
Text bleibt immer erhalten. Teile, für die keine übertragbare Darstellung von
ACP vorhanden ist, werden übersprungen, und ein Prompt, der überhaupt keinen Block
ergibt, wird abgelehnt.
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?;
Von einem ADK-Agenten delegieren
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()?;
Jeder Aufruf von AcpAgentTool startet einen neuen Prozess und eine neue Sitzung. Wählen Sie diese Form,
wenn die delegierte Aufgabe in sich abgeschlossen ist und der Koordinator nur den
abschließenden Text als Tool-Ergebnis benötigt.
Persistente Sitzungen und Abbruch
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?;
Das Abbruch-Handle sendet die offizielle session/cancel-Benachrichtigung. Der
Prompt sollte weiterhin abgewartet werden, bis der Abbruch-Grund für das Beenden eintrifft;
so kann dieselbe Sitzung einen weiteren Prompt akzeptieren, ohne dass sich eine veraltete
Antwort in ihrer Warteschlange befindet.
Einen Durchlauf in eine Benutzeroberfläche streamen
stream_prompt liefert OutputChunk-Werte für Agententext, Gedanken, Tool-Starts,
Berechtigungsentscheidungen, Abschluss und Fehler. Darüber hinaus stellt es
zwei umfangreichere Ansichten des Durchlaufs eines External_Agent bereit:
OutputChunk::ToolUpdate— die External_Agent-ToolCallUpdate, korreliert über den Tool-Aufrufid, mit dem gemeldeten Status, der Art, dem aktualisierten Titel, dem extrahierten Inhaltstext und den betroffenen Dateipfaden. Dadurch kann eine Benutzeroberfläche den Tool-Fortschritt, Diffs und Listen betroffener Dateien darstellen, anstatt nur den finalen Text.OutputChunk::Usage— die External_Agent-UsageUpdate, die die Tokenusedund das Kontextfenstersizesowie die kumulativen Wertecostundcurrencyenthält, sofern der Agent diese meldet, sodass eine Benutzeroberfläche die Nutzung des Kontextfensters anzeigen kann.
Der Nachrichtentext des Agents wird weiterhin exakt wie zuvor bereitgestellt, sodass eine Benutzeroberfläche,
die ausschließlich Textabschnitte liest, davon nicht betroffen ist. Die Anwendung kann Gedankengänge ausblenden,
Tool-Aktivitäten separat darstellen und das gemeinsame StatusTracker in ihrer Oberfläche bereitstellen.
Die vollständige Schleife finden Sie im ausführbaren Crate acp_client_host.
Den Agent Dateien anfordern lassen
Implementieren Sie AcpFileSystem und binden Sie es mit AcpAgentConfig::filesystem ein. Lese- und
Schreibfunktionen werden unabhängig voneinander über supports_read
und supports_write angekündigt.
Der Callback empfängt absolute Pfade. Ein Host für den Produktiveinsatz sollte:
- den genehmigten Arbeitsbereich und den angeforderten Pfad kanonisieren;
- Pfade außerhalb genehmigter Stammverzeichnisse ablehnen, einschließlich Umgehungen über symbolische Links;
- entscheiden, ob nicht gespeicherte Editorpuffer den Inhalt auf dem Datenträger überschreiben;
- Beschränkungen für Dateigröße und Zeilenbereiche anwenden;
- Schreibvorgänge nur dann ankündigen, wenn die Anwendung diese implementiert und autorisiert.
Das Arbeitsverzeichnis ist Kontext, keine Sandbox. Dateisystemvalidierung und eine Prozessgrenze auf Betriebssystemebene lösen unterschiedliche Probleme.
Den Agent Befehle ausführen lassen
Implementieren Sie AcpTerminal und binden Sie es mit AcpAgentConfig::terminal ein. ACP
kündigt das Terminal als eine Fähigkeit an, daher muss der Host den vollständigen
Lebenszyklus zum Erstellen, Ausgeben, Warten, Beenden und Freigeben implementieren.
Der Host legt Zulassungslisten für Befehle, Regeln für Arbeitsverzeichnisse, Umgebungsvariablen, Ausgabelimits, Prozessisolierung und das Bereinigungsverhalten fest. Terminal-Callbacks werden außerhalb der JSON-RPC-Dispatch-Schleife ausgeführt, sodass eine lange Wartezeit den Datenverkehr für Berechtigungen oder Abbruch nicht einfriert.
Einen MCP-Server für die Sitzung bereitstellen
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);
Die stabile Version 1 von ACP erfordert, dass Agents die
stdio-MCP-Konfiguration akzeptieren. HTTP- und SSE-Einträge werden nur
gesendet, wenn der externe Agent diese optionalen Transporte ankündigt.
AcpAgentConfig-Debugausgaben listen Namen und Umgebungsschlüssel auf, ohne geheime
Werte auszugeben.
Berechtigungsrichtlinien
Jede Berechtigungsanfrage enthält die Sitzungs-ID, die exakte Tool-Aufruf-ID, die Tool-Art, die unverarbeiteten Eingabedaten und alle vom Agent angebotenen Optionen. Options-IDs sind undurchsichtig. ADK-Rust gleicht Zulassungs- und Ablehnungssemantik ab und gibt anschließend die ursprüngliche ID zurück; eine fingierte Auswahl wird zum Abbruch.
PermissionPolicy::async_custom kann auf einen Desktop-Dialog, eine Web-Genehmigungsoberfläche oder
einen Organisationsrichtliniendienst warten. Halten Sie die Dispatch-Schleife
reaktionsfähig, indem Sie über dieses API auf menschliche Interaktion
warten, anstatt einen Thread zu blockieren.