A2A Server
Publish Agent Cards and accept task submissions
A2A Client
Discover external agents and send tasks to them
Agent Card
An Agent Card is a JSON document that describes an agent’s identity, capabilities, and supported interaction modes. It is served at the well-known path/.well-known/agent.json per the A2A specification.
Agent Card Structure
Agent Capabilities
Agent Skills
A2A skills are capability descriptors, not the same as OpenFang skills. These describe what the agent can do for cross-framework discovery.
Example Agent Card
build_agent_card(). Each tool in the agent’s capability list becomes an A2A skill descriptor.
A2A Server
OpenFang serves A2A requests through the REST API:Agent Card
Publication at
/.well-known/agent.jsonAgent Listing
All agents at
/a2a/agentsTask Tracking
Via
A2aTaskStoreA2aTaskStore
TheA2aTaskStore is an in-memory, bounded store for tracking A2A task lifecycle:
Key Properties
- Bounded: When reaching
max_tasks, evicts oldest completed/failed/cancelled task (FIFO) - Thread-safe: Uses
Mutex<HashMap>for concurrent access - Kernel field: Stored as
kernel.a2a_task_store
Methods
insert(task)
insert(task)
Add a new task, evicting old ones if at capacity
get(task_id)
get(task_id)
Retrieve a task by ID
update_status(task_id, status)
update_status(task_id, status)
Change a task’s status
complete(task_id, response, artifacts)
complete(task_id, response, artifacts)
Mark as completed with response
fail(task_id, error_message)
fail(task_id, error_message)
Mark as failed with error
cancel(task_id)
cancel(task_id)
Mark as cancelled
Task Submission Flow
WhenPOST /a2a/tasks/send is called:
1
Extract message
Extract the message text from A2A request format (parts with type “text”)
2
Find target agent
Locate the target agent (currently uses first registered agent)
3
Create task
Create an
A2aTask with status Working and insert into task store4
Send to agent
Send message to agent via
kernel.send_message()5
Handle response
On success: complete task with agent’s response
On failure: fail task with error message
On failure: fail task with error message
6
Return state
Return the final task state
A2A Client
TheA2aClient struct discovers and interacts with external A2A agents:
Methods
discover(url)
Fetches
{url}/.well-known/agent.json and parses the Agent Cardsend_task(...)
Sends a JSON-RPC task submission
get_task(...)
Polls for task status
Auto-Discovery at Boot
When the kernel starts and A2A is enabled with external agents configured:1
Create client
Creates an
A2aClient2
Iterate agents
Iterates each configured
ExternalAgent3
Fetch cards
Fetches each agent’s card from
{url}/.well-known/agent.json4
Log discoveries
Logs successful discoveries (name, URL, skill count)
5
Store results
Stores discovered
(name, AgentCard) pairs in kernel.a2a_external_agentsFailed discoveries are logged as warnings but do not prevent boot.
Sending Tasks to External Agents
Task Lifecycle
AnA2aTask tracks the full lifecycle of a cross-agent interaction:
Task States
Message Format
Messages use an A2A-specific format with typed content parts:Artifacts
Tasks can produce artifacts (files, structured data) alongside messages:A2A Configuration
A2A is configured inconfig.toml under the [a2a] section:
Configuration Fields
External Agent Configuration
If
a2a is None (not present in config), all A2A features are disabled. The A2A endpoints are always registered in the router but discovery and task store functionality requires enabled = true.A2A API Endpoints
GET /.well-known/agent.json
Returns the Agent Card for the first registered agent. If no agents are spawned, returns a placeholder card.GET /a2a/agents
Lists all registered agents as Agent Cards:POST /a2a/tasks/send
Submit a task. Request body follows JSON-RPC 2.0 format:GET /a2a/tasks/
Poll for task status. Returns404 if the task is not found or has been evicted.
POST /a2a/tasks//cancel
Cancel a running task. Sets its status toCancelled. Returns 404 if the task is not found.
Security
Rate Limiting
A2A endpoints go through the same GCRA rate limiter as all other API endpoints.
API Authentication
When
api_key is set in kernel config, all API endpoints (including A2A) require Authorization: Bearer <key> header. Exception: /.well-known/agent.json and health endpoint.Task Store Bounds
A2aTaskStore is bounded (default 1000 tasks) with FIFO eviction of completed/failed/cancelled tasks, preventing memory exhaustion.External Agent Discovery
A2aClient uses 30-second timeout and sends User-Agent: OpenFang/0.1 A2A header. Failed discoveries are logged but do not block kernel boot.Kernel-Level Protection
A2A tool execution flows through the same security pipeline as all other tool calls: capability-based access control, tool result truncation (50K character hard cap), universal 60-second timeout, loop guard detection, and taint tracking.
Source Files
- Protocol types and logic:
crates/openfang-runtime/src/a2a.rs - API routes:
crates/openfang-api/src/routes.rs - Config types:
crates/openfang-types/src/config.rs