@qwen-code/qwen-code 0.14.0-preview.1 → 0.14.0-preview.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -9
- package/bundled/qc-helper/SKILL.md +151 -0
- package/bundled/qc-helper/docs/_meta.ts +30 -0
- package/bundled/qc-helper/docs/common-workflow.md +571 -0
- package/bundled/qc-helper/docs/configuration/_meta.ts +10 -0
- package/bundled/qc-helper/docs/configuration/auth.md +366 -0
- package/bundled/qc-helper/docs/configuration/memory.md +0 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +542 -0
- package/bundled/qc-helper/docs/configuration/qwen-ignore.md +55 -0
- package/bundled/qc-helper/docs/configuration/settings.md +655 -0
- package/bundled/qc-helper/docs/configuration/themes.md +160 -0
- package/bundled/qc-helper/docs/configuration/trusted-folders.md +61 -0
- package/bundled/qc-helper/docs/extension/_meta.ts +9 -0
- package/bundled/qc-helper/docs/extension/extension-releasing.md +121 -0
- package/bundled/qc-helper/docs/extension/getting-started-extensions.md +299 -0
- package/bundled/qc-helper/docs/extension/introduction.md +310 -0
- package/bundled/qc-helper/docs/features/_meta.ts +18 -0
- package/bundled/qc-helper/docs/features/approval-mode.md +263 -0
- package/bundled/qc-helper/docs/features/arena.md +218 -0
- package/bundled/qc-helper/docs/features/channels/_meta.ts +7 -0
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +134 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +336 -0
- package/bundled/qc-helper/docs/features/channels/plugins.md +87 -0
- package/bundled/qc-helper/docs/features/channels/telegram.md +120 -0
- package/bundled/qc-helper/docs/features/channels/weixin.md +106 -0
- package/bundled/qc-helper/docs/features/checkpointing.md +77 -0
- package/bundled/qc-helper/docs/features/commands.md +312 -0
- package/bundled/qc-helper/docs/features/headless.md +318 -0
- package/bundled/qc-helper/docs/features/hooks.md +715 -0
- package/bundled/qc-helper/docs/features/language.md +139 -0
- package/bundled/qc-helper/docs/features/lsp.md +417 -0
- package/bundled/qc-helper/docs/features/mcp.md +281 -0
- package/bundled/qc-helper/docs/features/sandbox.md +241 -0
- package/bundled/qc-helper/docs/features/skills.md +289 -0
- package/bundled/qc-helper/docs/features/sub-agents.md +511 -0
- package/bundled/qc-helper/docs/features/token-caching.md +29 -0
- package/bundled/qc-helper/docs/ide-integration/_meta.ts +4 -0
- package/bundled/qc-helper/docs/ide-integration/ide-companion-spec.md +182 -0
- package/bundled/qc-helper/docs/ide-integration/ide-integration.md +144 -0
- package/bundled/qc-helper/docs/integration-github-action.md +241 -0
- package/bundled/qc-helper/docs/integration-jetbrains.md +81 -0
- package/bundled/qc-helper/docs/integration-vscode.md +39 -0
- package/bundled/qc-helper/docs/integration-zed.md +72 -0
- package/bundled/qc-helper/docs/overview.md +64 -0
- package/bundled/qc-helper/docs/quickstart.md +273 -0
- package/bundled/qc-helper/docs/reference/_meta.ts +3 -0
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +72 -0
- package/bundled/qc-helper/docs/support/Uninstall.md +42 -0
- package/bundled/qc-helper/docs/support/_meta.ts +6 -0
- package/bundled/qc-helper/docs/support/tos-privacy.md +112 -0
- package/bundled/qc-helper/docs/support/troubleshooting.md +123 -0
- package/cli.js +4795 -3839
- package/locales/de.js +2 -2
- package/locales/en.js +2 -2
- package/locales/ja.js +2 -2
- package/locales/pt.js +2 -2
- package/locales/ru.js +2 -2
- package/locales/zh.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Channels
|
|
2
|
+
|
|
3
|
+
Channels let you interact with a Qwen Code agent from messaging platforms like Telegram, WeChat, or DingTalk, instead of the terminal. You send messages from your phone or desktop chat app, and the agent responds just like it would in the CLI.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
When you run `qwen channel start`, Qwen Code:
|
|
8
|
+
|
|
9
|
+
1. Reads channel configurations from your `settings.json`
|
|
10
|
+
2. Spawns a single agent process using the [Agent Client Protocol (ACP)](../../developers/architecture)
|
|
11
|
+
3. Connects to each messaging platform and starts listening for messages
|
|
12
|
+
4. Routes incoming messages to the agent and sends responses back to the correct chat
|
|
13
|
+
|
|
14
|
+
All channels share one agent process with isolated sessions per user. Each channel can have its own working directory, model, and instructions.
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
1. Set up a bot on your messaging platform (see channel-specific guides: [Telegram](./telegram), [WeChat](./weixin), [DingTalk](./dingtalk))
|
|
19
|
+
2. Add the channel configuration to `~/.qwen/settings.json`
|
|
20
|
+
3. Run `qwen channel start` to start all channels, or `qwen channel start <name>` for a single channel
|
|
21
|
+
|
|
22
|
+
Want to connect a platform that isn't built in? See [Plugins](./plugins) to add a custom adapter as an extension.
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
Channels are configured under the `channels` key in `settings.json`. Each channel has a name and a set of options:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"channels": {
|
|
31
|
+
"my-channel": {
|
|
32
|
+
"type": "telegram",
|
|
33
|
+
"token": "$MY_BOT_TOKEN",
|
|
34
|
+
"senderPolicy": "allowlist",
|
|
35
|
+
"allowedUsers": ["123456789"],
|
|
36
|
+
"sessionScope": "user",
|
|
37
|
+
"cwd": "/path/to/working/directory",
|
|
38
|
+
"instructions": "Optional system instructions for the agent.",
|
|
39
|
+
"groupPolicy": "disabled",
|
|
40
|
+
"groups": {
|
|
41
|
+
"*": { "requireMention": true }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Options
|
|
49
|
+
|
|
50
|
+
| Option | Required | Description |
|
|
51
|
+
| ------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `type` | Yes | Channel type: `telegram`, `weixin`, `dingtalk`, or a custom type from an extension (see [Plugins](./plugins)) |
|
|
53
|
+
| `token` | Telegram | Bot token. Supports `$ENV_VAR` syntax to read from environment variables. Not needed for WeChat or DingTalk |
|
|
54
|
+
| `clientId` | DingTalk | DingTalk AppKey. Supports `$ENV_VAR` syntax |
|
|
55
|
+
| `clientSecret` | DingTalk | DingTalk AppSecret. Supports `$ENV_VAR` syntax |
|
|
56
|
+
| `model` | No | Model to use for this channel (e.g., `qwen3.5-plus`). Overrides the default model. Useful for multimodal models that support image input |
|
|
57
|
+
| `senderPolicy` | No | Who can talk to the bot: `allowlist` (default), `open`, or `pairing` |
|
|
58
|
+
| `allowedUsers` | No | List of user IDs allowed to use the bot (used by `allowlist` and `pairing` policies) |
|
|
59
|
+
| `sessionScope` | No | How sessions are scoped: `user` (default), `thread`, or `single` |
|
|
60
|
+
| `cwd` | No | Working directory for the agent. Defaults to the current directory |
|
|
61
|
+
| `instructions` | No | Custom instructions prepended to the first message of each session |
|
|
62
|
+
| `groupPolicy` | No | Group chat access: `disabled` (default), `allowlist`, or `open`. See [Group Chats](#group-chats) |
|
|
63
|
+
| `groups` | No | Per-group settings. Keys are group chat IDs or `"*"` for defaults. See [Group Chats](#group-chats) |
|
|
64
|
+
| `dispatchMode` | No | What happens when you send a message while the bot is busy: `steer` (default), `collect`, or `followup`. See [Dispatch Modes](#dispatch-modes) |
|
|
65
|
+
| `blockStreaming` | No | Progressive response delivery: `on` or `off` (default). See [Block Streaming](#block-streaming) |
|
|
66
|
+
| `blockStreamingChunk` | No | Chunk size bounds: `{ "minChars": 400, "maxChars": 1000 }`. See [Block Streaming](#block-streaming) |
|
|
67
|
+
| `blockStreamingCoalesce` | No | Idle flush: `{ "idleMs": 1500 }`. See [Block Streaming](#block-streaming) |
|
|
68
|
+
|
|
69
|
+
### Sender Policy
|
|
70
|
+
|
|
71
|
+
Controls who can interact with the bot:
|
|
72
|
+
|
|
73
|
+
- **`allowlist`** (default) — Only users listed in `allowedUsers` can send messages. Others are silently ignored.
|
|
74
|
+
- **`pairing`** — Unknown senders receive a pairing code. The bot operator approves them via CLI, and they're added to a persistent allowlist. Users in `allowedUsers` skip pairing entirely. See [DM Pairing](#dm-pairing) below.
|
|
75
|
+
- **`open`** — Anyone can send messages. Use with caution.
|
|
76
|
+
|
|
77
|
+
### Session Scope
|
|
78
|
+
|
|
79
|
+
Controls how conversation sessions are managed:
|
|
80
|
+
|
|
81
|
+
- **`user`** (default) — One session per user. All messages from the same user share a conversation.
|
|
82
|
+
- **`thread`** — One session per thread/topic. Useful for group chats with threads.
|
|
83
|
+
- **`single`** — One shared session for all users. Everyone shares the same conversation.
|
|
84
|
+
|
|
85
|
+
### Token Security
|
|
86
|
+
|
|
87
|
+
Bot tokens should not be stored directly in `settings.json`. Instead, use environment variable references:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"token": "$TELEGRAM_BOT_TOKEN"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Set the actual token in your shell environment or in a `.env` file that gets loaded before running the channel.
|
|
96
|
+
|
|
97
|
+
## DM Pairing
|
|
98
|
+
|
|
99
|
+
When `senderPolicy` is set to `"pairing"`, unknown senders go through an approval flow:
|
|
100
|
+
|
|
101
|
+
1. An unknown user sends a message to the bot
|
|
102
|
+
2. The bot replies with an 8-character pairing code (e.g., `VEQDDWXJ`)
|
|
103
|
+
3. The user shares the code with you (the bot operator)
|
|
104
|
+
4. You approve them via CLI:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
qwen channel pairing approve my-channel VEQDDWXJ
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Once approved, the user's ID is saved to `~/.qwen/channels/<name>-allowlist.json` and all future messages go through normally.
|
|
111
|
+
|
|
112
|
+
### Pairing CLI Commands
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# List pending pairing requests
|
|
116
|
+
qwen channel pairing list my-channel
|
|
117
|
+
|
|
118
|
+
# Approve a request by code
|
|
119
|
+
qwen channel pairing approve my-channel <CODE>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Pairing Rules
|
|
123
|
+
|
|
124
|
+
- Codes are 8 characters, uppercase, using an unambiguous alphabet (no `0`/`O`/`1`/`I`)
|
|
125
|
+
- Codes expire after 1 hour
|
|
126
|
+
- Maximum 3 pending requests per channel at a time — additional requests are ignored until one expires or is approved
|
|
127
|
+
- Users listed in `allowedUsers` in `settings.json` always skip pairing
|
|
128
|
+
- Approved users are stored in `~/.qwen/channels/<name>-allowlist.json` — treat this file as sensitive
|
|
129
|
+
|
|
130
|
+
## Group Chats
|
|
131
|
+
|
|
132
|
+
By default, the bot only works in direct messages. To enable group chat support, set `groupPolicy` to `"allowlist"` or `"open"`.
|
|
133
|
+
|
|
134
|
+
### Group Policy
|
|
135
|
+
|
|
136
|
+
Controls whether the bot participates in group chats at all:
|
|
137
|
+
|
|
138
|
+
- **`disabled`** (default) — The bot ignores all group messages. Safest option.
|
|
139
|
+
- **`allowlist`** — The bot only responds in groups explicitly listed in `groups` by chat ID. The `"*"` key provides default settings but does **not** act as a wildcard allow.
|
|
140
|
+
- **`open`** — The bot responds in all groups it's added to. Use with caution.
|
|
141
|
+
|
|
142
|
+
### Mention Gating
|
|
143
|
+
|
|
144
|
+
In groups, the bot requires an `@mention` or a reply to one of its messages by default. This prevents the bot from responding to every message in a group chat.
|
|
145
|
+
|
|
146
|
+
Configure per-group with the `groups` setting:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"groups": {
|
|
151
|
+
"*": { "requireMention": true },
|
|
152
|
+
"-100123456": { "requireMention": false }
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **`"*"`** — Default settings for all groups. Only sets config defaults, not an allowlist entry.
|
|
158
|
+
- **Group chat ID** — Override settings for a specific group. Overrides `"*"` defaults.
|
|
159
|
+
- **`requireMention`** (default: `true`) — When `true`, the bot only responds to messages that @mention it or reply to one of its messages. When `false`, the bot responds to all messages (useful for dedicated task groups).
|
|
160
|
+
|
|
161
|
+
### How group messages are evaluated
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
1. groupPolicy — is this group allowed? (no → ignore)
|
|
165
|
+
2. requireMention — was the bot mentioned/replied to? (no → ignore)
|
|
166
|
+
3. senderPolicy — is this sender approved? (no → pairing flow)
|
|
167
|
+
4. Route to session
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Telegram Setup for Groups
|
|
171
|
+
|
|
172
|
+
1. Add the bot to a group
|
|
173
|
+
2. **Disable privacy mode** in BotFather (`/mybots` → Bot Settings → Group Privacy → Turn Off) — otherwise the bot won't see non-command messages
|
|
174
|
+
3. **Remove and re-add the bot** to the group after changing privacy mode (Telegram caches this setting)
|
|
175
|
+
|
|
176
|
+
### Finding a Group Chat ID
|
|
177
|
+
|
|
178
|
+
To find a group's chat ID for the `groups` allowlist:
|
|
179
|
+
|
|
180
|
+
1. Stop the bot if it's running
|
|
181
|
+
2. Send a message mentioning the bot in the group
|
|
182
|
+
3. Use the Telegram Bot API to check queued updates:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | python3 -m json.tool
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Look for `message.chat.id` in the response — group IDs are negative numbers (e.g., `-5170296765`).
|
|
189
|
+
|
|
190
|
+
## Media Support
|
|
191
|
+
|
|
192
|
+
Channels support sending images and files to the agent, not just text.
|
|
193
|
+
|
|
194
|
+
### Images
|
|
195
|
+
|
|
196
|
+
Send a photo to the bot and the agent will see it — useful for sharing screenshots, error messages, or diagrams. The image is sent directly to the model as a vision input.
|
|
197
|
+
|
|
198
|
+
To use image support, configure a multimodal model for the channel:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"channels": {
|
|
203
|
+
"my-channel": {
|
|
204
|
+
"type": "telegram",
|
|
205
|
+
"model": "qwen3.5-plus",
|
|
206
|
+
...
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Files
|
|
213
|
+
|
|
214
|
+
Send a document (PDF, code file, text file, etc.) to the bot. The file is downloaded and saved to a temporary directory, and the agent is told the file path so it can read the contents using its file-reading tools.
|
|
215
|
+
|
|
216
|
+
Files work with any model — no multimodal support required.
|
|
217
|
+
|
|
218
|
+
### Platform differences
|
|
219
|
+
|
|
220
|
+
| Feature | Telegram | WeChat | DingTalk |
|
|
221
|
+
| -------- | -------------------------------------------- | -------------------------------- | --------------------------------------------- |
|
|
222
|
+
| Images | Direct download via Bot API | CDN download with AES decryption | downloadCode API (two-step) |
|
|
223
|
+
| Files | Direct download via Bot API (20MB limit) | CDN download with AES decryption | downloadCode API (two-step) |
|
|
224
|
+
| Captions | Photo/file captions included as message text | Not applicable | Rich text: mixed text + images in one message |
|
|
225
|
+
|
|
226
|
+
## Dispatch Modes
|
|
227
|
+
|
|
228
|
+
Controls what happens when you send a new message while the bot is still processing a previous one.
|
|
229
|
+
|
|
230
|
+
- **`steer`** (default) — The bot cancels the current request and starts working on your new message. Best for normal chat, where a follow-up usually means you want to correct or redirect the bot.
|
|
231
|
+
- **`collect`** — Your new messages are buffered. When the current request finishes, all buffered messages are combined into a single follow-up prompt. Good for async workflows where you want to queue up thoughts.
|
|
232
|
+
- **`followup`** — Each message is queued and processed as its own separate turn, in order. Useful for batch workflows where each message is independent.
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"channels": {
|
|
237
|
+
"my-channel": {
|
|
238
|
+
"type": "telegram",
|
|
239
|
+
"dispatchMode": "steer",
|
|
240
|
+
...
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
You can also set dispatch mode per group, overriding the channel default:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"groups": {
|
|
251
|
+
"*": { "requireMention": true, "dispatchMode": "steer" },
|
|
252
|
+
"-100123456": { "dispatchMode": "collect" }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Block Streaming
|
|
258
|
+
|
|
259
|
+
By default, the agent works for a while and then sends one large response. With block streaming enabled, the response arrives as multiple shorter messages while the agent is still working — similar to how ChatGPT or Claude show progressive output.
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"channels": {
|
|
264
|
+
"my-channel": {
|
|
265
|
+
"type": "telegram",
|
|
266
|
+
"blockStreaming": "on",
|
|
267
|
+
"blockStreamingChunk": { "minChars": 400, "maxChars": 1000 },
|
|
268
|
+
"blockStreamingCoalesce": { "idleMs": 1500 },
|
|
269
|
+
...
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### How it works
|
|
276
|
+
|
|
277
|
+
- The agent's response is split into blocks at paragraph boundaries and sent as separate messages
|
|
278
|
+
- `minChars` (default 400) — don't send a block until it's at least this long, to avoid spamming tiny messages
|
|
279
|
+
- `maxChars` (default 1000) — if a block gets this long without a natural break, send it anyway
|
|
280
|
+
- `idleMs` (default 1500) — if the agent pauses (e.g., running a tool), send what's buffered so far
|
|
281
|
+
- When the agent finishes, any remaining text is sent immediately
|
|
282
|
+
|
|
283
|
+
Only `blockStreaming` is required. The chunk and coalesce settings are optional and have sensible defaults.
|
|
284
|
+
|
|
285
|
+
## Slash Commands
|
|
286
|
+
|
|
287
|
+
Channels support slash commands. These are handled locally (no agent round-trip):
|
|
288
|
+
|
|
289
|
+
- `/help` — List available commands
|
|
290
|
+
- `/clear` — Clear your session and start fresh (aliases: `/reset`, `/new`)
|
|
291
|
+
- `/status` — Show session info and access policy
|
|
292
|
+
|
|
293
|
+
All other slash commands (e.g., `/compress`, `/summary`) are forwarded to the agent.
|
|
294
|
+
|
|
295
|
+
These commands work on all channel types (Telegram, WeChat, DingTalk).
|
|
296
|
+
|
|
297
|
+
## Running
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Start all configured channels (shared agent process)
|
|
301
|
+
qwen channel start
|
|
302
|
+
|
|
303
|
+
# Start a single channel
|
|
304
|
+
qwen channel start my-channel
|
|
305
|
+
|
|
306
|
+
# Check if the service is running
|
|
307
|
+
qwen channel status
|
|
308
|
+
|
|
309
|
+
# Stop the running service
|
|
310
|
+
qwen channel stop
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The bot runs in the foreground. Press `Ctrl+C` to stop, or use `qwen channel stop` from another terminal.
|
|
314
|
+
|
|
315
|
+
### Multi-Channel Mode
|
|
316
|
+
|
|
317
|
+
When you run `qwen channel start` without a name, all channels defined in `settings.json` start together sharing a single agent process. Each channel maintains its own sessions — a Telegram user and a WeChat user get separate conversations, even though they share the same agent.
|
|
318
|
+
|
|
319
|
+
Each channel uses its own `cwd` from its config, so different channels can work on different projects simultaneously.
|
|
320
|
+
|
|
321
|
+
### Service Management
|
|
322
|
+
|
|
323
|
+
The channel service uses a PID file (`~/.qwen/channels/service.pid`) to track the running instance:
|
|
324
|
+
|
|
325
|
+
- **Duplicate prevention**: Running `qwen channel start` while a service is already running will show an error instead of starting a second instance
|
|
326
|
+
- **`qwen channel stop`**: Gracefully stops the running service from another terminal
|
|
327
|
+
- **`qwen channel status`**: Shows whether the service is running, its uptime, and session counts per channel
|
|
328
|
+
|
|
329
|
+
### Crash Recovery
|
|
330
|
+
|
|
331
|
+
If the agent process crashes unexpectedly, the channel service automatically restarts it and attempts to restore all active sessions. Users can continue their conversations without starting over.
|
|
332
|
+
|
|
333
|
+
- Sessions are persisted to `~/.qwen/channels/sessions.json` while the service is running
|
|
334
|
+
- On crash: the agent restarts within 3 seconds and reloads saved sessions
|
|
335
|
+
- After 3 consecutive crashes, the service exits with an error
|
|
336
|
+
- On clean shutdown (Ctrl+C or `qwen channel stop`): session data is cleared — the next start is always fresh
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Custom Channel Plugins
|
|
2
|
+
|
|
3
|
+
You can extend the channel system with custom platform adapters packaged as [extensions](../../extension/introduction). This lets you connect Qwen Code to any messaging platform, webhook, or custom transport.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
Channel plugins are loaded at startup from active extensions. When `qwen channel start` runs, it:
|
|
8
|
+
|
|
9
|
+
1. Scans all enabled extensions for `channels` entries in their `qwen-extension.json`
|
|
10
|
+
2. Dynamically imports each channel's entry point
|
|
11
|
+
3. Registers the channel type so it can be referenced in `settings.json`
|
|
12
|
+
4. Creates channel instances using the plugin's factory function
|
|
13
|
+
|
|
14
|
+
Your custom channel gets the full shared pipeline for free: sender gating, group policies, session routing, slash commands, crash recovery, and the ACP bridge to the agent.
|
|
15
|
+
|
|
16
|
+
## Installing a Custom Channel
|
|
17
|
+
|
|
18
|
+
Install an extension that provides a channel plugin:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# From a local path (for development or private plugins)
|
|
22
|
+
qwen extensions install /path/to/my-channel-extension
|
|
23
|
+
|
|
24
|
+
# Or link it for development (changes are reflected immediately)
|
|
25
|
+
qwen extensions link /path/to/my-channel-extension
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Configuring a Custom Channel
|
|
29
|
+
|
|
30
|
+
Add a channel entry to `~/.qwen/settings.json` using the custom type provided by the extension:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"channels": {
|
|
35
|
+
"my-bot": {
|
|
36
|
+
"type": "my-platform",
|
|
37
|
+
"apiKey": "$MY_PLATFORM_API_KEY",
|
|
38
|
+
"senderPolicy": "open",
|
|
39
|
+
"cwd": "/path/to/project"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The `type` must match a channel type registered by an installed extension. Check the extension's documentation for which plugin-specific fields are required (e.g., `apiKey`, `webhookUrl`).
|
|
46
|
+
|
|
47
|
+
All standard channel options work with custom channels:
|
|
48
|
+
|
|
49
|
+
| Option | Description |
|
|
50
|
+
| -------------- | ---------------------------------------------- |
|
|
51
|
+
| `senderPolicy` | `allowlist`, `pairing`, or `open` |
|
|
52
|
+
| `allowedUsers` | Static allowlist of sender IDs |
|
|
53
|
+
| `sessionScope` | `user`, `thread`, or `single` |
|
|
54
|
+
| `cwd` | Working directory for the agent |
|
|
55
|
+
| `instructions` | Prepended to the first message of each session |
|
|
56
|
+
| `model` | Model override for the channel |
|
|
57
|
+
| `groupPolicy` | `disabled`, `allowlist`, or `open` |
|
|
58
|
+
| `groups` | Per-group settings |
|
|
59
|
+
|
|
60
|
+
See [Overview](./overview) for details on each option.
|
|
61
|
+
|
|
62
|
+
## Starting the Channel
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Start all channels including custom ones
|
|
66
|
+
qwen channel start
|
|
67
|
+
|
|
68
|
+
# Start just your custom channel
|
|
69
|
+
qwen channel start my-bot
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## What You Get for Free
|
|
73
|
+
|
|
74
|
+
Custom channels automatically support everything built-in channels do:
|
|
75
|
+
|
|
76
|
+
- **Sender policies** — `allowlist`, `pairing`, and `open` access control
|
|
77
|
+
- **Group policies** — Per-group settings with optional @mention gating
|
|
78
|
+
- **Session routing** — Per-user, per-thread, or single shared sessions
|
|
79
|
+
- **DM pairing** — Full pairing code flow for unknown users
|
|
80
|
+
- **Slash commands** — `/help`, `/clear`, `/status` work out of the box
|
|
81
|
+
- **Custom instructions** — Prepended to the first message in each session
|
|
82
|
+
- **Crash recovery** — Automatic restart with session preservation
|
|
83
|
+
- **Per-session serialization** — Messages are queued to prevent race conditions
|
|
84
|
+
|
|
85
|
+
## Building Your Own Channel Plugin
|
|
86
|
+
|
|
87
|
+
Want to build a channel plugin for a new platform? See the [Channel Plugin Developer Guide](/developers/channel-plugins) for the `ChannelPlugin` interface, the `Envelope` format, and extension points.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Telegram
|
|
2
|
+
|
|
3
|
+
This guide covers setting up a Qwen Code channel on Telegram.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- A Telegram account
|
|
8
|
+
- A Telegram bot token (see below)
|
|
9
|
+
|
|
10
|
+
## Creating a Bot
|
|
11
|
+
|
|
12
|
+
1. Open Telegram and search for [@BotFather](https://t.me/BotFather)
|
|
13
|
+
2. Send `/newbot` and follow the prompts to choose a name and username
|
|
14
|
+
3. BotFather will give you a bot token — save it securely
|
|
15
|
+
|
|
16
|
+
## Finding Your User ID
|
|
17
|
+
|
|
18
|
+
To use `senderPolicy: "allowlist"` or `"pairing"`, you need your Telegram user ID (a numeric ID, not your username).
|
|
19
|
+
|
|
20
|
+
The easiest way to find it:
|
|
21
|
+
|
|
22
|
+
1. Search for [@userinfobot](https://t.me/userinfobot) on Telegram
|
|
23
|
+
2. Send it any message — it will reply with your user ID
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
Add the channel to `~/.qwen/settings.json`:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"channels": {
|
|
32
|
+
"my-telegram": {
|
|
33
|
+
"type": "telegram",
|
|
34
|
+
"token": "$TELEGRAM_BOT_TOKEN",
|
|
35
|
+
"senderPolicy": "allowlist",
|
|
36
|
+
"allowedUsers": ["YOUR_USER_ID"],
|
|
37
|
+
"sessionScope": "user",
|
|
38
|
+
"cwd": "/path/to/your/project",
|
|
39
|
+
"instructions": "You are a concise coding assistant responding via Telegram. Keep responses short.",
|
|
40
|
+
"groupPolicy": "disabled",
|
|
41
|
+
"groups": {
|
|
42
|
+
"*": { "requireMention": true }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Set the bot token as an environment variable:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
export TELEGRAM_BOT_TOKEN=<your-token-from-botfather>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or add it to a `.env` file that gets sourced before running.
|
|
56
|
+
|
|
57
|
+
## Running
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Start only the Telegram channel
|
|
61
|
+
qwen channel start my-telegram
|
|
62
|
+
|
|
63
|
+
# Or start all configured channels together
|
|
64
|
+
qwen channel start
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then open your bot in Telegram and send a message. You should see "Working..." appear immediately, followed by the agent's response.
|
|
68
|
+
|
|
69
|
+
## Group Chats
|
|
70
|
+
|
|
71
|
+
To use the bot in Telegram groups:
|
|
72
|
+
|
|
73
|
+
1. Set `groupPolicy` to `"allowlist"` or `"open"` in your channel config
|
|
74
|
+
2. **Disable privacy mode** in BotFather: `/mybots` → select your bot → Bot Settings → Group Privacy → Turn Off
|
|
75
|
+
3. Add the bot to a group. If it was already in the group, **remove and re-add it** (Telegram caches privacy settings from when the bot joined)
|
|
76
|
+
4. If using `groupPolicy: "allowlist"`, add the group's chat ID to `groups` in your config
|
|
77
|
+
|
|
78
|
+
By default, the bot requires an @mention or a reply to respond in groups. Set `"requireMention": false` for a specific group to make it respond to all messages (useful for dedicated task groups). See [Group Chats](./overview#group-chats) for full details.
|
|
79
|
+
|
|
80
|
+
## Images and Files
|
|
81
|
+
|
|
82
|
+
You can send photos and documents to the bot, not just text.
|
|
83
|
+
|
|
84
|
+
**Photos:** Send a photo and the agent will analyze it using its vision capabilities. This requires a multimodal model — add `"model": "qwen3.5-plus"` (or another vision-capable model) to your channel config. Photo captions are passed as the message text.
|
|
85
|
+
|
|
86
|
+
**Documents:** Send a PDF, code file, or any document. The bot downloads it and saves it locally so the agent can read it with its file tools. This works with any model. Telegram's file size limit is 20MB.
|
|
87
|
+
|
|
88
|
+
## Tips
|
|
89
|
+
|
|
90
|
+
- **Keep instructions concise-focused** — Telegram has a 4096-character message limit. Adding instructions like "keep responses short" helps the agent stay within bounds.
|
|
91
|
+
- **Use `sessionScope: "user"`** — This gives each user their own conversation. Use `/clear` to start fresh.
|
|
92
|
+
- **Restrict access** — Use `senderPolicy: "allowlist"` for a fixed set of users, or `"pairing"` to let new users request access with a code you approve via CLI. See [DM Pairing](./overview#dm-pairing) for details.
|
|
93
|
+
|
|
94
|
+
## Message Formatting
|
|
95
|
+
|
|
96
|
+
The agent's markdown responses are automatically converted to Telegram-compatible HTML. Code blocks, bold, italic, links, and lists are all supported.
|
|
97
|
+
|
|
98
|
+
## Troubleshooting
|
|
99
|
+
|
|
100
|
+
### Bot doesn't respond
|
|
101
|
+
|
|
102
|
+
- Check that the bot token is correct and the environment variable is set
|
|
103
|
+
- Verify your user ID is in `allowedUsers` if using `senderPolicy: "allowlist"`, or that you've been approved if using `"pairing"`
|
|
104
|
+
- Check the terminal output for errors
|
|
105
|
+
|
|
106
|
+
### Bot doesn't respond in groups
|
|
107
|
+
|
|
108
|
+
- Check that `groupPolicy` is set to `"allowlist"` or `"open"` (default is `"disabled"`)
|
|
109
|
+
- If using `"allowlist"`, verify the group's chat ID is in the `groups` config
|
|
110
|
+
- Make sure **Group Privacy is turned off** in BotFather — without this, the bot can't see non-command messages in groups
|
|
111
|
+
- If you changed privacy mode after adding the bot to a group, **remove and re-add the bot** to the group
|
|
112
|
+
- By default, the bot requires an @mention or a reply. Send `@yourbotname hello` to test
|
|
113
|
+
|
|
114
|
+
### "Sorry, something went wrong processing your message"
|
|
115
|
+
|
|
116
|
+
This usually means the agent encountered an error. Check the terminal output for details.
|
|
117
|
+
|
|
118
|
+
### Bot takes a long time to respond
|
|
119
|
+
|
|
120
|
+
The agent may be running multiple tool calls (reading files, searching, etc.). The "Working..." indicator shows while the agent is processing. Complex tasks can take a minute or more.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# WeChat (Weixin)
|
|
2
|
+
|
|
3
|
+
This guide covers setting up a Qwen Code channel on WeChat via the official iLink Bot API.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- A WeChat account that can scan QR codes (mobile app)
|
|
8
|
+
- Access to the iLink Bot platform (WeChat's official bot API)
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
### 1. Log in via QR code
|
|
13
|
+
|
|
14
|
+
WeChat uses QR code authentication instead of a static bot token. Run the login command:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
qwen channel configure-weixin
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This will display a QR code URL. Scan it with your WeChat mobile app to authenticate. Your credentials are saved to `~/.qwen/channels/weixin/account.json`.
|
|
21
|
+
|
|
22
|
+
### 2. Configure the channel
|
|
23
|
+
|
|
24
|
+
Add the channel to `~/.qwen/settings.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"channels": {
|
|
29
|
+
"my-weixin": {
|
|
30
|
+
"type": "weixin",
|
|
31
|
+
"senderPolicy": "pairing",
|
|
32
|
+
"allowedUsers": [],
|
|
33
|
+
"sessionScope": "user",
|
|
34
|
+
"cwd": "/path/to/your/project",
|
|
35
|
+
"model": "qwen3.5-plus",
|
|
36
|
+
"instructions": "You are a concise coding assistant responding via WeChat. Keep responses under 500 characters. Use plain text only."
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Note: WeChat channels do not use a `token` field — credentials come from the QR login step.
|
|
43
|
+
|
|
44
|
+
### 3. Start the channel
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Start only the WeChat channel
|
|
48
|
+
qwen channel start my-weixin
|
|
49
|
+
|
|
50
|
+
# Or start all configured channels together
|
|
51
|
+
qwen channel start
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Open WeChat and send a message to the bot. You should see a typing indicator ("...") while the agent processes, followed by the response.
|
|
55
|
+
|
|
56
|
+
## Images and Files
|
|
57
|
+
|
|
58
|
+
You can send photos and documents to the bot, not just text.
|
|
59
|
+
|
|
60
|
+
**Photos:** Send an image (screenshot, photo, etc.) and the agent will analyze it using its vision capabilities. This requires a multimodal model — add `"model": "qwen3.5-plus"` (or another vision-capable model) to your channel config. A typing indicator shows while the image is being downloaded and processed.
|
|
61
|
+
|
|
62
|
+
**Files:** Send a PDF, code file, or any document. The bot downloads and decrypts it from WeChat's CDN, saves it locally, and the agent reads it with its file tools. This works with any model.
|
|
63
|
+
|
|
64
|
+
## Configuration Options
|
|
65
|
+
|
|
66
|
+
WeChat channels support all the standard channel options (see [Channel Overview](./overview#options)), plus:
|
|
67
|
+
|
|
68
|
+
| Option | Description |
|
|
69
|
+
| --------- | ------------------------------------------------------------------------------ |
|
|
70
|
+
| `baseUrl` | Override the iLink Bot API base URL (default: `https://ilinkai.weixin.qq.com`) |
|
|
71
|
+
|
|
72
|
+
## Key Differences from Telegram
|
|
73
|
+
|
|
74
|
+
- **Authentication:** QR code login instead of a static bot token. Sessions can expire — the channel will pause and log a message if this happens.
|
|
75
|
+
- **Formatting:** WeChat only supports plain text. Markdown in agent responses is automatically stripped.
|
|
76
|
+
- **Typing indicator:** WeChat has a native "..." typing indicator instead of a "Working..." text message.
|
|
77
|
+
- **Groups:** WeChat iLink Bot is DM-only — group chats are not supported.
|
|
78
|
+
- **Media encryption:** Images and files are encrypted on WeChat's CDN with AES-128-ECB. The channel handles decryption transparently.
|
|
79
|
+
|
|
80
|
+
## Tips
|
|
81
|
+
|
|
82
|
+
- **Use plain text instructions** — Since WeChat strips all markdown, add instructions like "Use plain text only" to avoid the agent producing formatted responses that look messy.
|
|
83
|
+
- **Keep responses short** — WeChat message bubbles work best with concise text. Adding a character limit to your instructions helps (e.g., "Keep responses under 500 characters").
|
|
84
|
+
- **Session expiry** — If you see "Session expired (errcode -14)" in the logs, your WeChat login has expired. Stop the channel and re-run `qwen channel configure-weixin` to log in again.
|
|
85
|
+
- **Restrict access** — Use `senderPolicy: "pairing"` or `"allowlist"` to control who can talk to the bot. See [DM Pairing](./overview#dm-pairing) for details.
|
|
86
|
+
|
|
87
|
+
## Troubleshooting
|
|
88
|
+
|
|
89
|
+
### "WeChat account not configured"
|
|
90
|
+
|
|
91
|
+
Run `qwen channel configure-weixin` to log in via QR code first.
|
|
92
|
+
|
|
93
|
+
### "Session expired (errcode -14)"
|
|
94
|
+
|
|
95
|
+
Your WeChat login session has expired. Stop the channel and run `qwen channel configure-weixin` again.
|
|
96
|
+
|
|
97
|
+
### Bot doesn't respond
|
|
98
|
+
|
|
99
|
+
- Check the terminal output for errors
|
|
100
|
+
- Verify the channel is running (`qwen channel start my-weixin`)
|
|
101
|
+
- If using `senderPolicy: "allowlist"`, make sure your WeChat user ID is in `allowedUsers`
|
|
102
|
+
|
|
103
|
+
### Images not working
|
|
104
|
+
|
|
105
|
+
- Make sure your channel config has a `model` that supports vision (e.g., `qwen3.5-plus`)
|
|
106
|
+
- Check the terminal for CDN download errors — these may indicate a network issue
|