Skip to content

feat(licensing): consume normalized UiPathAPIError from the LLM client#946

Open
vldcmp-uipath wants to merge 1 commit into
mainfrom
feat/licensing-consume-uipath-api-error
Open

feat(licensing): consume normalized UiPathAPIError from the LLM client#946
vldcmp-uipath wants to merge 1 commit into
mainfrom
feat/licensing-consume-uipath-api-error

Conversation

@vldcmp-uipath

@vldcmp-uipath vldcmp-uipath commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

uipath-langchain-client 1.15.0 (on uipath-llm-client 1.15.0) now normalizes provider HTTP errors into a UiPathAPIError carrying .status_code and .body (the gateway ProblemDetails). This PR makes the agent consume that normalized error instead of re-deriving it here.

  • llm_node catches UiPathAPIError (new clients) and, for the legacy in-repo clients (use_new_llm_clients=False) that still raise raw provider SDK exceptions, normalizes via as_uipath_error before mapping. Both map to an AgentRuntimeError reading the gateway message from body["detail"].
  • licensing.py maps the UiPathAPIError status code onto the agent taxonomy (403 → LICENSE_NOT_AVAILABLE / DEPLOYMENT, otherwise HTTP_ERROR / UNKNOWN).
  • Deletes chat/provider_errors.py (and its test) — the per-provider duck-typing extractor is no longer needed; the client owns that normalization.
  • Bumps the uipath-langchain-client floor >=1.14.1,<1.15.0>=1.15.0,<1.16.0; version → 0.13.13.

Verified end-to-end (on 1.15.0)

UiPathChatOpenAI.invoke() on a gateway 403 → UiPathAPIError(status_code=403, body=…)AgentRuntimeError(code=LICENSE_NOT_AVAILABLE, status=403, category=DEPLOYMENT, detail="License not available… 'AGU'").

Tests

tests/agent/test_licensing.py (unit: mapping + as_uipath_error) and tests/agent/react/test_llm_node.py::TestLLMNodeProviderErrorHandling (drives the actual llm_node except branches — new-client UiPathAPIError, legacy raw provider error, and non-HTTP propagation).

Follow-up (separate repo)

uipath-agents pins uipath-langchain[bedrock,vertex] exactly, so it needs its pin bumped to ==0.13.13 to pick this up — tracked in UiPath/uipath-agents-python#576 (draft, merge after this releases).

🤖 Generated with Claude Code

Development Package

  • Use uipath pack --nolock to get the latest dev build from this PR (requires version range).
  • Add this package as a dependency in your pyproject.toml:
[project]
dependencies = [
  # Exact version:
  "uipath-langchain==0.13.13.dev1009465083",

  # Any version from PR
  "uipath-langchain>=0.13.13.dev1009460000,<0.13.13.dev1009470000"
]

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true

[tool.uv.sources]
uipath-langchain = { index = "testpypi" }

[tool.uv]
override-dependencies = [
    "uipath-langchain>=0.13.13.dev1009460000,<0.13.13.dev1009470000",
]

Copilot AI review requested due to automatic review settings June 26, 2026 17:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the agent to consume the LLM client’s newly normalized UiPathAPIError (with .status_code and .body) for consistent provider HTTP error handling, removing the in-repo per-provider error “duck typing” logic and aligning dependency constraints to the newer client versions.

Changes:

  • Switch llm_node and licensing error mapping to handle UiPathAPIError directly and surface gateway body["detail"] when available.
  • Remove the legacy provider exception normalization module (chat/provider_errors.py) and its tests, replacing coverage with new licensing-focused tests.
  • Bump uipath-langchain to 0.13.12 and raise uipath-langchain-client floor to >=1.15.0,<1.16.0 (plus updated lockfile).

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
uv.lock Updates locked versions for uipath-langchain, uipath-langchain-client, and uipath-llm-client to support normalized UiPathAPIError.
pyproject.toml Bumps package version and updates uipath-langchain-client[...] dependency constraints to 1.15.x.
src/uipath_langchain/agent/react/llm_node.py Narrows LLM error handling to UiPathAPIError and routes it through licensing mapping.
src/uipath_langchain/agent/exceptions/licensing.py Rewrites mapping to consume UiPathAPIError.status_code / .body and convert to AgentRuntimeError.
src/uipath_langchain/chat/provider_errors.py Deleted: removes per-provider exception normalization logic.
tests/chat/test_provider_errors.py Deleted: removes tests for the deleted extractor.
tests/agent/test_licensing.py Added: validates UiPathAPIErrorAgentRuntimeError mapping for 403/non-403 and missing-detail bodies.

Comment thread src/uipath_langchain/agent/react/llm_node.py
Comment thread src/uipath_langchain/agent/react/llm_node.py Outdated
@vldcmp-uipath vldcmp-uipath force-pushed the feat/licensing-consume-uipath-api-error branch 6 times, most recently from 12a0341 to 9200b88 Compare June 29, 2026 10:35
uipath-langchain-client 1.15.0 (on uipath-llm-client 1.15.0) now normalizes
provider HTTP errors into a UiPathAPIError carrying .status_code and .body.
llm_node catches it and maps it to a structured AgentRuntimeError, reading the
gateway message from body["detail"].

This removes the in-repo chat/provider_errors.py duck-typing extractor — the
client owns that normalization now — and rewrites licensing.py to map the
UiPathAPIError status code onto the agent taxonomy (403 -> LICENSE_NOT_AVAILABLE,
otherwise HTTP_ERROR). Bumps the uipath-langchain-client floor to >=1.15.0,<1.16.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vldcmp-uipath vldcmp-uipath force-pushed the feat/licensing-consume-uipath-api-error branch from 9200b88 to 4a71422 Compare June 29, 2026 10:41
@sonarqubecloud

Copy link
Copy Markdown

except Exception as e:
# Legacy in-repo clients (use_new_llm_clients=False) raise raw provider SDK exceptions.
# Normalize via as_uipath_error and apply the same mapping when the error is HTTP-shaped; non-HTTP errors propagate.
uipath_error = as_uipath_error(e)

@radu-mocanu radu-mocanu Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks the legacy provider error mapping. Before, legacy Vertex/google-genai code/details errors and botocore Bedrock dict-shaped response errors with HTTP 403 would map to AgentRuntimeError(LICENSE_NOT_AVAILABLE). Now as_uipath_error() maps those shapes to plain UiPathError, so this falls through to raise and surfaces the raw provider error instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the provider exceptions already wrap over response which as_uipath_error() map to UiPathApiError

spec for this: https://github.com/UiPath/uipath-langchain-python/pull/946/changes#diff-81eb220e0d94c8aaad7befe42c87f1a220044879dfb57988ef4e9bb1180487a2R392

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants