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
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ção | ADK-Rust comportamento |
|---|---|
initialize | Negocia o protocolo v1 e retorna metadados exatos de implementação e capacidades |
session/new | Valida os caminhos do espaço de trabalho e cria uma sessão ADK persistida |
session/prompt | Converte blocos de conteúdo compatíveis (text, resource-link, embedded-resource, image, audio) e transmite o Runner |
session/load | Reativa uma sessão persistida (validando cwd) e reproduz sua conversa armazenada como notificações session/update ordenadas antes de concluir |
session/cancel | Cancela a invocação ativa do Runner e retorna um motivo de parada cancelado |
$/cancel_request | Cancela a solicitação JSON-RPC correspondente sem corromper a sessão |
session/close | Cancela o trabalho ativo e libera os processos pertencentes à sessão |
session/list | Lista as sessões persistidas visíveis para ACP |
session/resume | Reconecta à sessão e ao espaço de trabalho originais |
session/fork | Cria 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_mode | Valida e registra um modo de sessão declarado pelo SessionControls do agente, emitindo um CurrentModeUpdate |
session/set_config_option | Valida e registra um valor de configuração declarado pelo SessionControls do agente, emitindo um ConfigOptionUpdate |
session/delete | Remove 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
kindde 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
AvailableCommandsUpdatequando uma sessão se torna ativa, e um título de sessão registrado se torna umSessionInfoUpdate; - 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 ContentBlock ↔ adk_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:
- inicia cada filho no espaço de trabalho da sessão;
- aplica um handshake de inicialização com limite de tempo;
- encapsula a conexão como um ADK
McpToolset; - injeta o conjunto de ferramentas nessa invocação do Runner;
- 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
cwde 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
SessionServicedurá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.