* feat(cli): add daemon-managed channel worker * codex: address PR review feedback (#5978) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden serve channel worker lifecycle Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): cover channel worker edge cases Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address channel worker review followups Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): clear channel pidfile after worker exit Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address serve channel review feedback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden serve channel worker review issues Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): preserve channel worker exit errors Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden daemon channel worker startup Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address channel worker review cleanup Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): track channel worker exit explicitly Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address daemon worker startup review (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address daemon worker disconnect review (#6031) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address serve channel review feedback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address channel worker review feedback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
4 KiB
@qwen-code/channel-plugin-example
A reference channel plugin for Qwen Code. It connects to a WebSocket server and routes messages through the full channel pipeline (access control, session routing, agent bridge).
Use this package to:
- Try out the channel plugin system — install it as an extension and run it with the built-in mock server
- Use it as a starting point — fork the source to build your own channel adapter (see the Channel Plugin Developer Guide)
Quick start
1. Install the package
npm install @qwen-code/channel-plugin-example
2. Link it as a Qwen Code extension
The package ships a qwen-extension.json manifest, so it works as an extension out of the box:
qwen extensions link ./node_modules/@qwen-code/channel-plugin-example
3. Configure the channel
Add a channel entry to ~/.qwen/settings.json:
{
"channels": {
"my-plugin-test": {
"type": "plugin-example",
"serverWsUrl": "ws://localhost:9201",
"senderPolicy": "open",
"sessionScope": "user",
"cwd": "/path/to/your/project"
}
}
}
4. Start the mock server
npx qwen-channel-plugin-example-server
The server prints the HTTP and WebSocket URLs. You can customize ports with environment variables:
HTTP_PORT=8080 WS_PORT=8081 npx qwen-channel-plugin-example-server
5. Start the channel
In a separate terminal:
qwen channel start my-plugin-test
Or run the same adapter under the experimental daemon-managed channel worker:
cd /path/to/your/project
qwen serve --channel my-plugin-test
qwen serve --channel requires the channel's configured cwd to resolve to the daemon workspace.
6. Send a message
curl -sX POST http://localhost:9200/message \
-H 'Content-Type: application/json' \
-d '{"senderId":"user1","senderName":"Tester","text":"What is 2+2?"}'
You should get a JSON response with the agent's reply.
How it works
Mock Server (HTTP + WS)
↕ WebSocket
MockPluginChannel (this package)
→ Envelope → ChannelBase.handleInbound()
→ SenderGate → SessionRouter → ChannelAgentBridge.prompt()
→ qwen-code agent → model API
← response
← sendMessage() → WebSocket → Mock Server
← HTTP response
Building your own channel
See src/MockPluginChannel.ts for a working example. The key points:
- Extend
ChannelBaseand implementconnect(),sendMessage(),disconnect() - Build an
Envelopefrom incoming platform messages and callthis.handleInbound(envelope) - Type the adapter constructor bridge parameter as
ChannelAgentBridge - Export a
pluginobject conforming toChannelPlugin - Add a
qwen-extension.jsonmanifest
AcpBridge is still the current standalone qwen channel start implementation. Plugin adapters should depend on the ChannelAgentBridge abstraction provided by @qwen-code/channel-base.
Existing TypeScript plugins that explicitly type the adapter constructor or factory bridge parameter as AcpBridge should change that annotation to ChannelAgentBridge. JavaScript plugins are unaffected at runtime.
qwen serve --channel <name> hosts the same plugin through a daemon-managed worker backed by DaemonChannelBridge. The worker is owned by qwen serve; stop the daemon to stop serve-managed channels.
Features you get for free
- Block streaming — enable
blockStreaming: "on"in config and the agent's response is automatically split into multiple messages at paragraph boundaries - Attachments — populate
envelope.attachmentswith images/files andhandleInbound()routes them to the agent (images as vision input, files as paths in the prompt) - Streaming hooks — override
onResponseChunk()for progressive display (e.g., editing a message in-place) - Access control (allowlist, pairing, open), session routing, slash commands, crash recovery
Full guide: Channel Plugin Developer Guide