← Back to PRs

#18679: fix(agents): always downgrade orphaned OpenAI reasoning blocks

by battman21 open 2026-02-16 23:49 View on GitHub →
agents stale size: XS
## Summary - Removes the `modelChanged` gate from `downgradeOpenAIReasoningBlocks()` in `sanitizeSessionHistory()` so orphaned `rs_*` reasoning blocks are stripped unconditionally for OpenAI Responses API models - Previously the downgrade only ran on model switches (`modelChanged === true`), leaving orphaned reasoning blocks in initial sessions (no prior snapshot) and same-model compaction cycles — causing OpenAI to return 400 errors - Adds regression test for the null-snapshot scenario (the actual reported bug) Fixes #17019 ## Test plan - [x] Existing test updated: same-model session now asserts downgrade happens (was: skipped) - [x] Existing test renamed: model-change scenario still downgrades (unchanged behavior) - [x] New test added: no prior snapshot (initial session) — orphaned blocks are stripped - [x] All 9 sanitize-session-history tests pass - [x] All 4 downgrade-openai-reasoning helper tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Removes the `modelChanged` gate from `downgradeOpenAIReasoningBlocks()` in `sanitizeSessionHistory()` so orphaned OpenAI `rs_*` reasoning blocks are stripped unconditionally for OpenAI Responses API models. Previously, the downgrade only ran when `modelChanged === true`, which meant orphaned reasoning blocks persisted in two scenarios: (1) initial sessions with no prior model snapshot, and (2) same-model compaction cycles — both causing OpenAI 400 errors. - **Bug fix in `google.ts`**: The condition `isOpenAIResponsesApi && modelChanged` is simplified to just `isOpenAIResponsesApi`. The `downgradeOpenAIReasoningBlocks` function is safe to call unconditionally since it only drops orphaned reasoning blocks (those without following non-thinking content); valid blocks are preserved. The `modelChanged` variable remains in use for the `appendModelSnapshot` logic. - **Test coverage**: Three scenarios are now covered — same-model (updated from asserting no-op to asserting downgrade), model-change (renamed for clarity, behavior unchanged), and no-prior-snapshot (new regression test for the reported bug). <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it's a minimal, well-targeted bug fix with comprehensive test coverage. - The change is a 4-line simplification that removes an incorrect gate condition. The `downgradeOpenAIReasoningBlocks` function is idempotent and safe to call unconditionally (it only strips orphaned reasoning blocks). The `modelChanged` variable is not dead code — it's still used for snapshot persistence. All three relevant scenarios are tested. No risk of regression. - No files require special attention. <sub>Last reviewed commit: 7b7e558</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs