🛠️ Preserve adaptive Claude thinking through retries (#137)
## Summary
Proposed follow-up to closed #134 / PR #136. I ran into a remaining gap
on v2.5.2 where a selected adaptive Claude effort still did not reliably
reach LiteLLM, so summarized thinking was missing even though thinking
signatures could appear.
I am not sure this is the cleanest place to fix it — you know this retry
path better than I do. If you would rather handle it differently, I am
happy to close this or reshape it.
Related: umbrella #133. Prompt cache remains #135 and is not in this
change.
## What I still see on v2.5.2
v2.5.2 already enables adaptive `thinking` and signed `thinking_blocks`.
On live Opus 5 turns, though, the selected effort still did not survive
to LiteLLM in the native shape:
1. The request builder can send native `thinking` **and** flat
`reasoning_effort`. LiteLLM may remap that overlapping field and
overwrite `thinking`, so `display: "summarized"` never arrives.
Responses then look like thinking ran (`thinking` signatures) but
`reasoning_tokens` stays `0` and summaries are omitted.
2. If `reasoning_effort` is omitted so `display` can survive, retry init
still reads only that flat field. Native-only adaptive requests look
like “no effort”, and `thinking` / `output_config` are deleted **before
the first HTTP send**. Live Low / High / Medium then log `has_thinking:
false`.
GPT / Grok on flat `reasoning_effort` looked fine.
## Proposed approach
Keep one native adaptive representation through first send, cached
fallback, live fallback, overflow rebuild, and continuity retry:
```json
{
"thinking": { "type": "adaptive", "display": "summarized" },
"output_config": { "effort": "medium" }
}
```
and omit `reasoning_effort` on that path. Flat models stay on
`reasoning_effort` only.
I extracted a small read/apply helper so retry state comes from the full
representation (`thinking` + `output_config`, or flat
`reasoning_effort`), not from `reasoning_effort` alone.
Version bump left out on purpose.
## Validation
- `npm run compile` / `lint` / `format` / `test:coverage`
- Live Low → High → Medium Opus 5, plus one Sonnet 5 High, after
installing a rebuilt VSIX (Reload Window is not enough)
- Those outbound requests stayed `adaptive` with matching effort and
`display: "summarized"`
- Visible thinking parts / `reasoning_tokens > 0` on the turns that
actually thought
- Grok stayed flat (`reasoning_effort` only)
Happy to adjust if you would rather reopen #134, open a new follow-up,
or take a different approach in the retry coordinator. D
David Tai committed
129e36b5147f6b2253b6bd8a821d7b320f7f3196
Parent: 34f0b20
Committed by GitHub <noreply@github.com>
on 8/21/2026, 12:49:46 PM