Skip to main content
The Agent Control Protocol (ACP) provides a standardized interface for external tools—such as IDE extensions, terminal multiplexers, and custom scripts—to interact with the Palyra gateway. The primary implementation is the AcpBridge, which translates the JSON-RPC based ACP over stdio into the high-performance gRPC streams used by the Palyra daemon.

Architecture and Data Flow

The ACP Bridge acts as a protocol translator. It consumes standard input from a parent process (e.g., VS Code or Cursor), parses ACP JSON-RPC messages, and invokes corresponding methods on the GatewayRuntimeClient. Results and events from the gateway are then serialized back to standard output as ACP-compliant notifications or responses.

Protocol Mapping Diagram

The following diagram illustrates how “Natural Language Space” (ACP JSON-RPC) maps to “Code Entity Space” (gRPC/Rust structs). Sources: crates/palyra-cli/src/acp_bridge.rs#30-63, crates/palyra-cli/src/client/operator.rs#137-151, crates/palyra-cli/src/client/runtime.rs#203-215

The AcpBridge Implementation

The core of the ACP integration is the PalyraAcpAgent struct. It maintains the mapping between ACP session IDs and Palyra’s internal ULID-based session identifiers.

Key Components

ComponentCode EntityResponsibility
Agent StateBridgeStateTracks active SessionBinding and active_runs crates/palyra-cli/src/acp_bridge.rs#38-42.
Protocol HandlerPalyraAcpAgentImplements the acp::Client trait to handle incoming requests crates/palyra-cli/src/acp_bridge.rs#56-63.
Stream ManagerManagedRunStreamWraps the gRPC bidirectional stream for tool interaction crates/palyra-cli/src/client/operator.rs#31-35.
Permission BridgeClientBridgeRequestDispatches permission requests (e.g., tool execution approval) back to the ACP client crates/palyra-cli/src/acp_bridge.rs#44-53.

Session Resolution Logic

When an external tool initiates a session, the bridge uses SessionMetaOverrides to determine if a specific sessionKey or sessionLabel is required. It then calls OperatorRuntime::resolve_session to establish the connection to the daemon. Sources: crates/palyra-cli/src/acp_bridge.rs#163-170, crates/palyra-cli/src/acp_bridge.rs#100-116, crates/palyra-cli/src/client/operator.rs#112-118

Legacy Compatibility and Shims

To support older integration patterns and ensure a stable surface for third-party developers, the CLI provides specific shim commands.

ACP Shim Commands

The bridge behavior follows the same security posture as the standard CLI, including enforcement of allow_sensitive_tools and identity verification via AgentConnection crates/palyra-cli/src/acp_bridge.rs#56-63.

Integration with External Tools

External tools typically integrate by spawning the Palyra CLI in ACP mode: palyra acp run --session-key <KEY>

Permission Handling

ACP allows for granular permission requests. When the Palyra gateway encounters a tool call requiring human-in-the-loop (HITL) approval, the AcpBridge sends a RequestPermission message to the IDE. The IDE can respond with:
  • allow-once
  • allow-always
  • reject-once
  • reject-always
These are mapped to common_v1::ToolApprovalResponse and sent back through the ManagedRunStream to the orchestrator. Sources: crates/palyra-cli/src/acp_bridge.rs#25-28, crates/palyra-cli/src/acp_bridge.rs#118-131, crates/palyra-cli/src/client/operator.rs#50-68

Summary of Key Functions

FunctionLocationDescription
run_agent_interactive_asynccrates/palyra-cli/src/commands/agent.rs#115Manages the interactive loop for standard input/output.
execute_agent_streamcrates/palyra-cli/src/commands/agent.rs#73Low-level execution of a gRPC run stream.
send_session_updatecrates/palyra-cli/src/acp_bridge.rs#100Dispatches ACP notifications back to the tool.
build_agent_run_inputcrates/palyra-cli/src/commands/agent.rs#60Constructs the gRPC payload from CLI/ACP arguments.
Sources: crates/palyra-cli/src/acp_bridge.rs#1-131, crates/palyra-cli/src/commands/agent.rs#1-112, crates/palyra-cli/src/client/operator.rs#1-150