From 3543176e13c7c9360f51531543d5986c425fbe77 Mon Sep 17 00:00:00 2001 From: tudormatei Date: Fri, 17 Jul 2026 16:10:17 +0300 Subject: [PATCH] feat(errors): add ModelNotFoundError for discovery-miss lookups get_model_info raised a bare ValueError when a model name was absent from the discovery API response, indistinguishable from the other ValueErrors the factory/settings code can raise (unsupported vendor, missing agenthub_config, invalid kwargs). Callers had to match on the error message text to detect this specific case. Add ModelNotFoundError, raised by get_model_info on a discovery-miss. It subclasses ValueError (so existing `except ValueError` handlers keep working) and UiPathError (so it is catchable across the UiPath LLM error taxonomy) and carries the new UiPathLLMErrorCode.MODEL_NOT_FOUND code. Bumps core and langchain-client to 1.17.1, raises the langchain-client uipath-llm-client floor to >=1.17.1, and adds changelog entries. --- CHANGELOG.md | 6 ++++++ packages/uipath_langchain_client/CHANGELOG.md | 5 +++++ .../uipath_langchain_client/pyproject.toml | 2 +- .../uipath_langchain_client/__version__.py | 2 +- src/uipath/llm_client/__version__.py | 2 +- src/uipath/llm_client/settings/base.py | 5 +++-- src/uipath/llm_client/utils/exceptions.py | 20 +++++++++++++++++++ 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 976e5276..b9f0c0f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to `uipath_llm_client` (core package) will be documented in this file. +## [1.17.1] - 2026-07-17 + +### Added +- `ModelNotFoundError` — raised by `UiPathBaseSettings.get_model_info` when a model name is absent from the discovery API response. It subclasses both `ValueError` (so existing `except ValueError` handlers are unaffected) and `UiPathError` (so it is catchable across the UiPath LLM error taxonomy), and carries the new `UiPathLLMErrorCode.MODEL_NOT_FOUND` code. This lets callers distinguish a genuine discovery-miss from the other `ValueError`s the factory/settings code can raise (unsupported vendor, missing `agenthub_config`, invalid kwargs) instead of matching on message text. +- `UiPathLLMErrorCode.MODEL_NOT_FOUND` semantic error code. + ## [1.17.0] - 2026-07-14 ### Changed diff --git a/packages/uipath_langchain_client/CHANGELOG.md b/packages/uipath_langchain_client/CHANGELOG.md index 96d1f652..0e31b821 100644 --- a/packages/uipath_langchain_client/CHANGELOG.md +++ b/packages/uipath_langchain_client/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to `uipath_langchain_client` will be documented in this file. +## [1.17.1] - 2026-07-17 + +### Changed +- Picks up core `uipath-llm-client` 1.17.1, which adds `ModelNotFoundError` (raised by `get_model_info` on a discovery-miss) and the `UiPathLLMErrorCode.MODEL_NOT_FOUND` code. Bumped the `uipath-llm-client` floor to `>=1.17.1`. + ## [1.17.0] - 2026-07-14 ### Changed diff --git a/packages/uipath_langchain_client/pyproject.toml b/packages/uipath_langchain_client/pyproject.toml index aec80cbb..b5b2cf28 100644 --- a/packages/uipath_langchain_client/pyproject.toml +++ b/packages/uipath_langchain_client/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "langchain>=1.2.15,<2.0.0", - "uipath-llm-client>=1.17.0,<2.0.0", + "uipath-llm-client>=1.17.1,<2.0.0", ] [project.optional-dependencies] 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 c7cde983..618fd904 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.17.0" +__version__ = "1.17.1" diff --git a/src/uipath/llm_client/__version__.py b/src/uipath/llm_client/__version__.py index c3f66b27..ca1169f8 100644 --- a/src/uipath/llm_client/__version__.py +++ b/src/uipath/llm_client/__version__.py @@ -1,3 +1,3 @@ __title__ = "UiPath LLM Client" __description__ = "A Python client for interacting with UiPath's LLM services." -__version__ = "1.17.0" +__version__ = "1.17.1" diff --git a/src/uipath/llm_client/settings/base.py b/src/uipath/llm_client/settings/base.py index 050d871a..661182fd 100644 --- a/src/uipath/llm_client/settings/base.py +++ b/src/uipath/llm_client/settings/base.py @@ -14,6 +14,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict from uipath.llm_client.settings.constants import ApiFlavor, ApiType, RoutingMode, VendorType +from uipath.llm_client.utils.exceptions import ModelNotFoundError class UiPathAPIConfig(BaseModel): @@ -204,7 +205,7 @@ def get_model_info( The first matching model info dictionary. Raises: - ValueError: If no matching model is found. + ModelNotFoundError: If no matching model is found. """ available_models = self.get_available_models() @@ -239,7 +240,7 @@ def get_model_info( ] if not matching_models: - raise ValueError( + raise ModelNotFoundError( f"Model {model_name} not found. " f"Available models are: {[m['modelName'] for m in available_models]}" ) diff --git a/src/uipath/llm_client/utils/exceptions.py b/src/uipath/llm_client/utils/exceptions.py index d1309025..26483215 100644 --- a/src/uipath/llm_client/utils/exceptions.py +++ b/src/uipath/llm_client/utils/exceptions.py @@ -49,6 +49,7 @@ class UiPathLLMErrorCode(StrEnum): """ UNSUPPORTED_MIME_TYPE = "UNSUPPORTED_MIME_TYPE" + MODEL_NOT_FOUND = "MODEL_NOT_FOUND" class UiPathError(Exception): @@ -95,6 +96,24 @@ def __init__( self.detail = detail +class ModelNotFoundError(UiPathError, ValueError): + """Raised when a model name is absent from the discovery API response. + + This is a client-side lookup failure — the model was never returned by the + discovery endpoint — and is therefore distinct from the HTTP-status + ``UiPath*Error`` classes (e.g. :class:`UiPathNotFoundError`, which is an + actual HTTP 404 carrying a response). + + Subclasses ``ValueError`` so existing ``except ValueError`` handlers keep + working, and :class:`UiPathError` so it is catchable alongside every other + UiPath LLM error and carries the stable + :attr:`UiPathLLMErrorCode.MODEL_NOT_FOUND` code. + """ + + def __init__(self, detail: str | None = None) -> None: + UiPathError.__init__(self, detail, error_code=UiPathLLMErrorCode.MODEL_NOT_FOUND) + + class UiPathAPIError(UiPathError, HTTPStatusError): """Base exception for all UiPath API errors. @@ -466,6 +485,7 @@ def wrap_provider_errors() -> Iterator[None]: __all__ = [ "UiPathError", "UiPathLLMErrorCode", + "ModelNotFoundError", "UiPathAPIError", "UiPathBadRequestError", "UiPathAuthenticationError",