From 41000c029a3d1d9b79661cbcac95efe23d375c29 Mon Sep 17 00:00:00 2001 From: Ahmed Tammaa Date: Sun, 13 Jul 2025 01:52:06 +0300 Subject: [PATCH 1/3] fix: update tool_choice logic for Azure-hosted models Modified the tool_choice assignment in BaseChatOpenAI to set a default value based on the API base URL. If the base URL indicates an Azure-hosted model, the tool_choice is set to "required"; otherwise, it defaults to the tool name. This change enhances compatibility with Azure deployments. --- .../openai/langchain_openai/chat_models/base.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index b5dea2b0f87..fdc5327218e 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -1870,11 +1870,22 @@ class BaseChatOpenAI(BaseChatModel): "schema must be specified when method is not 'json_mode'. " "Received None." ) + tool_name = convert_to_openai_tool(schema)["function"]["name"] + base_url = ( + getattr(self, "openai_api_base", "") or getattr(self, "api_base", "") or "" + ).lower() + # The Azure-Hosted Models routes to this function + # so we need to set the tool_choice to required + if "azure.com" in base_url: + tool_choice_default = "required" + else: + tool_choice_default = tool_name + bind_kwargs = self._filter_disabled_params( **{ **dict( - tool_choice=tool_name, + tool_choice=tool_choice_default, parallel_tool_calls=False, strict=strict, ls_structured_output_format={ From d75d2d43e9b2bf0a0ce86309259204d98b8adbe5 Mon Sep 17 00:00:00 2001 From: Ahmed Tammaa Date: Sun, 13 Jul 2025 02:03:13 +0300 Subject: [PATCH 2/3] [lint] --- libs/partners/openai/langchain_openai/chat_models/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index fdc5327218e..cfb479906f1 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -1873,7 +1873,8 @@ class BaseChatOpenAI(BaseChatModel): tool_name = convert_to_openai_tool(schema)["function"]["name"] base_url = ( - getattr(self, "openai_api_base", "") or getattr(self, "api_base", "") or "" + getattr(self, "openai_api_base", "") + or getattr(self, "api_base", "") or "" ).lower() # The Azure-Hosted Models routes to this function # so we need to set the tool_choice to required From 758c59fc31bc2b139d6664c986b38b337ec0939d Mon Sep 17 00:00:00 2001 From: Ahmed Tammaa Date: Sun, 13 Jul 2025 02:13:41 +0300 Subject: [PATCH 3/3] formatting --- libs/partners/openai/langchain_openai/chat_models/base.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index cfb479906f1..a262a53b76e 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -1870,11 +1870,12 @@ class BaseChatOpenAI(BaseChatModel): "schema must be specified when method is not 'json_mode'. " "Received None." ) - + tool_name = convert_to_openai_tool(schema)["function"]["name"] base_url = ( getattr(self, "openai_api_base", "") - or getattr(self, "api_base", "") or "" + or getattr(self, "api_base", "") + or "" ).lower() # The Azure-Hosted Models routes to this function # so we need to set the tool_choice to required