You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6afc62d
Browse filesBrowse the repository at this point in the historyBrowse files
LCORE-2914: add A2A client support for external agent delegation
Enable LCS to discover and delegate tasks to external A2A-compliant
agents. The delegation is exposed as a pydantic-ai capability, so any
agent-powered endpoint (query, streaming, A2A) can use it.
- A2AAgentsConfiguration: YAML config for remote agent endpoints
with timeout, max_retries, and optional auth_token
- A2AClientManager: singleton that resolves agent cards at startup
and holds Client instances with httpx timeout/retry transport
- A2ADelegationCapability: pydantic-ai tools (list_agents,
delegate_to_agent) auto-injected into build_agent()
- Startup/shutdown lifecycle wired into FastAPI lifespan
- A2A protocol docs updated with client documentation
- OpenAPI schema regenerated
- Example config: examples/lightspeed-stack-a2a-agents.yaml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/devel_doc/openapi.json
+80Lines changed: 80 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -10874,6 +10874,74 @@
10874
10874
},
10875
10875
"components": {
10876
10876
"schemas": {
10877
+
"A2AAgentEndpointConfiguration": {
10878
+
"properties": {
10879
+
"name": {
10880
+
"type": "string",
10881
+
"title": "Agent name",
10882
+
"description": "Unique identifier for this agent, used by the delegation tool."
10883
+
},
10884
+
"url": {
10885
+
"type": "string",
10886
+
"minLength": 1,
10887
+
"format": "uri",
10888
+
"title": "Agent URL",
10889
+
"description": "Base URL of the external A2A agent."
10890
+
},
10891
+
"auth_token": {
10892
+
"anyOf": [
10893
+
{
10894
+
"type": "string",
10895
+
"format": "password",
10896
+
"writeOnly": true
10897
+
},
10898
+
{
10899
+
"type": "null"
10900
+
}
10901
+
],
10902
+
"title": "Auth token",
10903
+
"description": "Static bearer token for authenticating with this agent."
10904
+
},
10905
+
"timeout": {
10906
+
"type": "integer",
10907
+
"exclusiveMinimum": 0.0,
10908
+
"title": "Request timeout",
10909
+
"description": "Timeout in seconds for requests to this agent. Default is 30 seconds.",
10910
+
"default": 30
10911
+
},
10912
+
"max_retries": {
10913
+
"type": "integer",
10914
+
"minimum": 0.0,
10915
+
"title": "Maximum retries",
10916
+
"description": "Maximum number of retry attempts on transient failures. Set to 0 to disable retries.",
10917
+
"default": 3
10918
+
}
10919
+
},
10920
+
"additionalProperties": false,
10921
+
"type": "object",
10922
+
"required": [
10923
+
"name",
10924
+
"url"
10925
+
],
10926
+
"title": "A2AAgentEndpointConfiguration",
10927
+
"description": "Configuration for a single external A2A agent endpoint.\n\nAttributes:\n name: Agent identifier used in delegation tool calls.\n url: Base URL of the A2A agent.\n auth_token: Optional static bearer token for authenticating with this agent.\n timeout: Request timeout in seconds for this agent.\n max_retries: Maximum retry attempts on transient failures."
Copy file name to clipboardExpand all lines: docs/user_doc/a2a_protocol.md
+91-4Lines changed: 91 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,10 @@ This document describes the A2A (Agent-to-Agent) protocol implementation in Ligh
4
4
5
5
## Overview
6
6
7
-
The A2A protocol is an open standard for agent-to-agent communication that allows different AI agents to discover, communicate, and collaborate with each other. Lightspeed Core Stack implements the A2A protocol to expose its AI capabilities to other agents and systems.
7
+
The A2A protocol is an open standard for agent-to-agent communication that allows different AI agents to discover, communicate, and collaborate with each other. Lightspeed Core Stack implements both sides of the A2A protocol:
8
+
9
+
-**A2A Server**: Other agents can call LCS to leverage its AI capabilities, MCP tools, and RAG
10
+
-**A2A Client**: LCS can discover and delegate tasks to external A2A-compliant agents during inference
8
11
9
12
### Key Concepts
10
13
@@ -310,8 +313,8 @@ The `A2AAgentExecutor` class implements the A2A `AgentExecutor` interface:
310
313
311
314
1. **Receives A2A Request**: Extracts user input from the A2A message
312
315
2. **Creates Query Request**: Builds an internal `QueryRequest` with conversation context
313
-
3. **Calls Llama Stack**: Uses the Responses API to get streaming responses
314
-
4. **Converts Events**: Transforms Responses API streaming chunks to A2A events
316
+
3. **Builds Pydantic-AI Agent**: Uses `build_agent()` with the same capabilities as the query/streaming endpoints (skills, A2A delegation)
317
+
4. **Streams via Agent**: Runs `agent.run_stream_events()` and converts pydantic-ai events to A2A events
315
318
5. **Manages State**: Tracks task state and publishes status updates
316
319
317
320
### Event Flow
@@ -786,8 +789,92 @@ protocolVersion: "0.3.0"
786
789
787
790
The protocol version is included in the agent card response and indicates which version of the A2A protocol specification the agent implements.
788
791
792
+
## A2A Client: Delegating to Remote Agents
793
+
794
+
LCS can also act as an **A2A client**, discovering and delegating tasks to external A2A-compliant agents during inference. This enables multi-agent orchestration where a single LCS instance coordinates work across specialized agents.
| `timeout` | int | 30 | Request timeout in seconds |
848
+
| `max_retries` | int | 3 | Retry attempts on connection failures |
849
+
850
+
### How It Works
851
+
852
+
1. **Startup**: LCS connects to each configured agent, fetches its agent card, and caches its capabilities.
853
+
854
+
2. **Tool registration**: An `A2ADelegationCapability` is added to the pydantic-ai agent (used by query, streaming, and A2A endpoints) with two tools:
855
+
- `list_agents()`— returns agent names and descriptions
856
+
- `delegate_to_agent(agent_name, task)`— sends a task to a remote agent via A2A and returns its response
857
+
858
+
3. **Runtime**: The LLM decides when to delegate based on the agent descriptions injected into the system prompt. It can delegate to one or multiple agents per turn.
859
+
860
+
4. **Parallel delegation**: If the LLM emits multiple `delegate_to_agent` calls in one response, they run concurrently.
861
+
862
+
5. **Error handling**: If a remote agent is unavailable or times out, the tool returns an error message to the LLM, which can try another agent or answer directly.
863
+
864
+
### Authentication
865
+
866
+
The orchestrator authenticates to remote agents using **service account credentials** (the `auth_token` field), not end-user tokens. Each remote agent validates the token using its own authentication module.
867
+
868
+
| Scenario | Configuration |
869
+
|----------|---------------|
870
+
| No auth (internal network) | Omit `auth_token` |
871
+
| Static bearer token | Set `auth_token` in YAML |
0 commit comments