Repository navigation
fix(core): eliminate OOM from debugResponses accumulation - #4982
Conversation
DragonnZhang
left a comment
There was a problem hiding this comment.
No issues found. Clean dead-code removal: debugResponses array, getDebugResponses(), and extractUsageFromGeminiClient are fully removed with zero remaining references. Test updates are consistent — the usage test in nonInteractiveCli.test.ts correctly relies on computeUsageFromMetrics via setupMetricsMock, matching the production path. CI test failures (all 3 platforms) appear pre-existing and unrelated to this change; Lint and CodeQL pass. LGTM.
|
Thanks for the review! @DragonnZhang
|
wenshao
left a comment
There was a problem hiding this comment.
No issues found. Clean dead-code removal: debugResponses array, getDebugResponses(), and extractUsageFromGeminiClient are fully removed with zero remaining references (git grep confirmed). Test updates are consistent — usage test in nonInteractiveCli.test.ts correctly migrated from mockGetDebugResponses to setupMetricsMock / computeUsageFromMetrics path. Build passes, tsc 0 errors, eslint 0 errors, 120 tests pass across all three affected test files. CI 13/13 green. ✅ — qwen3.7-max via Qwen Code /review
|
@qwen-code /triage |
Local verification report (maintainer)Verified this PR locally with real runs, not just the test suite. Since the PR's merge-base is ~50 commits behind 1. Dead-code claim — confirmed, plus one stronger finding
2. Build / typecheck / tests (merged tree)
On the
3. Real-run smoke tests (bundled CLI from the merged tree, driven via tmux)
4. Memory-retention benchmark — the OOM claim holds empiricallyDrove
Both builds emitted an identical event stream (2001 events) — behavior parity. A Verdict✅ Safe to merge. Dead code with zero references after merging into latest 中文版(Chinese version)本地验证报告(维护者)本 PR 在本地做了真实运行验证,而不仅是跑测试。由于 PR 的 merge-base 落后 1. 死代码声明 — 成立,且有一个更强的发现
2. 构建 / 类型检查 / 测试(合并树)
关于
3. 真实运行冒烟测试(合并树打包出的 CLI,tmux 驱动)
4. 内存滞留基准 — OOM 声明有实证支撑直接驱动
两个构建产出完全相同的事件流(2001 个事件)——行为等价。 结论✅ 可以安全合并。 死代码在合入最新 |
What this PR does
Removes
debugResponsesarray andextractUsageFromGeminiClient. Both are dead code.Turn.debugResponsespushed every streaming chunk into an array. Nothing in production ever read it.extractUsageFromGeminiClientwas exported but never imported by production code. Non-interactive mode usescomputeUsageFromMetricsfrom the telemetry pipeline instead.Closes: #4815
Follow-up to #4824
Why it is needed
Every streaming chunk was pushed into
debugResponsesand held in memory for the lifetime of theTurnobject. In goal mode, nested turns are not cleaned up between iterations, so the array keeps growing. A single long session can accumulate gigabytes of response objects that are never read, leading to OOM.debugResponsesholds a reference to every streaming chunk for the lifetime of the Turn object. Two scenarios cause OOM:GenerateContentResponse. The array grows unbounded within one turn.sendMessageStreamcalls hold inner Turn objects as references until the outer call completes. Each nested turn accumulates its owndebugResponses. The chain never releases until the top-level goal finishes, so memory grows across the entire nesting depth.Reviewer Test Plan
Before / After
Before:
Turnhas adebugResponsesarray that collects every chunk.extractUsageFromGeminiClientis exported but unused.After: Neither exists. Zero references left.
How to verify
中文
删除
debugResponses数组和extractUsageFromGeminiClient函数。每个 streaming chunk 都被 push 进
debugResponses并在 Turn 生命周期内一直持有。goal 模式下嵌套的 turn 不会被清理,数组持续增长,单次长会话可以累积 GB 级别的无用对象,最终 OOM。extractUsageFromGeminiClient从初始提交起就没有被生产代码调用过,非交互模式实际走的computeUsageFromMetrics。