Expand description
A2A Server - handler functions for the Agent-to-Agent protocol.
Provides A2AServer which holds an underlying agent (a BaseChain) and
exposes handler functions that can be plugged into any HTTP framework
(axum, actix, warp, etc.) rather than running its own server.
§Endpoints
GET /.well-known/agent-card.json-> returnsAgentCard(viaget_agent_card)POST /-> acceptsA2ARequest, dispatches, returnsA2AResponse(viahandle_a2a_request/handle_a2a_request_authenticated)
§Task Model
tasks/send follows the A2A asynchronous task lifecycle. The request is
acknowledged immediately with a submitted task and the chain runs in the
background, transitioning the task submitted -> working -> completed
(or failed). Poll tasks/get to observe progress. Every transition is
guarded by the TaskStatus state machine, so a task cancelled while the
chain is still running is never clobbered back to a live state.
§Multi-turn & Input-Required (P2-2/P2-3)
Re-sending tasks/send with a taskId appends a message to the existing
task’s history and re-runs the chain over the whole conversation. A chain
that needs more information returns a ChainError::MissingInput /
ChainError::InputError, which the server maps to the input-required
state; the client then resumes with tasks/send {taskId, message}.
§Ownership & Idempotency (P1-4/P1-6)
Tasks carry an optional owner taken from request metadata. tasks/get
and tasks/cancel from a caller whose metadata owner does not match the
task’s are rejected (-32003). A message_id in request metadata makes
tasks/send idempotent: re-sending the same id returns the already
created task instead of running the chain twice.
§Task Persistence (P1-1)
Tasks are stored through the TaskStore trait, defaulting to an
in-memory InMemoryTaskStore shared with background workers. Swap in
your own backend with A2AServer::with_store. Terminal tasks older than
the configured TTL are cleaned up lazily on read access.
§Streaming (P2-1)
Enable A2AServer::with_streaming to get a broadcast channel of
TaskPushNotifications (subscribe()), which an HTTP layer can expose
as an SSE endpoint. The agent card then advertises {"sse": true}.
§Skill routing (P2-4)
A2AServer::with_skill_router dispatches tasks/send requests that
carry a skillId param to a different chain based on the card’s skills.
§Example
use lc_a2a::{A2AServer, AgentCard};
use lc_chains::LLMChain;
use std::sync::Arc;
let chain = Arc::new(LLMChain::new(llm, "You are a helpful assistant"));
let server = A2AServer::new(chain)
.with_card(AgentCard::new("my-agent", "A helpful agent", "http://localhost:8080"));
// In your HTTP handler:
let response = server.handle_a2a_request(request).await;Structs§
- A2AServer
- A2A Server - wraps an agent and provides handler functions.