Skip to content

Commit 9396ae2

Browse files
Merge branch 'main' of https://github.com/UiPath/uipath-langchain-python into feat-df-agent-integrations-fixes
2 parents 98460a9 + f02cacc commit 9396ae2

71 files changed

Lines changed: 3309 additions & 560 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/commitlint.yml

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,5 @@ jobs:
1616
with:
1717
fetch-depth: 0
1818

19-
- name: Setup Node
20-
uses: actions/setup-node@v3
21-
with:
22-
node-version: 22
23-
24-
- name: Install Git
25-
run: |
26-
if ! command -v git &> /dev/null; then
27-
echo "Git is not installed. Installing..."
28-
sudo apt-get update
29-
sudo apt-get install -y git
30-
else
31-
echo "Git is already installed."
32-
fi
33-
34-
- name: Install commitlint
35-
run: |
36-
npm install conventional-changelog-conventionalcommits
37-
npm install commitlint@latest
38-
npm install @commitlint/config-conventional
39-
40-
- name: Configure
41-
run: |
42-
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
43-
4419
- name: Validate PR commits with commitlint
45-
run: |
46-
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr_branch
47-
npx commitlint --from ${{ github.event.pull_request.base.sha }} --to pr_branch --verbose
20+
uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6

CLAUDE.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
`uipath-langchain` is a Python SDK that extends UiPath's Python SDK with LangChain/LangGraph integration. It implements the UiPath Runtime Protocol to deploy LangGraph agents to UiPath Cloud Platform. Requires Python 3.11+.
8+
9+
## Common Commands
10+
11+
```bash
12+
# Install dependencies (uses uv)
13+
uv sync --all-extras
14+
15+
# Run all tests
16+
uv run pytest
17+
18+
# Run a single test file
19+
uv run pytest tests/path/to/test_file.py
20+
21+
# Run a single test
22+
uv run pytest tests/path/to/test_file.py::test_name
23+
24+
# Lint
25+
just lint # ruff check + httpx client lint
26+
just format # ruff format check + fix
27+
28+
# Build
29+
uv build
30+
```
31+
32+
## Architecture
33+
34+
### Package: `src/uipath_langchain/`
35+
36+
- **`runtime/`**`UiPathLangGraphRuntime` executes LangGraph graphs within the UiPath framework. Async execution with streaming, breakpoints, and message mapping. Registered as an entry point via `uipath_langchain.runtime:register_runtime_factory`.
37+
38+
- **`agent/`** — Agent implementation with sub-packages:
39+
- `react/` — ReAct agent pattern (agent, LLM node, router, tool node, guardrails)
40+
- `tools/` — Structured tools: context, escalation, extraction, integration, process, MCP adapters, durable interrupts. All inherit from `BaseUiPathStructuredTool`.
41+
- `guardrails/` — Input/output validation within agent execution
42+
- `multimodal/` — Multimodal invoke support
43+
- `exceptions/` — Structured error types (`AgentRuntimeError`, `AgentStartupError`) and helpers for agent error handling
44+
- `wrappers/` — Agent decorators and wrappers
45+
46+
- **`chat/`** — LLM provider interfaces for OpenAI, Azure OpenAI, AWS Bedrock, Google Vertex AI. Uses **lazy imports** via `__getattr__` in `__init__.py` to keep CLI startup fast. Includes `hitl.py` with the `requires_approval` decorator for human-in-the-loop workflows. Factory pattern via `chat_model_factory.py`.
47+
48+
- **`retrievers/`** and **`vectorstores/`** — Context grounding retrieval and vector storage.
49+
50+
- **`guardrails/`** — Top-level guardrails with actions, enums, models, and middleware.
51+
52+
- **`_cli/`** — CLI commands (`uipath init`, `uipath new`) with project templates.
53+
54+
- **`_tracing/`** — OpenTelemetry instrumentation.
55+
56+
- **`_utils/`** — Shared utilities: HTTP request mixin, settings, sleep policy, environment helpers.
57+
58+
- **`middlewares.py`** — Entry point registered as `uipath_langchain.middlewares:register_middleware`.
59+
60+
### Entry Points (pyproject.toml)
61+
62+
The package registers two entry points consumed by the `uipath` CLI:
63+
- `uipath.middleware``uipath_langchain.middlewares:register_middleware`
64+
- `uipath.runtime_factory``uipath_langchain.runtime:register_runtime_factory`
65+
66+
## Key Conventions
67+
68+
- **httpx clients**: Always use `**get_httpx_client_kwargs()` when constructing `httpx.Client()` or `httpx.AsyncClient()`. A custom AST linter (`scripts/lint_httpx_client.py`) enforces this — it runs as part of `just lint`.
69+
70+
- **Lazy imports**: The `chat/` module defers heavy imports (langchain_openai, openai SDK) to optimize CLI startup. Use `__getattr__` pattern in `__init__.py` when adding new chat model providers.
71+
72+
- **Naming conventions for SDK methods**: `retrieve` (single by key), `retrieve_by_[field]` (single by other field), `list` (multiple resources).
73+
74+
- **Testing**: pytest only (no unittest). Tests in `./tests/` mirror source structure. Use pytest-asyncio for async tests (mode: auto). A circular import test (`test_no_circular_imports.py`) auto-discovers and validates all modules.
75+
76+
- **Type annotations**: All functions and classes require type annotations. Public APIs require Google-style docstrings.
77+
78+
- **Linting**: Ruff with rules E, F, B, I. Line length 88. mypy with pydantic plugin for type checking.
79+
80+
- **Bedrock/Vertex imports**: `bedrock.py` and `vertex.py` have per-file E402 ignores for conditional imports.
81+
82+
- **Exception handling in `agent/`**: Use the error types and helpers from `agent/exceptions/`. Do not raise raw exceptions or invent new error types. New error codes may be defined.
29.3 KB
Loading

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[project]
22
name = "uipath-langchain"
3-
version = "0.8.14"
3+
version = "0.9.2"
44
description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath>=2.10.0, <2.11.0",
8+
"uipath>=2.10.22, <2.11.0",
99
"uipath-core>=0.5.2, <0.6.0",
10-
"uipath-platform>=0.0.18, <0.1.0",
10+
"uipath-platform>=0.1.5, <0.2.0",
1111
"uipath-runtime>=0.9.1, <0.10.0",
1212
"langgraph>=1.0.0, <2.0.0",
1313
"langchain-core>=1.2.11, <2.0.0",

samples/ticket-classification/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,26 @@ cd uipath-langchain-python/samples/ticket-classification
9494

9595
The Ticket Classification Agent utilizes HITL (Human In The Loop) technology, allowing the system to incorporate feedback directly from supervisory personnel. We'll leverage UiPath [Action Center](https://docs.uipath.com/action-center/automation-suite/2023.4/user-guide/introduction) for this functionality.
9696

97+
There are two ways to configure the escalation app:
98+
99+
#### Option A: Use App Bindings (recommended — no code changes required)
100+
101+
After publishing the agent package, you can override the escalation app directly from the **Package Requirements** tab in UiPath, without modifying any code. This is made possible by the `bindings.json` file included in this sample.
102+
103+
![app-binding-package-requirements](../../docs/sample_images/ticket-classification/app-binding-package-requirements.png)
104+
105+
In the **Package Requirements** tab, select the app you want to use as the escalation app. The app you bind **must respect the following contract** expected by the agent code:
106+
107+
- **Inputs:**
108+
- `AgentOutput` (string) — the classification summary sent to the reviewer
109+
- `AgentName` (string) — the name of the agent creating the task
110+
- **Output:**
111+
- `Answer` (boolean) — `true` to approve, `false` to reject
112+
113+
> This approach allows you to use any compatible UiPath App as the escalation interface, swapping it out without redeploying or editing code.
114+
115+
#### Option B: Deploy the pre-built solution app
116+
97117
Follow these steps to deploy the pre-built application using [UiPath Solutions Management](https://docs.uipath.com/solutions-management/automation-cloud/latest/user-guide/solutions-management-overview):
98118

99119
1. **Upload Solution Package**
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"version": "2.0",
3+
"resources": [
4+
{
5+
"resource": "app",
6+
"key": "escalation_agent_app.app_folder_path",
7+
"value": {
8+
"name": {
9+
"defaultValue": "escalation_agent_app",
10+
"isExpression": false,
11+
"displayName": "App Name"
12+
},
13+
"folderPath": {
14+
"defaultValue": "app_folder_path",
15+
"isExpression": false,
16+
"displayName": "App Folder Path"
17+
}
18+
},
19+
"metadata": {
20+
"ActivityName": "create_async",
21+
"BindingsVersion": "2.2",
22+
"DisplayLabel": "app_name"
23+
}
24+
}
25+
]
26+
}

samples/ticket-classification/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ async def wait_for_human(state: GraphState) -> Command:
125125
"AgentName": "ticket-classification "},
126126
app_version=1,
127127
assignee=state.get("assignee", None),
128-
app_folder_path="FOLDER_PATH_PLACEHOLDER",
128+
app_folder_path="app_folder_path",
129129
))
130130

131131
return Command(

src/uipath_langchain/_cli/cli_new.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def generate_pyproject(target_directory, project_name):
3131
description = "{project_name}"
3232
authors = [{{ name = "John Doe", email = "john.doe@myemail.com" }}]
3333
dependencies = [
34-
"uipath-langchain>=0.2.0",
34+
"uipath-langchain>=0.8.0, <0.9.0",
3535
]
3636
requires-python = ">=3.11"
3737
"""

src/uipath_langchain/agent/tools/durable_interrupt/__init__.py renamed to src/uipath_langchain/_utils/durable_interrupt/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""Durable interrupt package for side-effect-safe interrupt/resume in LangGraph."""
22

3-
from .decorator import _durable_state, durable_interrupt
3+
from .decorator import (
4+
_durable_state,
5+
durable_interrupt,
6+
)
47
from .skip_interrupt import SkipInterruptValue
58

69
__all__ = [

src/uipath_langchain/agent/tools/durable_interrupt/decorator.py renamed to src/uipath_langchain/_utils/durable_interrupt/decorator.py

File renamed without changes.

0 commit comments

Comments
 (0)