Merge pull request #220 from ggozad/fix/openai-non-reasoning-model
Fix non-reasoning OpenAI models that do not support reasoning config
This commit is contained in:
commit
af380c8e52
3 changed files with 27 additions and 5 deletions
|
|
@ -1,6 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **OpenAI Non-Reasoning Models**: Fixed `reasoning_effort` parameter being sent to non-reasoning OpenAI models (gpt-4o, gpt-4o-mini), causing 400 errors. Now correctly detects reasoning models (o1, o3 series) using pydantic-ai's model profile.
|
||||||
|
- **Bedrock Non-Reasoning Models**: Fixed same issue for OpenAI models on Bedrock.
|
||||||
|
|
||||||
## [0.24.0] - 2026-01-07
|
## [0.24.0] - 2026-01-07
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import sys
|
||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
from importlib import metadata
|
from importlib import metadata
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
from dateutil import parser as dateutil_parser
|
from dateutil import parser as dateutil_parser
|
||||||
from packaging.version import Version, parse
|
from packaging.version import Version, parse
|
||||||
|
|
@ -145,10 +145,16 @@ def get_model(
|
||||||
)
|
)
|
||||||
|
|
||||||
elif provider == "openai":
|
elif provider == "openai":
|
||||||
|
from pydantic_ai.profiles.openai import OpenAIModelProfile, openai_model_profile
|
||||||
|
|
||||||
openai_settings: Any = None
|
openai_settings: Any = None
|
||||||
|
|
||||||
# Apply thinking control
|
# Apply thinking control only for reasoning models (o-series, gpt-5)
|
||||||
if model_config.enable_thinking is not None:
|
profile = cast(OpenAIModelProfile, openai_model_profile(model))
|
||||||
|
if (
|
||||||
|
model_config.enable_thinking is not None
|
||||||
|
and profile.openai_supports_encrypted_reasoning_content
|
||||||
|
):
|
||||||
if model_config.enable_thinking is False:
|
if model_config.enable_thinking is False:
|
||||||
openai_settings = OpenAIChatModelSettings(openai_reasoning_effort="low")
|
openai_settings = OpenAIChatModelSettings(openai_reasoning_effort="low")
|
||||||
else:
|
else:
|
||||||
|
|
@ -247,8 +253,8 @@ def get_model(
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
additional_fields = {"thinking": {"type": "disabled"}}
|
additional_fields = {"thinking": {"type": "disabled"}}
|
||||||
elif "gpt" in model or "o1" in model or "o3" in model:
|
elif "o1" in model or "o3" in model:
|
||||||
# OpenAI models on Bedrock
|
# OpenAI reasoning models on Bedrock (o-series only, not gpt-4o)
|
||||||
additional_fields = {
|
additional_fields = {
|
||||||
"reasoning_effort": "high"
|
"reasoning_effort": "high"
|
||||||
if model_config.enable_thinking
|
if model_config.enable_thinking
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,17 @@ def test_get_model_openai_with_thinking():
|
||||||
assert isinstance(result, OpenAIChatModel)
|
assert isinstance(result, OpenAIChatModel)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_model_openai_non_reasoning_model_ignores_thinking():
|
||||||
|
"""Test that non-reasoning OpenAI models don't get reasoning_effort setting."""
|
||||||
|
model_config = ModelConfig(
|
||||||
|
provider="openai", name="gpt-4o-mini", enable_thinking=False
|
||||||
|
)
|
||||||
|
result = get_model(model_config)
|
||||||
|
assert isinstance(result, OpenAIChatModel)
|
||||||
|
# Non-reasoning models should not have reasoning_effort set
|
||||||
|
assert result._settings is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_ANTHROPIC, reason="Anthropic not installed")
|
@pytest.mark.skipif(not HAS_ANTHROPIC, reason="Anthropic not installed")
|
||||||
def test_get_model_anthropic():
|
def test_get_model_anthropic():
|
||||||
"""Test get_model returns AnthropicModel for Anthropic."""
|
"""Test get_model returns AnthropicModel for Anthropic."""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue