feat(licensing): consume normalized UiPathAPIError from the LLM client#946
feat(licensing): consume normalized UiPathAPIError from the LLM client#946vldcmp-uipath wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
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_nodeand licensing error mapping to handleUiPathAPIErrordirectly and surface gatewaybody["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-langchainto0.13.12and raiseuipath-langchain-clientfloor 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 UiPathAPIError → AgentRuntimeError mapping for 403/non-403 and missing-detail bodies. |
12a0341 to
9200b88
Compare
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>
9200b88 to
4a71422
Compare
|
| 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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
the provider exceptions already wrap over response which as_uipath_error() map to UiPathApiError



Summary
uipath-langchain-client1.15.0 (onuipath-llm-client1.15.0) now normalizes provider HTTP errors into aUiPathAPIErrorcarrying.status_codeand.body(the gateway ProblemDetails). This PR makes the agent consume that normalized error instead of re-deriving it here.llm_nodecatchesUiPathAPIError(new clients) and, for the legacy in-repo clients (use_new_llm_clients=False) that still raise raw provider SDK exceptions, normalizes viaas_uipath_errorbefore mapping. Both map to anAgentRuntimeErrorreading the gateway message frombody["detail"].licensing.pymaps theUiPathAPIErrorstatus code onto the agent taxonomy (403 → LICENSE_NOT_AVAILABLE/DEPLOYMENT, otherwiseHTTP_ERROR/UNKNOWN).chat/provider_errors.py(and its test) — the per-provider duck-typing extractor is no longer needed; the client owns that normalization.uipath-langchain-clientfloor>=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) andtests/agent/react/test_llm_node.py::TestLLMNodeProviderErrorHandling(drives the actualllm_nodeexceptbranches — new-clientUiPathAPIError, legacy raw provider error, and non-HTTP propagation).Follow-up (separate repo)
uipath-agentspinsuipath-langchain[bedrock,vertex]exactly, so it needs its pin bumped to==0.13.13to pick this up — tracked in UiPath/uipath-agents-python#576 (draft, merge after this releases).🤖 Generated with Claude Code
Development Package
uipath pack --nolockto get the latest dev build from this PR (requires version range).