src — protocols
src — protocols
The src/protocols module defines the communication standards and implementations for inter-agent and enhanced agent interactions within the Code Buddy system. It currently encompasses two primary protocols:
- A2A (Agent-to-Agent) Protocol: Handles the core mechanics of task delegation, lifecycle management, and message exchange between agents.
- ACP (Enhanced Agent Communication Protocol): Provides advanced capabilities like context injection, tool delegation, and dynamic capability discovery, typically exposed via HTTP endpoints.
This module is crucial for enabling Code Buddy to operate as a multi-agent system, allowing different specialized agents to collaborate and delegate work.
A2A Protocol: Agent-to-Agent Communication (src/protocols/a2a/index.ts)
The A2A protocol implements a standardized way for agents to communicate, delegate tasks, and manage their lifecycle. It's designed for robust, asynchronous task execution and multi-turn interactions.
Purpose
The A2A protocol facilitates:
- Task Delegation: An orchestrator agent can submit a task to a specialist agent.
- Lifecycle Management: Tasks progress through defined states (submitted, working, completed, failed, etc.).
- Multi-Turn Interactions: Agents can request further input or yield control, allowing for complex conversational flows.
- Discovery: Agents can publish their capabilities for others to discover.
Core Concepts
The protocol is built around several key data structures:
AgentCard: A discovery document (/.well-known/agent.jsonequivalent) describing an agent's name, description, URL, version, and a list ofAgentSkills.AgentSkill: Defines a specific capability an agent possesses, including its ID, name, description, and supported input/output MIME types.Task: The central unit of work. It encapsulates:id,sessionId(for grouping multi-turn interactions).status(TaskStatewithTaskStatusenum).messages(A2AMessages exchanged between user/agent).artifacts(outputs produced by the task).history(a log ofTaskStatechanges).yieldPayload(for pausing and resuming tasks).A2AMessage: A communication unit within a task, consisting ofParts (text or file content) and arole(useroragent).Artifact: Output generated by a task, also composed ofParts.YieldPayload: A mechanism to pause a task, providing a reason, an optional state snapshot, and a hint for resumption.
Task Lifecycle
Tasks progress through various states, managed by the A2AAgentServer.
graph TD
A[Task Submitted] -->|submitTask| B(Status: SUBMITTED)
B -->|updateTaskStatus| C(Status: WORKING)
C -->|TaskExecutor completes| D(Status: COMPLETED)
C -->|TaskExecutor fails| E(Status: FAILED)
C -->|yieldTask| F(Status: INPUT_REQUIRED)
F -->|sendMessage or resumeTask| C
B -->|cancelTask| G(Status: CANCELED)
C -->|cancelTask| G
F -->|cancelTask| G
Key Components
A2AAgentServer
This class represents an agent that receives and executes tasks. It acts as the server-side implementation of the A2A protocol.
- Constructor:
new A2AAgentServer(card: AgentCard, executor: TaskExecutor) - Requires an
AgentCardto describe its capabilities. - Requires a
TaskExecutorfunction, which is the core logic for how this agent processes aTask. submitTask(request: { id, sessionId?, message, metadata? }): Initiates a new task. It sets the task status toSUBMITTED, thenWORKING, calls the providedTaskExecutor, and updates the status toCOMPLETEDorFAILEDbased on the executor's outcome.sendMessage(taskId: string, message: A2AMessage): Used for multi-turn interactions. Adds a new message to an existing task that is inINPUT_REQUIREDstatus, then re-enters theTaskExecutor.yieldTask(taskId: string, payload: Omit: Pauses a) WORKINGtask, setting its status toINPUT_REQUIREDand storing theYieldPayload. This allows an orchestrator to intervene or provide further input.resumeTask(taskId: string, resumeMessage?: A2AMessage, injectedState?: Record: Resumes a task that was previously yielded. It clears the) yieldPayload, optionally injects state into the task's metadata, and re-enters theTaskExecutor.getAgentCard(): Returns the agent's discovery document.getTask(id: string): Retrieves a task by its ID.cancelTask(id: string): Attempts to cancel a task if it's not already completed or failed.- Event Emitter:
A2AAgentServerextendsEventEmitterand emits events for key task lifecycle changes: task:submittedtask:completedtask:failedtask:canceledtask:yieldedtask:resumed
A2AAgentClient
This class represents an entity (typically an orchestrator) that sends tasks to other agents. In this implementation, it's designed for in-process communication with A2AAgentServer instances.
registerAgent(key: string, agent: A2AAgentServer): Registers anA2AAgentServerinstance under a unique key, allowing the client to interact with it locally.submitTask(agentKey: string, request: string, metadata?: Record: Submits a new task to a registered agent. It internally calls the) submitTaskmethod of the targetA2AAgentServer.- Discovery Methods:
getAgentCard(key: string): Retrieves theAgentCardof a registered agent.listAgents(): Returns keys of all registered agents.findAgentsWithSkill(skillId: string): Finds agents that declare a specific skill.getTask(agentKey: string, taskId: string): Retrieves a task from a registered agent.
Helper Functions
createAgentCard(config: { name, description, skills, url? }): A utility to easily construct anAgentCardobject.getTaskResult(task: Task): Extracts the primary result from a completed task, prioritizing artifacts, then the last agent message, or falling back to the task status message.
Integration Points
server/routes/a2a-protocol.ts: This module usesA2AAgentClientto expose A2A functionality via HTTP endpoints, allowing external systems to interact with Code Buddy's local agents. It also usescreateAgentCardandgetTaskResult.server/routes/acp.ts: Also usesA2AAgentClientfor certain operations, demonstrating how different protocols can leverage the same underlying agent communication layer.TaskExecutorImplementations: Any module that wants to act as an A2A agent must provide aTaskExecutorfunction toA2AAgentServer, defining its specific task processing logic.
ACP Protocol: Enhanced Agent Communication Protocol (src/protocols/acp/acp-server.ts)
The ACP protocol provides a set of advanced HTTP endpoints for interacting with Code Buddy, focusing on context management, tool execution, and dynamic capability discovery. It's designed to enhance agent communication beyond basic task delegation.
Purpose
The ACP protocol aims to:
- Inject Context: Allow external systems to feed contextual information directly into Code Buddy's context engine.
- Delegate Tools: Enable external agents or orchestrators to trigger Code Buddy's internal tools.
- Discover Capabilities: Provide a programmatic way to query Code Buddy's available tools and general agent capabilities.
Core Concepts
ACPContextPayload: Defines the structure for injecting context, includingtype,content,metadata, andpriority.ACPDelegatePayload: Defines the structure for delegating tool execution, specifying thetoolname,args, and an optionaltimeout.ACPCapability: Describes a single tool, including itsname,description,parameters(JSON Schema),readOnlystatus, andcategory.ACPCapabilitiesResponse: The response structure for the/capabilitiesendpoint, listing all available tools and general agent metadata.
createACPServerRoutes Function
This is a factory function that returns an Express Router configured with the ACP endpoints. It's designed to be integrated into an existing Express application.
createACPServerRoutes(options: { asyncHandler, getContextEngine?, getToolRegistry? }):asyncHandler: A wrapper function (e.g., fromserver/middleware/error-handler.ts) to handle asynchronous Express route errors.getContextEngine(): An optional getter function that returns an instance of theContextEngine(e.g., fromsrc/context/context-manager-v2.ts). If provided, the/contextendpoint will use it.getToolRegistry(): An optional getter function that returns an instance of a tool registry (e.g., fromsrc/mcp/mcp-client.ts). If provided, the/delegateand/capabilitiesendpoints will use it.
Endpoints
POST /api/acp/context
- Payload:
ACPContextPayload - Functionality:
- Validates
typeandcontent. - If
getContextEngine()is provided and returns an object with aningestmethod, it callsengine.ingest()to inject the context. - If no context engine is available, it logs that the context is "stored" (implying it's acknowledged but not actively processed).
- Returns
200 OKwith success status and details of the injected context. - Handles errors during injection, returning
500 Internal Server Error. - Dependencies:
logger,getContextEngine().ingest()(fromsrc/context/context-manager-v2.ts).
POST /api/acp/delegate
- Payload:
ACPDelegatePayload - Functionality:
- Validates
toolandargs. - If
getToolRegistry()is provided and returns an object with anexecuteToolmethod, it callsregistry.executeTool(tool, args). - Implements a timeout mechanism (default 30s, max 2min) for tool execution.
- Returns
200 OKwith success status, tool name, and the result of the execution. - Handles cases where the tool registry is unavailable (
503 Service Unavailable) or tool execution fails/times out (500 Internal Server Error). - Dependencies:
logger,getToolRegistry().executeTool()(fromsrc/mcp/mcp-client.tsor similar).
GET /api/acp/capabilities
- Functionality:
- Constructs a response containing a list of available tools and general agent capabilities.
- If
getToolRegistry()is provided and returns an object with alistToolsmethod, it populates thetoolsarray in the response by callingregistry.listTools(). - Includes hardcoded agent metadata (name, version, capabilities).
- Returns
200 OKwith theACPCapabilitiesResponse. - Dependencies:
logger,getToolRegistry().listTools()(fromsrc/mcp/mcp-client.tsor similar).
Integration Points
server/routes/acp.ts: This is the primary consumer ofcreateACPServerRoutes. It calls this function to mount the ACP endpoints onto the main Express application, providing the necessarygetContextEngineandgetToolRegistryimplementations from the Code Buddy core.src/context/context-manager-v2.ts: TheContextEngine'singestmethod is called by the/contextendpoint.src/mcp/mcp-client.ts: TheToolRegistry'sexecuteToolandlistToolsmethods are called by the/delegateand/capabilitiesendpoints, respectively.src/utils/logger.js: Used for logging operational details and errors within the ACP server.server/middleware/error-handler.ts: Provides theasyncHandlerwrapper for robust error handling in Express routes.
Relationship Between A2A and ACP
While both protocols deal with agent communication, they serve different purposes and operate at different levels:
- A2A is a lower-level, task-oriented protocol focused on the lifecycle of a delegated unit of work. It defines the core concepts of tasks, messages, and artifacts, and provides an in-process client/server for managing these.
- ACP is a higher-level, HTTP-based protocol that enhances agent communication by providing specific endpoints for common advanced operations like context injection and tool delegation. It can be seen as a specialized interface that might leverage or complement the underlying A2A task management.
For instance, an external orchestrator might use ACP's /delegate endpoint to ask Code Buddy to run a tool, and Code Buddy might internally use A2A to delegate parts of that tool's execution to another specialized local agent. The server/routes/acp.ts module demonstrates this by using A2AAgentClient alongside createACPServerRoutes, indicating that the ACP endpoints might interact with the A2A layer.