⚠️ EXPERIMENTAL — Issue #5302 D1 scope
The A2A Gateway is Experimental as of Sub-PR D1 (issue #5302). The gateway now persists tasks through the unified
TaskStore(issue #5301 Sub-PR A/C) and bridges A2A publish/subscribe onto the Runtime viaEventMeshA2ATransport— there is no longer a parallel in-memory transport. However, the following pieces land in follow-up PRs and are required before the gateway is suitable for production use:
- TaskExpirer reaper (Sub-PR D2): periodic
TaskStore.expireStale()sweep so terminal tasks do not accumulate in the Meta store.- AgentCard Meta-ization (Sub-PR D2):
A2APublishSubscribeServicestill uses an in-memoryConcurrentHashMapfor the agent-card registry; production needs a Meta-backedSessionStore(Sub-PR A) or equivalent.- End-to-end Testcontainers test (Sub-PR D2): fault-injection under a real Meta + Runtime wiring.
Until all three land, treat the gateway as Experimental — wire it up against the
MetaBackedTaskStoreonly on dev clusters.Canonical maturity level: Experimental — see the capability status table.
The EventMesh A2A (Agent-to-Agent) Protocol is a specialized, high-performance protocol plugin designed to enable asynchronous communication, collaboration, and task coordination between autonomous agents.
With the release of v2.0, A2A adopts the MCP (Model Context Protocol) architecture, transforming EventMesh into a robust Agent Collaboration Bus. It bridges the gap between synchronous LLM-based tool calls (JSON-RPC 2.0) and asynchronous Event-Driven Architectures (EDA), enabling scalable, distributed, and decoupled agent systems.
The architecture adheres to the principles outlined in the broader agent community (e.g., A2A Project, FIPA-ACL, and CloudEvents):
Traditional A2A implementations often rely on HTTP Webhooks (POST /inbox) for asynchronous callbacks. While functional, this Point-to-Point (P2P) model suffers from significant scaling issues:
EventMesh A2A solves this by introducing Native Pub/Sub capabilities:
A2A Protocol introduces a unique Hybrid Architecture that bridges the gap between the AI ecosystem (which prefers simple JSON) and the Cloud Native ecosystem (which prefers structured CloudEvents).
| Feature | JSON-RPC 2.0 Mode | Native CloudEvents Mode |
|---|---|---|
| Primary Audience | LLMs, Scripts (Python/JS), LangChain | EventMesh Apps, Knative, Java SDK |
| Philosophy | “Battery Included” | “Power User” |
| Usage | Send raw JSON ({"method":...}) | Send CloudEvent object |
| Complexity | Low (No SDK required) | Medium (Requires CE SDK) |
| Mechanism | Adaptor automatically wraps JSON in CE | Adaptor passes through the event |
Benefits:
curl or simple JSON libraries.eventmesh-protocol-a2a)The core protocol logic resides in the eventmesh-protocol-plugin module.
EnhancedA2AProtocolAdaptor: The central brain of the protocol.CloudEvents or HTTP adaptors when necessary.A2AProtocolConstants: Defines standard operations like task/get, message/sendStream.JsonRpc* Models: Strictly typed POJOs for JSON-RPC 2.0 compliance.AgentCard / AgentSkill / AgentInterface: Agent capability discovery models.A2ATopicFactory: Topic naming and parsing utility (request/response/status topics).A2AClient: Java SDK for agent developers — AgentCard registration, task submission (sync/async), task status query, heartbeat, and transport-based request handling. Returns typed TaskResult objects.A2AMessageTransport: Transport-agnostic pub/sub interface (InMemory implementation for dev/testing).eventmesh-runtime)The Gateway runtime provides a standalone HTTP server that bridges external clients to the A2A event bus.
| Component | Module | Responsibility |
|---|---|---|
A2AGatewayServer | runtime | Standalone Netty HTTP server entry point. Pre-registers mock agents, wires all components. |
A2AGatewayHttpHandler | runtime | HTTP request router. Maps REST endpoints to service calls. Supports SSE streaming. |
A2AGatewayService | runtime | Core orchestration: task submission, response handling, status subscription, SSE push. |
TaskRegistry | runtime | In-memory task lifecycle state machine with TTL auto-cleanup. |
A2APublishSubscribeService | runtime | AgentCard registration, discovery, and heartbeat management. |
InMemoryA2AMessageTransport | runtime | In-memory pub/sub implementation (replaceable by EventMesh broker). |
A2ACardHttpHandler | runtime | AgentCard CRUD REST endpoints (/a2a/cards/*). |
A2AClient | protocol-a2a | Java SDK for agent developers (HTTP + transport). |
SUBMITTED → WORKING → COMPLETED
↘ FAILED
↘ CANCELLED
ScheduledExecutorService runs cleanup every 60 seconds, preventing memory leaks from accumulated historical tasks.A2AGatewayService.submitTask(), the pending future is registered (pendingTasks.put()) before transport.publish(). This ordering is critical because InMemoryTransport delivers messages synchronously — if publish happened first, handleResponse() could execute before put() and the future would never complete.| Method | Path | Description |
|---|---|---|
POST | /a2a/tasks?mode=sync | Submit task synchronously (wait for result, 30s timeout) |
POST | /a2a/tasks?mode=async | Submit task asynchronously (return taskId immediately) |
GET | /a2a/tasks/{taskId} | Get task status and result |
DELETE | /a2a/tasks/{taskId} | Cancel a task |
GET | /a2a/tasks/{taskId}/wait | Long-poll wait for task result (configurable timeout) |
GET | /a2a/tasks/{taskId}/stream | SSE stream of task status updates (text/event-stream) |
GET | /a2a/agents | List all registered agents |
POST | /a2a/heartbeat | Agent heartbeat (keeps AgentCard alive) |
GET | /a2a/cards/list | List all AgentCards |
POST | /a2a/cards/card/{org}/{unit}/{agent} | Register an AgentCard |
The GET /a2a/tasks/{taskId}/stream endpoint provides real-time task status updates via Server-Sent Events:
Accept: text/event-stream.data: events.The handler writes directly to the Netty channel (returns null to skip the default writeAndFlush path), using DefaultHttpContent chunks with text/event-stream content type.
The A2AClient provides a typed Java API for agent developers:
A2AClient client = A2AClient.builder() .gatewayUrl("http://localhost:10105") .namespace("global") .agentName("my-agent") .agentCard(card) .heartbeatInterval(30_000) .build(); client.start(); // Typed return: TaskResult instead of raw JSON TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null); String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null); TaskResult status = client.getTaskStatus(taskId); List<String> agents = client.listAgents(); // typed List<String> boolean ok = client.cancelTask(taskId);
TaskResult uses @JsonAlias("result") to handle the server's result field name while exposing a data property to callers.
To support MCP on an Event Bus, synchronous RPC concepts are mapped to asynchronous events:
| Concept | MCP / JSON-RPC | CloudEvent Mapping |
|---|---|---|
| Action | method (e.g., tools/call) | Type: org.apache.eventmesh.a2a.tools.call.reqExtension: a2amethod |
| Correlation | id (e.g., req-123) | Extension: collaborationid (on Response)ID: Preserved on Request |
| Direction | Implicit (Request vs Result) | Extension: mcptype (request or response) |
| P2P Routing | params._agentId | Extension: targetagent |
| Pub/Sub Topic | params._topic | Subject: The topic value (e.g. market.btc) |
| Streaming Seq | params._seq | Extension: seq |
ProtocolTransportObject (byte array/string).jsonrpc: "2.0".method.message/sendStream, sets type suffix to .stream and extracts _seq._topic present, sets subject (Pub/Sub)._agentId present, sets targetagent (P2P).result/error. Sets collaborationid = id.List<CloudEvent>._agentId or _topic from JSON body to CloudEvent attributes.message/sendStream.stream event type and preserves sequence order via seq extension attribute.GET /a2a/tasks/{taskId}/streamtext/event-stream) pushes real-time task state transitions to the client.DefaultHttpContent chunks directly to the Netty channel, bypassing the standard FullHttpResponse path.TaskRegistry indefinitely, causing memory leaks.ScheduledExecutorService (a2a-task-ttl-cleanup thread) runs every 60 seconds, removing terminal-state tasks older than the TTL (default: 5 minutes).TaskRegistry(taskTtlMs, cleanupIntervalMs) constructor allows custom tuning.POST /a2a/cards/card/{org}/{unit}/{agent} registers an AgentCard.POST /a2a/heartbeat refreshes the agent's last-seen timestamp. Cards expire after 60 seconds without heartbeat.GET /a2a/agents returns all live agent cards.This mode is ideal for LLMs, scripts, and simple integrations where you want to send raw JSON without worrying about CloudEvent headers.
Client Sends (Raw JSON):
{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "weather", "city": "Shanghai", "_agentId": "weather-agent" }, "id": "req-101" }
EventMesh Converts to:
org.apache.eventmesh.a2a.tools.call.reqweather-agentrequestClient Sends (Raw JSON):
{ "jsonrpc": "2.0", "method": "notifications/alert", "params": { "message": "System Maintenance in 10 mins", "_topic": "system.alerts" } }
EventMesh Converts to:
org.apache.eventmesh.a2a.notifications.alertsystem.alertsnotification// See eventmesh-examples/src/main/java/org/apache/eventmesh/a2a/demo/mcp/McpCaller.java Map<String, Object> request = new HashMap<>(); request.put("jsonrpc", "2.0"); request.put("method", "tools/call"); request.put("params", Map.of("name", "weather", "_agentId", "weather-agent")); request.put("id", UUID.randomUUID().toString()); CloudEvent event = CloudEventBuilder.v1() .withType("org.apache.eventmesh.a2a.tools.call.req") .withData(JsonUtils.toJSONString(request).getBytes()) .withExtension("protocol", "A2A") // Critical to trigger A2A adaptor .build(); producer.publish(event);
This mode provides full control over all CloudEvent attributes and is recommended for robust, typed applications using the EventMesh SDK.
Client Sends (CloudEvent):
{ "specversion": "1.0", "type": "com.example.rpc.request", "source": "my-app", "id": "evt-123", "data": "...", "protocol": "A2A", "targetagent": "target-agent-001" }
Java SDK Example:
// See eventmesh-examples/src/main/java/org/apache/eventmesh/a2a/demo/ce/CloudEventsCaller.java CloudEvent event = CloudEventBuilder.v1() .withId(UUID.randomUUID().toString()) .withSource(URI.create("ce-client")) .withType("com.example.rpc.request") .withData("application/text", "RPC Payload".getBytes()) .withExtension("protocol", "A2A") .withExtension("targetagent", "target-agent-001") // Explicit routing .build(); producer.publish(event);
Client Sends (CloudEvent):
{ "specversion": "1.0", "type": "com.example.notification", "source": "my-app", "subject": "broadcast.topic", "protocol": "A2A" }
Client Sends (CloudEvent):
{ "specversion": "1.0", "type": "com.example.stream", "source": "my-app", "subject": "stream-topic", "protocol": "A2A", "sessionid": "session-555", "seq": "1" }
The A2A Gateway provides a REST API for external clients and non-Java agents.
curl -X POST 'http://localhost:10105/a2a/tasks?mode=sync' \ -H 'Content-Type: application/json' \ -d '{"targetAgent":"weather-agent","message":"Beijing"}'
Response:
{ "taskId": "task-a1b2c3d4", "state": "COMPLETED", "data": "The weather in Beijing is sunny, 25°C" }
curl -X POST 'http://localhost:10105/a2a/tasks?mode=async' \ -H 'Content-Type: application/json' \ -d '{"targetAgent":"weather-agent","message":"Shanghai"}'
Response (HTTP 202):
{ "taskId": "task-e5f6g7h8", "status": "accepted", "message": "Task submitted. Use GET /a2a/tasks/task-e5f6g7h8 to check status." }
curl -N http://localhost:10105/a2a/tasks/task-a1b2c3d4/stream
Response (text/event-stream):
data: {"taskId":"task-a1b2c3d4","state":"SUBMITTED"}
data: {"taskId":"task-a1b2c3d4","state":"WORKING","data":"processing..."}
data: {"taskId":"task-a1b2c3d4","state":"completed","data":"The weather in Beijing is sunny, 25°C"}
curl http://localhost:10105/a2a/agents
A2AClient client = A2AClient.builder() .gatewayUrl("http://localhost:10105") .namespace("global") .agentName("my-agent") .agentCard(card) .heartbeatInterval(30_000) .build(); client.start(); // Synchronous task (returns typed TaskResult) TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null); // Asynchronous task (returns taskId immediately) String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null); // Poll status TaskResult status = client.getTaskStatus(taskId); // Cancel boolean cancelled = client.cancelTask(taskId); // List registered agents (typed List<String>) List<String> agents = client.listAgents(); client.shutdown();
InMemoryA2AMessageTransport with the real EventMesh broker for production deployment.methods/list.TaskRegistry state to a durable store (Redis/DB) for crash recovery.A2A 协议已成功重构为采用 MCP (Model Context Protocol) 架构,将 EventMesh 定位为现代化的 智能体协作总线 (Agent Collaboration Bus)。
EnhancedA2AProtocolAdaptor)jsonrpc 字段自动分发处理逻辑。*.req 事件,属性 mcptype=request。*.resp 事件,属性 mcptype=response。id 映射到 CloudEvent collaborationid 来处理。params._agentId -> CloudEvent 扩展属性 targetagent (P2P)。params._topic -> CloudEvent Subject (Pub/Sub)。_topic 映射到 CloudEvent Subject,支持 O(1) 广播复杂度。message/sendStream 操作,映射为 .stream 事件类型,并通过 _seq -> seq 扩展属性保证顺序。JsonRpcRequest、JsonRpcResponse、JsonRpcError POJO 对象。McpMethods 常量,支持标准操作如 tools/call、resources/read。AgentCard、AgentSkill、AgentInterface、AgentCapabilities 等完整的 Agent 能力描述模型。eventmesh-runtime)完整的独立 HTTP Gateway 服务,桥接外部客户端到 A2A 事件总线。
| 组件 | 职责 |
|---|---|
A2AGatewayServer | Netty HTTP 服务器入口,预注册 mock agent,组装所有组件 |
A2AGatewayHttpHandler | HTTP 请求路由,支持 SSE 流式响应 |
A2AGatewayService | 核心编排:任务提交、响应处理、状态订阅、SSE 推送 |
TaskRegistry | 内存任务状态机 + TTL 自动清理 |
A2APublishSubscribeService | AgentCard 注册、发现、心跳管理 |
InMemoryA2AMessageTransport | 内存 pub/sub 实现(可替换为 EventMesh broker) |
A2ACardHttpHandler | AgentCard CRUD REST 端点 |
A2AClient | Java SDK,提供类型化 API |
| 方法 | 路径 | 说明 |
|---|---|---|
POST | /a2a/tasks?mode=sync | 同步提交任务 |
POST | /a2a/tasks?mode=async | 异步提交任务 |
GET | /a2a/tasks/{taskId} | 查询任务状态 |
DELETE | /a2a/tasks/{taskId} | 取消任务 |
GET | /a2a/tasks/{taskId}/wait | 长轮询等待结果 |
GET | /a2a/tasks/{taskId}/stream | SSE 流式推送状态更新 |
GET | /a2a/agents | 列出已注册 agents |
POST | /a2a/heartbeat | Agent 心跳 |
GET | /a2a/cards/list | 列出所有 AgentCard |
POST | /a2a/cards/card/{org}/{unit}/{agent} | 注册 AgentCard |
ScheduledExecutorService 每 60 秒扫描一次,清理超过 TTL(默认 5 分钟)的终态任务。TaskRegistry(taskTtlMs, cleanupIntervalMs) 构造函数支持自定义调优。InMemoryTransport 同步投递消息,若 transport.publish() 在 pendingTasks.put() 之前执行,handleResponse() 会先于 put() 运行,导致 future 永不完成。pendingTasks.put(taskId, future) 在 transport.publish() 之前执行,并添加注释说明顺序重要性。getTaskStatus() 返回 TaskResult 对象(而非原始 JSON 字符串),listAgents() 返回 List<String>(而非原始 JSON)。TaskResult.data 字段使用 @JsonAlias("result") 注解,兼容服务端 result 字段名。GET /a2a/tasks/{taskId}/streamDefaultHttpContent chunks),返回 null 跳过标准 FullHttpResponse 路径。通过 StatusSubscriber 回调实时推送状态变更。eventmesh-examples/.../demo/README.md,包含架构图、API 表、curl 示例、SDK 用法、运行方式。EnhancedA2AProtocolAdaptorTest 覆盖请求/响应循环、错误处理、通知和批处理。A2ATopicFactoryTest 覆盖 topic 生成与解析。TaskRegistryTest — 任务状态机 + TTL 清理验证InMemoryA2AMessageTransportTest — 内存传输投递A2AGatewayServiceTest — Gateway 服务层A2AGatewayEndToEndTest — 进程内全链路A2AClientServerIntegrationTest — 真实 HTTP 客户端-服务端集成测试McpIntegrationDemoTest、McpPatternsIntegrationTest、McpComprehensiveDemoTest、CloudEventsComprehensiveDemoTestInMemoryA2AMessageTransport,实现生产级部署。targetagent 和 a2amethod 扩展属性实现高级路由规则。methods/list)。TaskRegistry 状态持久化到 Redis/DB,支持崩溃恢复。Date: 2026-06-19 Version: v2.0.0 (MCP Edition + Gateway Runtime) Status: ✅ PASS
The test suite provides comprehensive coverage across two layers: the Protocol Adaptor (JSON-RPC 2.0 & Native CloudEvents) and the Gateway Runtime (HTTP REST API, Task lifecycle, SSE streaming, AgentCard discovery).
| Test Class | Scenarios | Result | Description |
|---|---|---|---|
EnhancedA2AProtocolAdaptorTest | 12 | PASS | Unit tests covering core protocol logic, MCP parsing, Batching, Error handling, and A2A Standard Ops. |
McpIntegrationDemoTest | 1 | PASS | End-to-end RPC demo using MCP (JSON-RPC). |
McpPatternsIntegrationTest | 2 | PASS | End-to-end Pub/Sub and Streaming demos using MCP (JSON-RPC). |
McpComprehensiveDemoTest | 3 | PASS | Validation of all 3 patterns in MCP mode. |
CloudEventsComprehensiveDemoTest | 3 | PASS | Validation of all 3 patterns in Native CloudEvents mode. |
A2ATopicFactoryTest | 8 | PASS | Topic naming and parsing (request/response/status topics). |
| Test Class | Scenarios | Result | Description |
|---|---|---|---|
TaskRegistryTest | 6 | PASS | Task state machine transitions, parent-child relationships, TTL auto-cleanup. |
InMemoryA2AMessageTransportTest | 4 | PASS | In-memory pub/sub delivery, subscribe/unsubscribe, wildcard topics. |
A2AGatewayServiceTest | 8 | PASS | Gateway service layer: task submission (sync/async), response handling, cancel, status subscription. |
A2AGatewayEndToEndTest | 6 | PASS | In-process end-to-end: client → gateway → transport → agent → response → client. |
A2AClientServerIntegrationTest | 20 | PASS | Real HTTP client-server integration: AgentCard registration, sync/async tasks, status query, cancel, list agents, SSE streaming. |
Total Scenarios: 73 (All Passed)
EnhancedA2AProtocolAdaptorTest (Unit)task/get, message/sendStream mappings.A2ATopicFactoryTest (Unit)TaskRegistryTest (Unit)InMemoryA2AMessageTransportTest (Unit)A2AGatewayServiceTest (Integration)A2AGatewayEndToEndTest (Integration)A2AClientServerIntegrationTest (HTTP Integration)POST /a2a/tasks?mode=sync returns completed result.POST /a2a/tasks?mode=async returns taskId, then GET /a2a/tasks/{taskId} polls status.DELETE /a2a/tasks/{taskId} cancels the task.GET /a2a/agents returns registered agent list.A2AClient.getTaskStatus() returns TaskResult, listAgents() returns List<String>.GET /a2a/tasks/{taskId}/stream receives real-time state updates via text/event-stream.McpIntegrationDemoTest (Integration - RPC)req-id <-> collaborationid).McpPatternsIntegrationTest (Integration - Advanced)_topic -> subject mapping for Broadcast._seq -> seq mapping for ordered chunks.McpComprehensiveDemoTest (Protocol: JSON-RPC)CloudEventsComprehensiveDemoTest (Protocol: Native CloudEvents).req / .resp CloudEvents works.subject works.seq extension works.The A2A Protocol v2.0 implementation is stable, functionally complete, and ready for production deployment. It successfully supports:
您只需要发送标准的 JSON-RPC 格式消息到 EventMesh:
// 1. 构造 MCP Request JSON String mcpRequest = "{" "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "weather", "_agentId": "weather-agent" }, "id": "req-001" "}"; // 2. 通过 EventMesh SDK 发送 eventMeshProducer.publish(new A2AProtocolTransportObject(mcpRequest));
订阅相应的主题,处理业务逻辑,并发送回响应:
// 1. 订阅 MCP Request 主题 eventMeshConsumer.subscribe("org.apache.eventmesh.a2a.tools.call.req"); // 2. 收到消息后处理... public void handle(CloudEvent event) { // 解包 Request String reqJson = new String(event.getData().toBytes()); // ... 执行业务逻辑 ... // 3. 构造 Response String mcpResponse = "{" "jsonrpc": "2.0", "result": { "text": "Sunny" }, "id": """ + event.getId() + """ "}"; // 4. 发送回 EventMesh eventMeshProducer.publish(new A2AProtocolTransportObject(mcpResponse)); }
A2A Gateway 提供完整的 REST API,支持非 Java 客户端通过 HTTP 交互:
# 同步提交 task curl -X POST 'http://localhost:10105/a2a/tasks?mode=sync' \ -H 'Content-Type: application/json' \ -d '{"targetAgent":"weather-agent","message":"Beijing"}' # 异步提交 task curl -X POST 'http://localhost:10105/a2a/tasks?mode=async' \ -H 'Content-Type: application/json' \ -d '{"targetAgent":"weather-agent","message":"Shanghai"}' # 查询状态 curl http://localhost:10105/a2a/tasks/{taskId} # 列出 tasks(支持 state/limit/offset) curl 'http://localhost:10105/a2a/tasks?state=COMPLETED&limit=20&offset=0' # SSE 流式推送(含 heartbeat 保活) curl -N http://localhost:10105/a2a/tasks/{taskId}/stream # 健康检查 curl http://localhost:10105/a2a/health # 列出 agents curl http://localhost:10105/a2a/agents
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /a2a/tasks?mode=sync | 同步提交 task(等待结果) |
| POST | /a2a/tasks?mode=async | 异步提交 task(立即返回 taskId) |
| GET | /a2a/tasks?state=&limit=&offset= | 分页列出 tasks,可按状态过滤 |
| GET | /a2a/tasks/{taskId} | 查询 task 状态 |
| DELETE | /a2a/tasks/{taskId} | 取消 task |
| GET | /a2a/tasks/{taskId}/wait | 长轮询等待 task 结果 |
| GET | /a2a/tasks/{taskId}/stream | SSE 流式推送 task 状态更新 |
| GET | /a2a/agents | 列出所有已注册 agents |
| POST | /a2a/heartbeat | Agent 心跳 |
| GET | /a2a/cards/list | 列出所有 AgentCard |
| POST | /a2a/cards/card/{org}/{unit}/{agent} | 注册 AgentCard |
A2AClient client = A2AClient.builder() .gatewayUrl("http://localhost:10105") .namespace("global") .agentName("my-agent") .agentCard(card) .heartbeatInterval(30_000) .build(); client.start(); // 同步 task(返回类型化 TaskResult) TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null); // 异步 task(返回 taskId) String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null); // 查询状态 TaskResult status = client.getTaskStatus(taskId); // 取消 boolean cancelled = client.cancelTask(taskId); // 列出 agents(返回 List<String>) List<String> agents = client.listAgents(); client.shutdown();
A2A 协议不限制 method 的名称。您可以定义自己的业务方法,例如 agents/negotiate 或 tasks/submit。EventMesh 会自动将其映射为 CloudEvent 类型 org.apache.eventmesh.a2a.agents.negotiate.req。
由于 A2A 兼容标准的 JSON-RPC 2.0,您可以轻松编写适配器,将 LangChain 的 Tool 调用转换为 EventMesh 消息,从而让您的 LLM 应用具备分布式、异步的通信能力。
v2.0.0: 全面拥抱 MCP (Model Context Protocol)
EnhancedA2AProtocolAdaptor,支持 JSON-RPC 2.0。v2.1.0: Gateway 运行时架构
A2AGatewayServer (Netty HTTP) 独立 Gateway 服务。TaskRegistry 任务状态机 + TTL 自动清理(5 分钟)。GET /a2a/tasks/{taskId}/stream)。A2AClient SDK 返回类型化对象 (TaskResult, List<String>)。pendingTasks 竞态条件(put-before-publish)。欢迎贡献代码和文档!请参考以下步骤:
Apache License 2.0