Agent Control Protocol (ACP)
Relevant source files
The following files were used as context for generating this wiki page:
The Agent Control Protocol (ACP) is a communication framework used by QQcode to expose its capabilities as a standardized agent to external clients, such as the Zed editor or the project's own VS Code extension. It facilitates a structured exchange between a client and the QQcode agent, allowing for session management, model selection, and multi-modal content handling.
ACP acts as a bridge between the core VibeAgent logic and the specific requirements of IDE integrations. It manages asynchronous task execution for agent "acts," handles permission requests for tool execution, and translates QQcode's internal events into protocol-compliant notifications.
Sources: vibe/acp/acp_agent.py:1-80, CLAUDE.md:37-39
Architecture and Components
The ACP implementation is centered around the VibeAcpAgent class, which extends the base AcpAgent from the agent-client-protocol library. It maintains a mapping of active sessions and interacts with the core Agent to perform actual computations.
Core Components
| Component | Description |
|---|---|
VibeAcpAgent | The main protocol handler that implements standard ACP methods like initialize, newSession, and prompt. |
AcpSession | A data structure that pairs a VibeAgent instance with session-specific state, including the current execution mode and the active asynchronous task. |
AgentSideConnection | Manages the transport layer (typically stdio) for sending and receiving protocol messages. |
VibeAgent | The underlying orchestrator that manages LLM interactions and tool execution. |
Sources: vibe/acp/acp_agent.py:65-80, vibe/acp/acp_agent.py:141-160, CLAUDE.md:43-46
Session Lifecycle
The lifecycle of an ACP interaction begins with initialization, followed by session creation, and iterative prompting.
This diagram shows the high-level flow of requests between an ACP client and the VibeAcpAgent.
Sources: vibe/acp/acp_agent.py:85-300
Protocol Operations
Initialization and Capabilities
During the initialize call, the agent communicates its version and capabilities to the client. It specifically checks for terminal-auth support in the client to determine if it should offer a setup flow for API keys.
- Agent Info: Named
@qqcode/qqcodewith title "QQcode". - Capabilities: Supports
embeddedContextbut currently disablesloadSession,audio, andimageprompts. - Dynamic Tool Disabling: Tools like
bash,read_file, andwrite_fileare disabled if the client's capabilities (e.g., terminal or filesystem access) are restricted.
Sources: vibe/acp/acp_agent.py:85-135, tests/acp/test_initialize.py:27-50
Content Handling
ACP supports multiple content types within a prompt, which the agent flattens into a single text string for the underlying LLM.
- Text Blocks: Standard user input.
- Resource Blocks: Embedded file contents (URI, text/blob).
- Resource Link Blocks: References to external resources (metadata including name, title, description, size, and mimeType).
Sources: vibe/acp/acp_agent.py:338-379, tests/acp/test_content.py:48-125
Approval and Mode Management
The protocol implements a two-stage approval system: one for individual tool calls and another for implementation plans (Plan Mode).
Tool Execution Approval
When the agent is in APPROVAL_REQUIRED mode, it uses an AsyncApprovalCallback to pause execution and request permission from the client.
This sequence illustrates how tool calls are gated by user approval through the ACP protocol.
Sources: vibe/acp/acp_agent.py:192-234
Plan Approval Flow
Specific to "Plan Mode," the agent submits a Markdown plan using the submit_plan tool. This triggers a switch_mode kind of permission request, allowing the user to transition the agent into implementation.
| Option ID | Resulting Action |
|---|---|
auto_approve | Agent resumes with all subsequent tools automatically approved. |
approval_required | Agent resumes in interactive mode requiring individual approvals. |
plan | Agent stays in plan mode (usually for revisions). |
Sources: vibe/acp/acp_agent.py:236-285, vibe/acp/utils.py
Implementation Details
Internal Loop Translation
The agent acts by iterating over an asynchronous stream of events. The VibeAcpAgent translates these internal events into ACP SessionUpdate notifications.
# vibe/acp/acp_agent.py:381-417
async for event in session.agent.act(rendered_prompt):
if isinstance(event, AssistantEvent):
yield AgentMessageChunk(
sessionUpdate="agent_message_chunk",
content=TextContentBlock(type="text", text=event.content),
)
elif isinstance(event, ToolCallEvent):
# ... logic to update tool state and yield session_update ...
elif isinstance(event, ToolResultEvent):
# ... yield tool_result_session_update ...
elif isinstance(event, ModeChangedEvent):
yield CurrentModeUpdate(...)
Sources: vibe/acp/acp_agent.py:381-417
VS Code Extension Integration
The VS Code extension utilizes a ChatViewProvider to communicate with the backend. While it often interacts via programmatic CLI flags, it reflects the same state-driven architecture as the ACP agent, tracking currentSessionId, currentMode, and pendingApproval states.
Sources: vscode-extension/src/chatView/ChatViewProvider.ts:20-60
Conclusion
The Agent Control Protocol (ACP) provides a robust, session-based interface for QQcode. By abstracting tool approvals and content management into a standardized protocol, it allows QQcode to function seamlessly across different developer environments while maintaining safety through its interactive permission system.