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

ProduktformAPI
Eine isolierte Aufgabe mit einem neuen Prozessprompt_agent_with_policy
Eine isolierte Aufgabe mit nicht-textlichen (Bild-, Audio-, Ressourcen-)Inhaltenprompt_agent_content_with_policy
Ein für einen LLM-Agenten verfügbarer Programmier-SpezialistAcpAgentTool
Mehrere benannte Programmier-SpezialistenAcpToolset
Ein fortlaufendes ProjektgesprächAcpSession
Während des Ablaufs der Runde gerenderter Text- und Tool-Fortschrittstream_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-Aufruf id, 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 Token used und das Kontextfenster size sowie die kumulativen Werte cost und currency enthä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:

  1. den genehmigten Arbeitsbereich und den angeforderten Pfad kanonisieren;
  2. Pfade außerhalb genehmigter Stammverzeichnisse ablehnen, einschließlich Umgehungen über symbolische Links;
  3. entscheiden, ob nicht gespeicherte Editorpuffer den Inhalt auf dem Datenträger überschreiben;
  4. Beschränkungen für Dateigröße und Zeilenbereiche anwenden;
  5. 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.

Weiter