Gate Reasoning(effort=...) on registry support#528
Conversation
OpenAI's Responses API rejects reasoning.effort on non-reasoning models like gpt-4o with `unsupported_parameter`, so any scan with the default STRIX_REASONING_EFFORT=high against gpt-4o crashed at the first model call. drop_params=True absorbs the rejected param on LiteLLM-routed models but the SDK's native OpenAI path has no equivalent. Lift model_supports_reasoning to a public helper that strips litellm/, any-llm/, openai/ prefixes and falls back to last-segment lookup so prefixed forms like anthropic/claude-opus-4-7 resolve through the bare model_cost entry. make_model_settings regains model_name and skips Reasoning() when the registry doesn't confirm support. uses_chat_completions_tool_schema reuses the same helper (was duplicating the lookup under a misleading name).
Greptile SummaryThis PR fixes crashes caused by
Confidence Score: 4/5Safe to merge; the crash fix is correct and the only call site for make_model_settings has been updated. The change correctly prevents reasoning effort from being sent to non-reasoning models via the Responses API. The renamed helper now drives both the new reasoning gate and the existing tool-schema routing; the shared last-segment fallback logic is new and could affect tool schema routing for openai// style names. strix/config/models.py — the renamed helper drives both the reasoning gate and tool-schema routing; the new fallback logic is worth a second look. Important Files Changed
|
| entry = litellm.model_cost.get(name) | ||
| if entry is None and "/" in name: | ||
| entry = litellm.model_cost.get(name.rsplit("/", 1)[1]) | ||
| return bool(entry and entry.get("supports_reasoning")) |
There was a problem hiding this comment.
Last-segment fallback can produce false positives for openrouter-style deep paths
name.rsplit("/", 1)[1] resolves openrouter/openai/o3 to o3 — which is fine for the make_model_settings path because those models travel through litellm's drop_params=True layer and a wrong flag is a no-op. However, the same fallback is reached from uses_chat_completions_tool_schema for any openai/<provider>/<model> pattern: if the provider segment is non-empty after stripping openai/ and the resulting name still contains /, the fallback kicks in and the final model segment drives the Responses-vs-chat-completions routing decision. Explicit testing with a path like openai/custom/o3 would confirm whether this edge case is intentional.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/config/models.py
Line: 133-136
Comment:
**Last-segment fallback can produce false positives for openrouter-style deep paths**
`name.rsplit("/", 1)[1]` resolves `openrouter/openai/o3` to `o3` — which is fine for the `make_model_settings` path because those models travel through litellm's `drop_params=True` layer and a wrong flag is a no-op. However, the same fallback is reached from `uses_chat_completions_tool_schema` for any `openai/<provider>/<model>` pattern: if the provider segment is non-empty after stripping `openai/` and the resulting name still contains `/`, the fallback kicks in and the final model segment drives the Responses-vs-chat-completions routing decision. Explicit testing with a path like `openai/custom/o3` would confirm whether this edge case is intentional.
How can I resolve this? If you propose a fix, please make it concise.
OpenAI's Responses API rejects
reasoning.efforton non-reasoning models (gpt-4o, etc.) withunsupported_parameter. Scans with the defaultSTRIX_REASONING_EFFORT=highcrashed at the first model call.Lifts
model_supports_reasoningto a public helper (handleslitellm//any-llm//openai/prefixes + falls back to last-segment lookup), gatesReasoning(effort=...)on it inmake_model_settings, and unifiesuses_chat_completions_tool_schemato share the same helper.22/22 cases verified across gpt-4o, gpt-5.x, o-series, claude-4.x, deepseek, gemini, groq, mistral, xai, openrouter, plus legacy
litellm/...prefix form and unknown SKUs.