Skip to content

A2A Protocol

scarecr0w12 edited this page Jun 24, 2026 · 7 revisions

A2A Protocol

Google Agent-to-Agent (A2A) v1.0 protocol implementation, allowing CortexPrism agents to interoperate with external AI agents using a standardized JSON-RPC 2.0 interface.

Architecture

Seven files in packages/server/src/a2a/:

File Purpose
types.ts Core data model: AgentCard, Task, Message, Part, Artifact, events, and config types
server.ts JSON-RPC 2.0 server over HTTP at /a2a endpoint
client.ts Client for delegating tasks to remote A2A-compliant agents
agent-card.ts Agent Card generation from tool registry
tool-wrapper.ts Wraps remote A2A agents as Cortex Tool objects
executor.ts Wires the Cortex agent loop into the A2A server
mod.ts Module barrel exports

A2A Server

Exposes Cortex agents as A2A-compliant endpoints using JSON-RPC 2.0 over HTTP at the /a2a endpoint.

Supported RPC Methods

Method Description
GetAgentCard Returns the agent's capability card (name, skills, interfaces)
GetExtendedAgentCard Alias for GetAgentCard
SendMessage Non-streaming task execution; blocks until completion
SendStreamingMessage SSE-based streaming task execution
GetTask Retrieve a task by ID
ListTasks List all active tasks
CancelTask Cancel a running task

Task Lifecycle

The spec defines seven states; five are implemented:

TASK_STATE_WORKING → TASK_STATE_COMPLETED
                   → TASK_STATE_FAILED
                   → TASK_STATE_CANCELED

TASK_STATE_UNSPECIFIED, TASK_STATE_REJECTED, and TASK_STATE_INPUT_REQUIRED are defined in the spec types but not yet wired into server logic.

Stream Format

Streaming responses use text/event-stream (SSE) with data: prefixed JSON lines and [DONE] termination:

data: {"jsonrpc":"2.0","id":"...","result":{"task":{...}}}

data: {"type":"TaskArtifactUpdateEvent","taskId":"...","artifact":{...},"lastChunk":true}

data: {"type":"TaskStatusUpdateEvent","taskId":"...","status":{...},"final":true}

[DONE]

Server Configuration

Key Type Default Description
enabled boolean false Enable A2A server
server.port number Override listen port
server.bindAddress string Bind address
server.allowedOrigins string[] CORS origins

Resource Limits

Constant Value Description
MAX_TASKS 1000 Maximum concurrent tasks
MAX_CONTEXTS 500 Maximum conversation contexts
TASK_TTL_MS 3,600,000 Task expiry (1 hour)
IDLE_CLEANUP_INTERVAL_MS 300,000 Cleanup interval (5 min)

A2A Client

Delegates tasks to remote A2A-compliant agents.

Key Functions

Function Description
fetchAgentCard(endpoint) Retrieves Agent Card via /.well-known/agent-card.json
sendMessage(card, request) Sends a non-streaming task via JSON-RPC SendMessage
sendStreamingMessage(card, request, onChunk, onStatus) Sends a streaming task via SSE
getTask(card, taskId) Retrieves task status from remote agent
listTasks(card, request) Lists tasks with pagination support
cancelTask(card, taskId) Cancels a remote task

Streaming Client

The streaming client reads SSE from the remote agent, parsing TaskArtifactUpdateEvent (text chunks delivered via onChunk) and TaskStatusUpdateEvent (state transitions via onStatus). Default timeout: 120 seconds.

Agent Card Generation

generateAgentCard() builds an Agent Card from the Cortex tool registry. Each tool is converted to an AgentSkill:

  • id: tool definition name
  • name: human-readable title (snake_case → Title Case)
  • description: from tool definition
  • tags: from tool capabilities
  • examples: pre-defined mappings for common tools (file_read, shell, web_search, etc.)

Default skills include code-generation, debugging, code-review, architecture, and search when no tools are registered. The card advertises streaming: true, stateTransitionHistory: true, and a single json-rpc interface at /a2a.

Tool Integration Wrapper

createA2AToolWrapper() wraps a remote A2A agent as a Cortex Tool (a2a_<agentName>).

  • Parameters: message (string, required), contextId (string, optional)
  • Capability: network:fetch
  • Caching: Agent Cards are cached after first fetch
  • Error handling: Auto-clears card cache on errors, returns retryable A2A_ERROR

Configuration

{
  "a2a": {
    "enabled": true,
    "server": {
      "port": 3000,
      "bindAddress": "0.0.0.0"
    },
    "remoteAgents": {
      "partner-bot": {
        "endpoint": "https://partner.example.com",
        "agentCardUrl": "https://partner.example.com/.well-known/agent-card.json",
        "authToken": "sk-...",
        "timeout": 60000
      }
    }
  }
}

REST API Endpoints

Method Path Description
POST /a2a JSON-RPC 2.0 entry point for all A2A operations
GET /.well-known/agent-card.json Agent Card discovery endpoint
GET /api/a2a/agent-card.json Agent Card alias (same as well-known)

CLI Commands

cortex mcp a2a card             # Show A2A agent card
cortex mcp a2a skills           # List A2A skills
cortex mcp a2a remote           # List remote A2A agents

Swarm Transport (v0.51.0+)

The A2A protocol serves as the wire transport for the distributed agent swarm. Swarm directives are mapped to A2A SendMessage JSON-RPC calls via packages/infra/src/swarm/transport.ts. The A2A server integrates with the swarm via registerSwarmHandler() — incoming messages with metadata.swarmKind are routed to the directive handler instead of the normal Cortex executor, supporting 5 directive kinds: spawn_agent, execute_task, query_resources, forward_message, sync_state.

See Also

Clone this wiki locally