Skip to content

Commit 4147aa8

Browse files
committed
docs(developers): add daemon-mode developer deep-dive documentation set (Chinese)
Adds 21-file Chinese developer documentation set under docs/developers/daemon/ for qwen serve daemon mode. Plus one nav entry in docs/developers/_meta.ts and a sub-nav under docs/developers/daemon/_meta.ts. The set complements (not replaces) the existing daemon docs: - docs/users/qwen-serve.md — operator quickstart, flags, threat model - docs/developers/qwen-serve-protocol.md — wire-level HTTP routes - docs/developers/examples/daemon-client-quickstart.md — TS walkthrough - docs/developers/daemon-client-adapters/* — adapter design drafts - docs/design/f2-mcp-transport-pool.md — F2 design v2.2 It is the developer architecture reference that's been missing — a new contributor's path through the system, with one architectural diagram doc + per-component deep-dives + a quickstart/operations chapter. Document set: Foundation - 00-index.md navigation, glossary, reading paths - 01-architecture.md system architecture + 6 Mermaid diagrams Server core - 02-serve-runtime.md runQwenServe bootstrap, Express, lifecycle, validatePolicyConfig + InvalidPolicyConfigError - 03-acp-bridge.md @qwen-code/acp-bridge package internals - 04-permission-mediation.md MultiClientPermissionMediator — four policies, N=floor(M/2)+1 quorum + M=2 unanimity edge case, X-Qwen-Client-Id self-declaration security caveat - 05-mcp-transport-pool.md McpTransportPool (F2) including pool-aware snapshot fields (entryCount / entrySummary), MCPCallInterruptedError on silent transport drop, canonicalOAuth fingerprint normalization, extension-uninstall orphan reap via MAX_IDLE_MS, IDE-close drain path, /mcp refresh pool gate - 06-mcp-budget-guardrails.md WorkspaceMcpBudget — modes, hysteresis, refused-batch coalescing, scope: 'pool' future reservation - 07-workspace-filesystem.md WorkspaceFileSystem sandbox + FsError preservation over ACP wire - 08-session-lifecycle.md create/attach/load/resume, identity, heartbeat, eviction - 09-event-schema.md typed event schema v1 (29 known event types) with payloads, reducers, envelope-level metadata (_meta.serverTimestamp), tool-call _meta (provenance + serverId), SDK reducer behavior (awaitingResync flag, RESYNC_PASSTHROUGH_TYPES) - 10-event-bus.md EventBus + Last-Event-ID replay + ring-eviction-on-resume state_resync_required recovery flow - 11-capabilities-versioning.md capability registry, protocol version, conditional advertisement - 12-auth-security.md bearer, host allowlist, mutation gate, --require-auth, /health exemption, device-flow, X-Qwen-Client-Id identity caveat, sanitizeForStderr CVE-2021-42574 defense Clients - 13-sdk-daemon-client.md TypeScript SDK — DaemonClient, DaemonSessionClient, DaemonAuthFlow, SSE, MCP_RESTART_DEFAULT_TIMEOUT_MS 330s rationale - 14-cli-tui-adapter.md DaemonTuiAdapter - 15-channel-adapters.md DaemonChannelBridge + DingTalk / WeChat / Telegram - 16-vscode-ide-adapter.md DaemonIdeConnection (loopback-only) Reference appendices - 17-configuration.md env vars + CLI flags + settings.json keys - 18-error-taxonomy.md typed errors per layer (filesystem boundary, bridge errors, daemon-host error kinds, boot-time config errors, device-flow) - 19-observability.md QWEN_SERVE_DEBUG, debug recipes, /demo console Quickstart / operations - 20-quickstart-operations.md 9 startup recipes; full CLI flag / env / settings.json reference; boot fail-loud scenarios; curl validation checklist; /demo console usage; full call chain from `qwen serve` to listening server with line numbers; embedded-mode examples; graceful vs force shutdown Each topic doc follows: 概览 / 职责 / 架构 / 流程 (with Mermaid diagrams) / 状态与生命周期 / 依赖 / 配置 / 注意 & 已知局限 / 参考. Pinned to the daemon_mode_b_main code surface (F2 pool, F3 mediator, F4 prereqs). Some referenced files (McpTransportPool, state_resync_ required, validatePolicyConfig, FsError-over-wire, sanitizeForStderr) land on main only when daemon_mode_b_main next batches up — the doc set arrives ahead of the feature merges by design. History: prior revision of this PR was bilingual EN+ZH; switched to Chinese-only per maintainer preference and added 20-quickstart- operations.md to consolidate startup / validation / call-chain content that surfaced during review.
1 parent 48b0a8b commit 4147aa8

23 files changed

Lines changed: 4430 additions & 0 deletions

docs/developers/_meta.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default {
2121
'channel-plugins': 'Channel Plugin Guide',
2222
tools: 'Tools',
2323
'qwen-serve-protocol': 'qwen serve HTTP protocol',
24+
daemon: 'Daemon 模式 · 开发者深度指南',
2425

2526
examples: {
2627
display: 'hidden',

docs/developers/daemon/00-index.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Daemon 开发者文档
2+
这是 **qwen-code daemon 模式**面向开发者的技术文档集 —— 涵盖 `qwen serve` HTTP daemon、底层的 `acp-bridge` 包、工作区粒度的 MCP transport 池、多客户端权限协调器、Typed Daemon Event Schema v1、TypeScript SDK daemon 客户端,以及所有上层适配器(CLI TUI、IM 渠道机器人、VSCode IDE 等)。
3+
4+
它是对现有文档的补充,而不是替代:
5+
6+
| 现有文档 | 受众 | 仍是该主题的事实来源 |
7+
| ------------------------------------------------------------------------------------ | ------------------ | ---------------------------------------------------------------------- |
8+
| [`../../users/qwen-serve.md`](../../users/qwen-serve.md) | 运维 / 使用者 | 启动方式、命令行参数、威胁模型 |
9+
| [`../qwen-serve-protocol.md`](../qwen-serve-protocol.md) | 协议实现者 | HTTP 路由清单、请求/响应结构、错误码 |
10+
| [`../examples/daemon-client-quickstart.md`](../examples/daemon-client-quickstart.md) | SDK 使用者 | TS 端到端示例 |
11+
| [`../daemon-client-adapters/`](../daemon-client-adapters/) | 适配器作者(草案) | 每种客户端的设计草案 |
12+
| [`../../design/f2-mcp-transport-pool.md`](../../design/f2-mcp-transport-pool.md) | F2 维护者 | 工作区共享 MCP transport 池设计 v2.2(32 条 review fold-in changelog) |
13+
14+
如果你想 **快速把 daemon 跑起来 + 验证它工作**,直接看 [`20-quickstart-operations.md`](./20-quickstart-operations.md);如果你想 **基于 wire 协议构建一个客户端**,先看 `qwen-serve-protocol.md`;如果你想 **理解 daemon 内部如何工作、扩展它或调试它**,就读本文档集 01–19。
15+
16+
## 阅读顺序
17+
18+
按目标挑路径:
19+
20+
- **想先跑起来再看原理** — 直接 `20 → 17 → 19`(快速上手 + 配置 + 调试),有问题再回来看 01 + 02。
21+
- **新贡献者** — 依次:`01 → 02 → 03 → 08 → 09 → 10 → 11 → 12`,覆盖系统、运行时、bridge、wire 侧基础。`20` 任意时候作为「跑起来怎么验」的副本。
22+
- **新增客户端适配器**`01 → 09 → 10 → 13 → (14 / 15 / 16)`:架构、事件模式、SSE bus、SDK,再看与你最接近的适配器。
23+
- **修改 MCP 池 / 预算**`01 → 03 → 05 → 06`
24+
- **修改权限相关代码**`01 → 03 → 04 → 12`
25+
- **线上排查问题**`19 → 18 → 17 → 20`
26+
27+
## 文档清单
28+
29+
### 基础
30+
31+
- [`01-architecture.md`](./01-architecture.md) — 系统架构、进程拓扑、包关系、6 张顶层时序图。
32+
33+
### 服务端核心
34+
35+
- [`02-serve-runtime.md`](./02-serve-runtime.md)`runQwenServe` 引导、Express 应用、中间件链、优雅退出。
36+
- [`03-acp-bridge.md`](./03-acp-bridge.md)`@qwen-code/acp-bridge` 包内部、会话多路复用、channel 工厂、ACP 子进程拉起。
37+
- [`04-permission-mediation.md`](./04-permission-mediation.md)`MultiClientPermissionMediator` 四种策略、N1 超时不变式、取消哨兵。
38+
- [`05-mcp-transport-pool.md`](./05-mcp-transport-pool.md) — F2 引入的 `McpTransportPool`、池条目、反向索引、重启、drain。
39+
- [`06-mcp-budget-guardrails.md`](./06-mcp-budget-guardrails.md)`WorkspaceMcpBudget`、模式(off/warn/enforce)、滞回阈值、批量拒绝合并。
40+
- [`07-workspace-filesystem.md`](./07-workspace-filesystem.md)`WorkspaceFileSystem` 沙箱、路径策略、审计、`BridgeFileSystem` 契约。
41+
- [`08-session-lifecycle.md`](./08-session-lifecycle.md) — 创建 / 附加 / 载入 / 恢复、`X-Qwen-Client-Id`、心跳、剔除、元数据。
42+
- [`09-event-schema.md`](./09-event-schema.md) — Typed Event Schema v1:29 种已知事件、payload、reducer、向前兼容。
43+
- [`10-event-bus.md`](./10-event-bus.md)`EventBus`、单调 ID、环形缓冲重放、`Last-Event-ID`、慢消费者反压、`client_evicted`
44+
- [`11-capabilities-versioning.md`](./11-capabilities-versioning.md) — 能力注册表、协议版本、Schema 版本、条件广播。
45+
- [`12-auth-security.md`](./12-auth-security.md) — Bearer 中间件、Host 白名单、CORS 拒绝、Mutation Gate、`--require-auth``/health` 豁免、Device Flow。
46+
47+
### 客户端
48+
49+
- [`13-sdk-daemon-client.md`](./13-sdk-daemon-client.md) — TS SDK:`DaemonClient``DaemonSessionClient``DaemonAuthFlow`、SSE 解析器、事件 reducer,以及新的 `ui/*` 子包。
50+
- [`14-cli-tui-adapter.md`](./14-cli-tui-adapter.md)**共享 UI Transcript 层**(SDK `ui/*`)。原 `DaemonTuiAdapter.ts` 已在 #4328 中删除;本篇覆盖新的 transcript 归一 / reduce / selector 原语与 webui `DaemonSessionProvider` 消费方。
51+
- [`15-channel-adapters.md`](./15-channel-adapters.md)`DaemonChannelBridge` 共享基座 + 钉钉、微信、Telegram 适配器。
52+
- [`16-vscode-ide-adapter.md`](./16-vscode-ide-adapter.md)`DaemonIdeConnection`、Loopback 强制、Webview 桥接。
53+
54+
### 参考附录
55+
56+
- [`17-configuration.md`](./17-configuration.md) — 影响 daemon 的环境变量、命令行参数、`settings.json` 键。
57+
- [`18-error-taxonomy.md`](./18-error-taxonomy.md) — 各层的 typed error 与修复建议。
58+
- [`19-observability.md`](./19-observability.md)`QWEN_SERVE_DEBUG`、调试套路、Telemetry 现状缺口。
59+
60+
### 快速上手 / 运维向
61+
62+
- [`20-quickstart-operations.md`](./20-quickstart-operations.md) — 9 种启动姿势、全部 CLI 参数 / env / `settings.json` 速查表、boot 拒启动场景、`curl` 验证清单、`/demo` 用法、`qwen serve` → listening server 的完整调用链、嵌入式调用示例、优雅退出 vs 强退。**想先跑起来再看原理的话从这篇开始。**
63+
64+
## 术语表
65+
66+
- **ACP** — Agent Client Protocol,daemon bridge 与 ACP 子进程之间通过 stdio 跑的 JSON-RPC;不要和客户端用来访问 daemon 的 HTTP 协议混淆。
67+
- **ACP 子进程** — daemon 拉起的子进程(`qwen --acp`),里面跑真正的 agent 运行时;daemon 的 bridge 把一个 ACP 子进程多路复用给多个连进来的客户端。
68+
- **acp-bridge**`@qwen-code/acp-bridge` 包(`packages/acp-bridge/`),负责会话多路复用、权限协调器、事件总线、channel 工厂。
69+
- **BridgeClient**`packages/acp-bridge/src/bridgeClient.ts`,封装一条 ACP `ClientSideConnection`,处理 `requestPermission` / `sendPrompt` / `cancelSession`
70+
- **Channel 工厂** — 可插拔策略,决定 bridge 如何拉起 / 附加 ACP 子进程:默认 `spawnChannel``qwen --acp` 跑成子进程;`inMemoryChannel` 在进程内跑用于测试。
71+
- **DaemonClient**`packages/sdk-typescript/src/daemon/DaemonClient.ts`,TS SDK 对 daemon 的 HTTP 门面。
72+
- **DaemonSessionClient**`packages/sdk-typescript/src/daemon/DaemonSessionClient.ts`,会话级封装,自动跟踪 `lastSeenEventId` 用于 SSE 重放。
73+
- **EventBus**`packages/acp-bridge/src/eventBus.ts`,按会话维度的内存 pub/sub:单调 ID、环形缓冲、每订阅者反压。
74+
- **F1 / F2 / F3 / F4**[#4175](https://github.com/QwenLM/qwen-code/issues/4175) 的里程碑:F1 bridge 抽取 + `BridgeFileSystem`;F2 工作区共享 MCP transport 池;F3 多客户端权限协调;F4 协议补齐 + `qwen --serve` 同进程托管(进行中)。
75+
- **MCP** — Model Context Protocol,MCP server 暴露 tool / resource / prompt,daemon 的 ACP 子进程连这些 server。
76+
- **McpTransportPool**`packages/core/src/tools/mcp-transport-pool.ts`,F2 的工作区共享池,按 (server 名 + 配置指纹) 复用一个 MCP transport。
77+
- **Mediator policy**`first-responder` / `designated` / `consensus` / `local-only` 之一,决定多客户端权限投票如何裁决。
78+
- **Originator client id** — 触发当前权限请求的那次 prompt 所用的 `X-Qwen-Client-Id``designated` 策略只接受这个 id 的投票。
79+
- **PoolEntry**`packages/core/src/tools/mcp-pool-entry.ts``McpTransportPool` 里的一条记录:一条 MCP transport、引用此条目的会话引用计数、空闲 drain 定时器。
80+
- **Session scope**`single`(所有客户端共享一个 ACP 会话)或 `per-client`(每客户端一个会话),默认 `single`
81+
- **SSE** — Server-Sent Events,daemon 的出站事件通道(`GET /session/:id/events`)。
82+
- **Workspace** — daemon 启动时绑定的目录(`--workspace``cwd`),一个 daemon 进程 = 一个 workspace。
83+
84+
## 本文档集****覆盖的内容
85+
86+
- **Java / Python SDK 的 daemon 客户端** — 目前只有 TS SDK 有 daemon 客户端,第 13 篇只覆盖 TS。
87+
- **Web UI 详细产品形态** — 自 [#4328](https://github.com/QwenLM/qwen-code/pull/4328)`packages/webui/src/daemon/` 已经是真正的 daemon 前端(React `DaemonSessionProvider` + transcriptAdapter,消费 SDK `ui/*` 子包)。架构走法和 selectors 在 [`14-cli-tui-adapter.md`](./14-cli-tui-adapter.md) 一并讲;webui 自身的产品形态(设计、布局、复用到哪里)参考 [`../daemon-client-adapters/web-ui.md`](../daemon-client-adapters/web-ui.md)[`../daemon-ui/README.md`](../daemon-ui/README.md)
88+
- **Zed extension (`packages/zed-extension/`)** — 直接用 stdio ACP 拉起 `qwen --acp`,不走 daemon,不需要 daemon 章节。
89+
- **F4(进行中)** — 协议补齐和 `qwen --serve` 同进程托管。写文档时该 surface 还不稳定,等落地后再补章。
90+
91+
## 本版本新增了什么(F4 prereq 已合入)
92+
93+
本文档集原本锁在 `cb206da36`。merge `origin/daemon_mode_b_main`(commit `a60c1c52a` 加之前的 F 系列 fold-in)之后,F4-prereq surface 已经在树里,文档直接覆盖:
94+
95+
| Surface | 现在记在哪 | 源代码定位 |
96+
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
97+
| `state_resync_required` 合成帧(第 29 种已知事件) | [`09-event-schema.md`](./09-event-schema.md) Subscriber 级合成帧 + SDK reducer 行为;[`10-event-bus.md`](./10-event-bus.md) 环驱逐 → `state_resync_required` 恢复流 | `packages/acp-bridge/src/eventBus.ts:359-402``packages/sdk-typescript/src/daemon/events.ts:13-63, 256-280` |
98+
| `_meta.serverTimestamp` envelope 字段 | [`09-event-schema.md`](./09-event-schema.md) Envelope 级元数据 | `packages/cli/src/serve/server.ts:2602+``formatSseFrame`|
99+
| `tool_call.provenance` + `serverId`(在 `data._meta`,不是 envelope) | [`09-event-schema.md`](./09-event-schema.md) Tool-call `_meta` | `packages/cli/src/acp-integration/session/emitters/ToolCallEmitter.ts:218-237``resolveToolProvenance`|
100+
| `awaitingResync` reducer 标志 + `RESYNC_PASSTHROUGH_TYPES` | [`09-event-schema.md`](./09-event-schema.md) SDK reducer 行为 | `packages/sdk-typescript/src/daemon/events.ts:870-905, 1120-1140` |
101+
| FsError 在 ACP wire 上的保留 | [`07-workspace-filesystem.md`](./07-workspace-filesystem.md) FsError 在 ACP wire 上的保留 | `packages/acp-bridge/src/bridgeClient.ts:40-100+``isFsErrorShape``preserveFsErrorOverAcp`|
102+
103+
向前兼容没破:已经按 `narrowDaemonEvent → kind: 'unknown'` fallback 实现的 SDK 消费方在 29th 类型落地时零破坏。
104+
105+
## 本次合入(共享 UI Transcript 层 + F2 cleanup)
106+
107+
merge `origin/daemon_mode_b_main`(HEAD `a9d0c5fd1`,覆盖 [#4328](https://github.com/QwenLM/qwen-code/pull/4328) + [#4353](https://github.com/QwenLM/qwen-code/pull/4353) + [#4411](https://github.com/QwenLM/qwen-code/pull/4411) + [#4460](https://github.com/QwenLM/qwen-code/pull/4460) + [#4445](https://github.com/QwenLM/qwen-code/pull/4445) + main sync)之后,新增 surface 进了下面这些文档:
108+
109+
| Surface | 文档落点 | 源代码定位 |
110+
|---|---|---|
111+
| **共享 UI Transcript 层** `packages/sdk-typescript/src/daemon/ui/`(28+ `DaemonUiEventType`、reduce、selectors、render / terminal / conformance) | [`14-cli-tui-adapter.md`](./14-cli-tui-adapter.md)**整篇重写**)+ [`13-sdk-daemon-client.md`](./13-sdk-daemon-client.md) 新「`ui/*` 子包」段 | `packages/sdk-typescript/src/daemon/ui/{types,normalizer,transcript,store,render,terminal,toolPreview,conformance,utils,index}.ts` |
112+
| **webui daemon 前端** `packages/webui/src/daemon/`(React `DaemonSessionProvider` + transcriptAdapter) | [`14-cli-tui-adapter.md`](./14-cli-tui-adapter.md)「消费方」段 + 本文「不覆盖」段 webui 条目改写 | `packages/webui/src/daemon/DaemonSessionProvider.tsx``transcriptAdapter.ts``index.ts` |
113+
| **`DaemonTuiAdapter.ts` 已删** | [`14-cli-tui-adapter.md`](./14-cli-tui-adapter.md) 顶部「历史变更」+「与老 DaemonTuiAdapter 对比」段 | `packages/cli/src/ui/daemon/` 目录在 #4328 中删除 |
114+
| **`McpClient.lastTransportError`**(W133-a 自愈可观测性) | [`05-mcp-transport-pool.md`](./05-mcp-transport-pool.md) 新「自愈可观测性」段 | `packages/core/src/tools/mcp-client.ts:106-161, 336-346` |
115+
| **`SweepResult` 结构化返回**(W134 孤儿 pid 报告) | [`05-mcp-transport-pool.md`](./05-mcp-transport-pool.md) 新「自愈可观测性」段 | `packages/core/src/tools/mcp-pool-entry.ts:111+, 804+` |
116+
| **`McpClientManager` options-object ctor**(R9 重构) | [`05-mcp-transport-pool.md`](./05-mcp-transport-pool.md) 新「options-object ctor」段 | `packages/core/src/tools/mcp-client-manager.ts`(7 位置参数 → `(config, toolRegistry, options?)`|
117+
| **F1 测试拆分**`httpAcpBridge.test.ts``bridge.test.ts` 移到 acp-bridge 包) | 不影响文档面(无产品行为变化) | `packages/acp-bridge/src/bridge.test.ts` |
118+
| **上游新文档** `docs/developers/daemon-ui/{README,MIGRATION}.md``docs/developers/daemon-client-adapters/web-ui.md` | 本文上方「现有文档」表 + 第 14、13 篇交叉引用;老 `docs/developers/daemon-client-adapters/tui.md` 已被 #4328| upstream |
119+
120+
如果你 grep 老的 `DaemonTuiAdapter` / `reduceDaemonEventToTuiUpdates` / `DaemonTuiUpdate`,要替换成 SDK `ui/*` 的对应 API(`reduceDaemonTranscriptEvents` / `DaemonTranscriptBlock` 等,详见第 14 篇与 `docs/developers/daemon-ui/MIGRATION.md`)。

0 commit comments

Comments
 (0)