From 5cb6039fee93c61a86a03ef0c07f776d82446bda Mon Sep 17 00:00:00 2001 From: Ionut Mihalache <67947900+ionut-mihalache-uipath@users.noreply.github.com> Date: Thu, 21 May 2026 18:48:05 +0300 Subject: [PATCH] feat: make converse as default api flavor for bedrock --- packages/uipath_langchain_client/CHANGELOG.md | 8 ++ .../uipath_langchain_client/__version__.py | 2 +- .../src/uipath_langchain_client/factory.py | 21 +---- .../features/test_factory_function.py | 88 +++++++++++++++++++ 4 files changed, 99 insertions(+), 20 deletions(-) diff --git a/packages/uipath_langchain_client/CHANGELOG.md b/packages/uipath_langchain_client/CHANGELOG.md index 6cd7dd6..2d55dcb 100644 --- a/packages/uipath_langchain_client/CHANGELOG.md +++ b/packages/uipath_langchain_client/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to `uipath_langchain_client` will be documented in this file. +## [1.12.0] - 2026-05-21 + +### Changed +- `get_chat_model` routes the AWSBEDROCK branch purely by `api_flavor`: `ApiFlavor.INVOKE` selects `UiPathChatBedrock`, while `None` or `ApiFlavor.CONVERSE` select `UiPathChatBedrockConverse`. Model family no longer influences the choice. + +### Removed +- The AWSBEDROCK branch no longer auto-selects `UiPathChatAnthropicBedrock` for `ANTHROPIC_CLAUDE` models. Callers who want that class can pass it via the `custom_class` kwarg. + ## [1.11.3] - 2026-05-21 ### Fixed diff --git a/packages/uipath_langchain_client/src/uipath_langchain_client/__version__.py b/packages/uipath_langchain_client/src/uipath_langchain_client/__version__.py index 82ad789..b167423 100644 --- a/packages/uipath_langchain_client/src/uipath_langchain_client/__version__.py +++ b/packages/uipath_langchain_client/src/uipath_langchain_client/__version__.py @@ -1,3 +1,3 @@ __title__ = "UiPath LangChain Client" __description__ = "A Python client for interacting with UiPath's LLM services via LangChain." -__version__ = "1.11.3" +__version__ = "1.12.0" diff --git a/packages/uipath_langchain_client/src/uipath_langchain_client/factory.py b/packages/uipath_langchain_client/src/uipath_langchain_client/factory.py index ee18854..7063f86 100644 --- a/packages/uipath_langchain_client/src/uipath_langchain_client/factory.py +++ b/packages/uipath_langchain_client/src/uipath_langchain_client/factory.py @@ -22,7 +22,6 @@ from typing import Any -from uipath.llm_client.utils.model_family import is_anthropic_model_name from uipath_langchain_client.base_client import ( UiPathBaseChatModel, UiPathBaseEmbeddings, @@ -65,9 +64,8 @@ def get_chat_model( If not provided, auto-detected from the model discovery endpoint. api_flavor: Vendor-specific API flavor to use. Effects: - OpenAI: ApiFlavor.RESPONSES sets use_responses_api=True. - - Bedrock Claude: Default uses UiPathChatAnthropicBedrock. - ApiFlavor.CONVERSE uses UiPathChatBedrockConverse, - ApiFlavor.INVOKE uses UiPathChatBedrock. + - Bedrock: ApiFlavor.INVOKE uses UiPathChatBedrock; otherwise + (None or ApiFlavor.CONVERSE) uses UiPathChatBedrockConverse. custom_class: A custom class to use for instantiating the chat model instead of the auto-detected one. Must be a subclass of UiPathBaseChatModel. When provided, the factory skips vendor detection and uses this class directly. @@ -190,21 +188,6 @@ def get_chat_model( **model_kwargs, ) case VendorType.AWSBEDROCK: - if ( - model_family == ModelFamily.ANTHROPIC_CLAUDE and api_flavor != ApiFlavor.CONVERSE - ) or (api_flavor == ApiFlavor.INVOKE and is_anthropic_model_name(model_name)): - from uipath_langchain_client.clients.bedrock.chat_models import ( - UiPathChatAnthropicBedrock, - ) - - return UiPathChatAnthropicBedrock( - model=model_name, - settings=client_settings, - byo_connection_id=byo_connection_id, - model_details=model_details, - **model_kwargs, - ) - if api_flavor == ApiFlavor.INVOKE: from uipath_langchain_client.clients.bedrock.chat_models import ( UiPathChatBedrock, diff --git a/tests/langchain/features/test_factory_function.py b/tests/langchain/features/test_factory_function.py index fa35014..428eb3a 100644 --- a/tests/langchain/features/test_factory_function.py +++ b/tests/langchain/features/test_factory_function.py @@ -130,6 +130,94 @@ def test_openai_chat_respects_discovered_byom_chat_completions( assert captured["api_flavor"] == ApiFlavor.CHAT_COMPLETIONS +class TestFactoryBedrockApiFlavorRouting: + """The AWSBEDROCK branch routes purely on ``api_flavor``: + + - ``ApiFlavor.INVOKE`` -> ``UiPathChatBedrock`` + - ``ApiFlavor.CONVERSE`` or ``None`` -> ``UiPathChatBedrockConverse`` + + Model family (e.g. ANTHROPIC_CLAUDE) no longer influences the choice. + """ + + def _patch_bedrock_classes(self, monkeypatch: pytest.MonkeyPatch) -> dict: + """Replace the three bedrock chat classes with sentinels and record which one was built.""" + chosen: dict = {} + + def _make_stub(name: str): + class _Stub: + def __init__(self, **kwargs): + chosen["class"] = name + chosen["kwargs"] = kwargs + + return _Stub + + for name in ( + "UiPathChatBedrockConverse", + "UiPathChatBedrock", + "UiPathChatAnthropicBedrock", + ): + monkeypatch.setattr( + f"uipath_langchain_client.clients.bedrock.chat_models.{name}", + _make_stub(name), + ) + return chosen + + def _settings_with_model_info(self, model_info: dict): + settings = MagicMock() + settings.get_model_info.return_value = model_info + return settings + + def test_no_api_flavor_uses_bedrock_converse(self, monkeypatch: pytest.MonkeyPatch): + chosen = self._patch_bedrock_classes(monkeypatch) + settings = self._settings_with_model_info( + { + "modelName": "anthropic.claude-3-5-sonnet-20240620-v1:0", + "vendor": "AwsBedrock", + "apiFlavor": None, + "modelFamily": None, + } + ) + get_chat_model( + model_name="anthropic.claude-3-5-sonnet-20240620-v1:0", + client_settings=settings, + ) + assert chosen["class"] == "UiPathChatBedrockConverse" + + def test_converse_api_flavor_uses_bedrock_converse(self, monkeypatch: pytest.MonkeyPatch): + chosen = self._patch_bedrock_classes(monkeypatch) + settings = self._settings_with_model_info( + { + "modelName": "anthropic.claude-3-5-sonnet-20240620-v1:0", + "vendor": "AwsBedrock", + "apiFlavor": None, + "modelFamily": None, + } + ) + get_chat_model( + model_name="anthropic.claude-3-5-sonnet-20240620-v1:0", + client_settings=settings, + api_flavor=ApiFlavor.CONVERSE, + ) + assert chosen["class"] == "UiPathChatBedrockConverse" + + def test_invoke_api_flavor_uses_bedrock_invoke(self, monkeypatch: pytest.MonkeyPatch): + chosen = self._patch_bedrock_classes(monkeypatch) + settings = self._settings_with_model_info( + { + "modelName": "amazon.titan-text-express-v1", + "vendor": "AwsBedrock", + "apiFlavor": None, + "modelFamily": None, + } + ) + get_chat_model( + model_name="amazon.titan-text-express-v1", + client_settings=settings, + api_flavor=ApiFlavor.INVOKE, + ) + assert chosen["class"] == "UiPathChatBedrock" + + class TestFactoryAgentHubConfig: """The ``agenthub_config`` factory kwarg overrides ``client_settings.agenthub_config`` via ``model_copy`` so the caller's instance is not mutated."""