Gate Reasoning(effort=...) on registry support (#528)
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).
This commit is contained in:
+11
-5
@@ -119,15 +119,21 @@ def uses_chat_completions_tool_schema(model_name: str, settings: Settings) -> bo
|
|||||||
return True
|
return True
|
||||||
if settings.llm.api_base:
|
if settings.llm.api_base:
|
||||||
return True
|
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
|
import litellm
|
||||||
|
|
||||||
name = model_name.strip().lower().removeprefix("openai/")
|
name = model_name.strip().lower()
|
||||||
entry = litellm.model_cost.get(name) or {}
|
for prefix in ("litellm/", "any-llm/", "openai/"):
|
||||||
return bool(entry.get("supports_reasoning"))
|
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:
|
def is_known_openai_bare_model(model_name: str) -> bool:
|
||||||
|
|||||||
+11
-3
@@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Any
|
|||||||
from agents.model_settings import ModelSettings
|
from agents.model_settings import ModelSettings
|
||||||
from openai.types.shared import Reasoning
|
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:
|
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(
|
model_settings = ModelSettings(
|
||||||
parallel_tool_calls=False,
|
parallel_tool_calls=False,
|
||||||
retry=DEFAULT_MODEL_RETRY,
|
retry=DEFAULT_MODEL_RETRY,
|
||||||
include_usage=True,
|
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(
|
model_settings = model_settings.resolve(
|
||||||
ModelSettings(reasoning=Reasoning(effort=reasoning_effort)),
|
ModelSettings(reasoning=Reasoning(effort=reasoning_effort)),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -153,7 +153,10 @@ async def run_strix_scan(
|
|||||||
is_whitebox = any(t.get("type") == "local_code" for t in targets)
|
is_whitebox = any(t.get("type") == "local_code" for t in targets)
|
||||||
skills = list(scan_config.get("skills") or [])
|
skills = list(scan_config.get("skills") or [])
|
||||||
root_task = build_root_task(scan_config)
|
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(
|
run_config = RunConfig(
|
||||||
model=resolved_model,
|
model=resolved_model,
|
||||||
model_provider=StrixProvider(),
|
model_provider=StrixProvider(),
|
||||||
|
|||||||
Reference in New Issue
Block a user