Agent-to-Agent (A2A) Communication
ASTRA agents in the same program communicate with ASTRA messages. Agents built with other frameworks, and running in other processes, need a shared protocol. The Agent2Agent (A2A) protocol is an open standard for this: it lets an agent advertise what it can do, accept tasks from other agents and return results over HTTP, whatever framework each agent is built with.
The astra-langchain4j-tools library connects ASTRA to A2A. An ASTRA agent can publish skills as an A2A service and call other A2A agents, using ordinary rules, goals and events. The library is built on the official A2A Java SDK and implements version 1.0 of the protocol over JSON-RPC.
The service and client walkthroughs below describe the earlier standalone API and retain their example versions. For ASTRA 2.8.4, shared A2A declarations and native runtime contracts live in astra-langchain4j, while standalone infrastructure lives in astra-langchain4j-tools. Use the current A2A example project for current source, and see unified capabilities and MAMS integrations for the new integration paths.
A2A concepts
Concept |
Meaning |
|---|---|
AgentCard |
A JSON document that describes an agent: its name, description, version, the content types it accepts and returns, and its skills. A service publishes its card at |
Skill |
Something the agent can do, with an identifier, a name, a description, tags and example inputs |
Message |
A request sent to the agent. Its content is made of parts: text, structured data or files |
Task |
The unit of work created for a request. A task moves through states such as working, completed, failed or canceled. Progress updates are reported on the task, and the result is returned as one or more artifacts |
How ASTRA fits
The library fixes a small set of conventions so that the application only writes agent code:
Requests and results are JSON objects. A request may carry one text part or one data part. A text part
Adareaches the agent as{"text":"Ada"}; a data part reaches it unchanged. The agent returns one JSON object, which becomes the task’s single artifact.A service is an ASTRA class. It declares the AgentCard and its skills with actions of the
A2Amodule, and handles requests with rules.Each request has its own agent. The library creates a worker agent of the service class for each incoming task and terminates it when the task ends. Requests do not share state through the worker’s beliefs.
A2A interaction arrives as events. An incoming request is a
$a2a.request(...)event. Results of an outgoing call are$a2a.response(...),$a2a.failure(...)and$a2a.progress(...)events. Network I/O runs on separate threads, so no intention is blocked while a request is in flight.
A service process looks like this:
A2A client (any framework)
│ HTTP: AgentCard, SendMessage, GetTask, CancelTask
▼
┌─────────────────── service process ────────────────────┐
│ A2A JSON-RPC server (Quarkus + A2A Java SDK) │
│ │ │
│ Manager agent ── creates ──► describer agent │
│ │ declares the AgentCard │
│ └── creates per task ──► worker agent │
│ $a2a.request(...) │
│ a2a.progress / a2a.complete │
└────────────────────────────────────────────────────────┘
When the service starts, the library’s Manager agent creates an agent of the service class, named a2a-description, with the main goal ["describe"]. That agent declares the card and skills and publishes them. For each task, the manager creates a worker named a2a-worker-<task id> from the class that declared the requested skill, with the main goal [id, contextId, skill, payload]. The worker asks to receive the request as an event, handles it, and reports progress, completion or failure. The manager then retires the worker.
The client side needs no server. Any ASTRA agent with the A2A module can send a request to an A2A service and handle the reply as events.
Current scope
The library supports:
new tasks, sent as blocking requests or as immediate responses followed by polling;
progress updates, streaming over server-sent events, and task cancellation;
text or JSON requests, and JSON object results;
AgentCard discovery, including from non-ASTRA A2A clients and servers.
Push notifications, continuing an existing task, and authenticated deployment are not yet supported. The examples in this section bind the service to the local machine and disable authorization; do not expose such a service on a network.
The default runtime hosts one service class per process and runs at most four tasks at a time. A request is limited to 8,000 characters of JSON, and a task that takes more than 60 seconds fails. Outgoing calls use four I/O threads with a queue of sixteen calls. Canceling a task discards its result and retires the worker, but a model call that is already running is not interrupted.
The A2A SDK can represent integers in JSON data as floating-point numbers. Read transported numbers with valueAsDouble, or send them as strings when the exact representation matters.
In this section
Publishing an A2A service builds an ASTRA service, calls it with
curl, and puts a reasoning agent behind a skill.Calling A2A services calls a service from an ASTRA agent and uses a remote agent as a ReAct tool.
The complete A2A example project combines both: a MultiStepChainOfThought solver published as an A2A service, and a ReAct coordinator that calls it. It also includes tests against non-ASTRA A2A agents.