diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b5cbc6..506490ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `tool_web_fetch()` is supported by Claude (requires beta header) and Google. * New content types `ContentToolRequestSearch`, `ContentToolResponseSearch`, `ContentToolRequestFetch`, and `ContentToolResponseFetch` capture web tool interactions. * `ChatOpenAI()` and `ChatAzureOpenAI()` gain a new `service_tier` parameter to request a specific service tier (e.g., `"flex"` for slower/cheaper or `"priority"` for faster/more expensive). (#204) +* `ChatAzureOpenAI()` gains a `reasoning` parameter. (#260) * `Chat` and `Turn` now have a `_repr_markdown_` method and an overall improved `repr()` experience. (#245) ### Changes @@ -39,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed MCP tools not working with `ChatGoogle()`. (#257) * Tool functions parameters that are `typing.Annotated` with a `pydantic.Field` (e.g., `def add(x: Annotated[int, Field(description="First number")])`) are now handled correctly. (#251) + ## [0.14.0] - 2025-12-09 ### New features diff --git a/chatlas/_provider_openai.py b/chatlas/_provider_openai.py index 5d91920e..6623bd9a 100644 --- a/chatlas/_provider_openai.py +++ b/chatlas/_provider_openai.py @@ -279,7 +279,7 @@ def _chat_perform_args( # Request reasoning content for reasoning models include = [] - if is_reasoning_model(self.model): + if "reasoning" in kwargs_full or is_reasoning_model(self.model): include.append("reasoning.encrypted_content") if "log_probs" in kwargs_full: diff --git a/chatlas/_provider_openai_azure.py b/chatlas/_provider_openai_azure.py index 0f2bc39d..be5ad3d6 100644 --- a/chatlas/_provider_openai_azure.py +++ b/chatlas/_provider_openai_azure.py @@ -11,7 +11,15 @@ from ._utils import MISSING, MISSING_TYPE, is_testing, split_http_client_kwargs if TYPE_CHECKING: - from .types.openai import ChatAzureClientArgs, SubmitInputArgs + from openai.types.responses import Response + from openai.types.shared.reasoning_effort import ReasoningEffort + from openai.types.shared_params.reasoning import Reasoning + + from .types.openai import ( + ChatAzureClientArgs, + ResponsesSubmitInputArgs, + SubmitInputArgs, + ) def ChatAzureOpenAI( @@ -21,11 +29,12 @@ def ChatAzureOpenAI( api_version: str, api_key: Optional[str] = None, system_prompt: Optional[str] = None, + reasoning: "Optional[ReasoningEffort | Reasoning]" = None, service_tier: Optional[ Literal["auto", "default", "flex", "scale", "priority"] ] = None, kwargs: Optional["ChatAzureClientArgs"] = None, -) -> Chat["SubmitInputArgs", ChatCompletion]: +) -> "Chat[ResponsesSubmitInputArgs, Response]": """ Chat with a model hosted on Azure OpenAI. @@ -65,6 +74,11 @@ def ChatAzureOpenAI( variable. system_prompt A system prompt to set the behavior of the assistant. + reasoning + The reasoning effort (e.g., `"low"`, `"medium"`, `"high"`) for + reasoning-capable models like the o and gpt-5 series. To use the default + reasoning settings in a way that will work for multi-turn conversations, + set this to an empty dictionary `{}`. service_tier Request a specific service tier. Options: - `"auto"` (default): uses the service tier configured in Project settings. @@ -81,7 +95,13 @@ def ChatAzureOpenAI( A Chat object. """ - kwargs_chat: "SubmitInputArgs" = {} + kwargs_chat: "ResponsesSubmitInputArgs" = {} + + if reasoning is not None: + if isinstance(reasoning, str): + reasoning = {"effort": reasoning, "summary": "auto"} + kwargs_chat["reasoning"] = reasoning + if service_tier is not None: kwargs_chat["service_tier"] = service_tier