ADK-Rust 에이전트를 ACP를 통해 노출

편집기 또는 다른 ACP 클라이언트가 사용자의 ADK-Rust 바이너리를 시작하고 코딩 인터페이스에서 해당 에이전트를 사용해야 할 때 서버 방향을 사용합니다. 사용자의 Rust 프로세스가 에이전트, 모델, 도구, 워크플로, 세션, 메모리 및 운영 정책을 소유합니다. 클라이언트에는 ACP을 통해 게시된 기능과 세션 수명 주기만 표시됩니다.

서버 기능 설치

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

에이전트 빌드 및 제공

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

서버는 공식 SDK Agent 빌더와 stdio 전송을 사용합니다. 프로토콜 트래픽만 stdout에 기록되며, tracing 및 진단은 stderr를 사용하도록 구성합니다.

런타임 매핑

Rendering architecture…

핸들러는 절대 cwd를 검증하고, 세션 용량을 예약하며, ADK 세션을 생성하거나 재개한 다음 구성된 에이전트를 실행합니다. 프롬프트가 활성화된 동안 형식화된 ADK 이벤트는 ACP session/update 알림으로 변환됩니다.

구현된 수명 주기

ACP 작업ADK-Rust 동작
initialize프로토콜 v1을 협상하고 정확한 구현 및 기능 메타데이터를 반환합니다
session/new작업 공간 경로의 유효성을 검사하고 하나의 영구 ADK 세션을 생성합니다
session/prompt지원되는 콘텐츠 블록(text, resource-link, embedded-resource, image, audio)을 변환하고 Runner를 스트리밍합니다
session/load영속화된 세션을 재활성화하고(cwd 검증) 완료하기 전에 저장된 대화를 순서가 지정된 session/update 알림으로 재생합니다
session/cancel활성 Runner 호출을 취소하고 취소된 중지 이유를 반환합니다
$/cancel_request세션을 손상시키지 않고 일치하는 JSON-RPC 요청을 취소합니다
session/close활성 작업을 취소하고 세션이 소유한 프로세스를 해제합니다
session/list영속화된 ACP에서 볼 수 있는 세션을 나열합니다
session/resume원래 세션과 작업 공간에 다시 연결합니다
session/fork영속화된 세션을 새 세션 ID로 분기하여 기록과 관련 상태를 복사하고 원본은 변경하지 않은 상태로 유지합니다
session/set_mode에이전트의 SessionControls에서 선언한 세션 모드를 검증하고 기록하며, CurrentModeUpdate을 생성합니다
session/set_config_option에이전트의 SessionControls에서 선언한 구성 값을 검증하고 기록하며, ConfigOptionUpdate을 생성합니다
session/delete저장된 기록을 제거하고 활성 리소스를 해제합니다

세션당 하나의 프롬프트만 실행할 수 있습니다. 서로 다른 세션은 max_sessions까지 동시에 실행할 수 있습니다.

이벤트 매핑

  • 모델 텍스트는 agent_message_chunk이 됩니다.
  • 모델 사고 콘텐츠는 agent_thought_chunk이 됩니다.
  • 포함된 리소스 콘텐츠는 ACP 포함된 리소스 agent_message_chunk이 됩니다.
  • ADK 함수 호출은 추론된 도구 kind가 포함된 ACP 도구 시작 업데이트가 됩니다.
  • 함수 응답은 결과 콘텐츠와 영향을 받은 파일 위치로 보강된 도구 완료 업데이트가 되며, 시작된 도구 호출을 기준으로 연결됩니다.
  • 사용량 메타데이터를 전달하는 이벤트는 UsageUpdate 알림이 됩니다(토큰 수와 보고된 경우 USD 기준 비용 포함).
  • 에이전트가 선언한 명령은 세션이 활성화될 때 AvailableCommandsUpdate이 되며, 기록된 세션 제목은 SessionInfoUpdate가 됩니다.
  • 계획 항목은 Plan 업데이트가 됩니다. 이 매핑은 존재하지만 ADK 계획 기본 요소가 계획 항목을 표시할 때까지 비활성 상태로 유지됩니다.
  • 취소는 StopReason::Cancelled가 됩니다.
  • 정상 완료는 StopReason::EndTurn가 됩니다.

공유 콘텐츠 모듈은 양방향으로 ContentBlockadk_core::Part 매핑을 관리합니다. 임베디드 리소스 프롬프트 콘텐츠는 Part::EmbeddedResource에 매핑되며, 원본 URI, 선택적 MIME 유형 및 콘텐츠를 보존합니다. 텍스트 리소스는 있는 그대로 보존되는 반면, 바이너리 리소스는 전송 시 base64로 인코딩되고 내부적으로 원시 바이트로 디코딩됩니다. 이미지 및 오디오 프롬프트 콘텐츠는 Part::InlineData에 매핑되며, MIME 유형, 디코딩된 바이트, 주석 및 이미지의 선택적 소스 URI를 보존합니다. 이러한 필드는 세션 JSON에 유지되며 session/load에 의해 복원됩니다. 프롬프트 핸들러는 임베디드 리소스, 이미지 및 오디오 콘텐츠를 허용하므로 서버는 embedded_context, imageaudio 프롬프트 기능을 광고합니다. 서버가 광고하지 않은 콘텐츠 유형을 포함하는 프롬프트는 부분적으로 처리되는 대신 설명적인 오류와 함께 거부됩니다.

로드 및 기록 재생

session/load는 클라이언트가 다시 연결할 때 영속화된 세션의 표시 가능한 기록을 복원합니다. 핸들러는 session/resume와 동일한 방식으로 세션을 다시 활성화합니다. 즉, 호출자가 원래 cwd을 제공했는지 검증하고, 알 수 없는 식별자에 대해서는 세션을 찾을 수 없음 오류를 반환한 다음 재생 단계를 수행합니다. 세션 서비스를 통해 영속화된 이벤트를 읽고 저장된 각 사용자, 에이전트, 사고 및 도구 이벤트를 해당 session/update 알림에 매핑하며, 로드 요청이 완료되기 전에 원래의 시간순으로 처리합니다. 서버는 load_session 기능을 광고하므로 클라이언트는 다시 연결하여 대화 보기를 재구성할 수 있습니다.

세션 모드, 구성 옵션 및 포크

에이전트는 AcpServerConfigBuilder::session_controls을 통해 SessionControls provider를 제공하여 대화형 세션 제어 기능을 선택적으로 활성화합니다. provider는 사용 가능한 모드(SessionModeState), 구성 옵션(선택 항목 및 토글), 그리고 ACP 슬래시 명령을 선언합니다. 서버는 provider가 선언한 내용을 정확히 광고합니다. 즉, provider가 없는 에이전트는 모드도 옵션도 광고하지 않으며, 이를 session/new, session/load, session/resumesession/fork 응답에 표시합니다.

session/set_mode은 요청된 모드 id가 광고된 집합에 포함되는지 검증하고, 이를 기록한 후 CurrentModeUpdate을 발생시킵니다. 알 수 없는 id는 거부되며 현재 모드는 변경되지 않습니다. session/set_config_option은 값을 옵션에 선언된 선택 항목과 비교하여 검증하고, 이를 기록한 후 ConfigOptionUpdate를 발생시킵니다. 알 수 없는 옵션이나 유효하지 않은 값은 거부됩니다. 두 선택 사항은 ADK 세션 상태의 acp:modeacp:config:<id> 아래에 저장되므로 로드, 재개 및 분기 후에도 유지됩니다.

session/fork는 저장된 세션을 분기합니다. 원본 세션을 읽고, 새 세션 id를 생성한 다음, 저장된 이벤트와 관련 상태(cwd, 추가 디렉터리, 모드 및 구성을 새 세션에 복사하고 새 id를 반환합니다. 원본 세션의 저장된 기록은 바이트 단위로 변경되지 않은 상태로 유지됩니다. 알 수 없는 세션 식별자에 대한 분기는 세션을 찾을 수 없음 오류를 반환합니다. 핸들러가 등록되어 있으므로 서버는 fork 세션 기능을 광고합니다.

세션이 활성화되면 서버는 provider가 선언한 모든 명령에 대해 AvailableCommandsUpdate도 발생시킵니다(아무것도 선언하지 않은 경우에는 발생시키지 않음). 또한 acp:title 아래에 세션 제목이 기록되어 있는 경우(set_session_title을 통해 설정됨) 해당 제목을 담은 SessionInfoUpdate을 발생시킵니다. Plan 업데이트 매핑은 존재하지만, ADK 계획 프리미티브가 계획 항목을 표시할 때까지는 비활성 상태로 유지됩니다.

클라이언트가 제공하는 MCP 서버

클라이언트는 session/new 또는 session/resume에 stdio MCP 서버를 포함할 수 있습니다. 서버는 프로세스를 시작하기 전에 이름, 명령, 인수 및 환경 항목을 검증합니다. 그런 다음:

  1. 각 자식을 세션 작업 공간에서 시작합니다.
  2. 제한된 시작 핸드셰이크를 적용합니다.
  3. 연결을 ADK McpToolset로 래핑합니다.
  4. 해당 Runner 호출에 도구 세트를 주입합니다.
  5. 종료, 삭제, 시작 실패 또는 서버 종료 시 MCP 서비스를 취소합니다.

호출 범위 도구 세트는 현재 LlmAgentCodeActAgent에 의해 확인됩니다. 선택적 HTTP 및 SSE MCP 전송은 서버에서 광고되지 않습니다.

지속성 결정

InMemorySessionService은 로컬 편집기 프로세스와 테스트에 적합합니다. 세션이 프로세스 재시작 후에도 유지되어야 한다면 내구성 있는 서비스를 사용합니다. 재개 시 호출자가 원래의 cwd을 제공하는지 검증합니다. 세션을 다른 프로젝트에 자동으로 다시 연결할 수는 없습니다.

도구 승인 경계

서버는 ADK 도구 확인을 기본 ACP 권한 요청으로 연결합니다. 구성된 에이전트가 프롬프트 턴 중 ToolConfirmationRequest에서 일시 중지되면 — 에이전트가 도구 호출에 대한 사람의 승인을 기다릴 때 event.actions.tool_confirmation에 표시됨 — 서버는 도구와 해당 인수를 설명하는 session/request_permission 요청을 보내고, 클라이언트의 결과를 기다린 다음, 매핑된 결정으로 실행을 재개합니다. 승인은 허용으로 매핑되고 거부 또는 취소는 모두 거부로 매핑되므로, 취소된 요청은 도구를 절대 실행하지 않습니다. 각 결과는 해당 함수 호출 식별자를 통해 정확한 호출과 연결되며 RunConfig::tool_confirmation_decisions을 통해 runner로 다시 전달됩니다.

중첩된 session/request_permission은 이미 외부 session/prompt을 처리하고 ConnectionTo::spawn을 통해 생성된 작업에서 발행되므로, 연결의 디스패치 루프를 차단하지 않으며 외부 프롬프트 응답도 계속 완료됩니다. 공식 Rust SDK이 중첩 양방향 요청 후 외부 프롬프트 응답을 잃는다는 이전 우려는 이 일시 중지/재개 흐름에서는 재현되지 않으며, 메모리 내 상호 운용성 테스트에서 다뤄집니다.

서버가 소유하는 도구 권한 부여, 읽기 전용 도구, RBAC, 가드레일 및 워크플로 중단은 승인이 전적으로 ADK-Rust 프로세스 내부에서 이루어져야 하는 경우에도 계속 사용할 수 있습니다. 외부 ACP 에이전트를 위한 클라이언트 측 권한 경로도 완전히 구현되어 있습니다.

안전하게 배포하기

  • 의도한 프로젝트 작업 공간으로 바이너리를 시작합니다.
  • cwd 및 추가 루트는 OS 격리가 아닌 컨텍스트로 취급합니다.
  • 신뢰할 수 없는 프롬프트와 명령에는 adk-sandbox, 컨테이너 또는 다른 프로세스 경계를 적용합니다.
  • 모델 및 MCP 자격 증명은 클라이언트 비밀 저장소나 프로세스 환경에 보관합니다.
  • 배너, 디버그 객체 또는 로그를 프로토콜 표준 출력에 절대 기록하지 않습니다.
  • 재개가 프로세스 재시작 후에도 유지되어야 한다면 영속적인 SessionService을 사용합니다.
  • 유한한 세션 제한을 설정하고 비활성 세션을 종료합니다.

실행 가능한 acp_server 크레이트에는 Gemini 기반 에이전트, 작업 공간으로 범위가 제한된 읽기 도구, stderr 추적 및 편집기 프로세스 구성이 포함되어 있습니다.

다음 단계