diff --git a/libs/partners/openai/langchain_openai/chat_models/azure.py b/libs/partners/openai/langchain_openai/chat_models/azure.py index c812de60b65..af108e10c97 100644 --- a/libs/partners/openai/langchain_openai/chat_models/azure.py +++ b/libs/partners/openai/langchain_openai/chat_models/azure.py @@ -754,6 +754,26 @@ class AzureChatOpenAI(BaseChatOpenAI): return chat_result + def _get_request_payload( + self, + input_: LanguageModelInput, + *, + stop: Optional[list[str]] = None, + **kwargs: Any, + ) -> dict: + """Get the request payload, using deployment name for Azure Responses API.""" + payload = super()._get_request_payload(input_, stop=stop, **kwargs) + + # For Azure Responses API, use deployment name instead of model name + if ( + self._use_responses_api(payload) + and not payload.get("model") + and self.deployment_name + ): + payload["model"] = self.deployment_name + + return payload + def _stream(self, *args: Any, **kwargs: Any) -> Iterator[ChatGenerationChunk]: """Route to Chat Completions or Responses API.""" if self._use_responses_api({**kwargs, **self.model_kwargs}): diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index 7965e45d922..6f7c386776e 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -3541,7 +3541,7 @@ def _construct_responses_api_payload( payload["reasoning"] = {"effort": payload.pop("reasoning_effort")} # Remove temperature parameter for models that don't support it in responses API - model = payload.get("model", "") + model = payload.get("model") or "" if model.startswith("gpt-5") and "chat" not in model: # gpt-5-chat supports payload.pop("temperature", None) diff --git a/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py b/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py index 278f8dcaaed..96cd02bc6cd 100644 --- a/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py +++ b/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py @@ -21,7 +21,6 @@ class TestAzureOpenAIStandard(ChatModelIntegrationTests): def chat_model_params(self) -> dict: return { "deployment_name": os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"], - "model": "gpt-4o-mini", "openai_api_version": OPENAI_API_VERSION, "azure_endpoint": OPENAI_API_BASE, "stream_usage": True, @@ -49,7 +48,6 @@ class TestAzureOpenAIResponses(ChatModelIntegrationTests): def chat_model_params(self) -> dict: return { "deployment_name": os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"], - "model": "gpt-4o-mini", "openai_api_version": OPENAI_API_VERSION, "azure_endpoint": OPENAI_API_BASE, "use_responses_api": True, diff --git a/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py b/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py index f1d97ab8ebb..1640c120544 100644 --- a/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py +++ b/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py @@ -5,6 +5,7 @@ from unittest import mock import pytest from langchain_core.messages import HumanMessage +from pydantic import SecretStr from typing_extensions import TypedDict from langchain_openai import AzureChatOpenAI @@ -99,3 +100,42 @@ def test_max_completion_tokens_in_payload() -> None: "stream": False, "max_completion_tokens": 300, } + + +def test_responses_api_uses_deployment_name() -> None: + """Test that Azure deployment name is used for Responses API.""" + llm = AzureChatOpenAI( + azure_deployment="your_deployment", + api_version="2025-04-01-preview", + azure_endpoint="your_endpoint", + api_key=SecretStr("your_api_key"), + # Force Responses API usage by including a Responses-only parameter + use_responses_api=True, + output_version="responses/v1", + ) + messages = [HumanMessage("Hello")] + payload = llm._get_request_payload(messages) + + # For Responses API, the model field should be the deployment name + assert payload["model"] == "your_deployment" + assert "input" in payload # Responses API uses 'input' instead of 'messages' + + +def test_chat_completions_api_uses_model_name() -> None: + """Test that regular Chat Completions API still uses model name.""" + llm = AzureChatOpenAI( + azure_deployment="your_deployment", + model="gpt-5", # This is the OpenAI model name + api_version="2025-04-01-preview", + azure_endpoint="your_endpoint", + api_key=SecretStr("your_api_key"), + # No Responses-only parameters, so Chat Completions API will be used + ) + messages = [HumanMessage("Hello")] + payload = llm._get_request_payload(messages) + + # For Chat Completions API, the model field should still be None/model_name + # Azure Chat Completions uses deployment in the URL, not in the model field + assert payload["model"] == "gpt-5" + assert "messages" in payload # Chat Completions API uses 'messages' + assert "input" not in payload