Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/cd-langchain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Wait for package indexing
if: github.event_name == 'workflow_run'
run: sleep 60

- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to `uipath_llm_client` (core package) will be documented in this file.

## [1.1.1] - 2026-02-12

### Fix
- Small fixes on openai client

## [1.1.0] - 2026-02-11

### Stable release
Expand Down
7 changes: 7 additions & 0 deletions packages/uipath_langchain_client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to `uipath_langchain_client` will be documented in this file.

## [1.1.3] - 2026-02-12

### Fixes
- Fixes on openai langchain client on resposes_api
- Allow the flavor to be set up at requst time, not just when instantiating the llm
- Some fixes for the anthropic client

## [1.1.2] - 2026-02-12

### Refactor
Expand Down
2 changes: 1 addition & 1 deletion packages/uipath_langchain_client/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"langchain>=1.2.7",
"uipath-llm-client>=1.1.0",
"uipath-llm-client>=1.1.1",
]

[project.optional-dependencies]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__title__ = "UiPath LangChain Client"
__description__ = "A Python client for interacting with UiPath's LLM services via LangChain."
__version__ = "1.1.2"
__version__ = "1.1.3"
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ class UiPathChatAnthropic(UiPathBaseLLMClient, ChatAnthropic):
vendor_type="anthropic",
freeze_base_url=True,
)
vendor_type: Literal["anthropic", "azure", "vertexai", "awsbedrock"] = "awsbedrock"
vendor_type: Literal["anthropic", "azure", "vertexai", "awsbedrock"] = "anthropic"

@model_validator(mode="after")
def setup_api_flavor_and_version(self) -> Self:
self.api_config.vendor_type = self.vendor_type
match self.vendor_type:
case "vertexai":
self.api_config.api_flavor = "anthropic-claude"
self.api_config.api_version = "v1beta1"
case "awsbedrock":
self.api_config.api_flavor = "invoke"
case _:
raise ValueError("Those vendors are currently not supported")
self.api_config.vendor_type = self.vendor_type
raise ValueError(
"anthropic and azure vendors are currently not supported by UiPath"
)
return self

# Override fields to avoid typing issues and fix stuff
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections.abc import Awaitable, Callable
from typing import Self

from httpx import URL, Request
from pydantic import Field, SecretStr, model_validator
from uipath_langchain_client.base_client import UiPathBaseLLMClient
from uipath_langchain_client.settings import UiPathAPIConfig
Expand All @@ -21,25 +22,38 @@ class UiPathChatOpenAI(UiPathBaseLLMClient, ChatOpenAI): # type: ignore[overrid
api_type="completions",
client_type="passthrough",
vendor_type="openai",
freeze_base_url=True,
api_version="2025-03-01-preview",
freeze_base_url=False,
)

# Override fields to avoid errors when instantiating the class
openai_api_key: SecretStr | None | Callable[[], str] | Callable[[], Awaitable[str]] = Field(
alias="api_key", default=SecretStr("PLACEHOLDER")
)

@model_validator(mode="after")
def setup_uipath_api_flavor_and_version(self) -> Self:
self.api_config.api_version = "2025-03-01-preview"
if self._use_responses_api({}):
self.api_config.api_flavor = "responses"
else:
self.api_config.api_flavor = "chat-completions"
return self

@model_validator(mode="after")
def setup_uipath_client(self) -> Self:
base_url = str(self.uipath_sync_client.base_url).rstrip("/")

def fix_url_and_api_flavor_header(request: Request):
url_suffix = str(request.url).split(base_url)[-1]
if "responses" in url_suffix:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "responses"
else:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "chat-completions"
request.url = URL(base_url)

async def fix_url_and_api_flavor_header_async(request: Request):
url_suffix = str(request.url).split(base_url)[-1]
if "responses" in url_suffix:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "responses"
else:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "chat-completions"
request.url = URL(base_url)

self.uipath_sync_client.event_hooks["request"].append(fix_url_and_api_flavor_header)
self.uipath_async_client.event_hooks["request"].append(fix_url_and_api_flavor_header_async)

self.root_client = OpenAI(
api_key="PLACEHOLDER",
timeout=None, # handled by the UiPath client
Expand All @@ -62,25 +76,37 @@ class UiPathAzureChatOpenAI(UiPathBaseLLMClient, AzureChatOpenAI): # type: igno
api_type="completions",
client_type="passthrough",
vendor_type="openai",
freeze_base_url=True,
api_version="2025-03-01-preview",
freeze_base_url=False,
)

# Override fields to avoid errors when instantiating the class
azure_endpoint: str | None = Field(default="PLACEHOLDER")
openai_api_version: str | None = Field(default="PLACEHOLDER", alias="api_version")
openai_api_key: SecretStr | None = Field(default=SecretStr("PLACEHOLDER"), alias="api_key")

@model_validator(mode="after")
def setup_uipath_api_flavor_and_version(self) -> Self:
self.api_config.api_version = "2025-03-01-preview"
if self._use_responses_api({}):
self.api_config.api_flavor = "responses"
else:
self.api_config.api_flavor = "chat-completions"
return self

@model_validator(mode="after")
def setup_uipath_client(self) -> Self:
base_url = str(self.uipath_sync_client.base_url).rstrip("/")

def fix_url_and_api_flavor_header(request: Request):
url_suffix = str(request.url).split(base_url)[-1]
if "responses" in url_suffix:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "responses"
else:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "chat-completions"
request.url = URL(base_url)

async def fix_url_and_api_flavor_header_async(request: Request):
url_suffix = str(request.url).split(base_url)[-1]
if "responses" in url_suffix:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "responses"
else:
request.headers["X-UiPath-LlmGateway-ApiFlavor"] = "chat-completions"
request.url = URL(base_url)

self.uipath_sync_client.event_hooks["request"].append(fix_url_and_api_flavor_header)
self.uipath_async_client.event_hooks["request"].append(fix_url_and_api_flavor_header_async)
self.root_client = AzureOpenAI(
azure_endpoint="PLACEHOLDER",
api_version="PLACEHOLDER",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ def get_chat_model(
return UiPathChatAnthropic(
model=model_name,
settings=client_settings,
vendor_type=vendor_type,
**model_kwargs,
)
else:
Expand Down
2 changes: 1 addition & 1 deletion src/uipath_llm_client/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__titile__ = "UiPath LLM Client"
__description__ = "A Python client for interacting with UiPath's LLM services."
__version__ = "1.1.0"
__version__ = "1.1.1"
2 changes: 1 addition & 1 deletion src/uipath_llm_client/httpx_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class UiPathHttpxAsyncClient(AsyncClient):

_streaming_header: str = "X-UiPath-Streaming-Enabled"
_default_headers: Mapping[str, str] = {
"X-UiPath-LLMGateway-TimeoutSeconds": "30", # server side timeout, default is 10, maximum is 300
"X-UiPath-LLMGateway-TimeoutSeconds": "295", # server side timeout, default is 10, maximum is 300
"X-UiPath-LLMGateway-AllowFull4xxResponse": "true", # allow full 4xx responses (default is false)
}

Expand Down
1 change: 1 addition & 0 deletions tests/langchain/test_langchain_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def setup_models(self, request: pytest.FixtureRequest, client_settings: UiPathBa
self._completions_kwargs = {
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0",
"client_settings": client_settings,
"vendor_type": "awsbedrock",
}

@property
Expand Down
48 changes: 24 additions & 24 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.