Exponer un agente ADK-Rust mediante ACP

Usa la modalidad de servidor cuando un editor u otro cliente ACP deba iniciar tu binario ADK-Rust y utilizar su agente dentro de una interfaz de programación. Tu proceso de Rust es propietario del agente, el modelo, las herramientas, los flujos de trabajo, las sesiones, la memoria y la política operativa. El cliente solo ve las capacidades y el ciclo de vida de las sesiones publicados mediante ACP.

Instalar la función del servidor

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

Compilar y servir un agente

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?;

El servidor utiliza el constructor oficial SDK Agent y el transporte stdio. El tráfico del protocolo es el único dato escrito en stdout; configura el registro y los diagnósticos para que utilicen stderr.

Mapeo en tiempo de ejecución

Rendering architecture…

El controlador valida un cwd absoluto, reserva capacidad para la sesión, crea o reanuda la sesión ADK y ejecuta el agente configurado. Los eventos tipados ADK se traducen en notificaciones session/update de ACP mientras el mensaje está activo.

Ciclo de vida implementado

operación ACPcomportamiento ADK-Rust
initializeNegocia el protocolo v1 y devuelve metadatos exactos de implementación y capacidades
session/newValida las rutas del espacio de trabajo y crea una sesión ADK persistida
session/promptConvierte los bloques de contenido compatibles (texto, enlace a recurso, recurso incrustado, imagen, audio) y transmite el Runner
session/loadReactiva una sesión persistida (validando cwd) y reproduce su conversación almacenada como notificaciones session/update ordenadas antes de completarse
session/cancelCancela la invocación activa del Runner y devuelve un motivo de detención cancelado
$/cancel_requestCancela la solicitud JSON-RPC coincidente sin corromper la sesión
session/closeCancela el trabajo activo y libera los procesos propiedad de la sesión
session/listEnumera las sesiones persistentes visibles para ACP
session/resumeSe vuelve a conectar con la sesión y el espacio de trabajo originales
session/forkRamifica una sesión persistente en un nuevo id de sesión, copiando su historial y el estado pertinente, y dejando el origen sin cambios
session/set_modeValida y registra un modo de sesión declarado por el SessionControls del agente, emitiendo un CurrentModeUpdate
session/set_config_optionValida y registra un valor de configuración declarado por el SessionControls del agente, emitiendo un ConfigOptionUpdate
session/deleteElimina el historial persistido y libera los recursos activos

Solo puede ejecutarse una solicitud a la vez en una sesión. Se pueden ejecutar sesiones diferentes de forma simultánea hasta max_sessions.

Mapeo de eventos

  • el texto del modelo se convierte en agent_message_chunk;
  • el contenido del razonamiento del modelo se convierte en agent_thought_chunk;
  • el contenido del recurso incrustado se convierte en un recurso incrustado ACP agent_message_chunk;
  • las llamadas a funciones ADK se convierten en actualizaciones de inicio de herramienta ACP con una kind de herramienta inferida;
  • las respuestas de las funciones se convierten en actualizaciones de finalización de herramienta enriquecidas con el contenido del resultado y cualquier ubicación de archivo afectada, vinculadas a la llamada de herramienta de origen;
  • los eventos que contienen metadatos de uso se convierten en notificaciones UsageUpdate (recuentos de tokens, además del coste en USD cuando se informa);
  • los comandos declarados por el agente se convierten en un AvailableCommandsUpdate cuando una sesión se activa, y el título registrado de la sesión se convierte en un SessionInfoUpdate;
  • las entradas del plan se convertirían en una actualización Plan — este mapeo existe, pero permanece inactivo hasta que una primitiva de plan ADK exponga las entradas del plan;
  • la cancelación se convierte en StopReason::Cancelled;
  • la finalización normal se convierte en StopReason::EndTurn.

Un módulo de contenido compartido gestiona la asignación ContentBlockadk_core::Part en ambas direcciones. El contenido de las indicaciones de recursos incrustados se asigna a Part::EmbeddedResource, conservando el URI de origen, el tipo MIME opcional y el contenido; los recursos de texto se conservan literalmente, mientras que los recursos binarios se codifican en base64 durante la transmisión y se decodifican internamente como bytes sin procesar. El contenido de las indicaciones de imágenes y audio se asigna a Part::InlineData, conservando el tipo MIME, los bytes decodificados, las anotaciones y el URI de origen opcional de una imagen. Estos campos permanecen en la JSON de sesión y son restaurados por session/load. Puesto que el controlador de indicaciones acepta contenido de recursos incrustados, imágenes y audio, el servidor anuncia las capacidades de indicaciones embedded_context, image y audio. Una indicación que contiene un tipo de contenido que el servidor no ha anunciado se rechaza con un error descriptivo en lugar de gestionarse parcialmente.

Carga y reproducción del historial

session/load restaura el historial visible de una sesión persistida cuando un cliente se vuelve a conectar. El controlador reactiva la sesión del mismo modo que lo hace session/resume: valida que la persona que realiza la llamada haya proporcionado el cwd original y devuelve un error de sesión no encontrada para un identificador desconocido; después, realiza una pasada de reproducción. Lee los eventos persistidos a través del servicio de sesiones y asigna cada evento almacenado de usuario, agente, pensamiento y herramienta a su notificación session/update correspondiente, en el orden cronológico original, antes de que se complete la solicitud de carga. El servidor anuncia la capacidad load_session para que un cliente sepa que puede volver a conectarse y reconstruir la vista de la conversación.

Modos de sesión, opciones de configuración y bifurcación

Un agente opta por los controles de sesión interactiva proporcionando un SessionControls mediante AcpServerConfigBuilder::session_controls. El proveedor declara los modos disponibles (un SessionModeState), las opciones de configuración (selectores y conmutadores) y los comandos slash ACP. El servidor anuncia exactamente lo que declara el proveedor —un agente sin proveedor no anuncia modos ni opciones— y los expone en las respuestas session/new, session/load, session/resume y session/fork.

session/set_mode valida el id del modo solicitado con respecto al conjunto anunciado, lo registra y emite un CurrentModeUpdate; un id desconocido se rechaza y el modo actual no cambia. session/set_config_option valida el valor con respecto a las opciones declaradas de la opción, lo registra y emite un ConfigOptionUpdate; una opción desconocida o un valor no válido se rechaza. Ambas selecciones persisten en el estado de sesión ADK bajo acp:mode y acp:config:<id>, por lo que sobreviven a la carga, la reanudación y la bifurcación.

session/fork bifurca una sesión persistida: lee la sesión de origen, crea un nuevo id de sesión, copia en ella los eventos almacenados y el estado relevante (cwd, directorios adicionales, modo y configuración) y devuelve el nuevo id. El historial persistido de la sesión de origen queda sin cambios, byte por byte. Una bifurcación para un identificador de sesión desconocido devuelve un error de sesión no encontrada. El servidor anuncia la capacidad de sesión fork porque el controlador está registrado.

Al activar una sesión, el servidor también emite un AvailableCommandsUpdate para cualquier comando que declare el proveedor (y ninguno cuando no declare ninguno), y un SessionInfoUpdate que contiene el título de la sesión cuando hay uno registrado bajo acp:title (establecido mediante set_session_title). Existe una asignación de actualización Plan, pero permanece inactiva hasta que una primitiva de plan ADK expone entradas del plan.

Servidores MCP proporcionados por el cliente

El cliente puede incluir servidores MCP stdio en session/new o session/resume. El servidor valida los nombres, comandos, argumentos y entradas de entorno antes de iniciar un proceso. Luego:

  1. inicia cada proceso secundario en el espacio de trabajo de la sesión;
  2. aplica un protocolo de enlace de inicio con límites;
  3. encapsula la conexión como un ADK McpToolset;
  4. inyecta el conjunto de herramientas en esa invocación de Runner;
  5. cancela los servicios MCP al cerrar, eliminar, producirse un fallo durante el inicio o apagar el servidor.

Actualmente, los conjuntos de herramientas con ámbito de invocación se resuelven mediante LlmAgent y CodeActAgent. Los transportes opcionales HTTP y SSE MCP no son anunciados por el servidor.

Decisiones de persistencia

InMemorySessionService es adecuado para un proceso de editor local y para pruebas. Usa un servicio duradero cuando las sesiones deban sobrevivir a los reinicios del proceso. Reanudar valida que el llamador proporcione el cwd original; una sesión no puede volver a adjuntarse silenciosamente a un proyecto diferente.

Límite de aprobación de herramientas

El servidor conecta las confirmaciones de herramientas de ADK con las solicitudes nativas de permisos de ACP. Cuando el agente configurado se pausa en un ToolConfirmationRequest durante un turno de solicitud —que se muestra en event.actions.tool_confirmation cuando un agente espera la aprobación humana de una llamada de herramienta—, el servidor envía una solicitud session/request_permission que describe la herramienta y sus argumentos, espera el resultado del cliente y reanuda la ejecución con la decisión asignada. Una aprobación se asigna a permitir, y una denegación o cancelación se asignan a denegar, por lo que una solicitud cancelada nunca ejecuta la herramienta. Cada resultado se correlaciona con la llamada exacta mediante su identificador de llamada de función y se devuelve al ejecutor mediante RunConfig::tool_confirmation_decisions.

El session/request_permission anidado se emite desde la tarea que ya gestiona el session/prompt externo, iniciado mediante ConnectionTo::spawn, por lo que no bloquea el bucle de despacho de la conexión y la respuesta de la solicitud externa sigue completándose. Una preocupación anterior de que el SDK oficial de Rust pierda la respuesta de la solicitud externa después de una solicitud bidireccional anidada no se reproduce con este flujo de pausa/reanudación; está cubierta por las pruebas de interoperabilidad en memoria.

La autorización de herramientas gestionada por el servidor, las herramientas de solo lectura, RBAC, las barreras de protección y las interrupciones del flujo de trabajo siguen disponibles cuando la aprobación debe realizarse por completo dentro del proceso ADK-Rust. La ruta de permisos del cliente para agentes ACP externos también está completamente implementada.

Desplegar de forma segura

  • Inicia el binario con el espacio de trabajo del proyecto previsto.
  • Trata cwd y las raíces adicionales como contexto, no como aislamiento del sistema operativo.
  • Aplica adk-sandbox, un contenedor u otra frontera de procesos para las solicitudes y los comandos que no sean de confianza.
  • Mantén las credenciales del modelo y de MCP en un almacén de secretos del cliente o en el entorno del proceso.
  • No escribas nunca banners, objetos de depuración ni registros en la salida estándar del protocolo.
  • Usa un SessionService duradero cuando la reanudación deba sobrevivir al reinicio del proceso.
  • Establece un límite de sesión finito y cierra las sesiones inactivas.

El crate ejecutable acp_server incluye un agente respaldado por Gemini, herramientas de lectura limitadas al espacio de trabajo, trazas en stderr y configuración del proceso del editor.

Siguiente

Exponer un agente ADK-Rust mediante ACP - Documentación ADK-Rust | ADK-Rust