feat(model_prices): let a map entry declare its exact reasoning_effort levels - #38481
Conversation
|
@greptileai can you reply here with a score and why that score? |
|
bugbot run |
|
Score: 4/5 (high confidence). The change is narrowly scoped and internally consistent:
I’m not giving 5/5 because the PR documents two remaining semantic gaps: |
Greptile SummaryAdds an exact
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| litellm/router_utils/reasoning_effort_capability.py | Resolves explicit effort declarations before legacy flags while preserving fallback behavior for undeclared or malformed values. |
| litellm/llms/anthropic/experimental_pass_through/utils.py | Uses declared levels when normalizing max, xhigh, and minimal effort values through degradation chains. |
| litellm/utils.py | Hydrates the new reasoning-effort declaration from model catalog entries. |
| model_prices_and_context_window.json | Declares provider-specific Kimi K3 reasoning-effort sets. |
| tests/test_litellm/router_utils/test_reasoning_effort_capability.py | Covers declaration precedence, malformed values, model-info hydration, provider metadata, and mixed-group intersections. |
| tests/test_litellm/llms/anthropic/experimental_pass_through/test_reasoning_effort_fields.py | Covers declaration-aware effort preservation and degradation without changing undeclared models. |
Reviews (6): Last reviewed commit: "feat(model_prices): let a map entry decl..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit aba9a37. Configure here.
aba9a37 to
49655da
Compare
|
@greptileai both 4/5 reasons are addressed: /v1/messages now honors the declaration, and Perplexity declares its own six levels. Score? |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 49655da. Configure here.
|
codecov/patch is red at 55%, but the resolver measures 100% locally and CI logs show the new tests ran. Flagging rather than absorbing. |
|
Correction: codecov/patch went green once the last shard upload merged. All checks pass; disregard the note above. |
49655da to
481f256
Compare
|
Pushed: trimmed overlong lines and condensed the test prose per the repo comment rule. All within 120 now. |
|
bugbot run |
|
@greptileai line lengths and test comments addressed. Score? |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 481f256. Configure here.
481f256 to
5e02f0a
Compare
|
Fixed a precedence leak: a declaration now wins whole on /v1/messages too, so a flag cannot re-add a level the list omits. |
|
bugbot run |
|
@greptileai added declaration-beats-flags precedence on the messages gate, with tests. Score? |
5e02f0a to
0dc08e6
Compare
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5e02f0a. Configure here.
|
bugbot run |
|
@greptileai can you reply here with a score and why that score? |
|
Score: 5/5 (high confidence). The previously identified gaps are addressed: |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0dc08e6. Configure here.
…t levels Kimi K3 accepts exactly low, high and max, defaults to max, and always thinks. The map could not say that: medium and high have no supports_*_reasoning_effort flag because every other reasoning model takes them, so the ten kimi-k3 entries carried supports_reasoning alone and resolved to unknown. The dashboard then fell back to a capability-blind level list that deliberately omits max, which is why a kimi-k3 tier cannot be set to max thinking today. Add reasoning_effort_levels, an array key in the shape the map already uses for supported_endpoints and supported_modalities. Where present it is read first and wins whole; every other entry keeps answering through the per-level flags, unchanged. It is deliberately a different name from the computed ModelGroupInfo.supported_reasoning_efforts, which stays derived from a group's deployments and is never seeded from one deployment's model_info. The levels are per entry rather than per model, because the deployments differ: Moonshot, Together, Fireworks and Azure Foundry all forward the level unchanged and get the model's own low/high/max, while Perplexity documents a six-value enum it maps down internally and gets that. The /v1/messages degradation chain consults the same declaration, so the level the map advertises is the level that path forwards.
0dc08e6 to
e377a04
Compare
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e377a04. Configure here.
|
A mechanical, deterministic script can be made to backfill the nested supports keys for other models. We can keep both for now, defaulting to the nested, then after enough time, remove the old non-nested keys |
TLDR
Problem this solves:
How it solves it:
reasoning_effort_levelsarray key on a map entryUser Flow
Before: an admin building an auto-router cannot put Kimi K3 on the max thinking its own docs call the default
kimi-k3in the Complex tiermaxis absent, so they cannot select it, and four levels Kimi does not document are offered insteadhighand lose the depth Kimi K3 runs at by defaultAfter: the same dropdown offers exactly what Kimi K3 accepts
kimi-k3in the Complex tiermaxand save the routerreasoning_effort: maxRelevant issues
maxon kimi-k3 is stacked on this branchLinear ticket
Resolves LIT-6325
Pre-Submission checklist
Screenshots / Proof of Fix
Two identical rigs, one per leg: before at
493bca667b(the merge base) and after ate377a0472e(the PR tip). Each leg is its own worktree running a live proxy on a random port with 2 uvicorn workers, a real Postgres database andLITELLM_LOCAL_MODEL_COST_MAP=True, so the proxy reads the map at that commit. The model list registers real Moonshot and Fireworks Kimi K3 deployments (both providers sell it, and the real calls below hit them and cost real money), plus copies of the same litellm model strings pointed at a local echo upstream that replies with thereasoning_effortit received, which makes the wire value the gateway sends observable.gpt56-stubis anopenai/gpt-5.6deployment on the echo upstream andkimi-mixedholds one Moonshot kimi-k3 plus oneopenai/gpt-5.6. One pre-existing gate to know about, identical at both commits: of the five providers with a declared kimi-k3 entry, onlyfireworks_ailets an explicitreasoning_effortthrough on chat completions (perplexityappends it whensupports_reasoningresolves), whilemoonshot,together_aiandazure_aireject it with UnsupportedParamsError unless the caller passesallowed_openai_params: ["reasoning_effort"]or setsdrop_params. That is why the stub cases below ride the Fireworks model string and the real Moonshot call carries the hatch; LIT-6330 tracks itBefore (493bca6, the merge base)
Case 1: what the proxy advertises
curl -s -H "Authorization: Bearer $KEY" http://127.0.0.1:51296/model_group/infoOutput, one line per group:
Every kimi-k3 group answers None, which the dashboard reads as "this proxy knows nothing" and falls back to a capability-blind list that leaves out max.
kimi-mixedtakes the gpt-5.6 set whole because the kimi deployment carries no opinionCase 2: /v1/chat/completions request path
curl -s -X POST http://127.0.0.1:51296/v1/chat/completions -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{"model":"kimi-k3-fw-stub","messages":[{"role":"user","content":"hi"}],"reasoning_effort":"max"}'forwarded reasoning_effort=maxCase 3: /v1/responses request path
curl -s -X POST http://127.0.0.1:51296/v1/responses -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{"model":"kimi-k3-fw-stub","input":"hi","reasoning":{"effort":"max"}}'forwarded reasoning_effort=maxCase 4: /v1/messages request path
curl -s -X POST http://127.0.0.1:51296/v1/messages -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{"model":"kimi-k3-fw-stub","max_tokens":128,"messages":[{"role":"user","content":"hi"}],"thinking":{"type":"adaptive"},"output_config":{"effort":"max"}}'forwarded reasoning_effort=highoutput_config.effortintoreasoning_effortonly when the body carries"thinking": {"type": "adaptive"}; its degradation chain reads the per-level boolean flags, finds no max flag on the kimi entry and lowers a level the model actually takesCase 5: real provider calls
curl -s -X POST http://127.0.0.1:51296/v1/chat/completions -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{"model":"kimi-k3-fireworks","messages":[{"role":"user","content":"Reply with exactly: ok"}],"reasoning_effort":"max","max_tokens":600}'ok, usage 93/114 tokensCase 6: Admin UI reasoning-effort dropdown
ui/litellm-dashboardpointed at this leg's proxy. The dashboard build packaged in_experimental/outpredates the capability-aware dropdown, and this PR touches noui/files, so the identical dashboard source ran against both legskimi-k3in the Complex tier and open the Reasoning effort dropdown beside it: it offers Default, none, minimal, low, medium, high, xhigh. No maxkimi-mixedin the Reasoning tier: its dropdown offers the gpt-5.6 set, Default, none, low, medium, high, xhighAfter (e377a04)
Case 1: what the proxy advertises
Same curl against the after rig:
curl -s -H "Authorization: Bearer $KEY" http://127.0.0.1:47594/model_group/infoOutput:
Each kimi-k3 group now names the three levels Kimi documents and gpt56-stub is byte-identical to before.
kimi-mixednarrows to the intersection because a kimi deployment now carries an opinion where it used to carry none: that is the one behavior change a mixed group sees, and it is the intended oneCase 2: /v1/chat/completions request path
forwarded reasoning_effort=maxCase 3: /v1/responses request path
forwarded reasoning_effort=maxCase 4: /v1/messages request path
forwarded reasoning_effort=maxCase 5: real provider calls
ok, usage 93/14 tokenscurl -s -X POST http://127.0.0.1:47594/v1/messages -H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{"model":"kimi-k3","max_tokens":600,"messages":[{"role":"user","content":"Reply with exactly: ok"}],"thinking":{"type":"adaptive"},"output_config":{"effort":"max"},"allowed_openai_params":["reasoning_effort"]}'ok, with the max effort carried through the hatchCase 6: Admin UI reasoning-effort dropdown
kimi-k3in the Complex tierkimi-mixedin the Reasoning tier narrows to Default, low, highType
🆕 New Feature
Caveats (if any)
Low
reasoning_efforttodaymoonshot,together_aiandazure_ai400 on chat completionsfireworks_aiforwards itperplexityappends it whensupports_reasoningresolvesallowed_openai_paramsordrop_params; LIT-6330 tracks real supportFinal Attestation
Note
Medium Risk
Changes shared reasoning-effort resolution and request normalization for any entry with the new key; mixed model groups now intersect to narrower effort sets when Kimi deployments declare levels.
Overview
Adds
reasoning_effort_levelson model catalog entries so deployments can advertise an exact set ofreasoning_effortvalues (e.g. Kimi K3’s low / high / max) instead of inferring from per-levelsupports_*flags, which cannot express “no medium.”When present, the list wins over the boolean flags in
resolve_supported_reasoning_efforts(router /model_group/info) and innormalize_reasoning_effort_valueon the Anthropic messages path, somaxis no longer silently degraded tohighfor declared Kimi entries. Schema,ModelInfo, and model-info hydration carry the new field; Kimi K3 variants across Moonshot, Fireworks, Together, Azure AI, and Perplexity are populated in the price map.Reviewed by Cursor Bugbot for commit e377a04. Bugbot is set up for automated code reviews on this repo. Configure here.