-
Notifications
You must be signed in to change notification settings - Fork 3k
feat(channel): add daemon bridge spike #4203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6a4a7f0
dc9587f
7d53fe5
7fca894
a550850
46a4f0e
1381074
b24c2e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # Channel And Web Backend Daemon Adapter Draft | ||
|
|
||
| ## Goal | ||
|
|
||
| Let channel adapters and web chat backends consume `qwen serve` through | ||
| `DaemonSessionClient` while keeping existing channel ACP subprocess behavior as | ||
| the default. | ||
|
|
||
| This draft covers server-side clients only: | ||
|
|
||
| - Channel bot backend -> `qwen serve` | ||
| - Web browser -> web backend / BFF -> `qwen serve` | ||
|
|
||
| It explicitly does not allow browser JavaScript to call the daemon directly. | ||
| The daemon currently rejects browser `Origin` requests by design. | ||
|
|
||
| ## Proposed Entry Points | ||
|
|
||
| Channel backend: | ||
|
|
||
| ```bash | ||
| QWEN_CHANNEL_DAEMON_URL=http://127.0.0.1:4170 qwen channel start telegram | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low — 端口写死 例子里 建议加一句:端口可通过 daemon 启动参数 / 配置文件调整,这里只用 |
||
| ``` | ||
|
|
||
| Web backend: | ||
|
|
||
| ```bash | ||
| QWEN_WEB_DAEMON_URL=http://127.0.0.1:4170 qwen web-chat-backend | ||
| ``` | ||
|
|
||
| Shared optional variables: | ||
|
|
||
| ```bash | ||
| QWEN_DAEMON_TOKEN=... | ||
| QWEN_DAEMON_WORKSPACE=/repo | ||
| ``` | ||
|
|
||
| ## Minimal Channel Flow | ||
|
|
||
| This PR adds `DaemonChannelBridge`, a locally verifiable server-side bridge for | ||
| channel and web-backend adapters. It keeps the existing ACP bridge as the | ||
| default and owns daemon session state inside the backend process. | ||
|
|
||
| 1. Resolve channel sender/thread to a channel session key. | ||
| 2. Use `DaemonClient` + `DaemonSessionClient.createOrAttach()`. | ||
| 3. Submit inbound user text with `session.prompt()`. | ||
| 4. Subscribe to `session.events()` and collect assistant text chunks. | ||
| 5. Send final text back through the platform adapter. | ||
| 6. Cast permission votes through `session.respondToPermission()`. | ||
| 7. Cancel active work through `session.cancel()`. | ||
|
|
||
| ## Minimal Web Backend Flow | ||
|
|
||
| 1. Browser opens a websocket or HTTP stream to the web backend. | ||
| 2. Backend owns `DaemonSessionClient`. | ||
| 3. Backend translates browser messages to daemon prompts. | ||
| 4. Backend translates daemon SSE events to browser-safe app events. | ||
| 5. Backend stores the daemon `sessionId` and last seen event id server-side. | ||
|
|
||
| Browser clients must not receive daemon bearer tokens. | ||
|
|
||
| ## Session Isolation Constraint | ||
|
|
||
| Current daemon Stage 1 behavior is effectively `sessionScope: single` at the | ||
| daemon setting level. Until per-request `sessionScope` lands, multi-user channel | ||
| or web deployments must choose one of these safe shapes: | ||
|
|
||
| - one daemon per channel thread / web room | ||
| - one daemon per user workspace | ||
| - single-user demo only | ||
|
|
||
| Do not silently multiplex unrelated channel threads into one daemon session. | ||
|
|
||
| ## Event Mapping Contract | ||
|
|
||
| | Daemon event | Channel/web backend handling | | ||
| | ---------------------------------------- | -------------------------------------- | | ||
| | `session_update` / `agent_message_chunk` | Append assistant text | | ||
| | `session_update` / `agent_thought_chunk` | Optional hidden/debug stream | | ||
| | `session_update` / `tool_call` | Emit tool status card/message | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low — 事件映射表与实现不一致 表格只列了 |
||
| | `permission_request` | Platform-specific approval interaction | | ||
| | `permission_resolved` | Close/update approval interaction | | ||
| | `model_switched` | Update backend session metadata | | ||
| | `session_died` | Notify user and stop stream | | ||
|
|
||
| Unknown daemon events must be ignored or forwarded as debug metadata, not fatal. | ||
|
|
||
| The bridge is not wired into `qwen channel start` yet. Existing Telegram, | ||
| Weixin, Dingtalk, plugin channel, and browser behavior remains unchanged. | ||
|
|
||
| ## Explicit Non-Goals | ||
|
|
||
| - No browser direct-to-daemon fetch or EventSource. | ||
| - No CORS relaxation in this adapter PR. | ||
| - No default migration of Telegram, Weixin, Dingtalk, or plugin channels. | ||
| - No file CRUD, memory CRUD, MCP restart, or provider mutation. | ||
| - No sessionScope emulation in the client when daemon-side support is absent. | ||
|
|
||
| ## Merge Safety | ||
|
|
||
| - Default off. | ||
| - Existing ACP channel bridge remains the default. | ||
| - Web backend is an explicit BFF layer, not a daemon security change. | ||
| - No channel adapter should import daemon tokens into frontend/browser code. | ||
|
|
||
| ## Validation Plan | ||
|
|
||
| - Unit-test channel session-key to daemon-session binding. | ||
| - Unit-test daemon event to channel/web message mapping. | ||
| - Unit-test prompt, cancel, model switch, and permission response forwarding. | ||
| - Smoke-test one single-user channel backend against local `qwen serve`. | ||
| - Smoke-test browser -> BFF -> daemon without exposing daemon token. | ||
|
|
||
| ## Blockers Before Default Migration | ||
|
|
||
| - Per-request `sessionScope`. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| - Session metadata + close/delete lifecycle. | ||
| - Daemon-stamped client identity. | ||
| - Session-scoped permission route. | ||
| - Read-only diagnostics for MCP, skills, providers, and environment. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Suggestion] Mark these entry points as future/illustrative instead of runnable commands. The document later says the daemon bridge is not wired into
qwen channel startyet, and the PR does not addQWEN_CHANNEL_DAEMON_URL,QWEN_WEB_DAEMON_URL, orqwen web-chat-backendwiring. As written, readers can reasonably copy these commands and expect them to work.Please rename this section to something like
Future Entry Pointsor add a short note before the snippets that these commands are proposed examples, not implemented by this PR.— gpt-5.5 via Qwen Code /review