diff --git a/strix/config/models.py b/strix/config/models.py index 7b18c90..4d2e072 100644 --- a/strix/config/models.py +++ b/strix/config/models.py @@ -119,15 +119,21 @@ def uses_chat_completions_tool_schema(model_name: str, settings: Settings) -> bo return True if settings.llm.api_base: return True - return not _supports_responses_custom_tools(model_name) + return not model_supports_reasoning(model_name) -def _supports_responses_custom_tools(model_name: str) -> bool: +def model_supports_reasoning(model_name: str) -> bool: import litellm - name = model_name.strip().lower().removeprefix("openai/") - entry = litellm.model_cost.get(name) or {} - return bool(entry.get("supports_reasoning")) + name = model_name.strip().lower() + for prefix in ("litellm/", "any-llm/", "openai/"): + if name.startswith(prefix): + name = name[len(prefix) :] + break + 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")) def is_known_openai_bare_model(model_name: str) -> bool: diff --git a/strix/core/inputs.py b/strix/core/inputs.py index b82d888..b86daa4 100644 --- a/strix/core/inputs.py +++ b/strix/core/inputs.py @@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Any from agents.model_settings import ModelSettings from openai.types.shared import Reasoning -from strix.config.models import DEFAULT_MODEL_RETRY +from strix.config.models import DEFAULT_MODEL_RETRY, model_supports_reasoning if TYPE_CHECKING: @@ -106,13 +106,21 @@ def build_scope_context(scan_config: dict[str, Any]) -> dict[str, Any]: } -def make_model_settings(reasoning_effort: ReasoningEffort | None) -> ModelSettings: +def make_model_settings( + reasoning_effort: ReasoningEffort | None, + *, + model_name: str, +) -> ModelSettings: model_settings = ModelSettings( parallel_tool_calls=False, retry=DEFAULT_MODEL_RETRY, include_usage=True, ) - if reasoning_effort is not None and reasoning_effort != "none": + if ( + reasoning_effort is not None + and reasoning_effort != "none" + and model_supports_reasoning(model_name) + ): model_settings = model_settings.resolve( ModelSettings(reasoning=Reasoning(effort=reasoning_effort)), ) diff --git a/strix/core/runner.py b/strix/core/runner.py index d042cdf..a7371e9 100644 --- a/strix/core/runner.py +++ b/strix/core/runner.py @@ -153,7 +153,10 @@ async def run_strix_scan( is_whitebox = any(t.get("type") == "local_code" for t in targets) skills = list(scan_config.get("skills") or []) root_task = build_root_task(scan_config) - model_settings = make_model_settings(settings.llm.reasoning_effort) + model_settings = make_model_settings( + settings.llm.reasoning_effort, + model_name=resolved_model, + ) run_config = RunConfig( model=resolved_model, model_provider=StrixProvider(),