Exponha um agente ADK-Rust por meio de ACP

Use a abordagem de servidor quando um editor ou outro cliente ACP precisar iniciar seu binário ADK-Rust e usar o agente em uma interface de programação. Seu processo Rust é responsável pelo agente, modelo, ferramentas, fluxos de trabalho, sessões, memória e política operacional. O cliente vê apenas os recursos e o ciclo de vida da sessão publicados por meio de ACP.

Instale o recurso do servidor

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

Compile e disponibilize um 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?;

O servidor usa o construtor oficial SDK Agent e o transporte stdio. O tráfego do protocolo é o único dado escrito em stdout; configure o rastreamento e os diagnósticos para usar stderr.

Mapeamento em tempo de execução

Rendering architecture…

O manipulador valida um cwd absoluto, reserva capacidade para a sessão, cria ou retoma a sessão ADK e executa o agente configurado. Os eventos ADK tipados são traduzidos em notificações ACP session/update enquanto o prompt está ativo.

Ciclo de vida implementado

ACP operaçãoADK-Rust comportamento
initializeNegocia o protocolo v1 e retorna metadados exatos de implementação e capacidades
session/newValida os caminhos do espaço de trabalho e cria uma sessão ADK persistida
session/promptConverte blocos de conteúdo compatíveis (text, resource-link, embedded-resource, image, audio) e transmite o Runner
session/loadReativa uma sessão persistida (validando cwd) e reproduz sua conversa armazenada como notificações session/update ordenadas antes de concluir
session/cancelCancela a invocação ativa do Runner e retorna um motivo de parada cancelado
$/cancel_requestCancela a solicitação JSON-RPC correspondente sem corromper a sessão
session/closeCancela o trabalho ativo e libera os processos pertencentes à sessão
session/listLista as sessões persistidas visíveis para ACP
session/resumeReconecta à sessão e ao espaço de trabalho originais
session/forkCria uma ramificação de uma sessão persistida em um novo id de sessão, copiando seu histórico e o estado relevante, e mantendo a origem inalterada
session/set_modeValida e registra um modo de sessão declarado pelo SessionControls do agente, emitindo um CurrentModeUpdate
session/set_config_optionValida e registra um valor de configuração declarado pelo SessionControls do agente, emitindo um ConfigOptionUpdate
session/deleteRemove o histórico persistido e libera os recursos ativos

Somente um prompt pode ser executado em uma sessão por vez. Sessões diferentes podem ser executadas simultaneamente, até max_sessions.

Mapeamento de eventos

  • o texto do modelo se torna agent_message_chunk;
  • o conteúdo do pensamento do modelo se torna agent_thought_chunk;
  • o conteúdo do recurso incorporado se torna um recurso incorporado ACP agent_message_chunk;
  • chamadas de função ADK se tornam atualizações de início de ferramenta ACP com uma kind de ferramenta inferida;
  • as respostas de função se tornam atualizações de conclusão de ferramenta, enriquecidas com o conteúdo do resultado e quaisquer localizações de arquivo afetadas, associadas à chamada de ferramenta de origem;
  • eventos que transportam metadados de uso se tornam notificações UsageUpdate (contagens de tokens, além do custo em USD quando informado);
  • comandos declarados pelo agente se tornam um AvailableCommandsUpdate quando uma sessão se torna ativa, e um título de sessão registrado se torna um SessionInfoUpdate;
  • as entradas do plano se tornariam uma atualização Plan — esse mapeamento existe, mas permanece inativo até que uma primitiva de plano ADK exponha as entradas do plano;
  • o cancelamento se torna StopReason::Cancelled;
  • a conclusão normal se torna StopReason::EndTurn.

Um módulo de conteúdo compartilhado gerencia o mapeamento ContentBlockadk_core::Part em ambas as direções. O conteúdo de prompt de recursos incorporados é mapeado para Part::EmbeddedResource, preservando o URI de origem, o tipo MIME opcional e o conteúdo; os recursos de texto são preservados literalmente, enquanto os recursos binários são codificados em base64 durante a transmissão e decodificados internamente para bytes brutos. O conteúdo de prompt de imagem e áudio é mapeado para Part::InlineData, preservando o tipo MIME, os bytes decodificados, as anotações e o URI opcional de uma imagem. Esses campos permanecem na JSON da sessão e são restaurados por session/load. Como o manipulador de prompt aceita conteúdo incorporado, de imagem e de áudio, o servidor anuncia as capacidades de prompt embedded_context, image e audio. Um prompt que contenha um tipo de conteúdo que o servidor não anunciou é rejeitado com um erro descritivo, em vez de ser tratado parcialmente.

Carregamento e reprodução do histórico

session/load restaura o histórico visível de uma sessão persistida quando um cliente se reconecta. O manipulador reativa a sessão da mesma forma que session/resume faz — validando que o chamador forneceu o cwd original e retornando um erro de sessão não encontrada para um identificador desconhecido — e então executa uma passagem de reprodução. Ele lê os eventos persistidos por meio do serviço de sessão e mapeia cada evento armazenado de usuário, agente, pensamento e ferramenta para sua notificação session/update correspondente, na ordem cronológica original, antes que a solicitação de carregamento seja concluída. O servidor anuncia a capacidade load_session para que um cliente saiba que pode se reconectar e reconstruir a visualização da conversa.

Modos de sessão, opções de configuração e bifurcação

Um agente opta por controles de sessão interativos fornecendo um SessionControls por meio de AcpServerConfigBuilder::session_controls. O provedor declara os modos disponíveis (um SessionModeState), opções de configuração (seleções e alternâncias) e comandos de barra ACP. O servidor anuncia exatamente o que o provedor declara — um agente sem provedor não anuncia modos nem opções — e os disponibiliza nas respostas session/new, session/load, session/resume e session/fork.

session/set_mode valida o id do modo solicitado em relação ao conjunto anunciado, registra-o e emite um CurrentModeUpdate; um id desconhecido é rejeitado e o modo atual permanece inalterado. session/set_config_option valida o valor em relação às escolhas declaradas pela opção, registra-o e emite um ConfigOptionUpdate; uma opção desconhecida ou um valor inválido é rejeitado. Ambas as seleções persistem no estado da sessão ADK sob acp:mode e acp:config:<id>, portanto sobrevivem ao carregamento, à retomada e à bifurcação.

session/fork ramifica uma sessão persistida: lê a sessão de origem, cria um novo id de sessão, copia os eventos armazenados e o estado relevante (cwd, diretórios adicionais, modo e configuração) para ela e retorna o novo id. O histórico persistido da sessão de origem permanece inalterado byte a byte. Uma bifurcação para um identificador de sessão desconhecido retorna um erro de sessão não encontrada. O servidor anuncia o recurso de sessão fork porque o manipulador está registrado.

Na ativação da sessão, o servidor também emite um AvailableCommandsUpdate para quaisquer comandos declarados pelo provedor (e nenhum quando ele não declara nenhum) e um SessionInfoUpdate contendo o título da sessão quando houver um registrado sob acp:title (definido por meio de set_session_title). Existe um mapeamento de atualização Plan, mas ele permanece inativo até que um primitivo de plano ADK disponibilize entradas do plano.

Servidores MCP fornecidos pelo cliente

O cliente pode incluir servidores stdio MCP em session/new ou session/resume. O servidor valida nomes, comandos, argumentos e entradas de ambiente antes de iniciar um processo. Em seguida, ele:

  1. inicia cada filho no espaço de trabalho da sessão;
  2. aplica um handshake de inicialização com limite de tempo;
  3. encapsula a conexão como um ADK McpToolset;
  4. injeta o conjunto de ferramentas nessa invocação do Runner;
  5. cancela os serviços MCP ao fechar, excluir, falhar na inicialização ou desligar o servidor.

Os conjuntos de ferramentas com escopo de invocação são atualmente resolvidos por LlmAgent e CodeActAgent. Os transportes HTTP e SSE MCP opcionais não são anunciados pelo servidor.

Decisões de persistência

InMemorySessionService é adequado para um processo de editor local e para testes. Use um serviço durável quando as sessões precisarem sobreviver a reinicializações do processo. A retomada valida se o chamador fornece o cwd original; uma sessão não pode ser reconectada silenciosamente a um projeto diferente.

Limite de aprovação de ferramentas

O servidor conecta as confirmações de ferramentas ADK às solicitações de permissão nativas ACP. Quando o agente configurado pausa em um ToolConfirmationRequest durante uma etapa de prompt — exposto em event.actions.tool_confirmation quando um agente aguarda a aprovação humana de uma chamada de ferramenta — o servidor envia uma solicitação session/request_permission descrevendo a ferramenta e seus argumentos, aguarda o resultado do cliente e retoma a execução com a decisão mapeada. Uma aprovação é mapeada para permitir, e uma recusa ou cancelamento é mapeado para negar; assim, uma solicitação cancelada nunca executa a ferramenta. Cada resultado é associado à chamada exata pelo seu identificador de chamada de função e enviado de volta ao runner por meio de RunConfig::tool_confirmation_decisions.

O session/request_permission aninhado é emitido pela tarefa que já gerencia o session/prompt externo, gerado por meio de ConnectionTo::spawn, portanto não bloqueia o loop de despacho da conexão e a resposta ao prompt externo ainda é concluída. Uma preocupação anterior de que o SDK oficial do Rust perdesse a resposta ao prompt externo após uma solicitação bidirecional aninhada não se reproduz com esse fluxo de pausa/retomada; isso é coberto pelos testes de interoperabilidade em memória.

A autorização de ferramentas gerenciada pelo servidor, as ferramentas somente leitura, RBAC, as proteções e as interrupções de fluxo de trabalho continuam disponíveis quando a aprovação precisa ocorrer inteiramente dentro do processo ADK-Rust. O caminho de permissões no cliente para agentes ACP externos também está totalmente implementado.

Implante com segurança

  • Inicie o binário com o espaço de trabalho do projeto pretendido.
  • Trate cwd e as raízes adicionais como contexto, não como isolamento do sistema operacional.
  • Aplique adk-sandbox, um contêiner ou outro limite de processo para prompts e comandos não confiáveis.
  • Mantenha as credenciais do modelo e de MCP em um armazenamento de segredos do cliente ou no ambiente do processo.
  • Nunca escreva banners, objetos de depuração ou logs na saída padrão do protocolo.
  • Use um SessionService durável quando a retomada precisar sobreviver à reinicialização do processo.
  • Defina um limite finito para as sessões e feche as sessões inativas.

O crate executável acp_server inclui um agente baseado em Gemini, ferramentas de leitura limitadas ao espaço de trabalho, rastreamento em stderr e configuração do processo do editor.

Próximos passos