Five independent reviewers cross-checked every provider's per-model
sampling-knob exposure against live docs (OpenAI, Anthropic, Gemini,
DeepSeek, Kimi, Mistral, OpenRouter, llama.cpp, vLLM, Ollama).
Applying the high-confidence drift fixes here; speculative items (pro
model effort restrictions, gpt-5.3 cap, OpenAI verbosity / o-series
output cap, Gemini topK / service_tier) are deferred to a follow-up
because they need backend wire changes or unverified doc claims.
Anthropic:
- Move claude-opus-4-6 from the 64k group into the 128k group (live
legacy table shows Opus 4.6 Max output = 128k tokens).
https://platform.claude.com/docs/en/about-claude/models/overview
- Add claude-sonnet-4 to the 64k group (was falling through to 32k
default; live legacy table shows Sonnet 4 Max output = 64k tokens).
- Extend ANTHROPIC_REASONING_MODELS with legacy claude-opus-4-1 /
claude-opus-4 / claude-sonnet-4 at none/low/medium/high (live
legacy table marks Extended thinking = Yes for all three).
OpenAI:
- Split the gpt-5/gpt-5.1/gpt-5.2 reasoning bucket. Per Azure docs
footnote ^7^, "minimal is only supported with the original GPT-5
reasoning models. minimal is not supported with gpt-5.1 or greater".
gpt-5.1 / gpt-5.2 now get none/low/medium/high/xhigh with
supportsOff=true; bare gpt-5 keeps minimal/low/medium/high
supportsOff=false. Ordering puts gpt-5.1 / gpt-5.2 before gpt-5 in
the find() loop so the longer prefix matches first.
https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/reasoning
DeepSeek:
- Hide `seed` and `parallel_tool_calls` in the deepseek capability
bucket. Neither field is in the current /chat/completions schema
(body fields: messages, model, thinking, max_tokens, response_format,
stop, stream, stream_options, temperature, top_p, tools, tool_choice,
logprobs, top_logprobs, user_id). Surfacing them in the UI would be
the silent-drop UX the file header warns against.
https://api-docs.deepseek.com/api/create-chat-completion
Mistral:
- magistral-medium-latest / magistral-small-latest are NATIVE
always-on reasoning models; injecting reasoning_effort returns 422
upstream. Switch both to withEnableThinkingStyle({reasoningAlwaysOn:
true}) instead of the old none/medium/high effort ladder.
- mistral-small-latest / mistral-medium-latest / mistral-vibe-cli-latest
expose the documented three-tier adjustable ladder
(none/low/medium/high), not the truncated none/high pair that was
here before. mistral-medium-latest was not handled at all and now
sits in the same bucket as small.
https://docs.mistral.ai/studio-api/conversations/reasoninghttps://mistral.ai/news/magistral
OpenRouter:
- Drop google/gemini-pro-latest from OPENROUTER_MANDATORY_REASONING_
MODELS; the gateway 404s the id today
(https://openrouter.ai/google/gemini-pro-latest). Removing rather
than re-pinning to a versioned id that may rotate again.
Local backends:
- Split LOCAL_LLAMA_CAPABILITIES into LLAMA_CPP_CAPABILITIES (full
chain — for llama_cpp + custom) and VLLM_OLLAMA_CAPABILITIES (OpenAI
subset + top_k/min_p/repetition_penalty/seed, no extended samplers).
vLLM's SamplingParams has no typical_p / top_n_sigma / repeat_last_n
/ dynatemp_* / mirostat* fields, and Ollama's OpenAI translator
(ollama/openai/openai.go FromChatRequest) only copies the OpenAI
subset. Surfacing the eight extra sliders for vllm / ollama was
silent-drop UX.
Tests:
- test_deepseek_payload_omits_seed_and_parallel_tool_calls: read the
TS file as text and assert the bucket has seed:false and
parallelToolCalls:false. Backend has no JS engine; this is the
cheapest way to lock the wire-drop invariant.
- 63/63 sampling_params_routing tests pass; frontend tsc clean.