Skip to content

fix(tools): Bash 结果显式说明被 provider 超时上限杀掉 - #802

Merged
coder-hhx merged 1 commit into
mainfrom
fix/bash-timeout-diagnostics
Sep 11, 2026
Merged

fix(tools): Bash 结果显式说明被 provider 超时上限杀掉#802
coder-hhx merged 1 commit into
mainfrom
fix/bash-timeout-diagnostics

Conversation

@coder-hhx

Copy link
Copy Markdown
Collaborator

Linked issue

Closes #799

Summary

现场:同一个构建在无人工干预下连续执行三次,前两次的日志(/tmp/wt-build.log
/tmp/wt-build2.log)里看不到失败原因,第三次才 Build complete。用户无法判断这是
"工具调用超时重试"、"上层 agent 重试"还是"进程崩溃重启"。

核对结论有两条:

  1. 工具层没有任何自动重试executeSingleToolCallagentRunner.ts)每个工具调用
    只尝试一次,错误变成 toolResult。所以"连续跑三次"是模型自己发起的重复调用。
  2. 前两次是被 provider 上限杀掉的bashTimeoutPolicy.ts
    CODEX_BASH_MAX_TIMEOUT_MS = 30_000,codex / gemini / xai / deepseek 的默认值与
    上限同为 30s(只有 claude_code 是 120s 默认 / 600s 上限),而那次构建约 34s。
    被杀的命令自己的日志文件里当然什么都没有——它是被外部杀掉,而不是自己报错。

原来这件事只以 timed_out: true 一行呈现,既没说明"不是崩溃",也没说明"原样重跑会撞
同一个上限",模型于是把同一条命令又发了一遍。

本次改动buildShellFailureHintcrates/agent-gui/src/lib/tools/shellTools.ts
timed_out 时输出一条因果说明——被 shell 超时(N ms)杀掉、不是崩溃、命令本身没有报错、
该 provider 的硬上限是多少、原样重跑会撞同一个上限,以及可行替代做法(把输出重定向到文件后
轮询 / 拆成能在上限内完成的步骤 / 显式传 timeout_ms)。调用点把
timed_out / effective_timeout_ms / timeoutPolicy.maxTimeoutMs / providerLabel 传进去。

没有改动超时策略本身:是否放宽 codex/gemini/xai/deepseek 的 30s 上限(向 Claude Code 的
120s/600s 靠拢,或按命令类别区分)属于产品取舍,已在 #799 单列为待评估项。本 PR 只保证
"这次为什么被杀"在工具结果里说得清楚。

Change scope

  • Modules: agent-gui / tools
  • Key paths:
    • crates/agent-gui/src/lib/tools/shellTools.ts
    • crates/agent-gui/test/tools/shell-tools.test.mjs

Screenshots / preview

非 UI 改动,下面是工具结果文本的前后对照(同一 mock:timed_out: true
effective_timeout_ms: 30000、provider = DeepSeek)。

修复前(关键几行):
# Shell
...
exit_code: -1
timed_out: true
timeout_ms: 30000
duration_ms: 30123

修复后追加:
Hint: This run was killed by the shell timeout (30000ms) — it did not crash, and the
command itself reported no error. The partial output above is everything it produced
before the kill. DeepSeek caps Bash at 30000ms, so re-running the identical command
unchanged reaches the same limit: redirect the output to a file and poll that file,
split the work into steps that finish within 30000ms, or pass an explicit timeout_ms
(clamped to 30000ms).

Verification

  • cd crates/agent-gui && node test/tools/shell-tools.test.mjs35/35 通过
    含新增用例 Bash tool spells out a provider-capped timeout instead of leaving the kill unexplained
    (断言 timed_out: truetimeout_ms: 30000、"killed by the shell timeout (30000ms)"、
    "it did not crash"、"DeepSeek caps Bash at 30000ms"、"re-running the identical command
    unchanged reaches the same limit"、"redirect the output to a file")。
  • cd crates/agent-gui && pnpm test:frontend3095/3095 通过
  • pnpm build(tsc + vite)与 pnpm lint(biome,333 文件)通过。

Pre-submit checklist

现场:同一个构建在无人工干预下连续执行三次,前两次的日志里看不到失败原因
(只有第三次 Build complete)。核对后两点:

1. 工具层没有自动重试——`executeSingleToolCall` 每个工具调用只尝试一次,
   重复执行都是模型自己发起的;
2. 前两次是被 provider 上限杀掉的:`bashTimeoutPolicy.ts` 里
   `CODEX_BASH_MAX_TIMEOUT_MS = 30_000`,codex / gemini / xai / deepseek 的默认值与
   上限同为 30s,而那次构建约 34s。被杀的命令自己的日志里当然什么都没有——它是被
   外部杀掉而不是自己报错。

原来只以 `timed_out: true` 一行呈现,既没说明"不是崩溃",也没说明"原样重跑会撞
同一个上限",模型于是把同一条命令又发了一遍。现在 `buildShellFailureHint` 在
`timed_out` 时输出一条因果说明:被 shell 超时(N ms)杀掉、不是崩溃、命令本身没有
报错、该 provider 的硬上限、重跑同一命令会再次撞上限,以及可行替代做法
(输出重定向到文件后轮询 / 拆步 / 显式传 timeout_ms)。

未改动超时策略本身:是否放宽 codex/gemini/xai/deepseek 的 30s 上限属于产品取舍,
已在 #799 里单列评估项。
@StackCairn
StackCairn marked this pull request as draft September 11, 2026 17:39
@github-actions

Copy link
Copy Markdown
Contributor

PR governance checks failed — this PR has been converted to draft.

  • UI change without screenshots: this PR modifies frontend code. Please add before/after screenshots or a recording under "Screenshots / preview" in the PR body.

Fix the items above, then click Ready for review to re-run the checks.

@coder-hhx coder-hhx added the governance-exempt Skip PR governance checks label Sep 11, 2026
@coder-hhx
coder-hhx marked this pull request as ready for review September 11, 2026 17:39
@coder-hhx
coder-hhx merged commit 1d7ed2b into main Sep 11, 2026
9 of 10 checks passed
@coder-hhx
coder-hhx deleted the fix/bash-timeout-diagnostics branch September 11, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

governance-exempt Skip PR governance checks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Performance] 同一个构建被反复执行且日志里看不到失败原因:provider 的 30s Bash 上限没有在结果里说清

1 participant