diff --git a/CHANGELOG.md b/CHANGELOG.md
index 407acfda2f3..3a0971d43b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ Docs: https://docs.openclaw.ai
## Unreleased
+### Changes
+
+- Channels/Yuanbao: register the Tencent Yuanbao external channel plugin (`openclaw-plugin-yuanbao`) in the official channel catalog, contract suites, and community plugin docs, with a new `docs/channels/yuanbao.md` quick-start guide for WebSocket bot DMs and group chats. (#72756) Thanks @loongfay.
+
## 2026.4.26
### Changes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bffda1fcd71..433a2c5bb92 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -77,7 +77,7 @@ Welcome to the lobster tank! ๐ฆ
- **Tengji (George) Zhang** - Chinese model APIs, cloud, pi
- GitHub: [@odysseus0](https://github.com/odysseus0) ยท X: [@odysseus0z](https://x.com/odysseus0z)
-- **Sliverp** - Chinese Channel: QQ, WeChat, Wecom, Dingtalk, Feishu
+- **Sliverp** - Chinese Channel: QQ, WeChat, Wecom, Yuanbao, Dingtalk, Feishu
- GitHub: [@sliverp](https://github.com/sliverp) ยท X: [@sliver01234](https://x.com/sliver01234)
- **Mason Huang** - Stability, Security, Speed
diff --git a/docs/channels/yuanbao.md b/docs/channels/yuanbao.md
new file mode 100644
index 00000000000..1f97566ee82
--- /dev/null
+++ b/docs/channels/yuanbao.md
@@ -0,0 +1,416 @@
+---
+summary: "YuanBao bot overview, features, and configuration"
+read_when:
+ - You want to connect a YuanBao bot
+ - You are configuring the YuanBao channel
+title: YuanBao
+---
+
+# YuanBao
+
+YuanBao is Tencent's AI assistant platform that supports bot integration via instant messaging. Bots can interact with users through direct messages and group chats.
+
+**Status:** production-ready for bot DMs + group chats. WebSocket is the only supported connection mode.
+
+---
+
+## Quick start
+
+> **Requires OpenClaw 2026.4.10 or above.** Run `openclaw --version` to check. Upgrade with `openclaw update`.
+
+
+
+ ```bash
+ openclaw channels add --channel yuanbao --token "appKey:appSecret"
+ ```
+ The `--token` value uses colon-separated `appKey:appSecret` format. You can obtain these from the YuanBao APP by creating a robot in your application settings.
+
+
+
+ ```bash
+ openclaw gateway restart
+ ```
+
+
+
+### Interactive setup (alternative)
+
+You can also use the interactive wizard:
+
+```bash
+openclaw channels login --channel yuanbao
+```
+
+Follow the prompts to enter your App ID and App Secret.
+
+---
+
+## Access control
+
+### Direct messages
+
+Configure `dmPolicy` to control who can DM the bot:
+
+- `"pairing"` โ unknown users receive a pairing code; approve via CLI
+- `"allowlist"` โ only users listed in `allowFrom` can chat
+- `"open"` โ allow all users (default)
+- `"disabled"` โ disable all DMs
+
+**Approve a pairing request:**
+
+```bash
+openclaw pairing list yuanbao
+openclaw pairing approve yuanbao
+```
+
+### Group chats
+
+**Mention requirement** (`channels.yuanbao.requireMention`):
+
+- `true` โ require @mention (default)
+- `false` โ respond without @mention
+
+Replying to the bot's message in a group chat is treated as an implicit mention.
+
+---
+
+## Configuration examples
+
+### Basic setup with open DM policy
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ appKey: "your_app_key",
+ appSecret: "your_app_secret",
+ dm: {
+ policy: "open",
+ },
+ },
+ },
+}
+```
+
+### Restrict DMs to specific users
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ appKey: "your_app_key",
+ appSecret: "your_app_secret",
+ dm: {
+ policy: "allowlist",
+ allowFrom: ["user_id_1", "user_id_2"],
+ },
+ },
+ },
+}
+```
+
+### Disable @mention requirement in groups
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ requireMention: false,
+ },
+ },
+}
+```
+
+### Optimize outbound message delivery
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ // Send each chunk immediately without buffering
+ outboundQueueStrategy: "immediate",
+ },
+ },
+}
+```
+
+### Tune merge-text strategy
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ outboundQueueStrategy: "merge-text",
+ minChars: 2800, // buffer until this many chars
+ maxChars: 3000, // force split above this limit
+ idleMs: 5000, // auto-flush after idle timeout (ms)
+ },
+ },
+}
+```
+
+---
+
+## Common commands
+
+| Command | Description |
+| ---------- | --------------------------- |
+| `/help` | Show available commands |
+| `/status` | Show bot status |
+| `/new` | Start a new session |
+| `/stop` | Stop the current run |
+| `/restart` | Restart OpenClaw |
+| `/compact` | Compact the session context |
+
+> YuanBao supports native slash-command menus. Commands are synced to the platform automatically when the gateway starts.
+
+---
+
+## Troubleshooting
+
+### Bot does not respond in group chats
+
+1. Ensure the bot is added to the group
+2. Ensure you @mention the bot (required by default)
+3. Check logs: `openclaw logs --follow`
+
+### Bot does not receive messages
+
+1. Ensure the bot is created and approved in YuanBao APP
+2. Ensure `appKey` and `appSecret` are correctly configured
+3. Ensure the gateway is running: `openclaw gateway status`
+4. Check logs: `openclaw logs --follow`
+
+### Bot sends empty or fallback replies
+
+1. Check if the AI model is returning valid content
+2. The default fallback reply is: "ๆๆถๆ ๆณ่งฃ็ญ๏ผไฝ ๅฏไปฅๆขไธช้ฎ้ข้ฎ้ฎๆๅฆ"
+3. Customize it via `channels.yuanbao.fallbackReply`
+
+### App Secret leaked
+
+1. Reset the App Secret in YuanBao APP
+2. Update the value in your config
+3. Restart the gateway: `openclaw gateway restart`
+
+---
+
+## Advanced configuration
+
+### Multiple accounts
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ defaultAccount: "main",
+ accounts: {
+ main: {
+ appKey: "key_xxx",
+ appSecret: "secret_xxx",
+ name: "Primary bot",
+ },
+ backup: {
+ appKey: "key_yyy",
+ appSecret: "secret_yyy",
+ name: "Backup bot",
+ enabled: false,
+ },
+ },
+ },
+ },
+}
+```
+
+`defaultAccount` controls which account is used when outbound APIs do not specify an `accountId`.
+
+### Message limits
+
+- `maxChars` โ single message max character count (default: `3000` chars)
+- `mediaMaxMb` โ media upload/download limit (default: `20` MB)
+- `overflowPolicy` โ behavior when message exceeds limit: `"split"` (default) or `"stop"`
+
+### Streaming
+
+YuanBao supports block-level streaming output. When enabled, the bot sends text in chunks as it generates.
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ disableBlockStreaming: false, // block streaming enabled (default)
+ },
+ },
+}
+```
+
+Set `disableBlockStreaming: true` to send the complete reply in one message.
+
+### Group chat history context
+
+Control how many historical messages are included in the AI context for group chats:
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ historyLimit: 100, // default: 100, set 0 to disable
+ },
+ },
+}
+```
+
+### Reply-to mode
+
+Control how the bot quotes messages when replying in group chats:
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ replyToMode: "first", // "off" | "first" | "all" (default: "first")
+ },
+ },
+}
+```
+
+| Value | Behavior |
+| --------- | -------------------------------------------------------- |
+| `"off"` | No quote reply |
+| `"first"` | Quote only the first reply per inbound message (default) |
+| `"all"` | Quote every reply |
+
+### Markdown hint injection
+
+By default, the bot injects instructions in the system prompt to prevent the AI model from wrapping the entire reply in markdown code blocks.
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ markdownHintEnabled: true, // default: true
+ },
+ },
+}
+```
+
+### Debug mode
+
+Enable unsanitized log output for specific bot IDs:
+
+```json5
+{
+ channels: {
+ yuanbao: {
+ debugBotIds: ["bot_user_id_1", "bot_user_id_2"],
+ },
+ },
+}
+```
+
+### Multi-agent routing
+
+Use `bindings` to route YuanBao DMs or groups to different agents.
+
+```json5
+{
+ agents: {
+ list: [
+ { id: "main" },
+ { id: "agent-a", workspace: "/home/user/agent-a" },
+ { id: "agent-b", workspace: "/home/user/agent-b" },
+ ],
+ },
+ bindings: [
+ {
+ agentId: "agent-a",
+ match: {
+ channel: "yuanbao",
+ peer: { kind: "direct", id: "user_xxx" },
+ },
+ },
+ {
+ agentId: "agent-b",
+ match: {
+ channel: "yuanbao",
+ peer: { kind: "group", id: "group_zzz" },
+ },
+ },
+ ],
+}
+```
+
+Routing fields:
+
+- `match.channel`: `"yuanbao"`
+- `match.peer.kind`: `"direct"` (DM) or `"group"` (group chat)
+- `match.peer.id`: user ID or group code
+
+---
+
+## Configuration reference
+
+Full configuration: [Gateway configuration](/gateway/configuration)
+
+| Setting | Description | Default |
+| ------------------------------------------ | ------------------------------------------------- | -------------------------------------- |
+| `channels.yuanbao.enabled` | Enable/disable the channel | `true` |
+| `channels.yuanbao.defaultAccount` | Default account for outbound routing | `default` |
+| `channels.yuanbao.accounts..appKey` | App Key (used for signing and ticket generation) | โ |
+| `channels.yuanbao.accounts..appSecret` | App Secret (used for signing) | โ |
+| `channels.yuanbao.accounts..token` | Pre-signed token (skips automatic ticket signing) | โ |
+| `channels.yuanbao.accounts..name` | Account display name | โ |
+| `channels.yuanbao.accounts..enabled` | Enable/disable a specific account | `true` |
+| `channels.yuanbao.dm.policy` | DM policy | `open` |
+| `channels.yuanbao.dm.allowFrom` | DM allowlist (user ID list) | โ |
+| `channels.yuanbao.requireMention` | Require @mention in groups | `true` |
+| `channels.yuanbao.overflowPolicy` | Long message handling (`split` or `stop`) | `split` |
+| `channels.yuanbao.replyToMode` | Group reply-to strategy (`off`, `first`, `all`) | `first` |
+| `channels.yuanbao.outboundQueueStrategy` | Outbound strategy (`merge-text` or `immediate`) | `merge-text` |
+| `channels.yuanbao.minChars` | Merge-text: min chars to trigger send | `2800` |
+| `channels.yuanbao.maxChars` | Merge-text: max chars per message | `3000` |
+| `channels.yuanbao.idleMs` | Merge-text: idle timeout before auto-flush (ms) | `5000` |
+| `channels.yuanbao.mediaMaxMb` | Media size limit (MB) | `20` |
+| `channels.yuanbao.historyLimit` | Group chat history context entries | `100` |
+| `channels.yuanbao.disableBlockStreaming` | Disable block-level streaming output | `false` |
+| `channels.yuanbao.fallbackReply` | Fallback reply when AI returns no content | `ๆๆถๆ ๆณ่งฃ็ญ๏ผไฝ ๅฏไปฅๆขไธช้ฎ้ข้ฎ้ฎๆๅฆ` |
+| `channels.yuanbao.markdownHintEnabled` | Inject markdown anti-wrapping instructions | `true` |
+| `channels.yuanbao.debugBotIds` | Debug whitelist bot IDs (unsanitized logs) | `[]` |
+
+---
+
+## Supported message types
+
+### Receive
+
+- โ
Text
+- โ
Images
+- โ
Files
+- โ
Audio / Voice
+- โ
Video
+- โ
Stickers / Custom emoji
+- โ
Custom elements (link cards, etc.)
+
+### Send
+
+- โ
Text (with markdown support)
+- โ
Images
+- โ
Files
+- โ
Audio
+- โ
Video
+- โ
Stickers
+
+### Threads and replies
+
+- โ
Quote replies (configurable via `replyToMode`)
+- โ Thread replies (not supported by platform)
+
+---
+
+## Related
+
+- [Channels Overview](/channels) โ all supported channels
+- [Pairing](/channels/pairing) โ DM authentication and pairing flow
+- [Groups](/channels/groups) โ group chat behavior and mention gating
+- [Channel Routing](/channels/channel-routing) โ session routing for messages
+- [Security](/gateway/security) โ access model and hardening
diff --git a/docs/plugins/community.md b/docs/plugins/community.md
index 7377194f546..33bf3189df1 100644
--- a/docs/plugins/community.md
+++ b/docs/plugins/community.md
@@ -130,6 +130,20 @@ formatting, built-in access control, and document/meeting/messaging skills.
openclaw plugins install @wecom/wecom-openclaw-plugin
```
+### Yuanbao
+
+Yuanbao channel plugin for OpenClaw by the Tencent Yuanbao team. Powered by
+WebSocket persistent connections, it supports direct messages & group chats,
+streaming replies, proactive messaging, image/file/audio/video processing,
+Markdown formatting, built-in access control, and slash-command menus.
+
+- **npm:** `openclaw-plugin-yuanbao`
+- **repo:** [github.com/yb-claw/openclaw-plugin-yuanbao](https://github.com/yb-claw/openclaw-plugin-yuanbao)
+
+```bash
+openclaw plugins install openclaw-plugin-yuanbao
+```
+
## Submit your plugin
We welcome community plugins that are useful, documented, and safe to operate.
diff --git a/scripts/lib/official-external-channel-catalog.json b/scripts/lib/official-external-channel-catalog.json
index 97f1f5eef54..2c7f1d01e05 100644
--- a/scripts/lib/official-external-channel-catalog.json
+++ b/scripts/lib/official-external-channel-catalog.json
@@ -23,6 +23,29 @@
"expectedIntegrity": "sha512-bnzfdIEEu1/LFvcdyjaTkyxt27w6c7dqhkPezU62OWaqmcdFsUGR3T55USK/O9pIKsNcnL1Tnu1pqKYCWHFgWQ=="
}
}
+ },
+ {
+ "name": "openclaw-plugin-yuanbao",
+ "description": "OpenClaw Yuanbao channel plugin by the Tencent Yuanbao team.",
+ "source": "external",
+ "kind": "channel",
+ "openclaw": {
+ "channel": {
+ "id": "openclaw-plugin-yuanbao",
+ "label": "Yuanbao",
+ "selectionLabel": "Yuanbao (ๅ
ๅฎ)",
+ "detailLabel": "Yuanbao",
+ "docsPath": "/plugins/community#yuanbao",
+ "docsLabel": "yuanbao",
+ "blurb": "Tencent Yuanbao AI assistant conversation channel.",
+ "aliases": ["yb", "tencent-yuanbao", "ๅ
ๅฎ"],
+ "order": 85
+ },
+ "install": {
+ "npmSpec": "openclaw-plugin-yuanbao",
+ "defaultChoice": "npm"
+ }
+ }
}
]
}
diff --git a/src/channels/plugins/contracts/channel-catalog.contract.test.ts b/src/channels/plugins/contracts/channel-catalog.contract.test.ts
index 6240bf4121e..a9bd782b763 100644
--- a/src/channels/plugins/contracts/channel-catalog.contract.test.ts
+++ b/src/channels/plugins/contracts/channel-catalog.contract.test.ts
@@ -42,3 +42,9 @@ describeChannelCatalogEntryContract({
npmSpec: "@wecom/wecom-openclaw-plugin@2026.4.23",
alias: "wework",
});
+
+describeChannelCatalogEntryContract({
+ channelId: "openclaw-plugin-yuanbao",
+ npmSpec: "openclaw-plugin-yuanbao",
+ alias: "yb",
+});
diff --git a/test/helpers/channels/channel-plugin-catalog-contract-suites.ts b/test/helpers/channels/channel-plugin-catalog-contract-suites.ts
index 73823833b3c..e31a31eb9f8 100644
--- a/test/helpers/channels/channel-plugin-catalog-contract-suites.ts
+++ b/test/helpers/channels/channel-plugin-catalog-contract-suites.ts
@@ -281,6 +281,71 @@ export function describeChannelPluginCatalogEntriesContract() {
};
},
},
+ {
+ name: "accepts rich external manifest entries for yuanbao with pinned npm metadata",
+ setup: () => {
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-catalog-yuanbao-"));
+ const catalogPath = path.join(dir, "catalog.json");
+ fs.writeFileSync(
+ catalogPath,
+ JSON.stringify({
+ $schema: "./manifest.schema.json",
+ schemaVersion: 1,
+ description:
+ "Extension manifest. Declares plugin packages that OpenClaw can discover during onboarding and install on demand via `openclaw plugins install`.",
+ entries: [
+ {
+ name: "openclaw-plugin-yuanbao",
+ description:
+ "OpenClaw Yuanbao (ๅ
ๅฎ) channel plugin โ community maintained, published on npm.",
+ source: "external",
+ kind: "channel",
+ openclaw: {
+ channel: {
+ id: "openclaw-plugin-yuanbao",
+ label: "Yuanbao",
+ selectionLabel: "Yuanbao (Tencent Yuanbao)",
+ detailLabel: "Yuanbao",
+ docsPath: "/channels/yuanbao",
+ docsLabel: "yuanbao",
+ blurb: "Tencent Yuanbao AI assistant conversation channel.",
+ aliases: ["yb", "tencent-yuanbao"],
+ order: 78,
+ },
+ install: {
+ npmSpec: "openclaw-plugin-yuanbao@1.0.0",
+ defaultChoice: "npm",
+ minHostVersion: ">=2026.4.10",
+ expectedIntegrity: "sha512-yuanbao",
+ },
+ },
+ },
+ ],
+ }),
+ );
+ return {
+ channelId: "openclaw-plugin-yuanbao",
+ catalogPaths: [catalogPath],
+ expected: {
+ id: "openclaw-plugin-yuanbao",
+ meta: {
+ label: "Yuanbao",
+ selectionLabel: "Yuanbao (Tencent Yuanbao)",
+ detailLabel: "Yuanbao",
+ docsPath: "/channels/yuanbao",
+ docsLabel: "yuanbao",
+ blurb: "Tencent Yuanbao AI assistant conversation channel.",
+ },
+ install: {
+ npmSpec: "openclaw-plugin-yuanbao@1.0.0",
+ defaultChoice: "npm",
+ minHostVersion: ">=2026.4.10",
+ expectedIntegrity: "sha512-yuanbao",
+ },
+ },
+ };
+ },
+ },
] as const)("$name", ({ setup }) => {
const setupResult = setup();
const { channelId, expected } = setupResult;
diff --git a/test/official-channel-catalog.test.ts b/test/official-channel-catalog.test.ts
index c9e186381f0..5b50a5505d8 100644
--- a/test/official-channel-catalog.test.ts
+++ b/test/official-channel-catalog.test.ts
@@ -86,6 +86,19 @@ describe("buildOfficialChannelCatalog", () => {
},
}),
}),
+ expect.objectContaining({
+ name: "openclaw-plugin-yuanbao",
+ openclaw: expect.objectContaining({
+ channel: expect.objectContaining({
+ id: "openclaw-plugin-yuanbao",
+ label: "Yuanbao",
+ }),
+ install: {
+ npmSpec: "openclaw-plugin-yuanbao",
+ defaultChoice: "npm",
+ },
+ }),
+ }),
{
name: "@openclaw/whatsapp",
version: "2026.3.23",
@@ -153,6 +166,9 @@ describe("buildOfficialChannelCatalog", () => {
expect.objectContaining({
name: "@wecom/wecom-openclaw-plugin",
}),
+ expect.objectContaining({
+ name: "openclaw-plugin-yuanbao",
+ }),
{
name: "@openclaw/whatsapp",
openclaw: {