From 1616891c40c42fb87105b1d4a00c2539ba8fb9e0 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Wed, 7 Jan 2026 18:46:50 +0200 Subject: [PATCH] Fix non-reasoning OpenAI models that do not support reasoning config --- CHANGELOG.md | 5 +++++ haiku_rag_slim/haiku/rag/utils.py | 16 +++++++++++----- tests/test_utils.py | 11 +++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6ee507d..7ebfbea7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog ## [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 ### Added diff --git a/haiku_rag_slim/haiku/rag/utils.py b/haiku_rag_slim/haiku/rag/utils.py index 060b3367..f6437e43 100644 --- a/haiku_rag_slim/haiku/rag/utils.py +++ b/haiku_rag_slim/haiku/rag/utils.py @@ -2,7 +2,7 @@ import sys from datetime import UTC, datetime from importlib import metadata 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 packaging.version import Version, parse @@ -145,10 +145,16 @@ def get_model( ) elif provider == "openai": + from pydantic_ai.profiles.openai import OpenAIModelProfile, openai_model_profile + openai_settings: Any = None - # Apply thinking control - if model_config.enable_thinking is not None: + # Apply thinking control only for reasoning models (o-series, gpt-5) + 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: openai_settings = OpenAIChatModelSettings(openai_reasoning_effort="low") else: @@ -247,8 +253,8 @@ def get_model( } else: additional_fields = {"thinking": {"type": "disabled"}} - elif "gpt" in model or "o1" in model or "o3" in model: - # OpenAI models on Bedrock + elif "o1" in model or "o3" in model: + # OpenAI reasoning models on Bedrock (o-series only, not gpt-4o) additional_fields = { "reasoning_effort": "high" if model_config.enable_thinking diff --git a/tests/test_utils.py b/tests/test_utils.py index 2005d18e..9afbe48c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -176,6 +176,17 @@ def test_get_model_openai_with_thinking(): 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") def test_get_model_anthropic(): """Test get_model returns AnthropicModel for Anthropic."""