A2A Protocol¶
Hector implements the A2A Protocol specification for seamless interoperability with any A2A-compliant system.
What is A2A?¶
The Agent-to-Agent (A2A) Protocol is an open standard for agent communication and interoperability.
Key Benefits¶
- Interoperability - Connect agents from different platforms
- Standardization - Consistent API across implementations
- Future-proof - Evolving standard with community support
- Multi-transport - gRPC, REST, JSON-RPC, WebSocket
Hector's A2A Compliance¶
Specification Version¶
Hector is 100% compliant with A2A Protocol v0.3.0
Protocol Native Design¶
Hector is built entirely on A2A protocol types:
┌─────────────────────────────────────┐
│ A2A Protocol v0.3.0 (Protobuf) │
├─────────────────────────────────────┤
│ Hector Implementation │
│ • Official proto files (unmodified)│
│ • Direct protobuf usage │
│ • No abstraction layers │
│ • Native type system │
└─────────────────────────────────────┘
Why this matters: - Maximum performance (no conversion overhead) - 100% spec compliance guaranteed - Native protocol evolution support - Direct compatibility with A2A ecosystem
Compliance Summary¶
| Feature | Status | Details |
|---|---|---|
| Protocol Version | ✅ Latest | Fully compliant with A2A specification |
| Core Methods | ✅ 100% | message/send, tasks/get, tasks/cancel, tasks/list |
| Optional Methods | ✅ 100% | message/stream, tasks/resubscribe |
| Task Management | ✅ 100% | All 8 task states, async execution, persistence |
| Agent Discovery | ✅ 100% | RFC 8615 .well-known endpoints |
| Authentication | ✅ 100% | JWT, Bearer tokens, API keys, OAuth2 |
| Transport | ✅ All 3 | gRPC (50051), REST (8080), JSON-RPC (8080) |
| REST Endpoints | ✅✅ Complete | Agent-scoped URLs for multi-agent support |
Core Methods¶
message/send¶
Send a message to an agent (blocking or non-blocking).
Endpoint: POST /v1/agents/{agent}/message:send
Request:
{
"message": {
"messageId": "msg-123",
"role": "user",
"parts": [{"text": "Hello"}]
},
"configuration": {
"blocking": false
}
}
Response (non-blocking):
{
"task": {
"id": "task-abc123",
"status": {
"state": "TASK_STATE_SUBMITTED"
}
}
}
message/stream¶
Send a message with streaming response via Server-Sent Events.
Endpoint: POST /v1/agents/{agent}/message:stream
Request: Same as message/send
Response: Stream of events
event: message
data: {"task":{"id":"task-123","status":{"state":"TASK_STATE_WORKING"}}}
event: message
data: {"msg":{"role":"agent","parts":[{"text":"Hello! How can I help?"}]}}
event: done
data: {}
tasks/get¶
Get task status and results.
Endpoint: GET /v1/agents/{agent}/tasks/{taskID}
Response:
{
"id": "task-abc123",
"contextId": "ctx-456",
"status": {
"state": "TASK_STATE_COMPLETED",
"update": {
"role": "agent",
"parts": [{"text": "Task completed"}]
}
},
"history": [
{"role": "user", "parts": [{"text": "Request"}]},
{"role": "agent", "parts": [{"text": "Response"}]}
]
}
CLI Usage:
hector task get <agent> <task-id> --url http://localhost:9876
See Tasks Documentation for detailed usage.
tasks/cancel¶
Cancel a running task.
Endpoint: POST /v1/agents/{agent}/tasks/{taskID}:cancel
Response:
{
"id": "task-abc123",
"status": {
"state": "TASK_STATE_CANCELLED"
}
}
CLI Usage:
hector task cancel <agent> <task-id> --url http://localhost:9876
tasks/list¶
List tasks with optional filtering and pagination (optional method).
Endpoint: GET /v1/agents/{agent}/tasks
Query Parameters:
- context_id - Filter by context/session
- status - Filter by task state
- page_size - Number of results (default: 50, max: 100)
- page_token - Pagination token
- history_length - Messages to include per task
- include_artifacts - Include artifacts (default: false)
Response:
{
"tasks": [
{"id": "task-1", "status": {"state": "TASK_STATE_COMPLETED"}},
{"id": "task-2", "status": {"state": "TASK_STATE_WORKING"}}
],
"nextPageToken": "page-2",
"totalSize": 42
}
See Also: Complete Task Management Documentation
Agent Discovery¶
Hector implements RFC 8615 .well-known endpoints for agent discovery.
Agent Card Location¶
Per A2A Specification Section 5.3, agent cards MUST be located at:
/.well-known/agent-card.json
For multi-agent services, each agent has its own dedicated path:
/v1/agents/{agent}/.well-known/agent-card.json
Multi-Agent Discovery¶
Endpoint: GET /v1/agents
List all agents via the discovery endpoint:
curl http://localhost:8080/v1/agents
{
"agents": [
{
"name": "assistant",
"url": "http://localhost:8080/v1/agents/assistant"
},
{
"name": "coder",
"url": "http://localhost:8080/v1/agents/coder"
}
]
}
Agent Card Structure¶
Endpoint: GET /v1/agents/{agent}/.well-known/agent-card.json
Get specific agent card:
{
"agent": {
"name": "My Assistant",
"description": "A helpful AI assistant",
"version": "1.0.0",
"capabilities": ["chat", "tools", "streaming"],
"supported_content_types": ["text"],
"security": {
"schemes": {
"bearer_auth": {
"type": "http",
"scheme": "bearer"
}
}
}
}
}
Message Format¶
Message Structure¶
message Message {
Role role = 1; // ROLE_USER | ROLE_AGENT | ROLE_UNSPECIFIED
repeated Part parts = 2; // Message parts (text, file, data)
string context_id = 3; // Optional session/context identifier
}
message Part {
oneof part {
string text = 1; // TextPart (Section 6.5.1)
File file = 2; // FilePart (Section 6.5.2)
google.protobuf.Struct data = 3; // DataPart (Section 6.5.3)
}
}
Note: The field is named parts (not content) per A2A v0.3.0 specification.
Roles¶
Per A2A Specification Section 6.4:
| Role | Value | Description |
|---|---|---|
ROLE_UNSPECIFIED |
0 | Default/system messages |
ROLE_USER |
1 | User message |
ROLE_AGENT |
2 | Agent response |
Part Types¶
Per A2A Specification Section 6.5:
| Type | Status | Description | Spec Section |
|---|---|---|---|
TextPart |
✅ Supported | Plain text messages | 6.5.1 |
FilePart |
✅ Supported | Multi-modal content (images, video, audio) | 6.5.2 |
DataPart |
✅ Supported | Structured JSON data | 6.5.3 |
FilePart (Multi-Modality)¶
FilePart enables sending images, video, audio, and other media types alongside text:
message FilePart {
oneof file {
string file_with_uri = 1; // HTTP/HTTPS URL or GCS URI
bytes file_with_bytes = 2; // Base64-encoded data
}
string media_type = 3; // MIME type (e.g., "image/jpeg")
string name = 4; // Optional filename
}
Field Details:
file_with_uri: HTTP/HTTPS URL or Google Cloud Storage URI (supported by OpenAI, Gemini)file_with_bytes: Base64-encoded file data (supported by all providers)media_type: MIME type identifier (required for proper processing)- Images:
image/jpeg,image/png,image/gif,image/webp - Video:
video/mp4,video/avi,video/mov(Gemini only) - Audio:
audio/wav,audio/mp3(Gemini only) name: Optional filename for reference
Example with Image:
{
"message": {
"role": "ROLE_USER",
"parts": [
{
"text": "What is in this image?"
},
{
"file": {
"file_with_uri": "https://example.com/photo.jpg",
"media_type": "image/jpeg",
"name": "photo.jpg"
}
}
]
}
}
Example with Base64 Image:
{
"message": {
"role": "ROLE_USER",
"parts": [
{
"text": "Analyze this image"
},
{
"file": {
"file_with_bytes": "iVBORw0KGgoAAAANSUhEUgAA...",
"media_type": "image/png",
"name": "screenshot.png"
}
}
]
}
}
Provider Support:
| Provider | URI Support | Base64 Support | Max Size | Media Types |
|---|---|---|---|---|
| OpenAI | ✅ HTTP/HTTPS | ✅ | 20MB | Images |
| Anthropic | ❌ | ✅ | 5MB | Images |
| Gemini | ✅ GCS, some HTTP | ✅ | 20MB | Images, Video, Audio |
| Ollama | ❌ | ✅ | 20MB | Images |
See Multi-Modality Support for complete documentation.
Task Lifecycle¶
Task States¶
Per A2A Specification Section 6.3, all 8 task states are supported:
SUBMITTED → WORKING → COMPLETED
→ FAILED
→ CANCELLED
→ INPUT_REQUIRED
→ REJECTED
→ AUTH_REQUIRED
| State | Description | Spec Section |
|---|---|---|
TASK_STATE_UNSPECIFIED |
Default/unknown state | 6.3 |
TASK_STATE_SUBMITTED |
Task created and queued | 6.3 |
TASK_STATE_WORKING |
Task actively processing | 6.3 |
TASK_STATE_COMPLETED |
Task finished successfully (terminal) | 6.3 |
TASK_STATE_FAILED |
Task encountered error (terminal) | 6.3 |
TASK_STATE_CANCELLED |
Task terminated by client (terminal) | 6.3 |
TASK_STATE_INPUT_REQUIRED |
Awaiting user input (interrupted) | 6.3 |
TASK_STATE_REJECTED |
Agent refused task (terminal) | 6.3 |
TASK_STATE_AUTH_REQUIRED |
Needs authentication | 6.3 |
For detailed task management, see: Tasks Documentation
Task Endpoints¶
All task operations use agent-scoped URLs:
Create Task:
POST /v1/agents/{agent}/message:send
Content-Type: application/json
{
"message": {"role": "user", "parts": [{"text": "Request"}]},
"configuration": {"blocking": false}
}
Get Task Status:
GET /v1/agents/{agent}/tasks/{task_id}
List Tasks:
GET /v1/agents/{agent}/tasks?page_size=50
Cancel Task:
POST /v1/agents/{agent}/tasks/{task_id}:cancel
Subscribe to Updates:
GET /v1/agents/{agent}/tasks/{task_id}:subscribe
Full Documentation: Task Lifecycle and Management
Authentication¶
JWT Tokens¶
Hector supports JWT-based authentication:
Authorization: Bearer <jwt_token>
Token Claims:
{
"sub": "user-123",
"iss": "https://auth.example.com",
"aud": "hector-api",
"roles": ["user", "admin"],
"exp": 1234567890
}
Security Schemes¶
Hector supports OpenAPI security schemes:
agents:
assistant:
security:
schemes:
bearer_auth:
type: "http"
scheme: "bearer"
api_key:
type: "apiKey"
name: "X-API-Key"
in: "header"
require:
- bearer_auth
Streaming¶
Hector supports multiple streaming protocols.
gRPC Streaming¶
rpc SendStreamingMessage(SendMessageRequest) returns (stream StreamResponse);
Server-Sent Events (SSE)¶
curl -N -H "Accept: text/event-stream" \
http://localhost:8080/v1/agents/assistant/message:stream
Response:
data: {"response":{"content":[{"text":"Hello"}]}}
data: {"response":{"content":[{"text":"!"}]}}
data: [DONE]
WebSocket¶
const ws = new WebSocket('ws://localhost:8080/v1/agents/assistant/stream');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data.response.content[0].text);
};
Interoperability¶
Connect to External A2A Agents¶
Hector can call any A2A-compliant agent:
agents:
external:
type: "a2a"
url: "https://external-agent.com"
credentials:
type: "bearer"
token: "${EXTERNAL_TOKEN}"
Expose Hector Agents¶
Any A2A client can call Hector agents:
# Start Hector server
hector serve --config config.yaml
# Call from any A2A client
curl -X POST http://localhost:8080/v1/agents/assistant/message:send \
-H "Content-Type: application/json" \
-d '{"message":{"role":"ROLE_USER","content":[{"text":"Hello"}]}}'
Transport Protocols¶
Hector implements all three A2A transport protocols on conventional ports:
| Transport | Port | Endpoint | Protocol |
|---|---|---|---|
| gRPC | 50051 | localhost:50051 |
HTTP/2 + Protobuf |
| REST | 8080 | http://localhost:8080/v1/* |
HTTP/1.1 + JSON |
| JSON-RPC | 8080 | http://localhost:8080/ |
HTTP/1.1 + JSON-RPC 2.0 |
gRPC (Port 50051)¶
Protocol: HTTP/2 with Protocol Buffers
Features: - Binary protocol - Bidirectional streaming - High performance - Native A2A proto support
Example:
grpcurl -plaintext \
-H 'agent-name: assistant' \
-d '{"request":{"role":"ROLE_USER","parts":[{"text":"Hello"}]}}' \
localhost:50051 \
a2a.v1.A2AService/SendMessage
REST (Port 8080)¶
Protocol: HTTP/1.1 with JSON
Features: - RESTful URLs - JSON payload - SSE streaming - Dual path support (spec + proto formats)
Examples:
Spec-preferred format (agent in path):
curl -X POST http://localhost:8080/v1/agents/assistant/message:send \
-H "Content-Type: application/json" \
-d '{"message":{"role":"ROLE_USER","parts":[{"text":"Hello"}]}}'
Proto-compatible format (agent in header):
curl -X POST http://localhost:8080/v1/message:send \
-H "Content-Type: application/json" \
-H "agent-name: assistant" \
-d '{"message":{"role":"ROLE_USER","parts":[{"text":"Hello"}]}}'
JSON-RPC (Port 8080)¶
Protocol: HTTP/1.1 with JSON-RPC 2.0
Features:
- Single endpoint: POST / (root path)
- Streaming endpoint: POST /stream (SSE)
- Method-based routing
- Simple integration
- Method names follow A2A spec (e.g., message/send, tasks/get)
Examples:
Send message:
curl -X POST http://localhost:8080/ \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {"role":"ROLE_USER","parts":[{"text":"Hello"}]}
},
"id": 1
}'
With agent selection (multi-agent mode):
curl -X POST "http://localhost:8080/?agent=assistant" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {"role":"ROLE_USER","parts":[{"text":"Hello"}]}
},
"id": 1
}'
Error Handling¶
Error Codes¶
| Code | HTTP | Description |
|---|---|---|
OK |
200 | Success |
INVALID_ARGUMENT |
400 | Invalid request |
UNAUTHENTICATED |
401 | Missing/invalid auth |
PERMISSION_DENIED |
403 | Insufficient permissions |
NOT_FOUND |
404 | Agent not found |
RESOURCE_EXHAUSTED |
429 | Rate limit exceeded |
INTERNAL |
500 | Internal error |
UNAVAILABLE |
503 | Service unavailable |
Error Response¶
{
"error": {
"code": "NOT_FOUND",
"message": "Agent not found: unknown_agent",
"details": {
"name": "unknown_agent"
}
}
}
Protocol Extensions¶
Hector supports protocol extensions while maintaining compatibility:
Tool Calling¶
{
"response": {
"role": "ROLE_AGENT",
"parts": [{"text": "I'll search for that."}],
"tool_calls": [
{
"id": "call_123",
"type": "function",
"function": {
"name": "search",
"arguments": "{\"query\":\"AI trends\"}"
}
}
]
}
}
Metadata¶
{
"response": {
"role": "ROLE_AGENT",
"parts": [{"text": "Response"}],
"metadata": {
"tokens_used": 150,
"model": "gpt-4o",
"execution_time": 1.5
}
}
}
Testing A2A Endpoints¶
Agent Discovery¶
# Get agent card (multi-agent service)
curl http://localhost:8080/v1/agents/assistant/.well-known/agent-card.json
# List all agents
curl http://localhost:8080/v1/agents
Send Message¶
curl -X POST http://localhost:8080/v1/agents/assistant/message:send \
-H "Content-Type: application/json" \
-d '{
"message": {
"role": "user",
"parts": [{"text": "Hello"}],
"contextId": "session-123"
}
}'
Stream Message (SSE)¶
curl -N -X POST http://localhost:8080/v1/agents/assistant/message:stream \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"message": {
"role": "user",
"parts": [{"text": "Hello"}],
"contextId": "session-123"
}
}'
JSON-RPC¶
curl -X POST http://localhost:8080/ \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{"text": "Hello"}],
"contextId": "session-123"
}
},
"id": 1
}'
Task Management¶
# Get task status
curl http://localhost:8080/v1/agents/assistant/tasks/task_abc123
# Cancel task
curl -X POST http://localhost:8080/v1/agents/assistant/tasks/task_abc123:cancel
Specification Reference¶
A2A Protocol Specification: https://a2a-protocol.org/latest/specification/
Official Proto Files: https://github.com/a2aproject/A2A/blob/main/specification/grpc/a2a.proto
Key Specification Sections: - Section 3: Transport Protocols (gRPC, REST, JSON-RPC) - Section 5: Agent Discovery (RFC 8615) - Section 6: Message Structure and Task Lifecycle - Section 11: Compliance Requirements
Hector Implementation Details: - All 3 transport protocols ✅ - All required methods + optional methods ✅ - Dual REST path support (spec + proto formats) ✅✅ - All 9 task states ✅ - All 3 message part types (text, file, data) ✅
Next Steps¶
- Tasks Documentation - Complete task management guide
- API Reference - Detailed API documentation
- Architecture - System architecture
- Multi-Agent - Multi-agent orchestration and A2A integration
Related Topics¶
- Tasks - Task lifecycle and management
- Security - Authentication setup
- Sessions - Session management
- Configuration Reference - Production deployment