Configuring A2A Agent Protocol for Task Delegation in OmniRoute
To configure A2A agent protocol for task delegation in OmniRoute, enable the A2A_ENABLED feature flag and use the JSON-RPC endpoint at /api/a2a to submit tasks with a specified skill and messages.
OmniRoute ships a built-in A2A (Agent-to-Agent) server that exposes a JSON-RPC 2.0 endpoint together with a REST wrapper for status inspection. This system enables external agents to delegate work to OmniRoute by sending structured task descriptions, selecting from available skills, and receiving generated artifacts. According to the OmniRoute source code, the A2A subsystem is organized into distinct layers for task lifecycle management, skill dispatch, and protocol entry points.
Enabling the A2A Server
The A2A server is gated by the feature flag A2A_ENABLED, which defaults to false. To activate task delegation capabilities, set the environment variable or update the feature flag definition.
Set via environment variable:
A2A_ENABLED=1
Or modify src/shared/constants/featureFlagDefinitions.ts to enable the flag permanently.
Once enabled, verify activation by checking the REST status endpoint:
curl /api/a2a/status
This returns A2ATaskStats and confirms that A2A is active.
How the A2A Task Delegation Protocol Works
The A2A implementation in OmniRoute follows a strict three-layer architecture:
1. Task Lifecycle Management (A2ATaskManager)
Located in src/lib/a2a/taskManager.ts, the A2ATaskManager class handles:
- UUID v4 assignment for each incoming task
- State tracking through
submitted → working → completed|failed|cancelled - TTL enforcement with a default 5-minute expiration
- Automatic cleanup of expired or terminal tasks
The state machine uses VALID_TRANSITIONS to prevent illegal state jumps, ensuring deterministic task progression.
2. Skill Dispatch (A2A_SKILL_HANDLERS)
The registry in src/lib/a2a/taskExecution.ts maps skill strings to async handlers. Six built-in skills are available under src/lib/a2a/skills/:
| Skill | Purpose |
|---|---|
smart-routing |
Intelligent request routing decisions |
quota-management |
Usage limit enforcement and tracking |
provider-discovery |
Available model/provider enumeration |
cost-analysis |
Pricing estimation and comparison |
health-report |
System status and diagnostic reporting |
list-capabilities |
Available feature enumeration |
3. JSON-RPC Entry Point (/api/a2a)
The Next.js App Router route in src/app/api/a2a/route.ts accepts JSON-RPC 2.0 requests with this structure:
{
"jsonrpc": "2.0",
"method": "task",
"id": "<uuid>",
"params": {
"skill": "<skill-name>",
"messages": [{"role": "...", "content": "..."}]
}
}
The handler:
- Creates a task via
getTaskManager().createTask() - Dispatches to
A2A_SKILL_HANDLERS[skill] - Executes via
executeA2ATaskWithState() - Returns artifacts or error in the JSON-RPC response
4. Agent Discovery (.well-known/agent.json)
The REST endpoint in src/app/api/a2a/status/route.ts returns the agent card—a public manifest containing name, description, capabilities, skill catalog, and authentication scheme. This is cached for one hour and requires no authentication, allowing any A2A-compatible client to discover OmniRoute's delegation capabilities.
Task Delegation Flow
The complete sequence for A2A task delegation:
- Client sends JSON-RPC request to
/api/a2awith skill and messages - Router creates task via
getTaskManager().createTask()→ statesubmitted - Skill handler executes — dynamically imports from
src/lib/a2a/skills/and runs - State transitions to
completed(withTaskArtifacts) orfailed(with error) - JSON-RPC response returns artifacts as text, JSON, or structured error
Implementing A2A Task Delegation
TypeScript Client Example
Submit a task programmatically using a JSON-RPC helper:
import { jsonRpc } from '@omniroute/open-sse';
async function runSmartRouting(messages: { role: string; content: string }[]) {
const response = await jsonRpc.post('/api/a2a', {
jsonrpc: '2.0',
method: 'task',
id: crypto.randomUUID(),
params: {
skill: 'smart-routing',
messages,
},
});
// response.result contains artifacts generated by the skill
console.log('Artifacts:', response.result.artifacts);
}
CLI Inspection Commands
# Display the public agent card for discovery
omniroute a2a status card
# Submit a task and monitor state progression
omniroute a2a task submit \
--skill smart-routing \
--message "You are a helpful assistant."
Extending A2A with Custom Skills
Add domain-specific capabilities by creating a new skill module and registering it in the handler map.
Create src/lib/a2a/skills/myCustomSkill.ts:
import type { A2ATask, TaskArtifact } from '../taskManager';
export async function executeMyCustomSkill(task: A2ATask): Promise<{
artifacts: TaskArtifact[];
metadata: Record<string, unknown>;
}> {
const result = `Echo: ${task.input.messages[0].content}`;
return {
artifacts: [{ type: 'text', content: result }],
metadata: { echoLength: result.length },
};
}
Register in src/lib/a2a/taskExecution.ts by adding to A2A_SKILL_HANDLERS:
"my-custom-skill": async (task) =>
import('./skills/myCustomSkill').then(m => m.executeMyCustomSkill(task))
Configuration Reference
| File | Purpose |
|---|---|
src/lib/a2a/taskManager.ts |
Task lifecycle, TTL cleanup, stats aggregation |
src/lib/a2a/taskExecution.ts |
Skill registry and executeA2ATaskWithState |
src/lib/a2a/skills/* |
Built-in and custom skill implementations |
src/app/api/a2a/route.ts |
JSON-RPC protocol entry point |
src/app/api/a2a/status/route.ts |
REST agent card and statistics |
docs/frameworks/A2A-SERVER.md |
Design and extension guide |
Summary
- Enable A2A by setting
A2A_ENABLED=1or updating feature flags - Submit tasks via JSON-RPC to
/api/a2awith askillparameter and message array - Track lifecycle through
A2ATaskManagerstates with automatic TTL cleanup - Discover capabilities via the unauthenticated
.well-known/agent.jsonendpoint - Extend functionality by adding TypeScript modules to
src/lib/a2a/skills/and registering inA2A_SKILL_HANDLERS
Frequently Asked Questions
What is the A2A protocol in OmniRoute?
The A2A (Agent-to-Agent) protocol is a JSON-RPC 2.0 based task delegation system that allows external agents to offload work to OmniRoute. It provides structured task submission, skill-based routing, stateful tracking, and artifact retrieval through a publicly discoverable agent card.
How do I enable the A2A server in OmniRoute?
Set the environment variable A2A_ENABLED=1 before starting OmniRoute, or modify src/shared/constants/featureFlagDefinitions.ts to change the default. Verify activation by querying /api/a2a/status for task statistics and server confirmation.
What skills are available for A2A task delegation?
OmniRoute includes six built-in skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, and list-capabilities. Custom skills can be added by implementing an async handler in src/lib/a2a/skills/ and registering it in A2A_SKILL_HANDLERS.
How long do A2A tasks persist in OmniRoute?
Tasks have a default TTL of 5 minutes as enforced by A2ATaskManager in src/lib/a2a/taskManager.ts. Expired or terminal tasks are automatically cleaned up from the in-memory store.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →