qwen-code Daemon 权限响应超时机制:`ask_user_question` 默认无限等待的设计与实现
qwen-code Daemon 权限响应超时机制ask_user_question默认无限等待的设计与实现【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本篇技术指南聚焦 qwen-code 开源仓库中 daemon 交互的权限响应超时permission-response timeout机制在 2026-08-24-daemon-ask-user-question-timeout.md 设计文档的规划下所有需要人类响应的 daemon 交互普通权限请求与 ACP 的ask_user_question提问默认无限期等待而需要墙钟wall-clock上限的运维场景可继续通过permissionResponseTimeoutMs桥接选项或qwen serve --permission-response-timeout-ms命令行参数显式设置。读完本文你将掌握该超时边界的来源、默认行为与可配置性、与既有取消机制的关系以及它在源码中的实际落地位置与验证方式。设计动机为什么默认等待改为无限在 qwen-code 的 daemon 架构中会话session内的 agent 可以发起两类需要人类介入的交互普通权限请求permission requestagent 执行敏感操作前向用户请求授权ACP 工具调用中的提问ask_user_question通过 ACPAgent Client Protocol标记为_meta.qwenInteractionKind user_question的工具调用向用户提出需要回答的问题。设计文档 2026-08-24-daemon-ask-user-question-timeout.md 明确的目标是让这些交互在默认情况下无限等待人类响应。其核心理由是——提问与授权本身是异步的人类决策由墙钟计时器强制中断不仅容易打断真实用户的思考还会在无人值守的自动化会话中造成误取消。需要硬性时间上限的运维场景例如定时任务、无人值守脚本则应显式配置超时而非依赖默认值。该变更由桥接层BridgeClient统一承载普通权限与带user_question标记的 ACP 工具调用都经由同一个 permission mediator权限中介转发而中介持有的是每请求单一计时器因此共享的桥接选项permissionResponseTimeoutMs依然是正确的配置边界——这一设计判断保证了新增的提问交互无需引入第二套超时体系。行为语义默认值与三种取值形态文档规定了三条精确的行为规则源码在 bridge.ts 中逐条落实省略或设为0不安装墙钟计时器。无论普通权限还是ask_user_question请求都会无限等待直到出现取消信号或用户明确决策。正数含 CLI 标志传入的值两类交互统一生效。该正数同时作用于普通权限与提问不存在只对提问生效的单独选项。不新增任何环境变量、线协议字段或提问专属选项。配置面保持单一降低运维心智负担。源码层的默认值与归一化在 bridge.ts 中默认值被显式定义为// Human permissions wait indefinitely by default and still resolve through // voter cancellation, session cancellation, and shutdown. Operators can set // BridgeOptions.permissionResponseTimeoutMs when they need a wall-clock cap. const DEFAULT_PERMISSION_TIMEOUT_MS 0;即DEFAULT_PERMISSION_TIMEOUT_MS 0对应禁用超时。随后在 bridge.ts 完成取值归一化const permissionTimeoutRaw opts.permissionResponseTimeoutMs ?? DEFAULT_PERMISSION_TIMEOUT_MS; const permissionTimeoutMs permissionTimeoutRaw 0 Number.isFinite(permissionTimeoutRaw) ? // Clamp to 2^31-1: Node treats setTimeout delays larger than // this as 1ms (TimeoutOverflowWarning) ... Math.min(permissionTimeoutRaw, 2_147_483_647) : 0; // 0 disabled值得注意的实现细节有二Infinity与0等效只要不是正有限数一律归一化为0禁用。这使permissionResponseTimeoutMs: Infinity可以作为一种显式的永久等待编程写法。钳制到2^31 - 1Node.js 将超过2^31-1约 24.8 天的setTimeout延迟视为 1ms 并发出TimeoutOverflowWarning若不对其钳制一个本意是永不超时的巨大值反而会导致权限几乎立即被取消——这与意图完全相反。该钳制与同文件中的resolvePositiveFiniteMs、resolvedChannelIdleTimeoutMs等兄弟实现保持一致。配置入口桥接选项与 CLI 标志桥接选项BridgeOptions.permissionResponseTimeoutMs作为共享配置边界该选项在 bridgeOptions.ts 中有完整的 JSDoc 契约/** * Per-requestPermission wall clock. After this many ms with no client * vote, the agents permission promise resolves as cancelled. Defaults to * disabled so human permissions and questions wait for an explicit decision * or session lifecycle cancellation. * 0 / Infinity / non-finite disable the timeout. */ permissionResponseTimeoutMs?: number;关键语义超时后的结果不是报错而是以已取消cancelled解析 agent 的 permission promise。JSDoc 同时确认0、Infinity与非有限值均禁用超时与上面DEFAULT_PERMISSION_TIMEOUT_MS 0的归一化逻辑呼应。CLI 标志--permission-response-timeout-msqwen serve子命令暴露了同名命令行入口位于 serve.ts.option(permission-response-timeout-ms, { // ...类型为 number语义与 BridgeOptions.permissionResponseTimeoutMs 一致 })并在 serve.ts 中把解析结果透传给桥接构造...(argv[permission-response-timeout-ms] ! undefined ? { permissionResponseTimeoutMs: argv[permission-response-timeout-ms], } : {})因此实操上两种写法等价# 方式一通过 CLI 标志为 daemon 设置 5 分钟墙钟上限 qwen serve --permission-response-timeout-ms 300000 # 方式二编程式构造桥接时传入选项0/Infinity 均表示禁用 const bridge createAcpSessionBridge({ permissionResponseTimeoutMs: 300000, // ...其他选项 });CLI 选项的解析与校验由serve命令的 option 定义与相应测试覆盖见下文验证一节。不变的行为边界与既有取消/清理机制的关系设计文档特别强调本次变更不触及任何既有的会话生命周期机制。以下路径在超时禁用后依然按原语义工作源码中的pendingInteractions模型与相应事件流可以佐证机制语义说明Voter cancellation投票者主动取消用户对权限/提问作出取消决策Session cancellation会话级取消会话被取消时挂起的交互随之终止Prompt cancellation提示词级取消当前 prompt 被取消其挂起的提问/授权一并取消Disconnect cleanup断连清理客户端断连后清理挂起交互Idle reaping空闲回收会话空闲超时被回收时清理挂起项Daemon shutdowndaemon 关闭关闭流程中清理所有挂起交互Pending-interaction caps挂起交互上限每会话挂起权限数上限默认 64等准入控制照常生效从源码结构看这些取消路径共享pendingInteractions登记表在 bridge.ts 的会话摘要构造中挂起交互会按interaction.kind user_question被区分为isWaitingForUserQuestion与isWaitingForPermission两种等待状态分别反映到会话摘要字段中——这说明无限等待并不意味着状态不可见daemon 的会话状态查询依然能区分当前到底在等人授权还是等人回答问题。明确非目标依据设计文档以下内容不属于本次变更范围读者不应期待该设计带来这些能力不改变**权限策略permission policy**本身——是否允许、如何批准仍由既有策略决定不改变**挂起交互快照pending interaction snapshots**的形态不改变 **daemon 重启后的恢复restart restoration**逻辑不引入prompt 级整体截止时间prompt-wide deadline——若需要整个 prompt 的总时间上限应使用其他既有机制如qwen serve的其他超时选项本设计仅覆盖单次权限/提问的响应等待。一句话概括这是一次纯超时默认值语义的调整不新增任何权限治理能力。验证与测试覆盖设计文档要求通过桥接测试与 CLI 测试双侧验证仓库中的落地情况如下桥接焦点测试bridge.test.ts覆盖两类交互普通权限与ask_user_question在两种配置下的行为——默认禁用计时器无限等待与显式有限超时。测试中通过qwenInteractionKind: user_question与toolName: ask_user_question构造 ACP 提问用例见 bridge.test.ts 等并借助vi.advanceTimersByTimeAsync推进假计时器验证超时路径。CLI 解析测试serve.test.ts覆盖--permission-response-timeout-ms的解析与校验确保非法值如负数、NaN被拒、合法值被正确透传。打包与类型检查验证共享选项在桥接构造链上的接线无误即serve→runQwenServe→createAcpSessionBridge的选项透传不漂移。典型使用场景建议基于以上语义可以给出如下配置建议供运维与集成方参考交互式终端 / 人机协作会话保持默认不设permissionResponseTimeoutMs让提问与授权无限等待用户避免用户在思考时被意外取消。无人值守自动化 / 定时任务显式设置qwen serve --permission-response-timeout-ms 毫秒为每次授权/提问设定墙钟上限超时后以已取消结果回传给 agent由 agent 决定降级路径如跳过该步骤或记录后继续。需要显式永不超时的编程式集成传入permissionResponseTimeoutMs: Infinity或0二者均被归一化为禁用状态等价于默认行为。超大值防护即便误传了大于2^31-1的值源码也会钳制到2^31-1不会出现 Node.jsTimeoutOverflowWarning导致的近乎立即取消反效果。小结ask_user_question默认无限等待的设计本质上是把人类决策节奏与机器墙钟解耦默认尊重人类响应显式选项留给需要硬性上限的运维场景。实现上通过BridgeClient共享的 permission mediator 单一计时器让普通权限与 ACP 提问共用permissionResponseTimeoutMs一个配置面DEFAULT_PERMISSION_TIMEOUT_MS 0、2^31-1钳制、Infinity归一化等细节进一步保证了默认语义的稳健与可预测。相关设计文档见 2026-08-24-daemon-ask-user-question-timeout.md实现与测试可分别在 bridge.ts、bridgeOptions.ts、bridge.test.ts 与 serve.ts 中深入阅读。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考