diff --git a/strix/config/models.py b/strix/config/models.py index 1f480ba7..b70192b5 100644 --- a/strix/config/models.py +++ b/strix/config/models.py @@ -168,6 +168,12 @@ def model_supports_adaptive_thinking(model_name: str) -> bool: return bool(entry and entry.get("supports_adaptive_thinking")) +def model_supports_xhigh_effort(model_name: str) -> bool: + """Whether the model accepts the ``xhigh`` effort tier.""" + entry = _model_cost_entry(model_name) + return bool(entry and entry.get("supports_xhigh_reasoning_effort")) + + def is_known_openai_bare_model(model_name: str) -> bool: import litellm diff --git a/strix/core/inputs.py b/strix/core/inputs.py index 9bdc4d9a..a736005c 100644 --- a/strix/core/inputs.py +++ b/strix/core/inputs.py @@ -12,6 +12,7 @@ from strix.config.models import ( DEFAULT_MODEL_RETRY, model_supports_adaptive_thinking, model_supports_reasoning, + model_supports_xhigh_effort, ) @@ -129,11 +130,19 @@ def make_model_settings( # Newer Anthropic models (e.g. Claude Opus 4.8) reject the legacy # ``thinking.type=enabled`` shape that LiteLLM emits from # ``reasoning_effort``. Send the adaptive-thinking API instead. + # Bedrock's ``output_config.effort`` only accepts low/medium/high + # (plus xhigh on models that advertise it), so normalize the wider + # ReasoningEffort range onto that set. + effort = reasoning_effort + if effort == "minimal": + effort = "low" + elif effort == "xhigh" and not model_supports_xhigh_effort(model_name): + effort = "high" model_settings = model_settings.resolve( ModelSettings( extra_args={ "thinking": {"type": "adaptive"}, - "output_config": {"effort": reasoning_effort}, + "output_config": {"effort": effort}, }, ), )