尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

qwen-code Shell 超时错误语义:从“成功返回“到结构化 EXECUTION_TIMEOUT 的修复实践

qwen-code Shell 超时错误语义:从“成功返回“到结构化 EXECUTION_TIMEOUT 的修复实践 qwen-code Shell 超时错误语义从成功返回到结构化 EXECUTION_TIMEOUT 的修复实践【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文深入剖析 qwen-code 中对前台 Shell 命令超时错误语义的一次关键修正此前命令超时只以文本描述、却返回成功的ToolResult导致下游链路将其记录为成功、模型函数响应带output字段甚至渲染成功指示器。本文以设计文档 shell-timeout-error-semantics.md 为骨架结合仓库源码packages/core/src/tools/shell.ts、packages/core/src/core/coreToolScheduler.ts、packages/core/src/services/shellExecutionService.ts讲解新的三通道结果契约、首因判定规则、预中止启动行为与各消费者适配。读完你将掌握 qwen-code 中超时 / 取消 / 提升promote三类中止的判别顺序、结构化错误在各协议层的编码方式以及这一修正对可观测性指标与安全边界的影响。背景问题超时被误记为成功设计文档开篇点明了缺陷的根源前台 Shell 命令超时后虽然错误文本中描述了 timeout但返回的ToolResult仍被标记为成功。由此引发一系列连锁错误下游代码将该调用记录为成功模型函数响应携带output字段而非error交互界面可以渲染成功指示器尽管命令实际并未完成超时之后到达的取消cancellation信号还可能覆盖原始原因在 PTY 发现PTY discovery阶段一个已被中止的调用仍可能拉起进程因为执行服务在启动完成前不会观察到该信号。结果契约三通道分离修复的核心是为前台 Shell 超时引入专用错误类型ToolErrorType.EXECUTION_TIMEOUT定义于 tool-error-type.ts枚举值为execution_timeout注释明确其为工具调用超过单工具执行超时并被中止。结果通过三个有意分离的通道输出通道受众超时内容error.messageHooks、遥测、spans、日志、告警仅简短超时摘要llmContent模型函数响应超时摘要 部分输出或显式无输出声明 任何截断提示returnDisplay交互历史与 ACP 客户端超时摘要 部分输出或无输出声明 任何截断提示调度器Core scheduler将超时llmContent转换为函数响应时其response携带error字段且没有output字段失败钩子failure hook的附加上下文只追加一次到模型面向的错误中。顶层ToolCallResponseInfo.error保持为简短运维摘要确保命令输出不会被复制进遥测或钩子错误参数。在源码层面shell.ts 展示了超时内容的组装逻辑const abortReasonName getAbortReasonName(combinedSignal); const wasTimeout result.aborted effectiveTimeout 0 abortReasonName TimeoutError; const timeoutSummary wasTimeout ? Command timed out after ${effectiveTimeout}ms before it could complete. : undefined; if (result.aborted) { if (wasTimeout) { llmContent timeoutSummary!; if (result.output.trim()) { llmContent Below is the output before it timed out:\n${result.output}; } else { llmContent There was no output before it timed out.; } } // ... }而结构化错误类型则在 shell.ts 中落地const executionError timeoutSummary ? { error: { message: timeoutSummary, type: ToolErrorType.EXECUTION_TIMEOUT, }, } : // ... 其它分支SHELL_EXECUTE_ERROR、信号终止、非零退出等其他软错误soft tool errors保留 Core 调度器既有行为ACP 与投机执行speculative execution则因为直接调用工具、缺少调度器分类步骤所有软错误都统一用错误信封error envelope编码。首因规则谁先发生就以谁为准AbortSignal.any()会保留第一个触发中止的信号的原因。Shell 分类在执行完成后只读取合并信号combined signal的原因判定顺序如下TimeoutError 已中止的执行 →超时background-promote 原因 已中止、但未提升的执行 → 既有的promote-refused 竞态其它已中止执行 →取消超时先发生 → 之后的用户取消或提升请求不改变它取消或提升请求先发生 → 之后的超时不改变它。Core 调度器还有一个可选的全局执行计时器第二计时器。工具返回的结构化超时即使父信号在调度器消费结果前已被中止仍是超时而当调度器自身计时器提供超时结果时只有当计时器触发时父信号尚未被中止它才胜出。即父信号取消在先、随后计时器对一个不配合的工具触发 → 结果仍是取消。相关实现可在 coreToolScheduler.ts 看到schedulerTimeoutResultSelected/schedulerTimeoutWon参与isTimeout判定并最终以ToolErrorType.EXECUTION_TIMEOUTTOOL_FAILURE_KIND_TIMEOUT构建timeoutResponse见 coreToolScheduler.ts。ACP 对结构化工具超时应用相同规则即使父信号事后被观察为已中止超时也编码为错误而非中断interrupt而抛出的异常thrown exceptions继续使用实时中止状态。启动行为预中止不再拉起进程ShellExecutionService.execute()在信号已经中止时立即返回一个已中止、无进程的句柄。PTY 发现阶段用getPty()与信号竞速并在竞速结束后移除临时监听器若中止获胜后续 PTY 的 resolve/reject 被直接消费既不会拉起 PTY、也不会回退到child_process。返回结果使用executionMethod: none且没有 pid。对应实现是 shellExecutionService.ts 中的早退检查if (abortSignal.aborted) { return createPreSpawnAbortedHandle(); }以及createPreSpawnAbortedHandle()shellExecutionService.ts构造的规范化结果——aborted: true、空输出、executionMethod: none、无 pid。PTY 竞速部分通过Promise.race([ptyResult, aborted])实现shellExecutionService.ts并在 PTY 解析、xterm headless 加载之后再次检查abortSignal.aborted。该行为影响仓库内所有该服务的消费者前台与后台 Shell 管道、用户!Shell、提示词命令注入prompt command injection、ACP 桥接 Shell 处理、git 归属探测attribution probes。唯一的行为变化是已中止的请求不再启动进程。消费者行为矩阵消费者超时行为Core 调度器status: error、短顶层错误、详细response.error、超时失败类别timeout failure kindACP 会话failed tool 更新、模型历史与记录中的详细错误信封、短运维元数据投机执行详细错误信封被接受的投机历史渲染为 ErrorAnthropic 适配器tool_result.is_error: trueOpenAI 兼容适配器显式详细错误文本协议层不存在错误位JSON 与 stream-jsonis_error: true优先详细嵌套错误内容而非短摘要上下文估算与批量预算response.output与response.error文本都计数超限卸载时保留 error 键微压缩microcompaction继续不动失败的工具结果而完整聊天压缩full chat compression现在能看见详细错误大小从而在正确的预算阈值触发。Claude Code 对比与设计取舍Claude Code 将命令超时视为失败的工具结果保留终止前产生的输出给模型与用户并在 Anthropic 协议中将工具结果标记为错误。本文设计采纳这些可观察属性同时保持 qwen-code 既有的ToolResult形状与遥测约定不会把命令输出复制进短运维错误通道。兼容性与可观测性影响这是一次有意的线上wire-level修正ACP 与投机执行的软失败从{ output }变为{ error }Core 仅在EXECUTION_TIMEOUT场景改变该形状超时计数从成功指标迁移到错误/超时指标失败钩子failure hooks取代成功钩子无schema、错误枚举、超时默认值、迁移或灰度开关变更。安全边界部分命令输出可能包含敏感数据。它仍然如修正前一样对模型、交互结果、聊天记录与显式 JSON 输出可见但不会被加入钩子错误参数、顶层错误、span 结果属性或运维日志摘要既有的截断与溢出到磁盘spill-to-disk限制继续作用于详细模型通道。明确不在范围内设计文档划定了清晰边界以下内容不属于本次修正心跳或周期性进度上报Todo 停止守卫stop guards或提示词变更非零退出码语义外部信号终止语义后台 Shell 超时全局调度器计时器胜出后等待部分输出新增超时设置或协议字段。验证与测试单元测试覆盖了预中止与 PTY 发现竞态、Shell 超时/取消/提升的排序、sed 模拟、调度器短/详细通道、Core 全局超时排序、ACP 与投机直接调用、Anthropic 转换、JSON 内容选择、错误大小估算与批量卸载。E2E 计划记录在.qwen/e2e-tests/shell-timeout-semantics.md该路径位于仓库运行时目录本文仅作设计文档中的验证说明引用。小结本次修正让 qwen-code 的 Shell 超时从文本提示 成功结果的误导性状态升级为结构化、三通道分离、首因确定的EXECUTION_TIMEOUT错误模型得到详细且含部分输出的错误内容运维与遥测只看到简短摘要协议适配层Anthropic / OpenAI / JSON / ACP / 投机执行各按其能力编码错误同时预中止请求不再启动进程从根本上消除了超时被计为成功与取消覆盖超时原因两类语义污染。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表