Four of the five defects in this release are the same mistake at different altitudes: the code said something that was not true — about which backend ran, about how long a request had, or about what would happen when a lane failed.
The headline was found by probing, not reading. With every response truncated, generate_file made three requests — all to local — and then reported backend_used: "nvidia_glm", a lane that was never called. The escalation flipped the variable on its final iteration and the loop then terminated. There was never any cloud spend; there was a false name in the response, and the same false name went into recordExecution and therefore into get_analytics.
Fixed
- Retry timeouts were frozen at attempt 1.
generate_fileandmodify_filecomputed a budget once, before their retry loop, then reused it while scaling tokens ×1.5 per retry and sometimes switching lanes. Attempt 3 could request 2.25× the tokens of attempt 1 under attempt 1's deadline, so a budget that was too small surfaced as "the backend timed out". Each attempt is now sized from its own live token count and backend. - Truncation reported a backend that never ran. The dead cloud-escalation branch is removed from both handlers. A truncation now stays on the lane the caller got, retries there with a larger budget, and reports honestly if it still does not fit.
modify_file's truncation retry never executed. Its loop condition re-tested a value that attempt 1 had already assigned, so token-scaling retries were dead code and a truncated modify got exactly one attempt.modify_fileattributed results to the wrong lane. Five of its six reporting and metric sites named the backend chosen before the retry loop rather than the one that served the request.- Eight hardcoded backend references are gone from the two handlers. An operator who had configured only, say, Groq was previously pointed at a lane they never set up.
Changed
- A backend you name explicitly no longer cascades. It gets one attempt, then an error distinguishing "your lane was tried and failed" from "your lane could not be attempted at all". A backend the router resolved — from
auto, a routing rule, or the content-length hint — cascades exactly as before. The API keys are yours, and silently rerouting a request you pinned to one lane can spend your credit on lanes you never asked for. Passbackend: "auto"for the previous behaviour. - A computed timeout is now capped by the lane's declared
config.timeout. On the shipped configuration a scaledmodify_fileretry computed 367500ms for a lane declared at 30000ms. The declared value outranks the handler's floor, so a lane declared below what a large request needs now fails fast rather than running past your declared patience. A lane that declares nothing is unchanged. If large generations or modifications on one backend start failing quickly after upgrading, raise that lane's declaredtimeoutfirst.
Notes
- 17 tools, unchanged. Nothing here adds, removes, or renames a tool.
- Test suite: 514 passing / 4 skipped, up from 478. Thirty-six net new tests, no assertion weakened or skipped.
See CHANGELOG.md for full details.