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

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 and maps it to an AgentRuntimeError, reading the gateway message from body["detail"].
  • licensing.py is rewritten to map 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 across every provider (OpenAI/Anthropic/Vertex/Bedrock), including the LangChain-wrapped cases.
  • Bumps the uipath-langchain-client floor >=1.14.1,<1.15.0>=1.15.0,<1.16.0.

Why

Previously provider_errors.py duck-typed each SDK's exception shape (.body / .details / .response) to recover (status_code, detail). That logic now lives once, in the LLM client (UiPathAPIError.from_provider), so the agent layer just catches UiPathAPIError and reads .status_code / .body.

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'"). Confirmed via the actual chat-model classes (openai/anthropic) and the licensing mapping.

Tests

New tests/agent/test_licensing.py: 403 → LICENSE_NOT_AVAILABLE with the detail surfaced; non-403 → HTTP_ERROR (detail preserved within the wrapped message); missing-detail body → safe fallback.

Follow-up (separate repo)

uipath-agents pins uipath-langchain[bedrock,vertex]==0.13.11 (exact) — it'll need its pin bumped to ==0.13.12 to pick this up.

🤖 Generated with Claude Code

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 on lines +121 to +125
try:
response = await llm.ainvoke(messages)
except Exception as e:
# LLM errors arrive as provider-specific exceptions (OpenAI, Bedrock,
# Vertex). Convert to a structured AgentRuntimeError with the HTTP
# status code so upstream handlers can categorise (e.g. 403 → licensing).
except UiPathAPIError as e:
raise_for_provider_http_error(e)
except Exception:

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.

excelent catch. will address this

@vldcmp-uipath vldcmp-uipath force-pushed the feat/licensing-consume-uipath-api-error branch 3 times, most recently from 1a24468 to 758f638 Compare June 26, 2026 18:20
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 758f638 to 11cdca7 Compare June 26, 2026 18:23
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
61.5% Coverage on New Code (required ≥ 90%)

See analysis details on SonarQube Cloud

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants