This is an automated email from the ASF dual-hosted git repository.
xwm1992 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/eventmesh-site.git
The following commit(s) were added to refs/heads/master by this push:
new abd96393e docs: add A2A protocol doc, fix typos (#254)
abd96393e is described below
commit abd96393e42c2f8005775372d47f8f093d72725b
Author: Eason Chen <[email protected]>
AuthorDate: Sun Jul 5 23:03:59 2026 +0800
docs: add A2A protocol doc, fix typos (#254)
* docs: add A2A protocol doc, fix stream typo, add chatgpt connector zh
translation
- Add A2A (Agent-to-Agent) protocol design document (EN + ZH)
Based on real source code: EnhancedA2AProtocolAdaptor, A2AGatewayServer,
A2AClient SDK, Gateway REST API, MCP/CloudEvents dual-mode architecture
- Fix typo in filename: data-steam-processing -> data-stream-processing (EN
+ ZH)
- Add Chinese translation for chatgpt-connector doc
- Register A2A doc in sidebar (sidebars/docs.js)
* fix: self-close <br/> tags in A2A docs for MDX build; fix architecture
diagram spacing
- Replace <br> with <br/> in EN/ZH a2a-protocol.md (Docusaurus 2.4.3 MDX v1
requires JSX-valid tags; caused CI build failure)
- Redistribute all 4 layers in architecture.svg with symmetric margins and
even spacing; fixes RabbitMQ box overlapping the Event Store outer frame
* feat: point 'Explore A2A Documentation' button to new A2A protocol doc
- EN: /docs/introduction -> /docs/design-document/a2a-protocol
- ZH: /zh/docs/introduction -> /zh/docs/design-document/a2a-protocol
---
...-processing.md => 00-data-stream-processing.md} | 0
docs/design-document/04-a2a-protocol.md | 293 +++++++++++++++++++++
...-processing.md => 00-data-stream-processing.md} | 0
.../03-connect/12-chatgpt-connector.md | 138 ++++++++++
.../current/design-document/04-a2a-protocol.md | 293 +++++++++++++++++++++
i18n/zh/docusaurus-plugin-content-pages/index.tsx | 2 +-
sidebars/docs.js | 1 +
src/pages/index.tsx | 2 +-
static/images/diagrams/architecture.svg | 88 +++----
9 files changed, 771 insertions(+), 46 deletions(-)
diff --git a/docs/application-scenario/00-data-steam-processing.md
b/docs/application-scenario/00-data-stream-processing.md
similarity index 100%
rename from docs/application-scenario/00-data-steam-processing.md
rename to docs/application-scenario/00-data-stream-processing.md
diff --git a/docs/design-document/04-a2a-protocol.md
b/docs/design-document/04-a2a-protocol.md
new file mode 100644
index 000000000..82dc1f6fb
--- /dev/null
+++ b/docs/design-document/04-a2a-protocol.md
@@ -0,0 +1,293 @@
+---
+title: A2A Protocol
+sidebar_position: 4
+---
+
+# EventMesh A2A (Agent-to-Agent) Protocol
+
+## Overview
+
+The **EventMesh A2A (Agent-to-Agent) Protocol** is a specialized,
high-performance protocol plugin that enables asynchronous communication,
collaboration, and task coordination between autonomous agents.
+
+Starting from 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.
+
+## Core Features
+
+### 1. MCP over CloudEvents
+
+- **Standard Compliance**: Fully supports standard MCP methods such as
`tools/call`, `resources/read`, and `tools/list`.
+- **Event-Driven**: Maps synchronous RPC calls to asynchronous
Request/Response event streams, leveraging EventMesh's high-concurrency
processing capabilities.
+- **Transport Agnostic**: All MCP messages are encapsulated within standard
CloudEvents envelopes, running over any transport layer supported by EventMesh
(HTTP, TCP, gRPC, Kafka).
+
+### 2. Dual-Mode Support (Hybrid Architecture)
+
+A2A Protocol features a unique Dual-Mode architecture that simultaneously
supports:
+
+1. **JSON-RPC 2.0 (MCP Mode)**:
+ - **Target**: LLMs, scripts (Python/JS), LangChain integration.
+ - **Benefit**: Extremely low barrier to entry. Clients send simple JSON
objects; the adaptor automatically wraps them in CloudEvents.
+2. **Native CloudEvents (Power Mode)**:
+ - **Target**: EventMesh native apps, Knative, serverless functions.
+ - **Benefit**: Full control over event metadata. Allows pass-through of
custom or binary data.
+
+The `EnhancedA2AProtocolAdaptor` intelligently detects the payload format. If
`jsonrpc: "2.0"` is present, it engages the MCP translation engine; otherwise,
it treats the payload as a standard CloudEvent (delegating to the underlying
CloudEvents adaptor).
+
+### 3. Native Pub/Sub Semantics
+
+- **O(1) Broadcast**: Publishers send messages once to a topic, and EventMesh
efficiently fans out to all subscribers.
+- **Temporal Decoupling**: Solves the scalability issues of traditional P2P
webhook callbacks (consumers need not be online at publish time).
+- **Backpressure Isolation**: A slow subscriber does not block the publisher.
+
+### 4. High Performance and Routing
+
+- **Batch Processing**: Natively supports JSON-RPC Batch requests. EventMesh
automatically splits them into parallel event streams.
+- **Intelligent Routing**: Extracts routing hints (`_agentId` for P2P,
`_topic` for Pub/Sub) from MCP parameters and injects them into CloudEvents
attributes for zero-decoding routing.
+
+### 5. Streaming Support
+
+Preserves message order for streaming operations (`message/sendStream`) using
sequence IDs (`seq` extension attribute).
+
+### 6. Agent Discovery and Lifecycle
+
+- **AgentCard**: Agents register their capabilities via AgentCard, supporting
online/offline status and heartbeat.
+- **Task Management**: Full task lifecycle with `task/get`, `task/list`,
`task/cancel`, `task/subscribe` operations and TTL-based auto-cleanup.
+
+## Architecture
+
+### Core Components
+
+```
++-------------------------------------------------------------+
+| EventMesh A2A Protocol v2.0 |
+| (MCP over CloudEvents Architecture) |
++-------------------------------------------------------------+
+| +-------------+ +-------------+ +-------------+ |
+| | MCP/JSON-RPC| | Native | | Protocol | |
+| | Handler | | Pub/Sub | | Delegator | |
+| +-------------+ +-------------+ +-------------+ |
++-------------------------------------------------------------+
+| +-------------------------------------------------------+ |
+| | Enhanced A2A Protocol Adaptor | |
+| | (Intelligent Parsing & CloudEvent Mapping) | |
+| +-------------------------------------------------------+ |
++-------------------------------------------------------------+
+| EventMesh Protocol Infrastructure |
+| +-------------+ +-------------+ +-------------+ |
+| | CloudEvents | | HTTP | | gRPC | |
+| | Protocol | | Protocol | | Protocol | |
+| +-------------+ +-------------+ +-------------+ |
++-------------------------------------------------------------+
+```
+
+### Gateway Runtime Architecture
+
+The A2A Gateway provides a standalone HTTP server (Netty-based) that
orchestrates agent task submission, response handling, and SSE streaming.
+
+| Component | Module | Responsibility |
+| :--- | :--- | :--- |
+| `A2AGatewayServer` | runtime | Netty HTTP server entry point, pre-registers
mock agents |
+| `A2AGatewayHttpHandler` | runtime | HTTP request router, supports SSE
streaming |
+| `A2AGatewayService` | runtime | Core orchestration: task submission,
response handling, SSE push |
+| `TaskRegistry` | runtime | In-memory task state machine + TTL auto-cleanup
(5 min) |
+| `A2APublishSubscribeService` | runtime | AgentCard registration, discovery,
heartbeat |
+| `InMemoryA2AMessageTransport` | runtime | In-memory pub/sub (replaceable by
EventMesh broker) |
+| `A2AClient` | protocol-a2a | Java SDK with typed API |
+| `EnhancedA2AProtocolAdaptor` | protocol-a2a | Intelligent parsing and
CloudEvent mapping |
+| `A2AProtocolConstants` | protocol-a2a | Protocol version, standard
operations, CE extensions |
+
+### Asynchronous RPC Mapping
+
+To support the MCP Request/Response model within an event-driven architecture,
A2A defines the following mapping rules:
+
+| MCP Concept | CloudEvent Mapping | Description |
+| :--- | :--- | :--- |
+| **Action** (`method`) | **Type**: `org.apache.eventmesh.a2a.<method>.req`
<br/> **Extension**: `a2amethod` | Request event type. |
+| **Response** (`result`) | **Type**:
`org.apache.eventmesh.a2a.common.response` <br/> **Extension**:
`mcptype=response` | Response event type. |
+| **Correlation** (`id`) | **Extension**: `collaborationid` (on Response)
<br/> **ID**: Preserved on Request | Links Response to Request. |
+| **P2P Routing** (`params._agentId`) | **Extension**: `targetagent` | Routing
target Agent ID. |
+| **Pub/Sub Topic** (`params._topic`) | **Subject**: `<topic_name>` |
Broadcast Topic. |
+| **Streaming Seq** (`params._seq`) | **Extension**: `seq` | Sequence order
for streaming. |
+
+### Protocol Constants
+
+The `A2AProtocolConstants` class defines the following standard operations
(protocol version `0.3`):
+
+| Category | Operations |
+| :--- | :--- |
+| **Message** | `message/send`, `message/sendStream` |
+| **Task** | `task/get`, `task/list`, `task/cancel`, `task/subscribe` |
+| **Notification Config** | `notification/config/set`, `get`, `list`, `delete`
|
+| **Agent Card** | `agent/card/get`, `register`, `delete`, `list`, `update` |
+
+## Protocol Message Format
+
+### 1. MCP Request (P2P)
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "get_weather",
+ "_agentId": "weather-service"
+ },
+ "id": "req-123"
+}
+```
+
+### 2. MCP Request (Pub/Sub)
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "market/update",
+ "params": {
+ "price": 50000,
+ "_topic": "market.btc"
+ }
+}
+```
+
+### 3. Native CloudEvents Request
+
+```json
+{
+ "specversion": "1.0",
+ "type": "com.example.rpc.request",
+ "source": "my-app",
+ "id": "evt-123",
+ "data": "...",
+ "protocol": "A2A",
+ "targetagent": "target-agent-001"
+}
+```
+
+## Usage Guide
+
+### 1. A2AClient Java SDK
+
+```java
+A2AClient client = A2AClient.builder()
+ .gatewayUrl("http://localhost:10105")
+ .namespace("global")
+ .agentName("my-agent")
+ .agentCard(card)
+ .heartbeatInterval(30_000)
+ .build();
+
+client.start();
+
+// Sync task (returns typed TaskResult)
+TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null);
+
+// Async task (returns taskId)
+String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null);
+
+// Query status
+TaskResult status = client.getTaskStatus(taskId);
+
+// Cancel
+boolean cancelled = client.cancelTask(taskId);
+
+// List agents
+List<String> agents = client.listAgents();
+
+client.shutdown();
+```
+
+### 2. EventMesh SDK (CloudEvents Mode)
+
+```java
+// 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")
+ .build();
+
+producer.publish(event);
+```
+
+### 3. Gateway REST API
+
+The A2A Gateway provides a full REST API for external clients and non-Java
agents:
+
+```bash
+# Sync task
+curl -X POST 'http://localhost:10105/a2a/tasks?mode=sync' \
+ -H 'Content-Type: application/json' \
+ -d '{"targetAgent":"weather-agent","message":"Beijing"}'
+
+# Async task
+curl -X POST 'http://localhost:10105/a2a/tasks?mode=async' \
+ -H 'Content-Type: application/json' \
+ -d '{"targetAgent":"weather-agent","message":"Shanghai"}'
+
+# Query status
+curl http://localhost:10105/a2a/tasks/{taskId}
+
+# SSE stream
+curl -N http://localhost:10105/a2a/tasks/{taskId}/stream
+
+# List agents
+curl http://localhost:10105/a2a/agents
+```
+
+#### REST API Endpoints
+
+| Method | Path | Description |
+|------|------|------|
+| POST | `/a2a/tasks?mode=sync` | Submit task synchronously (wait for result) |
+| POST | `/a2a/tasks?mode=async` | Submit task asynchronously (return taskId) |
+| GET | `/a2a/tasks/{taskId}` | Get task status |
+| DELETE | `/a2a/tasks/{taskId}` | Cancel task |
+| GET | `/a2a/tasks/{taskId}/wait` | Long-poll wait for result |
+| GET | `/a2a/tasks/{taskId}/stream` | SSE stream of task status updates |
+| GET | `/a2a/agents` | List registered agents |
+| POST | `/a2a/heartbeat` | Agent heartbeat |
+| GET | `/a2a/cards/list` | List all AgentCards |
+| POST | `/a2a/cards/card/{org}/{unit}/{agent}` | Register AgentCard |
+
+## SPI Registration
+
+The A2A protocol adaptor is registered via Java SPI:
+
+```
+# META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor
+a2a=org.apache.eventmesh.protocol.a2a.EnhancedA2AProtocolAdaptor
+```
+
+At runtime, `ProtocolPluginFactory` loads the adaptor by key `a2a`. The
adaptor delegates to `cloudevents` or `http` adaptors for underlying transport.
+
+## Version History
+
+- **v2.0.0**: Fully embraced MCP (Model Context Protocol)
+ - Introduced `EnhancedA2AProtocolAdaptor` supporting JSON-RPC 2.0.
+ - Implemented async RPC over CloudEvents pattern.
+ - Added native Pub/Sub support via `_topic` parameter.
+ - Added streaming support via `_seq` parameter.
+
+- **v2.1.0**: Gateway Runtime Architecture
+ - Added `A2AGatewayServer` (Netty HTTP) standalone gateway service.
+ - Implemented `TaskRegistry` task state machine + TTL auto-cleanup (5 min).
+ - Added SSE streaming response (`GET /a2a/tasks/{taskId}/stream`).
+ - `A2AClient` SDK returns typed objects (`TaskResult`, `List<String>`).
+ - AgentCard registration, discovery, and heartbeat management.
+
+## Module Structure
+
+| Module | Path | Description |
+| :--- | :--- | :--- |
+| Protocol Plugin | `eventmesh-protocol-plugin/eventmesh-protocol-a2a` | A2A
protocol adaptor, JSON-RPC models, MCP methods |
+| Runtime Gateway | `eventmesh-runtime/src/main/java/.../a2a/` | Gateway
server, service, task registry, transport |
+| Examples | `eventmesh-examples/src/main/java/.../a2a/demo/` | MCP
caller/provider, CloudEvents caller/provider, gateway demo |
+
+## References
+
+- [A2A Protocol Design
Document](https://github.com/apache/eventmesh/tree/master/docs/a2a-protocol)
(source code)
+- [MCP Specification](https://modelcontextprotocol.io/)
+- [CloudEvents Specification](https://cloudevents.io/)
diff --git
a/i18n/zh/docusaurus-plugin-content-docs/current/application-scenario/00-data-steam-processing.md
b/i18n/zh/docusaurus-plugin-content-docs/current/application-scenario/00-data-stream-processing.md
similarity index 100%
rename from
i18n/zh/docusaurus-plugin-content-docs/current/application-scenario/00-data-steam-processing.md
rename to
i18n/zh/docusaurus-plugin-content-docs/current/application-scenario/00-data-stream-processing.md
diff --git
a/i18n/zh/docusaurus-plugin-content-docs/current/design-document/03-connect/12-chatgpt-connector.md
b/i18n/zh/docusaurus-plugin-content-docs/current/design-document/03-connect/12-chatgpt-connector.md
new file mode 100644
index 000000000..aa9103fb1
--- /dev/null
+++
b/i18n/zh/docusaurus-plugin-content-docs/current/design-document/03-connect/12-chatgpt-connector.md
@@ -0,0 +1,138 @@
+# ChatGPT
+
+## ChatGPT Source Connector
+
+### 配置
+
+在使用 ChatGPT source connector 之前,你需要配置服务端。
+- 请在 `/resource/server-config.yml` 中将 `sourceEnable` 配置为 `true` 以启用 source 功能。
+- 请在 `/resource/source-config.yml` 中配置 source connector:
+ - `connectorConfig`
+ - `connectorName`,connector 的名称。
+ - `path`,API 的路径。
+ - `port`,API 的端口。
+ - `idleTimeout`,TCP 空闲连接超时时间(秒)。默认为 0,表示不超时。
+ - `proxyEnable`,openai 请求的代理开关,默认为 false。
+ - `parsePromptFileName`,用户使用解析请求时所需的解析提示词模板,默认为 resource 文件夹中的 "prompt" 文件。
+ - `openaiConfig`
+ - (必填)`token`,openai 的 token。
+ - `model`,openai 的模型。
+ - `timeout`,openai 连接超时时间(秒)。默认为 0,表示不超时。
+ - `temperature`,https://platform.openai.com/docs/api-reference/chat/create
`temperature`。
+ - `maxTokens`,https://platform.openai.com/docs/api-reference/chat/create
`max_tokens`。
+ -
`frequencyPenalty`,https://platform.openai.com/docs/api-reference/chat/create
`presence_penalty`。
+ - `user`,https://platform.openai.com/docs/api-reference/chat/create `user`。
+ - `stop`,https://platform.openai.com/docs/api-reference/chat/create `stop`。
+ - `logitBias`,https://platform.openai.com/docs/api-reference/chat/create
`logit_bias`。
+ - `openaiProxyConfig`,如果 `connectorConfig.proxyEnable` 为 true,则此配置为必填。
+ - `host`,openai 代理的主机。
+ - `port`,openai 代理的端口。
+
+### 启动
+
+1. 启动 EventMesh Runtime。
+2. 启动 eventmesh-connector-chatgpt。
+
+启动完成后,ChatGPT source connector 将作为 HTTP 服务器运行。
+
+### 发送消息
+
+你可以通过 HTTP 向 source connector 发送消息。
+
+```yaml
+connectorConfig:
+ connectorName: chatgptSource
+ path: /chatgpt
+ port: 3756
+ idleTimeout: 0
+ proxyEnable: false
+ parsePromptFileName: prompt
+openaiConfig:
+ token:
+ model: gpt-3.5-turbo
+ timeout: 0
+ temperature: 1
+ maxTokens:
+ frequencyPenalty: 0
+ presencePenalty: 0
+ user: eventMesh
+ stop: []
+ logitBias: {}
+
+openaiProxyConfig:
+ host: 127.0.0.1
+ port: 7890
+```
+
+上面的示例在 `source-config.yml` 中配置了 URL `http://localhost:3756/chatgpt`。
+
+你可以使用 `CHAT` 或 `PARSE` 请求类型发送消息,默认为 `CHAT`。
+
+#### CHAT
+
+"CHAT" 请求类型是与 ChatGPT 进行对话。
+
+- 构建请求体
+ - `requestType`,默认为 `CHAT`。
+ - `type`,默认为 `cloudevents`。
+ - `source`,默认为 `/`。
+ - `subject`,默认为 `chatGPT`。
+ - `datacontenttype`,默认为 `text/plain`。
+ - (必填)`text`,你想与 ChatGPT 聊天的内容。
+
+例如:
+```shell
+curl --location --request POST 'http://localhost:3756/chatgpt' \
+--data-raw '{
+ "requestType": "CHAR",
+ "type": "com.example.someevent",
+ "source": "/mycontext",
+ "subject":"test_topic",
+ "datacontenttype":"text/plain",
+ "text": "can you tell me a story."
+}'
+```
+
+#### PARSE
+
+"PARSE" 请求类型是输出解析,connector 将从 ChatGPT 获取解析结果。
+- 构建请求体
+ - (必填)`requestType`,值必须为 `PARSE`。
+ - `type`,默认为 `cloudevents`。
+ - `source`,默认为 `/`。
+ - `subject`,默认为 `chatGPT`。
+ - `datacontenttype`,默认为 `application/json`。
+ - (必填)`text`,非结构化数据。例如一篇文章或一段描述。
+ - (必填)`fields`,字段信息,ChatGPT 根据字段信息从文本中提取信息。
+
+例如:
+```shell
+curl --location --request POST 'http://localhost:3756/chatgpt' \
+--data-raw '{
+ "requestType": "PARSE",
+ "type": "com.example.someevent",
+ "source": "/mycontext",
+ "subject":"test_topic",
+ "datacontenttype":"application/json",
+ "text": "This leaf blower is pretty amazing. It has four settings: candle
blower, gentle breeze, windy city, and tornado. It arrived in two days, just in
time for my wife's anniversary present. I think my wife liked it so much she
was speechless. So far I've been the only one using it, and I've been using it
every other morning to clear the leaves on our lawn. It's slightly more
expensive than the other leaf blowers out there, but I think it's worth it for
the extra features.",
+ "fields": "gift:Was the item purchased as a gift for someone else? Answer
True if yes, False if not or unknown;delivery_days:How many days did it take
for the product to arrive? If this information is not found, output
-1;price_value:Extract any sentences about the value or price, and output them
as a comma separated Python list"
+}'
+```
+如果 `datacontenttype` 为 `application/json`,ChatGPT 结果:
+
+```json
+{
+ "gift": false,
+ "delivery_days": 2,
+ "price_value": ["It's slightly more expensive than the other leaf blowers
out there, but I think it's worth it for the extra features."]
+}
+```
+如果 `datacontenttype` 为 `application/xml`,xml 的根节点固定为 `<root></root>`,ChatGPT
结果:
+
+```xml
+<data>
+ <gift>False</gift>
+ <delivery_days>2</delivery_days>
+ <price_value>["It's slightly more expensive than the other leaf blowers out
there"]</price_value>
+</data>
+```
diff --git
a/i18n/zh/docusaurus-plugin-content-docs/current/design-document/04-a2a-protocol.md
b/i18n/zh/docusaurus-plugin-content-docs/current/design-document/04-a2a-protocol.md
new file mode 100644
index 000000000..b118d7220
--- /dev/null
+++
b/i18n/zh/docusaurus-plugin-content-docs/current/design-document/04-a2a-protocol.md
@@ -0,0 +1,293 @@
+---
+title: A2A 协议
+sidebar_position: 4
+---
+
+# EventMesh A2A(Agent-to-Agent)协议
+
+## 概述
+
+**EventMesh A2A(Agent-to-Agent)协议**是一个专用的高性能协议插件,用于实现自治 Agent 之间的异步通信、协作和任务协调。
+
+从 v2.0 开始,A2A 采用了 **MCP(Model Context Protocol)** 架构,将 EventMesh 转变为一个强大的
**Agent 协作总线**。它弥合了基于 LLM 的同步工具调用(JSON-RPC
2.0)与异步事件驱动架构(EDA)之间的差距,实现了可扩展、分布式和解耦的 Agent 系统。
+
+## 核心特性
+
+### 1. MCP over CloudEvents
+
+- **标准合规**:完全支持 MCP 定义的标准方法,如 `tools/call`、`resources/read` 和 `tools/list`。
+- **事件驱动**:将同步 RPC 调用映射为异步请求/响应事件流,充分利用 EventMesh 的高并发处理能力。
+- **传输无关**:所有 MCP 消息都封装在标准 CloudEvents 信封中,可在 EventMesh
支持的任意传输层(HTTP、TCP、gRPC、Kafka)上运行。
+
+### 2. 双模式支持(混合架构)
+
+A2A 协议具有独特的双模式架构,同时支持:
+
+1. **JSON-RPC 2.0(MCP 模式)**:
+ - **目标用户**:LLM、脚本(Python/JS)、LangChain 集成。
+ - **优势**:极低的使用门槛。客户端发送简单的 JSON 对象,适配器自动将其封装为 CloudEvents。
+2. **原生 CloudEvents(Power 模式)**:
+ - **目标用户**:EventMesh 原生应用、Knative、Serverless 函数。
+ - **优势**:完全控制事件元数据,支持自定义或二进制数据的透传。
+
+`EnhancedA2AProtocolAdaptor` 会智能检测负载格式。如果存在 `jsonrpc: "2.0"`,则启用 MCP
翻译引擎;否则,将负载视为标准 CloudEvent(委托给底层 CloudEvents 适配器处理)。
+
+### 3. 原生 Pub/Sub 语义
+
+- **O(1) 广播**:发布者只需向 Topic 发送一次消息,EventMesh 即可高效扇出到所有订阅者。
+- **时间解耦**:解决了传统 P2P Webhook 回调的可扩展性问题(消费者无需在发布时在线)。
+- **背压隔离**:慢速订阅者不会阻塞发布者。
+
+### 4. 高性能与路由
+
+- **批处理**:原生支持 JSON-RPC Batch 请求。EventMesh 自动将其拆分为并行事件流。
+- **智能路由**:从 MCP 参数中提取路由提示(`_agentId` 用于 P2P,`_topic` 用于 Pub/Sub),注入到
CloudEvents 属性中,实现零解码路由。
+
+### 5. 流式支持
+
+通过序列 ID(`seq` 扩展属性)为流式操作(`message/sendStream`)保持消息顺序。
+
+### 6. Agent 发现与生命周期
+
+- **AgentCard**:Agent 通过 AgentCard 注册自身能力,支持在线/离线状态和心跳。
+- **任务管理**:完整的任务生命周期,支持 `task/get`、`task/list`、`task/cancel`、`task/subscribe`
操作及基于 TTL 的自动清理。
+
+## 架构
+
+### 核心组件
+
+```
++-------------------------------------------------------------+
+| EventMesh A2A Protocol v2.0 |
+| (MCP over CloudEvents 架构) |
++-------------------------------------------------------------+
+| +-------------+ +-------------+ +-------------+ |
+| | MCP/JSON-RPC| | 原生 | | 协议 | |
+| | 处理器 | | Pub/Sub | | 委托器 | |
+| +-------------+ +-------------+ +-------------+ |
++-------------------------------------------------------------+
+| +-------------------------------------------------------+ |
+| | 增强 A2A 协议适配器 | |
+| | (智能解析与 CloudEvent 映射) | |
+| +-------------------------------------------------------+ |
++-------------------------------------------------------------+
+| EventMesh 协议基础设施 |
+| +-------------+ +-------------+ +-------------+ |
+| | CloudEvents | | HTTP | | gRPC | |
+| | 协议 | | 协议 | | 协议 | |
+| +-------------+ +-------------+ +-------------+ |
++-------------------------------------------------------------+
+```
+
+### 网关运行时架构
+
+A2A 网关提供独立的 HTTP 服务器(基于 Netty),负责编排 Agent 任务提交、响应处理和 SSE 流式推送。
+
+| 组件 | 模块 | 职责 |
+| :--- | :--- | :--- |
+| `A2AGatewayServer` | runtime | Netty HTTP 服务器入口,预注册 mock agent |
+| `A2AGatewayHttpHandler` | runtime | HTTP 请求路由,支持 SSE 流式响应 |
+| `A2AGatewayService` | runtime | 核心编排:任务提交、响应处理、SSE 推送 |
+| `TaskRegistry` | runtime | 内存任务状态机 + TTL 自动清理(5 分钟) |
+| `A2APublishSubscribeService` | runtime | AgentCard 注册、发现、心跳 |
+| `InMemoryA2AMessageTransport` | runtime | 内存 Pub/Sub(可替换为 EventMesh broker) |
+| `A2AClient` | protocol-a2a | Java SDK,提供类型化 API |
+| `EnhancedA2AProtocolAdaptor` | protocol-a2a | 智能解析与 CloudEvent 映射 |
+| `A2AProtocolConstants` | protocol-a2a | 协议版本、标准操作、CE 扩展属性 |
+
+### 异步 RPC 映射
+
+为在事件驱动架构中支持 MCP 请求/响应模型,A2A 定义了以下映射规则:
+
+| MCP 概念 | CloudEvent 映射 | 说明 |
+| :--- | :--- | :--- |
+| **动作**(`method`) | **Type**: `org.apache.eventmesh.a2a.<method>.req` <br/>
**Extension**: `a2amethod` | 请求事件类型 |
+| **响应**(`result`) | **Type**: `org.apache.eventmesh.a2a.common.response`
<br/> **Extension**: `mcptype=response` | 响应事件类型 |
+| **关联**(`id`) | **Extension**: `collaborationid`(响应上) <br/> **ID**: 请求上保留 |
将响应关联到请求 |
+| **P2P 路由**(`params._agentId`) | **Extension**: `targetagent` | 路由目标 Agent ID
|
+| **Pub/Sub Topic**(`params._topic`) | **Subject**: `<topic_name>` | 广播 Topic |
+| **流式序列**(`params._seq`) | **Extension**: `seq` | 流式消息顺序 |
+
+### 协议常量
+
+`A2AProtocolConstants` 类定义了以下标准操作(协议版本 `0.3`):
+
+| 类别 | 操作 |
+| :--- | :--- |
+| **消息** | `message/send`、`message/sendStream` |
+| **任务** | `task/get`、`task/list`、`task/cancel`、`task/subscribe` |
+| **通知配置** | `notification/config/set`、`get`、`list`、`delete` |
+| **Agent Card** | `agent/card/get`、`register`、`delete`、`list`、`update` |
+
+## 协议消息格式
+
+### 1. MCP 请求(P2P)
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "get_weather",
+ "_agentId": "weather-service"
+ },
+ "id": "req-123"
+}
+```
+
+### 2. MCP 请求(Pub/Sub)
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "market/update",
+ "params": {
+ "price": 50000,
+ "_topic": "market.btc"
+ }
+}
+```
+
+### 3. 原生 CloudEvents 请求
+
+```json
+{
+ "specversion": "1.0",
+ "type": "com.example.rpc.request",
+ "source": "my-app",
+ "id": "evt-123",
+ "data": "...",
+ "protocol": "A2A",
+ "targetagent": "target-agent-001"
+}
+```
+
+## 使用指南
+
+### 1. A2AClient Java SDK
+
+```java
+A2AClient client = A2AClient.builder()
+ .gatewayUrl("http://localhost:10105")
+ .namespace("global")
+ .agentName("my-agent")
+ .agentCard(card)
+ .heartbeatInterval(30_000)
+ .build();
+
+client.start();
+
+// 同步任务(返回类型化的 TaskResult)
+TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null);
+
+// 异步任务(返回 taskId)
+String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null);
+
+// 查询状态
+TaskResult status = client.getTaskStatus(taskId);
+
+// 取消任务
+boolean cancelled = client.cancelTask(taskId);
+
+// 列出 Agent
+List<String> agents = client.listAgents();
+
+client.shutdown();
+```
+
+### 2. EventMesh SDK(CloudEvents 模式)
+
+```java
+// 参见
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")
+ .build();
+
+producer.publish(event);
+```
+
+### 3. 网关 REST API
+
+A2A 网关为外部客户端和非 Java Agent 提供完整的 REST API:
+
+```bash
+# 同步任务
+curl -X POST 'http://localhost:10105/a2a/tasks?mode=sync' \
+ -H 'Content-Type: application/json' \
+ -d '{"targetAgent":"weather-agent","message":"Beijing"}'
+
+# 异步任务
+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}
+
+# SSE 流
+curl -N http://localhost:10105/a2a/tasks/{taskId}/stream
+
+# 列出 Agent
+curl http://localhost:10105/a2a/agents
+```
+
+#### REST API 端点
+
+| 方法 | 路径 | 说明 |
+|------|------|------|
+| POST | `/a2a/tasks?mode=sync` | 同步提交任务(等待结果) |
+| POST | `/a2a/tasks?mode=async` | 异步提交任务(返回 taskId) |
+| GET | `/a2a/tasks/{taskId}` | 获取任务状态 |
+| DELETE | `/a2a/tasks/{taskId}` | 取消任务 |
+| GET | `/a2a/tasks/{taskId}/wait` | 长轮询等待结果 |
+| GET | `/a2a/tasks/{taskId}/stream` | SSE 流式获取任务状态更新 |
+| GET | `/a2a/agents` | 列出已注册的 Agent |
+| POST | `/a2a/heartbeat` | Agent 心跳 |
+| GET | `/a2a/cards/list` | 列出所有 AgentCard |
+| POST | `/a2a/cards/card/{org}/{unit}/{agent}` | 注册 AgentCard |
+
+## SPI 注册
+
+A2A 协议适配器通过 Java SPI 注册:
+
+```
+# META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor
+a2a=org.apache.eventmesh.protocol.a2a.EnhancedA2AProtocolAdaptor
+```
+
+运行时,`ProtocolPluginFactory` 通过 key `a2a` 加载适配器。适配器将底层传输委托给 `cloudevents` 或
`http` 适配器。
+
+## 版本历史
+
+- **v2.0.0**:全面拥抱 MCP(Model Context Protocol)
+ - 引入 `EnhancedA2AProtocolAdaptor`,支持 JSON-RPC 2.0。
+ - 实现基于 CloudEvents 的异步 RPC 模式。
+ - 通过 `_topic` 参数添加原生 Pub/Sub 支持。
+ - 通过 `_seq` 参数添加流式支持。
+
+- **v2.1.0**:网关运行时架构
+ - 添加 `A2AGatewayServer`(Netty HTTP)独立网关服务。
+ - 实现 `TaskRegistry` 任务状态机 + TTL 自动清理(5 分钟)。
+ - 添加 SSE 流式响应(`GET /a2a/tasks/{taskId}/stream`)。
+ - `A2AClient` SDK 返回类型化对象(`TaskResult`、`List<String>`)。
+ - AgentCard 注册、发现和心跳管理。
+
+## 模块结构
+
+| 模块 | 路径 | 说明 |
+| :--- | :--- | :--- |
+| 协议插件 | `eventmesh-protocol-plugin/eventmesh-protocol-a2a` | A2A
协议适配器、JSON-RPC 模型、MCP 方法 |
+| 运行时网关 | `eventmesh-runtime/src/main/java/.../a2a/` | 网关服务器、服务、任务注册表、传输层 |
+| 示例 | `eventmesh-examples/src/main/java/.../a2a/demo/` | MCP
调用方/提供方、CloudEvents 调用方/提供方、网关示例 |
+
+## 参考
+
+- [A2A
协议设计文档](https://github.com/apache/eventmesh/tree/master/docs/a2a-protocol)(源码)
+- [MCP 规范](https://modelcontextprotocol.io/)
+- [CloudEvents 规范](https://cloudevents.io/)
diff --git a/i18n/zh/docusaurus-plugin-content-pages/index.tsx
b/i18n/zh/docusaurus-plugin-content-pages/index.tsx
index 5d4f95f55..10a3415df 100644
--- a/i18n/zh/docusaurus-plugin-content-pages/index.tsx
+++ b/i18n/zh/docusaurus-plugin-content-pages/index.tsx
@@ -305,7 +305,7 @@ export default function Home() {
</ul>
<div style={{marginTop: '32px'}}>
- <a href="/zh/docs/introduction" className="btn btn-primary">
+ <a href="/zh/docs/design-document/a2a-protocol" className="btn
btn-primary">
探索 A2A 文档
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"
stroke="currentColor" strokeWidth="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
diff --git a/sidebars/docs.js b/sidebars/docs.js
index 59cb6be89..c8fe4023d 100644
--- a/sidebars/docs.js
+++ b/sidebars/docs.js
@@ -77,6 +77,7 @@ module.exports = {
'design-document/schema-registry',
'design-document/spi',
'design-document/stream',
+ 'design-document/a2a-protocol',
],
},
{
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 1b320dc17..23abc8c26 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -307,7 +307,7 @@ export default function Home() {
</ul>
<div style={{marginTop: '32px'}}>
- <a href="/docs/introduction" className="btn btn-primary">
+ <a href="/docs/design-document/a2a-protocol" className="btn
btn-primary">
Explore A2A Documentation
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"
stroke="currentColor" strokeWidth="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
diff --git a/static/images/diagrams/architecture.svg
b/static/images/diagrams/architecture.svg
index 133d5413b..251fb33b8 100644
--- a/static/images/diagrams/architecture.svg
+++ b/static/images/diagrams/architecture.svg
@@ -40,62 +40,62 @@
<text x="480" y="24" text-anchor="middle" class="title"
fill="url(#grad-text)">EventMesh Architecture</text>
<rect x="30" y="45" width="900" height="95" rx="10"
fill="url(#card-glow-blue)" stroke="rgba(124,92,252,0.15)" stroke-width="1"
stroke-dasharray="4,4"/>
<text x="50" y="67" class="layer-label" fill="#7C5CFC">Applications</text>
- <rect x="200" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="260" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Microservices</text>
- <rect x="350" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="410" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Serverless</text>
- <rect x="500" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="560" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">AI Agents</text>
- <rect x="650" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="710" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">IoT Devices</text>
- <rect x="790" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="850" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Edge</text>
+ <rect x="80" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="140" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Microservices</text>
+ <rect x="250" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="310" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Serverless</text>
+ <rect x="420" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="480" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">AI Agents</text>
+ <rect x="590" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="650" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">IoT Devices</text>
+ <rect x="760" y="75" width="120" height="42" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="820" y="101" text-anchor="middle" class="node-label"
fill="#A0AAB8">Edge</text>
<path d="M480,142 L480,164" stroke="#00D97E" stroke-width="1.5"
stroke-opacity="0.5" fill="none" marker-end="url(#arrow-down)"/>
<text x="496" y="156" class="flow-text"
fill="rgba(0,217,126,0.5)">PROTOCOLS</text>
<rect x="30" y="168" width="900" height="85" rx="10"
fill="url(#card-glow-cyan)" stroke="rgba(34,211,238,0.15)" stroke-width="1"
stroke-dasharray="4,4"/>
<text x="50" y="190" class="layer-label" fill="#22D3EE">Protocols</text>
- <rect x="120" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="170" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">HTTP</text>
- <rect x="250" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="300" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">gRPC</text>
- <rect x="380" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="430" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">TCP</text>
- <rect x="510" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="560" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">WebSocket</text>
- <rect x="660" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="710" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">CloudEvents</text>
+ <rect x="50" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="100" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">HTTP</text>
+ <rect x="202" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="252" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">gRPC</text>
+ <rect x="354" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="404" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">TCP</text>
+ <rect x="506" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="556" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">WebSocket</text>
+ <rect x="658" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="708" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">CloudEvents</text>
<rect x="810" y="196" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
<text x="860" y="219" text-anchor="middle" class="node-label"
fill="#A0AAB8">A2A</text>
<path d="M480,255 L480,277" stroke="#00D97E" stroke-width="1.5"
stroke-opacity="0.5" fill="none" marker-end="url(#arrow-down)"/>
<text x="496" y="269" class="flow-text" fill="rgba(0,217,126,0.5)">EVENT
FLOW</text>
<rect x="30" y="281" width="900" height="95" rx="10"
fill="url(#card-glow-green)" stroke="rgba(0,217,126,0.25)" stroke-width="1.5"
stroke-dasharray="4,4"/>
<text x="50" y="303" class="layer-label" fill="#00D97E">EventMesh
Runtime</text>
- <rect x="100" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
- <text x="175" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Event Gateway</text>
- <text x="175" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
- <rect x="290" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
- <text x="365" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Event Router</text>
- <text x="365" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
- <rect x="480" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
- <text x="555" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Workflow Engine</text>
- <text x="555" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
- <rect x="670" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
- <text x="745" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Schema Registry</text>
- <text x="745" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
+ <rect x="120" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
+ <text x="195" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Event Gateway</text>
+ <text x="195" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
+ <rect x="310" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
+ <text x="385" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Event Router</text>
+ <text x="385" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
+ <rect x="500" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
+ <text x="575" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Workflow Engine</text>
+ <text x="575" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
+ <rect x="690" y="311" width="150" height="48" rx="8"
fill="rgba(0,217,126,0.06)" stroke="rgba(0,217,126,0.2)"
filter="url(#soft-glow)"/>
+ <text x="765" y="333" text-anchor="middle" class="node-label" fill="#00D97E"
font-weight="600">Schema Registry</text>
+ <text x="765" y="349" text-anchor="middle" class="node-sub"
fill="rgba(160,170,184,0.5)">core service</text>
<path d="M480,378 L480,400" stroke="#00D97E" stroke-width="1.5"
stroke-opacity="0.5" fill="none" marker-end="url(#arrow-down)"/>
<text x="496" y="392" class="flow-text" fill="rgba(0,217,126,0.5)">EVENT
STORE</text>
<rect x="30" y="404" width="900" height="85" rx="10"
fill="url(#card-glow-amber)" stroke="rgba(251,191,36,0.15)" stroke-width="1"
stroke-dasharray="4,4"/>
<text x="50" y="426" class="layer-label" fill="#FBBF24">Event Store</text>
- <rect x="100" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="150" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">RocketMQ</text>
- <rect x="250" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="300" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Kafka</text>
- <rect x="400" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="450" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">AutoMQ</text>
- <rect x="550" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="600" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Redis</text>
- <rect x="700" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="750" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Pulsar</text>
- <rect x="830" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
- <text x="880" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">RabbitMQ</text>
+ <rect x="50" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="100" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">RocketMQ</text>
+ <rect x="202" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="252" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Kafka</text>
+ <rect x="354" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="404" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">AutoMQ</text>
+ <rect x="506" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="556" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Redis</text>
+ <rect x="658" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="708" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">Pulsar</text>
+ <rect x="810" y="432" width="100" height="36" rx="8"
fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.08)"/>
+ <text x="860" y="455" text-anchor="middle" class="node-label"
fill="#A0AAB8">RabbitMQ</text>
</svg>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]