11from collections .abc import Awaitable , Callable
22from typing import Self
33
4+ from httpx import URL , Request
45from pydantic import Field , SecretStr , model_validator
56from uipath_langchain_client .base_client import UiPathBaseLLMClient
67from uipath_langchain_client .settings import UiPathAPIConfig
@@ -21,25 +22,38 @@ class UiPathChatOpenAI(UiPathBaseLLMClient, ChatOpenAI): # type: ignore[overrid
2122 api_type = "completions" ,
2223 client_type = "passthrough" ,
2324 vendor_type = "openai" ,
24- freeze_base_url = True ,
25+ api_version = "2025-03-01-preview" ,
26+ freeze_base_url = False ,
2527 )
2628
2729 # Override fields to avoid errors when instantiating the class
2830 openai_api_key : SecretStr | None | Callable [[], str ] | Callable [[], Awaitable [str ]] = Field (
2931 alias = "api_key" , default = SecretStr ("PLACEHOLDER" )
3032 )
3133
32- @model_validator (mode = "after" )
33- def setup_uipath_api_flavor_and_version (self ) -> Self :
34- self .api_config .api_version = "2025-03-01-preview"
35- if self ._use_responses_api ({}):
36- self .api_config .api_flavor = "responses"
37- else :
38- self .api_config .api_flavor = "chat-completions"
39- return self
40-
4134 @model_validator (mode = "after" )
4235 def setup_uipath_client (self ) -> Self :
36+ base_url = str (self .uipath_sync_client .base_url ).rstrip ("/" )
37+
38+ def fix_url_and_api_flavor_header (request : Request ):
39+ url_suffix = str (request .url ).split (base_url )[- 1 ]
40+ if "responses" in url_suffix :
41+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "responses"
42+ else :
43+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "chat-completions"
44+ request .url = URL (base_url )
45+
46+ async def fix_url_and_api_flavor_header_async (request : Request ):
47+ url_suffix = str (request .url ).split (base_url )[- 1 ]
48+ if "responses" in url_suffix :
49+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "responses"
50+ else :
51+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "chat-completions"
52+ request .url = URL (base_url )
53+
54+ self .uipath_sync_client .event_hooks ["request" ].append (fix_url_and_api_flavor_header )
55+ self .uipath_async_client .event_hooks ["request" ].append (fix_url_and_api_flavor_header_async )
56+
4357 self .root_client = OpenAI (
4458 api_key = "PLACEHOLDER" ,
4559 timeout = None , # handled by the UiPath client
@@ -62,25 +76,37 @@ class UiPathAzureChatOpenAI(UiPathBaseLLMClient, AzureChatOpenAI): # type: igno
6276 api_type = "completions" ,
6377 client_type = "passthrough" ,
6478 vendor_type = "openai" ,
65- freeze_base_url = True ,
79+ api_version = "2025-03-01-preview" ,
80+ freeze_base_url = False ,
6681 )
6782
6883 # Override fields to avoid errors when instantiating the class
6984 azure_endpoint : str | None = Field (default = "PLACEHOLDER" )
7085 openai_api_version : str | None = Field (default = "PLACEHOLDER" , alias = "api_version" )
7186 openai_api_key : SecretStr | None = Field (default = SecretStr ("PLACEHOLDER" ), alias = "api_key" )
7287
73- @model_validator (mode = "after" )
74- def setup_uipath_api_flavor_and_version (self ) -> Self :
75- self .api_config .api_version = "2025-03-01-preview"
76- if self ._use_responses_api ({}):
77- self .api_config .api_flavor = "responses"
78- else :
79- self .api_config .api_flavor = "chat-completions"
80- return self
81-
8288 @model_validator (mode = "after" )
8389 def setup_uipath_client (self ) -> Self :
90+ base_url = str (self .uipath_sync_client .base_url ).rstrip ("/" )
91+
92+ def fix_url_and_api_flavor_header (request : Request ):
93+ url_suffix = str (request .url ).split (base_url )[- 1 ]
94+ if "responses" in url_suffix :
95+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "responses"
96+ else :
97+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "chat-completions"
98+ request .url = URL (base_url )
99+
100+ async def fix_url_and_api_flavor_header_async (request : Request ):
101+ url_suffix = str (request .url ).split (base_url )[- 1 ]
102+ if "responses" in url_suffix :
103+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "responses"
104+ else :
105+ request .headers ["X-UiPath-LlmGateway-ApiFlavor" ] = "chat-completions"
106+ request .url = URL (base_url )
107+
108+ self .uipath_sync_client .event_hooks ["request" ].append (fix_url_and_api_flavor_header )
109+ self .uipath_async_client .event_hooks ["request" ].append (fix_url_and_api_flavor_header_async )
84110 self .root_client = AzureOpenAI (
85111 azure_endpoint = "PLACEHOLDER" ,
86112 api_version = "PLACEHOLDER" ,
0 commit comments