Skip to content

Commit 37dbe40

Browse files
authored
Merge pull request #24 from socutes/main
dev
2 parents d2f6ddb + da7bee4 commit 37dbe40

1 file changed

Lines changed: 134 additions & 74 deletions

File tree

README.md

Lines changed: 134 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,74 @@
1-
# mq9
1+
<p align="center">
2+
<picture>
3+
<img alt="mq9 Logo" src="website/public/logo.jpg" width="200">
4+
</picture>
5+
</p>
6+
7+
<p align="center">
8+
<img alt="License" src="https://img.shields.io/github/license/robustmq/mq9?style=flat">
9+
<img alt="GitHub issues" src="https://img.shields.io/github/issues/robustmq/mq9?style=flat">
10+
<img alt="GitHub stars" src="https://img.shields.io/github/stars/robustmq/mq9?style=flat">
11+
</p>
12+
13+
<h3 align="center">
14+
Agent registration, discovery, and reliable async messaging — in one broker.
15+
</h3>
16+
17+
<p align="center">
18+
<a href="#-why-mq9-exists">Why</a> •
19+
<a href="#-two-problems-one-broker">Two Problems</a> •
20+
<a href="#-try-it">Try It</a> •
21+
<a href="#-sdks">SDKs</a> •
22+
<a href="#-a2a-protocol-support">A2A</a> •
23+
<a href="#-langchain--langgraph">LangChain</a> •
24+
<a href="#-protocol">Protocol</a> •
25+
<a href="#-documentation">Docs</a>
26+
</p>
227

3-
**Agent registration, discovery, and reliable async messaging — in one broker.**
28+
---
429

530
mq9 is the infrastructure layer for multi-agent systems. It solves the two foundational problems every multi-agent system faces: how Agents find each other, and how they communicate reliably and asynchronously.
631

7-
Unlike general-purpose registries (etcd, Consul) combined with general-purpose queues (Kafka, NATS), mq9 is designed specifically for Agent communication. It provides an AgentCard data model, capability-based semantic discovery, per-Agent persistent mailboxes, N-to-N Agent topology, and long-task state retention — all in a single broker with shared runtime, storage, network, and cluster coordination. Agent state and message routing are consistent end-to-end.
32+
Unlike general-purpose registries (etcd, Consul) combined with general-purpose queues (Kafka, NATS), mq9 is designed specifically for Agent communication. It provides an AgentCard data model, capability-based semantic discovery, per-Agent persistent mailboxes, N-to-N Agent topology, and long-task state retention — all in a single broker with shared runtime, storage, network, and cluster coordination.
33+
34+
mq9 natively supports the **A2A (Agent-to-Agent)** protocol via the `mq9.a2a` SDK facade, wrapping the official a2a-sdk so developers can build a fully compliant A2A Agent in 15 lines of code.
35+
36+
> **mq9 = Broker + SDKs**
37+
> The **Broker** (server) code lives in [github.com/robustmq/robustmq](https://github.com/robustmq/robustmq) — mq9 is RobustMQ's fifth native protocol, documented at [robustmq.com](https://robustmq.com).
38+
> This repo contains the **SDKs** (Python, Java, Go, Rust, JavaScript), LangChain toolkit, demos, and the [mq9.robustmq.com](https://mq9.robustmq.com) documentation site.
839
9-
mq9 natively supports the A2A (Agent-to-Agent) protocol via the `mq9.a2a` SDK facade, wrapping the official a2a-sdk so developers can build a fully compliant A2A Agent in 15 lines of code. Native protocol access and forward compatibility with MCP and ANP are also supported.
40+
![mq9 Architecture](website/public/diagram-architecture.svg)
1041

11-
[mq9.robustmq.com](https://mq9.robustmq.com) · [Protocol Spec](./protocol.md) · [RobustMQ](https://github.com/robustmq/robustmq)
42+
[mq9.robustmq.com](https://mq9.robustmq.com) · [Protocol Spec](./protocol.md) · [Broker — RobustMQ](https://github.com/robustmq/robustmq)
1243

1344
---
1445

15-
## Why mq9 Exists
46+
## 🌟 Why mq9 Exists
1647

1748
AI Agents communicate differently from traditional services. Agent tasks are long-running (LLM inference, multi-step tool calls, human approvals). Agents are frequently offline or started on demand. Agents discover each other by capability, not by fixed address. Multi-agent collaboration requires N-to-N topology — something the request-response model doesn't naturally support.
1849

19-
The A2A protocol (originally from Google, now evolving under the Linux Foundation) has become the leading open standard for Agent communication. Its 1.0 spec intentionally leaves discovery, reliable transport, and long-task recovery to the ecosystem — explicitly marking discovery as "outside the scope of the A2A protocol itself" and providing transport extension points for community implementation.
50+
The A2A protocol has become the leading open standard for Agent communication. Its spec intentionally leaves discovery, reliable transport, and long-task recovery to the ecosystem. A survey of the A2A ecosystem shows the SDK, framework integration, and platform Runtime spaces are crowded — but Agent registry, reliable async transport, and protocol-neutral communication infrastructure are clear gaps.
2051

21-
A survey of the A2A ecosystem (awesome-a2a) shows the SDK, framework integration, and platform Runtime spaces are crowded — but Agent registry, reliable async transport, and protocol-neutral communication infrastructure are clear gaps. Teams building multi-agent systems today must either assemble general-purpose tools (etcd + Kafka + glue code) or accept the limitations of HTTP-only communication. Neither is ideal.
22-
23-
mq9 fills that gap: a broker purpose-built for Agent communication, with registration and messaging unified in one system.
52+
Teams building multi-agent systems today must either assemble general-purpose tools (etcd + Kafka + glue code) or accept the limitations of HTTP-only communication. mq9 fills that gap: a broker purpose-built for Agent communication, with registration and messaging unified in one system.
2453

2554
---
2655

27-
## Two Problems. One Broker.
56+
## 🤖 Two Problems. One Broker.
2857

2958
**Problem 1 — Agents cannot find each other.**
3059
Agents are dynamic. They come online with different capabilities, at different times. Without a registry, every team hardcodes addresses or builds their own directory. mq9 gives every Agent a place to publish its capabilities and be discovered by others — by keyword or by semantic intent.
3160

3261
**Problem 2 — Agents are not always online at the same time.**
3362
Agents are task-driven — they start, execute, and stop. When Agent A sends to Agent B and B is offline, the message is lost. HTTP requires both sides to be online. Redis pub/sub has no persistence. mq9 solves this with persistent mailboxes: send a message, the recipient gets it whenever they come online.
3463

64+
| Problem | mq9's answer |
65+
|---------|-------------|
66+
| How do Agents find each other? | Built-in registry: `AGENT.REGISTER` + `AGENT.DISCOVER` with full-text and semantic vector search |
67+
| How do Agents communicate reliably? | Persistent mailbox per Agent: messages wait until the recipient is online, with 3-tier priority and FETCH+ACK pull consumption |
68+
3569
---
3670

37-
## Try it — public demo server
71+
## 🚀 Try It — public demo server
3872

3973
```bash
4074
export NATS_URL=nats://demo.robustmq.com:4222
@@ -66,43 +100,34 @@ nats request '$mq9.AI.MSG.ACK.agent.translator' \
66100

67101
---
68102

69-
## SDKs
103+
## 📦 SDKs
70104

71-
| Language | Install | Directory |
72-
| ---------- | ----------------------------------- | ------------- |
73-
| Python | `pip install mq9` | `python/` |
74-
| JavaScript | `npm install mq9` | `javascript/` |
75-
| Go | `go get github.com/robustmq/mq9/go` | `go/` |
76-
| Rust | `cargo add mq9` | `rust/` |
77-
| Java | `io.mq9:mq9:0.1.0` | `java/` |
105+
| Language | Install | Directory |
106+
|----------|---------|-----------|
107+
| Python | `pip install mq9` | `python/` |
108+
| JavaScript | `npm install mq9` | `javascript/` |
109+
| Go | `go get github.com/robustmq/mq9/go` | `go/` |
110+
| Rust | `cargo add mq9` | `rust/` |
111+
| Java | `io.mq9:mq9:0.1.0` | `java/` |
78112

79113
### Python
80114

81115
```python
82116
from mq9 import Mq9Client, Priority
83117

84118
async with Mq9Client("nats://localhost:4222") as client:
85-
# Register Agent
86119
await client.agent_register({
87120
"name": "agent.translator",
88121
"mailbox": "agent.translator",
89122
"payload": "Multilingual translation; EN/ZH/JA/KO",
90123
})
91124

92-
# Discover Agents by semantic intent
93125
agents = await client.agent_discover(semantic="translate Chinese to English", limit=5)
94126

95-
# Create mailbox and send
96127
address = await client.mailbox_create(name="agent.inbox", ttl=3600)
97128
await client.send(address, b'{"task":"analyze"}', priority=Priority.URGENT)
98129

99-
# Continuous consume loop
100-
consumer = await client.consume(
101-
address,
102-
handler=async_handler,
103-
group_name="workers",
104-
auto_ack=True,
105-
)
130+
consumer = await client.consume(address, handler=my_handler, group_name="workers", auto_ack=True)
106131
await consumer.stop()
107132
```
108133

@@ -114,11 +139,8 @@ import { Mq9Client, Priority } from "mq9";
114139
const client = new Mq9Client("nats://localhost:4222");
115140
await client.connect();
116141

117-
await client.agentRegister({
118-
name: "agent.translator",
119-
mailbox: "agent.translator",
120-
payload: "Multilingual translation; EN/ZH/JA/KO",
121-
});
142+
await client.agentRegister({ name: "agent.translator", mailbox: "agent.translator",
143+
payload: "Multilingual translation; EN/ZH/JA/KO" });
122144

123145
const agents = await client.agentDiscover({ semantic: "translate Chinese to English", limit: 5 });
124146

@@ -132,11 +154,8 @@ await client.send(address, { task: "analyze" }, { priority: Priority.URGENT });
132154
client, _ := mq9.Connect("nats://localhost:4222")
133155
defer client.Close()
134156

135-
client.AgentRegister(ctx, mq9.AgentInfo{
136-
Name: "agent.translator",
137-
Mailbox: "agent.translator",
138-
Payload: "Multilingual translation; EN/ZH/JA/KO",
139-
})
157+
client.AgentRegister(ctx, mq9.AgentInfo{Name: "agent.translator", Mailbox: "agent.translator",
158+
Payload: "Multilingual translation; EN/ZH/JA/KO"})
140159

141160
agents, _ := client.AgentDiscover(ctx, mq9.DiscoverOptions{Semantic: "translate Chinese to English", Limit: 5})
142161

@@ -146,30 +165,56 @@ client.Send(ctx, address, []byte(`{"task":"analyze"}`), mq9.SendOptions{Priority
146165

147166
---
148167

149-
## Protocol
168+
## 🔗 A2A Protocol Support
150169

151-
10 commands over NATS request/reply under `$mq9.AI.*`:
170+
mq9 natively supports the **A2A (Agent-to-Agent)** protocol. The `mq9.a2a` SDK facade wraps the official `a2a-sdk` — build a fully compliant A2A Agent in 15 lines of code, with mq9 handling discovery, persistent delivery, and priority routing underneath.
152171

153-
| Category | Subject | Description |
154-
| -------- | ------- | ----------- |
155-
| Registry | `$mq9.AI.AGENT.REGISTER` | Register Agent with capability description |
156-
| Registry | `$mq9.AI.AGENT.DISCOVER` | Full-text + semantic vector search |
157-
| Registry | `$mq9.AI.AGENT.REPORT` | Heartbeat / status update |
158-
| Registry | `$mq9.AI.AGENT.UNREGISTER` | Unregister at shutdown |
159-
| Mailbox | `$mq9.AI.MAILBOX.CREATE` | Create persistent mailbox with TTL |
160-
| Messaging | `$mq9.AI.MSG.SEND.{addr}` | Send message (priority via `mq9-priority` header) |
161-
| Messaging | `$mq9.AI.MSG.FETCH.{addr}` | Pull messages; stateful or stateless |
162-
| Messaging | `$mq9.AI.MSG.ACK.{addr}` | Advance consumer group offset |
163-
| Messaging | `$mq9.AI.MSG.QUERY.{addr}` | Inspect mailbox without affecting offset |
164-
| Messaging | `$mq9.AI.MSG.DELETE.{addr}.{id}` | Delete a specific message |
172+
```python
173+
from mq9.a2a import Mq9A2AAgent
174+
from a2a.types.a2a_pb2 import TaskState, TaskStatus, TaskStatusUpdateEvent, TaskArtifactUpdateEvent
175+
176+
agent = Mq9A2AAgent()
177+
178+
# A2A protocol event sequence: WORKING → Artifact → COMPLETED
179+
@agent.on_message(group_name="translator.workers", deliver="earliest")
180+
async def handle(context, event_queue):
181+
await event_queue.enqueue_event(TaskStatusUpdateEvent(task_id=context.task_id,
182+
status=TaskStatus(state=TaskState.TASK_STATE_WORKING)))
183+
result = my_translate(context.message.parts[0].text)
184+
await event_queue.enqueue_event(TaskArtifactUpdateEvent(task_id=context.task_id,
185+
artifact=new_text_artifact("translation", result)))
186+
await event_queue.enqueue_event(TaskStatusUpdateEvent(task_id=context.task_id,
187+
status=TaskStatus(state=TaskState.TASK_STATE_COMPLETED)))
188+
189+
await agent.connect()
190+
await agent.create_mailbox("agent.translator")
191+
await agent.register(agent_card)
192+
```
165193

166-
Message headers: `mq9-priority` (critical/urgent/normal), `mq9-key` (dedup), `mq9-delay`, `mq9-ttl`, `mq9-tags`.
194+
Java:
167195

168-
Any NATS client works — no SDK required. Full spec: [protocol.md](./protocol.md).
196+
```java
197+
Mq9A2AAgent agent = Mq9A2AAgent.builder().build();
198+
199+
// A2A protocol event sequence: WORKING → Artifact → COMPLETED
200+
agent.onMessage(
201+
(ctx, queue) ->
202+
queue.working(ctx)
203+
.thenCompose(v -> queue.artifact(ctx, "translation",
204+
myTranslate(ctx.firstTextPart().orElse(""))))
205+
.thenCompose(v -> queue.completed(ctx)),
206+
ConsumeOptions.builder().groupName("translator.workers").deliver("earliest").build()
207+
);
208+
209+
agent.connect().join();
210+
agent.createMailbox("agent.translator", 0).join();
211+
```
212+
213+
[A2A Python docs](https://mq9.robustmq.com/docs/a2a/python) · [A2A Java docs](https://mq9.robustmq.com/docs/a2a/java)
169214

170215
---
171216

172-
## LangChain / LangGraph
217+
## 🧩 LangChain / LangGraph
173218

174219
`langchain-mq9` wraps all mq9 operations as LangChain tools:
175220

@@ -189,50 +234,59 @@ app = create_react_agent(llm, toolkit.get_tools())
189234

190235
---
191236

192-
## Key Scenarios
237+
## 📡 Protocol
238+
239+
10 commands over NATS request/reply under `$mq9.AI.*`:
240+
241+
| Category | Subject | Description |
242+
|----------|---------|-------------|
243+
| Registry | `$mq9.AI.AGENT.REGISTER` | Register Agent with capability description |
244+
| Registry | `$mq9.AI.AGENT.DISCOVER` | Full-text + semantic vector search |
245+
| Registry | `$mq9.AI.AGENT.REPORT` | Heartbeat / status update |
246+
| Registry | `$mq9.AI.AGENT.UNREGISTER` | Unregister at shutdown |
247+
| Mailbox | `$mq9.AI.MAILBOX.CREATE` | Create persistent mailbox with TTL |
248+
| Messaging | `$mq9.AI.MSG.SEND.{addr}` | Send message (priority via `mq9-priority` header) |
249+
| Messaging | `$mq9.AI.MSG.FETCH.{addr}` | Pull messages; stateful or stateless |
250+
| Messaging | `$mq9.AI.MSG.ACK.{addr}` | Advance consumer group offset |
251+
| Messaging | `$mq9.AI.MSG.QUERY.{addr}` | Inspect mailbox without affecting offset |
252+
| Messaging | `$mq9.AI.MSG.DELETE.{addr}.{id}` | Delete a specific message |
253+
254+
Message headers: `mq9-priority` (critical/urgent/normal), `mq9-key` (dedup), `mq9-delay`, `mq9-ttl`, `mq9-tags`.
193255

194-
| Scenario | Pattern |
195-
| -------- | ------- |
196-
| Capability-based routing | DISCOVER by intent → SEND to found Agent |
197-
| Sub-Agent result delivery | Private reply mailbox + `reply_to` field |
198-
| Multi-worker task queue | Shared `group_name` — each task to exactly one worker |
199-
| Cloud-to-edge | Messages persist during outage; FETCHed in priority order on reconnect |
200-
| Human-in-the-loop | Humans use the same protocol as Agents — no webhooks |
201-
| Async request-reply | A sends with `reply_to`; B replies when ready; A FETCHes |
256+
Any NATS client works — no SDK required. Full spec: [protocol.md](./protocol.md).
202257

203258
---
204259

205-
## Repository Structure
260+
## 🗂️ Repository Structure
206261

207262
```
208263
mq9/
209264
python/ — Python SDK (pip install mq9)
210265
javascript/ — TypeScript/JavaScript SDK (npm install mq9)
211266
java/ — Java SDK (io.mq9:mq9)
212-
go/ — Go SDK (github.com/robustmq/mq9/go)
213-
rust/ — Rust SDK (cargo add mq9)
267+
go/ — Go SDK
268+
rust/ — Rust SDK
214269
langchain-mq9/ — LangChain / LangGraph toolkit
215270
demo/ — Ready-to-run demos (all languages)
216271
website/ — Documentation site (mq9.robustmq.com)
217272
protocol.md — Full protocol specification
218273
VERSION — Single source of truth for all SDK versions
219274
```
220275

221-
---
222-
223-
## Demo
276+
### Demo
224277

225278
Ready-to-run demos in [`demo/`](./demo/):
226279

227280
| Demo | Description |
228-
| ---- | ----------- |
281+
|------|-------------|
229282
| `message_demo` | Mailbox, send/fetch/ack, priority, key dedup, tags, delay, query, delete |
230283
| `agent_demo` | Register, heartbeat, full-text search, semantic search, send to discovered agent |
284+
| `a2a_demo` | Two-way A2A communication over mq9 |
231285
| `langchain_demo` | LangChain + LangGraph tool usage (Python only) |
232286

233287
---
234288

235-
## Documentation
289+
## 📚 Documentation
236290

237291
[mq9.robustmq.com](https://mq9.robustmq.com)
238292

@@ -241,3 +295,9 @@ Ready-to-run demos in [`demo/`](./demo/):
241295
## Status
242296

243297
mq9 is under active development as part of [RobustMQ](https://github.com/robustmq/robustmq).
298+
299+
---
300+
301+
<div align="center">
302+
<sub>Built with ❤️ by the <a href="https://github.com/robustmq/robustmq/graphs/contributors">RobustMQ team</a>.</sub>
303+
</div>

0 commit comments

Comments
 (0)