Split canonical ReasoningEffort::Max out of Xhigh (providers P0c-1)
OpenAI (Responses) and Anthropic (Messages) treat xhigh and max as
DISTINCT effort levels in 2026, and the Kimi K3 wire's top tier is max —
the old parse alias (max→Xhigh) conflated them. Canonical Max now exists:
parse/as_str/serde split, Messages mapping sends xhigh and max as their
own tokens (was Xhigh→"max"), and the K3 menu token max carries
canonical Max end to end.
Kimi wire is byte-identical in all four flows (menu pick, restored
legacy xhigh session, --reasoning-effort flag, /effort command) —
adversarially traced and pinned: kimi_compat's string-level xhigh→max
rename covers legacy tokens, max passes through verbatim.
From the review:
- Rollback safety: persisted reasoning_effort (session summaries, chat
history) deserializes leniently — unknown future tokens degrade to
None with a warning instead of hiding sessions or failing resume.
- Restore migration: a pre-split xhigh override onto a model whose menu
offers max but not xhigh (K3) migrates once, healing display/active-row
drift and re-persisting the live vocabulary.
- /effort max now rejects (with the offered list) on models whose menu
lacks a max row instead of silently applying xhigh; deliberate, tested.
- The interim Responses-backend Max→xhigh downgrade (async-openai has no
Max variant through 0.41) warns loudly; real max wiring lands with the
OpenAI provider cycle via post-serialize body patch.
- Two rusted ignored-e2e wire pins asserted the pre-adapt reasoning_effort
key (deleted by the body adapter since ea0ce9d); they now pin the real
thinking.effort=max shape.
This commit is contained in:
@@ -110,6 +110,29 @@ pub(crate) async fn apply(
|
||||
.models_manager
|
||||
.model_supports_reasoning_effort(model_id.0.as_ref())
|
||||
{
|
||||
// Legacy migration: pre-split sessions persisted canonical
|
||||
// `xhigh` for models whose live menu now spells the top tier
|
||||
// `max` (K3). The wire is identical either way (kimi_compat
|
||||
// renames xhigh→max), but the menu has no xhigh-valued row, so
|
||||
// display/active-row would drift from the model vocabulary and
|
||||
// the stale token would be re-persisted forever. Migrate once.
|
||||
let eff = if eff == kigi_sampling_types::ReasoningEffort::Xhigh
|
||||
&& !agent
|
||||
.models_manager
|
||||
.model_offers_effort(model_id.0.as_ref(), eff)
|
||||
&& agent.models_manager.model_offers_effort(
|
||||
model_id.0.as_ref(),
|
||||
kigi_sampling_types::ReasoningEffort::Max,
|
||||
) {
|
||||
tracing::info!(
|
||||
session_id = % session_id.0,
|
||||
"set_session_model: migrating legacy xhigh override to max \
|
||||
(model menu offers max, not xhigh)"
|
||||
);
|
||||
kigi_sampling_types::ReasoningEffort::Max
|
||||
} else {
|
||||
eff
|
||||
};
|
||||
tracing::info!(
|
||||
session_id = % session_id.0, effort = % eff,
|
||||
"set_session_model: applying reasoning_effort override from meta"
|
||||
|
||||
Reference in New Issue
Block a user