Skip to content

Commit e045643

Browse files
CopilotvictordibiaekzhuBaillyM
authored
Add missing reasoning_effort parameter support for OpenAI GPT-5 models (#7054)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: victordibia <[email protected]> Co-authored-by: Eric Zhu <[email protected]> Co-authored-by: ekzhu <[email protected]> Co-authored-by: Maurice Bailly <[email protected]>
1 parent 29931b3 commit e045643

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ class CreateArguments(TypedDict, total=False):
5050
user: str
5151
stream_options: Optional[StreamOptions]
5252
parallel_tool_calls: Optional[bool]
53+
reasoning_effort: Optional[Literal["minimal", "low", "medium", "high"]]
54+
"""Controls the amount of effort the model uses for reasoning.
55+
Only applicable to reasoning models like o1 and o3-mini.
56+
- 'minimal': Fastest response with minimal reasoning
57+
- 'low': Faster responses with less reasoning
58+
- 'medium': Balanced reasoning and speed
59+
- 'high': More thorough reasoning, may take longer"""
5360

5461

5562
AsyncAzureADTokenProvider = Callable[[], Union[str, Awaitable[str]]]
@@ -99,6 +106,8 @@ class CreateArgumentsConfigModel(BaseModel):
99106
user: str | None = None
100107
stream_options: StreamOptions | None = None
101108
parallel_tool_calls: bool | None = None
109+
# Controls the amount of effort the model uses for reasoning (reasoning models only)
110+
reasoning_effort: Literal["minimal", "low", "medium", "high"] | None = None
102111

103112

104113
class BaseOpenAIClientConfigurationConfigModel(CreateArgumentsConfigModel):

python/packages/autogen-ext/tests/models/test_openai_model_client.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3269,3 +3269,112 @@ def _different_function(text: str) -> str:
32693269

32703270

32713271
# TODO: add integration tests for Azure OpenAI using AAD token.
3272+
3273+
3274+
@pytest.mark.asyncio
3275+
async def test_reasoning_effort_parameter() -> None:
3276+
"""Test that reasoning_effort parameter is properly handled in client configuration."""
3277+
3278+
# Test OpenAI client with reasoning_effort
3279+
openai_client = OpenAIChatCompletionClient(
3280+
model="gpt-5",
3281+
api_key="fake_key",
3282+
reasoning_effort="low",
3283+
)
3284+
assert openai_client._create_args["reasoning_effort"] == "low" # pyright: ignore[reportPrivateUsage]
3285+
3286+
# Test Azure OpenAI client with reasoning_effort
3287+
azure_client = AzureOpenAIChatCompletionClient(
3288+
model="gpt-5",
3289+
azure_endpoint="fake_endpoint",
3290+
azure_deployment="gpt-5-2025-08-07",
3291+
api_version="2025-02-01-preview",
3292+
api_key="fake_key",
3293+
reasoning_effort="medium",
3294+
)
3295+
assert azure_client._create_args["reasoning_effort"] == "medium" # pyright: ignore[reportPrivateUsage]
3296+
3297+
# Test load_component with reasoning_effort for OpenAI
3298+
from autogen_core.models import ChatCompletionClient
3299+
3300+
openai_config = {
3301+
"provider": "OpenAIChatCompletionClient",
3302+
"config": {
3303+
"model": "gpt-5",
3304+
"api_key": "fake_key",
3305+
"reasoning_effort": "high",
3306+
},
3307+
}
3308+
3309+
loaded_openai_client = ChatCompletionClient.load_component(openai_config)
3310+
assert loaded_openai_client._create_args["reasoning_effort"] == "high" # type: ignore[attr-defined] # pyright: ignore[reportPrivateUsage, reportUnknownMemberType, reportAttributeAccessIssue]
3311+
assert loaded_openai_client._raw_config["reasoning_effort"] == "high" # type: ignore[attr-defined] # pyright: ignore[reportPrivateUsage, reportUnknownMemberType, reportAttributeAccessIssue]
3312+
3313+
# Test load_component with reasoning_effort for Azure OpenAI
3314+
azure_config = {
3315+
"provider": "AzureOpenAIChatCompletionClient",
3316+
"config": {
3317+
"model": "gpt-5",
3318+
"azure_endpoint": "fake_endpoint",
3319+
"azure_deployment": "gpt-5-2025-08-07",
3320+
"api_version": "2025-02-01-preview",
3321+
"api_key": "fake_key",
3322+
"reasoning_effort": "low",
3323+
},
3324+
}
3325+
3326+
loaded_azure_client = ChatCompletionClient.load_component(azure_config)
3327+
assert loaded_azure_client._create_args["reasoning_effort"] == "low" # type: ignore[attr-defined] # pyright: ignore[reportPrivateUsage, reportUnknownMemberType, reportAttributeAccessIssue]
3328+
assert loaded_azure_client._raw_config["reasoning_effort"] == "low" # type: ignore[attr-defined] # pyright: ignore[reportPrivateUsage, reportUnknownMemberType, reportAttributeAccessIssue]
3329+
3330+
# Test serialization and deserialization
3331+
config_dict = openai_client.dump_component()
3332+
reloaded_client = OpenAIChatCompletionClient.load_component(config_dict)
3333+
assert reloaded_client._create_args["reasoning_effort"] == "low" # pyright: ignore[reportPrivateUsage]
3334+
3335+
3336+
@pytest.mark.asyncio
3337+
async def test_reasoning_effort_validation() -> None:
3338+
"""Test reasoning_effort parameter validation."""
3339+
3340+
# Test valid values
3341+
for valid_value in ["low", "medium", "high"]:
3342+
client = OpenAIChatCompletionClient(
3343+
model="gpt-5",
3344+
api_key="fake_key",
3345+
reasoning_effort=valid_value, # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
3346+
)
3347+
assert client._create_args["reasoning_effort"] == valid_value # pyright: ignore[reportPrivateUsage]
3348+
3349+
# Test None value (should be included if explicitly set)
3350+
client_with_none = OpenAIChatCompletionClient(
3351+
model="gpt-5",
3352+
api_key="fake_key",
3353+
reasoning_effort=None,
3354+
)
3355+
# When explicitly set to None, it will be included in create_args
3356+
assert client_with_none._create_args["reasoning_effort"] is None # pyright: ignore[reportPrivateUsage]
3357+
3358+
# Test not providing reasoning_effort (should not be in create_args)
3359+
client_without_reasoning = OpenAIChatCompletionClient(
3360+
model="gpt-5",
3361+
api_key="fake_key",
3362+
)
3363+
assert "reasoning_effort" not in client_without_reasoning._create_args # pyright: ignore[reportPrivateUsage]
3364+
3365+
# Test invalid value via load_component (Pydantic validation)
3366+
from pydantic import ValidationError
3367+
3368+
with pytest.raises(ValidationError): # Should raise ValidationError
3369+
from autogen_core.models import ChatCompletionClient
3370+
3371+
config = {
3372+
"provider": "OpenAIChatCompletionClient",
3373+
"config": {
3374+
"model": "gpt-5",
3375+
"api_key": "fake_key",
3376+
"reasoning_effort": "invalid_value",
3377+
},
3378+
}
3379+
3380+
ChatCompletionClient.load_component(config)

0 commit comments

Comments
 (0)