Fixes a cost-control hole: requests using OpenAI's current max_completion_tokens field were priced as if they had asked for nothing.
Fixed
- OpenAI deprecated
max_tokensin favour ofmax_completion_tokens, but ClawRouter only ever read the legacy field — the stringmax_completion_tokensappeared nowhere insrc/. Every request from a client on the modern field was sized at the 4096 default regardless of what it actually requested. - That number gates real money: routing,
estimateAmount(balance pre-check), the strict-modemaxCostPerRuncap,chargedOutputTokensinlogUsage, and pre-auth reuse. A request for 65536 output tokens was priced at 1/16th of its real cost and walked straight through a cost cap the user had set.src/proxy.max-tokens-cap.test.tsreproduces it: HTTP 200 before the fix, 429 after. src/payment-preauth.tshad the same gap but sized such a request at 0 tokens, so a payment authorization cached for a tiny request could be reused to pay for a much larger one.- Both now share
resolveMaxTokens()(newsrc/max-tokens.ts). It reads either field, rejects values that cannot be a token budget (NaN,Infinity, negatives, non-numbers — each of which would have silently disabled the cap comparison), and takes the larger when a client sends both: over-estimating tightens the pre-check, under-estimating defeats it.
Affects all 55+ models; exposure scaled with output price, so moonshot/kimi-k3 ($15/M out) was the worst case.
Verified: 696 unit tests · e2e 24 passed (mock + live gateway) · resilience quick suite 5/5 · dist smoke check.
Full changelog: https://github.com/BlockRunAI/ClawRouter/blob/main/CHANGELOG.md