Skip to content

Commit e33d8df

Browse files
cosminachoclaude
andcommitted
Feat: add BYOM API flavor constants and resolve them in factories
BYOM models from the discovery endpoint return new PascalCase API flavors (e.g. OpenAiChatCompletions, GeminiGenerateContent, AwsBedrockConverse). Add these as constants and automatically resolve them to the correct routing-level flavors and vendor types so clients are instantiated correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3c747c5 commit e33d8df

9 files changed

Lines changed: 64 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

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

5+
## [1.9.0] - 2026-04-16
6+
7+
### Added
8+
- BYOM API flavor constants for discovery endpoint: `OpenAiChatCompletions`, `OpenAiResponses`, `OpenAiEmbeddings`, `GeminiGenerateContent`, `GeminiEmbeddings`, `AwsBedrockInvoke`, `AwsBedrockConverse`
9+
- `BYOM_TO_ROUTING_FLAVOR` mapping to resolve BYOM discovery flavors to routing-level API flavors
10+
- Extended `API_FLAVOR_TO_VENDOR_TYPE` with BYOM flavor entries for automatic vendor resolution
11+
- LiteLLM client now resolves BYOM discovery flavors to correct routing flavors and litellm providers
12+
513
## [1.8.2] - 2026-04-13
614

715
### Fixed

packages/uipath_langchain_client/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

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

5+
## [1.9.0] - 2026-04-16
6+
7+
### Added
8+
- Factory functions (`get_chat_model`, `get_embedding_model`) now automatically resolve BYOM discovery API flavors to the correct client and routing flavor
9+
510
## [1.8.2] - 2026-04-13
611

712
### Changed

packages/uipath_langchain_client/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ readme = "README.md"
66
requires-python = ">=3.11"
77
dependencies = [
88
"langchain>=1.2.15",
9-
"uipath-llm-client>=1.8.2",
9+
"uipath-llm-client>=1.9.0",
1010
]
1111

1212
[project.optional-dependencies]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__title__ = "UiPath LangChain Client"
22
__description__ = "A Python client for interacting with UiPath's LLM services via LangChain."
3-
__version__ = "1.8.2"
3+
__version__ = "1.9.0"

packages/uipath_langchain_client/src/uipath_langchain_client/factory.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929
from uipath_langchain_client.settings import (
3030
API_FLAVOR_TO_VENDOR_TYPE,
31+
BYOM_TO_ROUTING_FLAVOR,
3132
ApiFlavor,
3233
RoutingMode,
3334
UiPathBaseSettings,
@@ -160,6 +161,10 @@ def get_chat_model(
160161
raise ValueError("No vendor type or api flavor found in model info")
161162
discovered_vendor_type = discovered_vendor_type.lower()
162163

164+
# For BYOM models, derive routing api_flavor from the discovered BYOM flavor
165+
if api_flavor is None and discovered_api_flavor is not None:
166+
api_flavor = BYOM_TO_ROUTING_FLAVOR.get(discovered_api_flavor)
167+
163168
match discovered_vendor_type:
164169
case VendorType.OPENAI:
165170
if api_flavor == ApiFlavor.RESPONSES:

packages/uipath_langchain_client/src/uipath_langchain_client/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
)
2525
from uipath.llm_client.settings.constants import (
2626
API_FLAVOR_TO_VENDOR_TYPE,
27+
BYOM_TO_ROUTING_FLAVOR,
2728
ApiFlavor,
2829
ApiType,
2930
RoutingMode,
@@ -41,4 +42,5 @@
4142
"ApiFlavor",
4243
"VendorType",
4344
"API_FLAVOR_TO_VENDOR_TYPE",
45+
"BYOM_TO_ROUTING_FLAVOR",
4446
]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__title__ = "UiPath LLM Client"
22
__description__ = "A Python client for interacting with UiPath's LLM services."
3-
__version__ = "1.8.2"
3+
__version__ = "1.9.0"

src/uipath/llm_client/clients/litellm/client.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from uipath.llm_client.settings.base import UiPathAPIConfig
2828
from uipath.llm_client.settings.constants import (
2929
API_FLAVOR_TO_VENDOR_TYPE,
30+
BYOM_TO_ROUTING_FLAVOR,
3031
ApiFlavor,
3132
ApiType,
3233
RoutingMode,
@@ -87,6 +88,14 @@
8788
"converse": "bedrock",
8889
"invoke": "bedrock",
8990
"anthropic-claude": "vertex_ai",
91+
# BYOM discovery flavors (mapped via routing flavor resolution)
92+
"OpenAiChatCompletions": "openai",
93+
"OpenAiResponses": "openai",
94+
"OpenAiEmbeddings": "openai",
95+
"GeminiGenerateContent": "gemini",
96+
"GeminiEmbeddings": "gemini",
97+
"AwsBedrockInvoke": "bedrock",
98+
"AwsBedrockConverse": "bedrock",
9099
}
91100

92101
_ANTHROPIC_FAMILY = "anthropicclaude"
@@ -212,6 +221,10 @@ def _discover_and_build_api_config(
212221
resolved_vendor = str(vendor_type or discovered_vendor).lower()
213222
resolved_flavor = str(api_flavor) if api_flavor is not None else discovered_flavor
214223

224+
# Resolve BYOM discovery flavors to routing-level flavors
225+
if resolved_flavor is not None:
226+
resolved_flavor = BYOM_TO_ROUTING_FLAVOR.get(resolved_flavor, resolved_flavor)
227+
215228
# OpenAI defaults to chat-completions when no flavor is discovered
216229
if resolved_flavor is None and resolved_vendor in ("openai", "azure"):
217230
resolved_flavor = ApiFlavor.CHAT_COMPLETIONS

src/uipath/llm_client/settings/constants.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,47 @@ class VendorType(StrEnum):
2020

2121

2222
class ApiFlavor(StrEnum):
23+
# Routing-level flavors (used in X-UiPath-LlmGateway-ApiFlavor header)
2324
CHAT_COMPLETIONS = "chat-completions"
2425
RESPONSES = "responses"
2526
GENERATE_CONTENT = "generate-content"
2627
CONVERSE = "converse"
2728
INVOKE = "invoke"
2829
ANTHROPIC_CLAUDE = "anthropic-claude"
2930

31+
# BYOM discovery flavors (returned by discovery endpoint for BYOM models)
32+
OPENAI_CHAT_COMPLETIONS = "OpenAiChatCompletions"
33+
OPENAI_RESPONSES = "OpenAiResponses"
34+
OPENAI_EMBEDDINGS = "OpenAiEmbeddings"
35+
GEMINI_GENERATE_CONTENT = "GeminiGenerateContent"
36+
GEMINI_EMBEDDINGS = "GeminiEmbeddings"
37+
AWS_BEDROCK_INVOKE = "AwsBedrockInvoke"
38+
AWS_BEDROCK_CONVERSE = "AwsBedrockConverse"
39+
3040

3141
API_FLAVOR_TO_VENDOR_TYPE: dict[ApiFlavor, VendorType] = {
42+
# Routing flavors
3243
ApiFlavor.CHAT_COMPLETIONS: VendorType.OPENAI,
3344
ApiFlavor.RESPONSES: VendorType.OPENAI,
3445
ApiFlavor.GENERATE_CONTENT: VendorType.VERTEXAI,
3546
ApiFlavor.ANTHROPIC_CLAUDE: VendorType.VERTEXAI,
3647
ApiFlavor.CONVERSE: VendorType.AWSBEDROCK,
3748
ApiFlavor.INVOKE: VendorType.AWSBEDROCK,
49+
# BYOM discovery flavors
50+
ApiFlavor.OPENAI_CHAT_COMPLETIONS: VendorType.OPENAI,
51+
ApiFlavor.OPENAI_RESPONSES: VendorType.OPENAI,
52+
ApiFlavor.OPENAI_EMBEDDINGS: VendorType.OPENAI,
53+
ApiFlavor.GEMINI_GENERATE_CONTENT: VendorType.VERTEXAI,
54+
ApiFlavor.GEMINI_EMBEDDINGS: VendorType.VERTEXAI,
55+
ApiFlavor.AWS_BEDROCK_INVOKE: VendorType.AWSBEDROCK,
56+
ApiFlavor.AWS_BEDROCK_CONVERSE: VendorType.AWSBEDROCK,
57+
}
58+
59+
60+
BYOM_TO_ROUTING_FLAVOR: dict[str, ApiFlavor] = {
61+
ApiFlavor.OPENAI_CHAT_COMPLETIONS: ApiFlavor.CHAT_COMPLETIONS,
62+
ApiFlavor.OPENAI_RESPONSES: ApiFlavor.RESPONSES,
63+
ApiFlavor.GEMINI_GENERATE_CONTENT: ApiFlavor.GENERATE_CONTENT,
64+
ApiFlavor.AWS_BEDROCK_INVOKE: ApiFlavor.INVOKE,
65+
ApiFlavor.AWS_BEDROCK_CONVERSE: ApiFlavor.CONVERSE,
3866
}

0 commit comments

Comments
 (0)