Skip to content

Commit 1d2ee34

Browse files
doudouOUCqwencoder
andauthored
docs(daemon): Refresh daemon docs in English (#5144)
* docs: Translate daemon developer docs to English Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs: Align daemon docs with main implementation Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix: apply auto-fixes from /review - eventRingSize default: 1024 → 8000 (01-architecture.md) - Restore full 8-step middleware chain in HTTP lifecycle diagram - Hysteresis re-arm condition: <= → < (06-mcp-budget-guardrails.md) - permissionMediator.ts line range: 1-1292 → 1-1198 - FsErrorKind count: 13 → 14 (07-workspace-filesystem.md) - Remove broken links to design/f2-mcp-transport-pool.md * docs: Smooth daemon developer docs language Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs: Sync daemon capability docs Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#5144) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#5144) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#5144) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
1 parent 7ace758 commit 1d2ee34

26 files changed

Lines changed: 2819 additions & 2555 deletions

docs/developers/_meta.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default {
1010
title: 'Agent SDK',
1111
type: 'separator',
1212
},
13-
'sdk-typescript': 'Typescript SDK',
13+
'sdk-typescript': 'TypeScript SDK',
1414
'sdk-python': 'Python SDK (alpha)',
1515
'sdk-java': 'Java SDK (alpha)',
1616
'Dive Into Qwen Code': {
@@ -21,7 +21,7 @@ export default {
2121
'channel-plugins': 'Channel Plugin Guide',
2222
tools: 'Tools',
2323
'qwen-serve-protocol': 'qwen serve HTTP protocol',
24-
daemon: 'Daemon 模式 · 开发者深度指南',
24+
daemon: 'Daemon Mode (Developer Deep Dive)',
2525

2626
examples: {
2727
display: 'hidden',

docs/developers/daemon-client-adapters/tui.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# TUI Daemon Adapter Draft
22

3-
> **⚠️ 已过时**:本文档描述的是早期 `DaemonTuiAdapter` spike。该 legacy adapter 仍在 `packages/cli/src/ui/daemon/` 中,但新的可复用方向是 SDK 里的共享 UI Transcript 层。当前架构请参考 [`../daemon/14-cli-tui-adapter.md`](../daemon/14-cli-tui-adapter.md)
3+
> **Deprecated**: this document describes the early `DaemonTuiAdapter` spike. The legacy adapter still exists in `packages/cli/src/ui/daemon/`, but the reusable direction is now the SDK shared UI transcript layer. For the current architecture, see [`../daemon/14-cli-tui-adapter.md`](../daemon/14-cli-tui-adapter.md).
44
55
---
66

@@ -10,7 +10,7 @@ Add a flag-gated TUI transport that talks to `qwen serve` through
1010
`DaemonSessionClient` instead of creating an in-process `Config` + agent
1111
runtime.
1212

13-
This is a dogfood path for Mode B client migration. It must not replace the
13+
This is an internal validation path for Mode B client migration. It must not replace the
1414
default TUI path until output sinks, typed daemon events, session-scoped
1515
permission, and lifecycle diagnostics are stable.
1616

docs/developers/daemon/00-index.md

Lines changed: 167 additions & 150 deletions
Large diffs are not rendered by default.

docs/developers/daemon/01-architecture.md

Lines changed: 56 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
# Daemon 架构
1+
# Daemon Architecture
22

3-
## 概览
3+
## Overview
44

5-
一个 `qwen serve` 进程坚持 ** daemon = workspace** 的不变式。它内嵌一个 Express HTTP 服务、持有一个 `acp-bridge` 实例、拉起一个 ACP 子进程(`qwen --acp`)来跑真正的 agent 运行时。多个客户端(CLI TUIIDE companionIM channel 机器人、Web BFF、自定义脚本)通过 HTTP + SSE 连进来,要么共享同一个 ACP session`sessionScope: 'single'`,默认),要么每个客户端各拿一个(`'thread'`)。
5+
A `qwen serve` process is **one daemon = one workspace**. It hosts a single Express HTTP server, owns an `@qwen-code/acp-bridge` instance, and spawns one ACP child process (`qwen --acp`) that runs the actual agent runtime. Multiple clients (CLI TUI, IDE companion, IM channel bots, web BFFs, custom scripts) connect over HTTP + SSE and either share one ACP session (`sessionScope: 'single'`, default) or split sessions by conversation thread (`sessionScope: 'thread'`).
66

7-
ACP 子进程内部,MCP server 通过 `McpTransportPool`(F2)实现工作区内共享:一对 (server name + 配置指纹) 对应一条 MCP transport,不管被几个 session 发现都只起一份。Bridge 的 `MultiClientPermissionMediator`(F3)在四种策略之一下协调多客户端的权限投票。
7+
Inside the ACP child, MCP servers are shared workspace-wide through `McpTransportPool` (F2): a single (server-name + config-fingerprint) tuple maps to one MCP transport, regardless of how many sessions discover it. The bridge's `MultiClientPermissionMediator` (F3) coordinates permission votes across all connected clients under one of four policies.
88

9-
本文给出 **系统级全景**,本文档集其余 18 篇文档都挂在它下面。每条主干流程都给一张 Mermaid 时序图,单个组件的实现细节请看对应的专题文档。
9+
This doc gives the **system-level picture** that the rest of this documentation set builds on. Each critical flow is shown as a Mermaid sequence diagram; per-component implementation details live in the other 18 docs.
1010

11-
## 进程拓扑
11+
## Process topology
1212

1313
```mermaid
1414
flowchart LR
1515
subgraph clients["Clients"]
1616
WUI["Web UI<br/>(packages/webui/src/daemon)"]
17-
TUI["CLI TUI<br/>(待迁移到 SDK ui/*)"]
18-
IDE["VSCode IDE<br/>(packages/vscode-ide-companion)"]
17+
TUI["CLI TUI<br/>(packages/cli/src/ui/daemon)"]
18+
IDE["VS Code IDE<br/>(packages/vscode-ide-companion)"]
1919
CH["Channel bots<br/>(DingTalk / WeChat / Telegram)"]
2020
SDK["Any SDK consumer<br/>(packages/sdk-typescript/src/daemon)"]
2121
end
@@ -57,12 +57,9 @@ flowchart LR
5757
POOL -- "shared transport" --> MCP2
5858
```
5959

60-
要点:
60+
The daemon process and the ACP child are connected by an `AcpChannel` (default: a real subprocess stdio pipe pair; `inMemoryChannel` for tests). Everything the daemon does is shaped by this split: HTTP and SSE traffic terminate in the daemon, agent decisions and tool invocations happen in the child, and the bridge connects the two.
6161

62-
- daemon 进程与 ACP 子进程通过 `AcpChannel` 连接,默认是真实的子进程 + 一对管道;`inMemoryChannel` 用于测试。
63-
- 所有架构都被这条「daemon ↔ child」缝隙塑造:HTTP / SSE 在 daemon 终止,agent 决策与工具调用在子进程发生,bridge 是中转。
64-
65-
## 包关系
62+
## Package map
6663

6764
```mermaid
6865
flowchart TB
@@ -102,6 +99,7 @@ flowchart TB
10299
103100
subgraph adapters["Adapters"]
104101
WUIP["webui/src/daemon/<br/>DaemonSessionProvider.tsx"]
102+
TUIA["cli/src/ui/daemon/<br/>DaemonTuiAdapter.ts"]
105103
CHB["channels/base/<br/>DaemonChannelBridge.ts"]
106104
DT["channels/dingtalk"]
107105
WX["channels/weixin"]
@@ -127,6 +125,7 @@ flowchart TB
127125
128126
WUIP --> DSC
129127
WUIP --> UI
128+
TUIA --> DSC
130129
CHB --> DSC
131130
DT --> CHB
132131
WX --> CHB
@@ -137,33 +136,26 @@ flowchart TB
137136
DC --> EVT
138137
DC --> SSE
139138
DC --> AUTHF
140-
UI --> EVT
141139
```
142140

143-
箭头方向表示编译期依赖:`serve/` 启动层依赖 `@qwen-code/acp-bridge`,bridge 包本身不反向 import `serve/`。HTTP、auth、filesystem adapter 留在 CLI 包里,ACP session 生命周期和权限协调留在 bridge 包里。
144-
145-
记住三条信任边界:
141+
Three trust boundaries matter: the HTTP edge (`serve/auth.ts` middleware chain), the bridge-to-ACP-child boundary (NDJSON over stdio, no auth; the child trusts the bridge implicitly), and the agent-to-MCP-server boundary (the agent may invoke tools that touch the host).
146142

147-
1. HTTP 入口边界:`serve/auth.ts` 中间件链。
148-
2. bridge ↔ ACP 子进程边界:stdio 上的 NDJSON,没有认证 —— 子进程默认信任 bridge。
149-
3. agent ↔ MCP server 边界:agent 可能触发涉及宿主资源的工具调用。
150-
151-
## 流程 1:HTTP 请求生命周期
143+
## Workflow 1: HTTP request lifecycle
152144

153145
```mermaid
154146
sequenceDiagram
155147
autonumber
156148
participant C as Client (SDK)
157-
participant MW as Middleware<br/>(CORS→host→log→bearer→rate-limit→JSON→telemetry)
149+
participant MW as Middleware<br/>(CORS→host→log→bearer→rate-limit→JSON→telemetry→mutationGate)
158150
participant R as Route handler
159151
participant BR as AcpBridge
160152
participant BC as BridgeClient
161153
participant CH as ACP child
162154
163155
C->>MW: POST /session/:id/prompt<br/>Authorization: Bearer …<br/>X-Qwen-Client-Id: …
164-
MW->>MW: deny/allow Origin CORS
156+
MW->>MW: denyBrowserOriginCors
165157
MW->>MW: hostAllowlist (DNS rebinding guard)
166-
MW->>MW: access-log hook (if daemonLog enabled)
158+
MW->>MW: access-log hook
167159
MW->>MW: bearerAuth (constant-time compare)
168160
MW->>MW: rateLimit (when enabled)
169161
MW->>MW: express.json body parser
@@ -179,9 +171,9 @@ sequenceDiagram
179171
R-->>C: 200 JSON
180172
```
181173

182-
非流式路由(promptcancelmodel 切换、metadataworkspace CRUD)以一次 JSON 响应结束。流式输出**不是**在该 HTTP 连接上以分块方式返回,而是走 SSE 通道;见流程 2。
174+
Non-streaming routes (prompt, cancel, model switch, metadata, workspace CRUD) terminate as a single JSON reply. Streaming output is delivered out-of-band on the SSE channel, **not** as a chunked HTTP body on this connection. See workflow 2.
183175

184-
## 流程 2:SSE 事件投递与重放
176+
## Workflow 2: SSE event delivery and replay
185177

186178
```mermaid
187179
sequenceDiagram
@@ -203,13 +195,9 @@ sequenceDiagram
203195
Note over EB,SR: If subscriber queue >= maxQueued,<br/>EventBus emits client_evicted terminal frame<br/>and closes subscriber.
204196
```
205197

206-
要点:
207-
208-
- 环形缓冲有上限(`eventRingSize`,默认 8000)。
209-
- 重连客户端如果 `Last-Event-ID` 已经落出环外,会收到合成 catch-up 信号,必须用 `loadSession` / `resumeSession` 重建更深层状态。
210-
- 慢消费者在队列 75% 触发 `slow_client_warning`,达到上限时收到 `client_evicted`(终态)后被关掉。
198+
The ring buffer is bounded (`eventRingSize`, default 8000). A reconnecting client whose `Last-Event-ID` is older than the ring's head receives a synthetic catch-up signal and must call `loadSession` / `resumeSession` to rebuild deeper state. Slow clients trigger `slow_client_warning` at 75% queue fill and `client_evicted` at the cap.
211199

212-
## 流程 3:多客户端权限协调
200+
## Workflow 3: Multi-client permission mediation
213201

214202
```mermaid
215203
sequenceDiagram
@@ -252,16 +240,9 @@ sequenceDiagram
252240
end
253241
```
254242

255-
跨策略「逃生口」:任何客户端都可以投 `CANCEL_VOTE_SENTINEL` 把请求短路成 `cancelled / agent_cancelled`bridge 防止 wire 端通过普通 `optionId` 字段偷偷塞这个哨兵(`InvalidPermissionOptionError`)。
243+
Cross-policy escape hatch: any client may vote `CANCEL_VOTE_SENTINEL` to short-circuit the request as `cancelled / agent_cancelled`. The bridge guards against wire callers smuggling the sentinel via the normal `optionId` field (`InvalidPermissionOptionError`).
256244

257-
四种策略一句话:
258-
259-
- `first-responder` — 第一个有效投票获胜(默认,保留 live 协作 UX)。
260-
- `designated` — 只有 `originatorClientId` 能投,其他客户端收 `permission_forbidden`
261-
- `consensus` — N-of-M 法定人数,过程中发 `permission_partial_vote` 让 UI 渲染进度。
262-
- `local-only` — 拒绝任何 HTTP 投票,只接受 loopback。
263-
264-
## 流程 4:MCP transport 池的 acquire / release / restart
245+
## Workflow 4: MCP transport pool acquire / release / restart
265246

266247
```mermaid
267248
sequenceDiagram
@@ -297,23 +278,20 @@ sequenceDiagram
297278
S->>P: release(id, sessionId)
298279
P->>E: detach session
299280
E->>E: arm drain timer (default 30s)
300-
Note over E: refs==0 → drain timer fires → close transport<br/>(MAX_IDLE_MS 5min hard cap survives flap)
281+
Note over E: refs==0 → drain timer fires → close transport<br/>(MAX_IDLE_MS 5min hard cap survives attach/detach churn)
301282
302283
Note over S,P: Operator restart flow…
303284
S->>P: restartByName(name, opts?)
304285
P->>E: drain + close
305286
P->>E: spawn replacement
306287
E->>SRV: reconnect
307-
P->>EB: publish mcp_server_restarted
288+
P->>EB: publish mcp_server_restarted<br/>with stable entryIndex
289+
P-->>S: single result or {entries: RestartResult[]}
308290
```
309291

310-
要点:
311-
312-
- `releaseSession(sessionId)` 借助 `sessionToEntries` 反向索引,以 O(refs) 释放该 session 持有的所有条目。
313-
- daemon 关停时 `drainAll()``draining` 标志(拒绝新的 acquire),并以可配置超时等待所有条目关闭。
314-
- `restartByName` 可以接 `entryIndex` 来精确重启某条;池里同名多条目时返回 `{entries: RestartResult[]}` 形状。
292+
`releaseSession(sessionId)` uses the reverse `sessionToEntries` index to release every entry the session holds in O(refs). On daemon shutdown, `drainAll()` sets the `draining` flag (refusing new acquires) and waits for every entry to close under a configurable timeout.
315293

316-
## 流程 5:生命周期 —— 启动与优雅退出
294+
## Workflow 5: Lifecycle — startup and graceful shutdown
317295

318296
```mermaid
319297
sequenceDiagram
@@ -342,35 +320,31 @@ sequenceDiagram
342320
Note over Op,RQS: Second SIGTERM during shutdown →<br/>bridge.killAllSync() + process.exit(1) (orphan prevention)
343321
```
344322

345-
为什么要分两阶段:
346-
347-
- 还在飞的 HTTP 请求、还连着的 SSE 订阅者、子进程里还在跑的工具调用都需要有上限的退出窗口。
348-
- 任何一条卡过窗口,force-close 路径会接管,避免子进程把 daemon 进程拖住。
349-
- 第二次 SIGTERM 直接走 `bridge.killAllSync()` + `process.exit(1)`,防孤儿。
350-
351-
## 关键文件
352-
353-
| 关注点 | 文件 |
354-
| ------------------ | -------------------------------------------------------------------- |
355-
| Bootstrap | `packages/cli/src/serve/runQwenServe.ts` |
356-
| Express 应用 | `packages/cli/src/serve/server.ts` |
357-
| 能力注册表 | `packages/cli/src/serve/capabilities.ts` |
358-
| Auth 中间件 | `packages/cli/src/serve/auth.ts` |
359-
| Bridge | `packages/acp-bridge/src/bridge.ts` |
360-
| BridgeClient | `packages/acp-bridge/src/bridgeClient.ts` |
361-
| 权限协调器 | `packages/acp-bridge/src/permissionMediator.ts` |
362-
| EventBus | `packages/acp-bridge/src/eventBus.ts` |
363-
| MCP transport 池 | `packages/core/src/tools/mcp-transport-pool.ts` |
364-
| Workspace MCP 预算 | `packages/core/src/tools/mcp-workspace-budget.ts` |
365-
| Workspace 文件系统 | `packages/cli/src/serve/fs/` |
366-
| SDK DaemonClient | `packages/sdk-typescript/src/daemon/DaemonClient.ts` |
367-
| SDK SessionClient | `packages/sdk-typescript/src/daemon/DaemonSessionClient.ts` (61-385) |
368-
| 事件 schema | `packages/sdk-typescript/src/daemon/events.ts` (14-112) |
369-
370-
## 参考
371-
372-
- 设计 issue:[#3803](https://github.com/QwenLM/qwen-code/issues/3803)(daemon 总体设计)、[#4175](https://github.com/QwenLM/qwen-code/issues/4175)(F 系列里程碑)。
373-
- 用户使用文档:[`../../users/qwen-serve.md`](../../users/qwen-serve.md)
374-
- Wire 协议参考:[`../qwen-serve-protocol.md`](../qwen-serve-protocol.md)
375-
- F2 设计文档(v2.2,含 32 条 review fold-in):[`../../design/f2-mcp-transport-pool.md`](../../design/f2-mcp-transport-pool.md)
376-
- F2 设计笔记:issue [#4175](https://github.com/QwenLM/qwen-code/issues/4175) commit 4-6。
323+
The two-phase shutdown matters because in-flight HTTP requests, in-flight SSE subscribers, and the ACP child's in-flight tool calls all need bounded teardown windows. If anything blocks past those deadlines, the force-close path takes over so a stuck child cannot keep the daemon process alive.
324+
325+
## Critical files
326+
327+
| Concern | File |
328+
| -------------------- | ----------------------------------------------------------- |
329+
| Bootstrap | `packages/cli/src/serve/runQwenServe.ts` |
330+
| Express app | `packages/cli/src/serve/server.ts` |
331+
| Capability registry | `packages/cli/src/serve/capabilities.ts` |
332+
| Auth middleware | `packages/cli/src/serve/auth.ts` |
333+
| Bridge | `packages/acp-bridge/src/bridge.ts` |
334+
| BridgeClient | `packages/acp-bridge/src/bridgeClient.ts` |
335+
| Permission mediator | `packages/acp-bridge/src/permissionMediator.ts` |
336+
| EventBus | `packages/acp-bridge/src/eventBus.ts` |
337+
| MCP transport pool | `packages/core/src/tools/mcp-transport-pool.ts` |
338+
| Workspace MCP budget | `packages/core/src/tools/mcp-workspace-budget.ts` |
339+
| Workspace FS | `packages/cli/src/serve/fs/` |
340+
| SDK DaemonClient | `packages/sdk-typescript/src/daemon/DaemonClient.ts` |
341+
| SDK SessionClient | `packages/sdk-typescript/src/daemon/DaemonSessionClient.ts` |
342+
| Event schema | `packages/sdk-typescript/src/daemon/events.ts` |
343+
344+
## References
345+
346+
- Design issues: [#3803](https://github.com/QwenLM/qwen-code/issues/3803) (daemon design), [#4175](https://github.com/QwenLM/qwen-code/issues/4175) (F-series milestones).
347+
- User guide: [`../../users/qwen-serve.md`](../../users/qwen-serve.md).
348+
- Wire protocol reference: [`../qwen-serve-protocol.md`](../qwen-serve-protocol.md).
349+
- F2 design document: [`../../design/f2-mcp-transport-pool.md`](../../design/f2-mcp-transport-pool.md).
350+
- F2 design notes: issue [#4175](https://github.com/QwenLM/qwen-code/issues/4175) commits 4-6.

0 commit comments

Comments
 (0)