Skip to content

Commit 1267059

Browse files
committed
feat: add agenthub_config kwarg to factory functions
1 parent 35d4d31 commit 1267059

4 files changed

Lines changed: 97 additions & 1 deletion

File tree

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.10.1] - 2026-05-08
6+
7+
### Added
8+
- `agenthub_config` kwarg on `get_chat_model` and `get_embedding_model`. When set, overrides `client_settings.agenthub_config` for that call via `model_copy`, so the caller's settings instance is not mutated. Lets callers (e.g. low-code agent runtimes) pass the per-execution AgentHub config (`agentsruntime`, `agentsplayground`, `agentsevals`, …) without rebuilding settings.
9+
510
## [1.10.0] - 2026-04-23
611

712
### Added
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.10.0"
3+
__version__ = "1.10.1"

packages/uipath_langchain_client/src/uipath_langchain_client/factory.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def get_chat_model(
4848
vendor_type: VendorType | str | None = None,
4949
api_flavor: ApiFlavor | str | None = None,
5050
custom_class: type[UiPathBaseChatModel] | None = None,
51+
agenthub_config: str | None = None,
5152
**model_kwargs: Any,
5253
) -> UiPathBaseChatModel:
5354
"""Factory function to create the appropriate LangChain chat model for a given model name.
@@ -70,6 +71,9 @@ def get_chat_model(
7071
custom_class: A custom class to use for instantiating the chat model instead of the
7172
auto-detected one. Must be a subclass of UiPathBaseChatModel. When provided,
7273
the factory skips vendor detection and uses this class directly.
74+
agenthub_config: AgentHub config header value to send with requests. When set,
75+
overrides ``client_settings.agenthub_config`` for this call. Returns a copy
76+
of ``client_settings`` so the caller's instance is not mutated.
7377
**model_kwargs: Additional keyword arguments to pass to the model constructor.
7478
7579
Returns:
@@ -79,6 +83,8 @@ def get_chat_model(
7983
ValueError: If the model is not found in available models or vendor is not supported.
8084
"""
8185
client_settings = client_settings or get_default_client_settings()
86+
if agenthub_config is not None and hasattr(client_settings, "agenthub_config"):
87+
client_settings = client_settings.model_copy(update={"agenthub_config": agenthub_config})
8288
model_info = client_settings.get_model_info(
8389
model_name,
8490
byo_connection_id=byo_connection_id,
@@ -238,6 +244,7 @@ def get_embedding_model(
238244
routing_mode: RoutingMode | str = RoutingMode.PASSTHROUGH,
239245
vendor_type: VendorType | str | None = None,
240246
custom_class: type[UiPathBaseEmbeddings] | None = None,
247+
agenthub_config: str | None = None,
241248
**model_kwargs: Any,
242249
) -> UiPathBaseEmbeddings:
243250
"""Factory function to create the appropriate LangChain embeddings model.
@@ -255,6 +262,9 @@ def get_embedding_model(
255262
custom_class: A custom class to use for instantiating the embedding model instead of
256263
the auto-detected one. Must be a subclass of UiPathBaseEmbeddings. When provided,
257264
the factory skips vendor detection and uses this class directly.
265+
agenthub_config: AgentHub config header value to send with requests. When set,
266+
overrides ``client_settings.agenthub_config`` for this call. Returns a copy
267+
of ``client_settings`` so the caller's instance is not mutated.
258268
**model_kwargs: Additional arguments passed to the embeddings constructor.
259269
260270
Returns:
@@ -269,6 +279,8 @@ def get_embedding_model(
269279
>>> vectors = embeddings.embed_documents(["Hello world"])
270280
"""
271281
client_settings = client_settings or get_default_client_settings()
282+
if agenthub_config is not None and hasattr(client_settings, "agenthub_config"):
283+
client_settings = client_settings.model_copy(update={"agenthub_config": agenthub_config})
272284
model_info = client_settings.get_model_info(
273285
model_name,
274286
byo_connection_id=byo_connection_id,

tests/langchain/features/test_factory_function.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,82 @@ def test_openai_chat_respects_discovered_byom_chat_completions(
128128
},
129129
)
130130
assert captured["api_flavor"] == ApiFlavor.CHAT_COMPLETIONS
131+
132+
133+
class TestFactoryAgentHubConfig:
134+
"""The ``agenthub_config`` factory kwarg overrides ``client_settings.agenthub_config``
135+
via ``model_copy`` so the caller's instance is not mutated."""
136+
137+
def _capture_settings(
138+
self,
139+
monkeypatch: pytest.MonkeyPatch,
140+
model_info: dict,
141+
original_settings,
142+
**factory_kwargs,
143+
):
144+
captured: dict = {}
145+
146+
class _StubModel:
147+
def __init__(self, **kwargs):
148+
captured.update(kwargs)
149+
150+
monkeypatch.setattr(
151+
"uipath_langchain_client.clients.openai.chat_models.UiPathAzureChatOpenAI",
152+
_StubModel,
153+
)
154+
get_chat_model(
155+
model_name=model_info["modelName"],
156+
client_settings=original_settings,
157+
**factory_kwargs,
158+
)
159+
return captured
160+
161+
def _make_settings(self, agenthub_config: str | None):
162+
settings = MagicMock()
163+
settings.get_model_info.return_value = {
164+
"modelName": "gpt-4o",
165+
"vendor": "OpenAi",
166+
"apiFlavor": None,
167+
"modelFamily": "OpenAi",
168+
}
169+
settings.agenthub_config = agenthub_config
170+
171+
def _model_copy(*, update):
172+
copied = MagicMock()
173+
copied.get_model_info.return_value = settings.get_model_info.return_value
174+
copied.agenthub_config = update.get("agenthub_config", agenthub_config)
175+
return copied
176+
177+
settings.model_copy.side_effect = _model_copy
178+
return settings
179+
180+
def test_kwarg_overrides_settings_value(self, monkeypatch: pytest.MonkeyPatch):
181+
original = self._make_settings(agenthub_config="agentsruntime")
182+
captured = self._capture_settings(
183+
monkeypatch,
184+
original.get_model_info.return_value,
185+
original,
186+
agenthub_config="agentsplayground",
187+
)
188+
assert captured["settings"].agenthub_config == "agentsplayground"
189+
original.model_copy.assert_called_once_with(update={"agenthub_config": "agentsplayground"})
190+
191+
def test_caller_settings_not_mutated(self, monkeypatch: pytest.MonkeyPatch):
192+
original = self._make_settings(agenthub_config="agentsruntime")
193+
self._capture_settings(
194+
monkeypatch,
195+
original.get_model_info.return_value,
196+
original,
197+
agenthub_config="agentsplayground",
198+
)
199+
assert original.agenthub_config == "agentsruntime"
200+
201+
def test_no_kwarg_keeps_settings_value(self, monkeypatch: pytest.MonkeyPatch):
202+
original = self._make_settings(agenthub_config="agentsruntime")
203+
captured = self._capture_settings(
204+
monkeypatch,
205+
original.get_model_info.return_value,
206+
original,
207+
)
208+
assert captured["settings"] is original
209+
original.model_copy.assert_not_called()

0 commit comments

Comments
 (0)