Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/lint-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,69 @@ jobs:
working-directory: packages/uipath-google-adk
run: uv run ruff format --check .

lint-pydantic-ai:
name: Lint uipath-pydantic-ai
needs: detect-changed-packages
runs-on: ubuntu-latest
steps:
- name: Check if package changed
id: check
run: |
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'test-core-dev-version') }}" == "true" ]]; then
echo "skip=true" >> $GITHUB_OUTPUT
echo "reason=custom-version-testing" >> $GITHUB_OUTPUT
elif echo '${{ needs.detect-changed-packages.outputs.packages }}' | jq -e 'index("uipath-pydantic-ai")' > /dev/null; then
echo "skip=false" >> $GITHUB_OUTPUT
else
echo "skip=true" >> $GITHUB_OUTPUT
echo "reason=no-changes" >> $GITHUB_OUTPUT
fi

- name: Skip
if: steps.check.outputs.skip == 'true'
run: |
if [[ "${{ steps.check.outputs.reason }}" == "custom-version-testing" ]]; then
echo "Skipping - custom version testing enabled"
else
echo "Skipping - no changes to uipath-pydantic-ai"
fi

- name: Checkout
if: steps.check.outputs.skip != 'true'
uses: actions/checkout@v4

- name: Setup uv
if: steps.check.outputs.skip != 'true'
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Setup Python
if: steps.check.outputs.skip != 'true'
uses: actions/setup-python@v5
with:
python-version-file: "packages/uipath-pydantic-ai/.python-version"

- name: Install dependencies
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv sync --all-extras

- name: Check static types
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv run mypy --config-file pyproject.toml .

- name: Check linting
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv run ruff check .

- name: Check formatting
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv run ruff format --check .

lint-agent-framework:
name: Lint uipath-agent-framework
needs: detect-changed-packages
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,4 @@ jobs:
- name: Publish
run: uv publish --index testpypi
env:
UV_PUBLISH_TOKEN: ${{ matrix.package == 'uipath-openai-agents' && secrets.TEST_PYPI_TOKEN_OPENAI_AGENTS || matrix.package == 'uipath-google-adk' && secrets.TEST_PYPI_TOKEN_GOOGLE_ADK || matrix.package == 'uipath-agent-framework' && secrets.TEST_PYPI_TOKEN_AGENT_FRAMEWORK || secrets.TEST_PYPI_TOKEN }}
UV_PUBLISH_TOKEN: ${{ matrix.package == 'uipath-openai-agents' && secrets.TEST_PYPI_TOKEN_OPENAI_AGENTS || matrix.package == 'uipath-google-adk' && secrets.TEST_PYPI_TOKEN_GOOGLE_ADK || matrix.package == 'uipath-agent-framework' && secrets.TEST_PYPI_TOKEN_AGENT_FRAMEWORK || matrix.package == 'uipath-pydantic-ai' && secrets.TEST_PYPI_TOKEN_PYDANTIC_AI || secrets.TEST_PYPI_TOKEN }}
49 changes: 49 additions & 0 deletions .github/workflows/test-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,55 @@ jobs:
working-directory: packages/uipath-google-adk
run: uv run pytest

test-pydantic-ai:
name: Test (uipath-pydantic-ai, ${{ matrix.python-version }}, ${{ matrix.os }})
needs: detect-changed-packages
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
os: [ubuntu-latest, windows-latest]
steps:
- name: Check if package changed
id: check
shell: bash
run: |
if echo '${{ needs.detect-changed-packages.outputs.packages }}' | jq -e 'index("uipath-pydantic-ai")' > /dev/null; then
echo "skip=false" >> $GITHUB_OUTPUT
else
echo "skip=true" >> $GITHUB_OUTPUT
fi

- name: Skip
if: steps.check.outputs.skip == 'true'
shell: bash
run: echo "Skipping - no changes to uipath-pydantic-ai"

- name: Checkout
if: steps.check.outputs.skip != 'true'
uses: actions/checkout@v4

- name: Setup uv
if: steps.check.outputs.skip != 'true'
uses: astral-sh/setup-uv@v5

- name: Setup Python
if: steps.check.outputs.skip != 'true'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv sync --all-extras --python ${{ matrix.python-version }}

- name: Run tests
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-pydantic-ai
run: uv run pytest

test-agent-framework:
name: Test (uipath-agent-framework, ${{ matrix.python-version }}, ${{ matrix.os }})
needs: detect-changed-packages
Expand Down
2 changes: 1 addition & 1 deletion packages/uipath-agent-framework/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ To properly use the CLI for packaging and publishing, your project should includ

### Developer Tools

Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive terminal application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.
Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.

### Setting Up a Development Environment

Expand Down
2 changes: 1 addition & 1 deletion packages/uipath-google-adk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ To properly use the CLI for packaging and publishing, your project should includ

### Developer Tools

Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive terminal application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.
Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.

### Setting Up a Development Environment

Expand Down
2 changes: 1 addition & 1 deletion packages/uipath-llamaindex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ To properly use the CLI for packaging and publishing, your project should includ

### Developer Tools

Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive terminal application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.
Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.

### Setting Up a Development Environment

Expand Down
2 changes: 1 addition & 1 deletion packages/uipath-openai-agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ To properly use the CLI for packaging and publishing, your project should includ

### Developer Tools

Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive terminal application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.
Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.

### Setting Up a Development Environment

Expand Down
1 change: 1 addition & 0 deletions packages/uipath-pydantic-ai/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
125 changes: 125 additions & 0 deletions packages/uipath-pydantic-ai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# UiPath PydanticAI Python SDK

[![PyPI - Version](https://img.shields.io/pypi/v/uipath-pydantic-ai)](https://pypi.org/project/uipath-pydantic-ai/)
[![PyPI downloads](https://img.shields.io/pypi/dm/uipath-pydantic-ai.svg)](https://pypi.org/project/uipath-pydantic-ai/)
[![Python versions](https://img.shields.io/pypi/pyversions/uipath-pydantic-ai.svg)](https://pypi.org/project/uipath-pydantic-ai/)

A Python SDK that enables developers to build and deploy PydanticAI agents to the UiPath Cloud Platform. It provides programmatic interaction with UiPath Cloud Platform services.

This package is an extension to the [UiPath Python SDK](https://github.com/UiPath/uipath-python) and implements the [UiPath Runtime Protocol](https://github.com/UiPath/uipath-runtime-python).

Check out these [sample projects](https://github.com/UiPath/uipath-integrations-python/tree/main/packages/uipath-pydantic-ai/samples) to see the SDK in action.

## Requirements

- Python 3.11 or higher
- UiPath Automation Cloud account

## Installation

```bash
pip install uipath-pydantic-ai
```

using `uv`:

```bash
uv add uipath-pydantic-ai
```

## Configuration

### Environment Variables

Create a `.env` file in your project root with the following variables:

```
UIPATH_URL=https://cloud.uipath.com/ACCOUNT_NAME/TENANT_NAME
UIPATH_ACCESS_TOKEN=YOUR_TOKEN_HERE
```

## Command Line Interface (CLI)

The SDK provides a command-line interface for creating, packaging, and deploying PydanticAI Agents:

### Authentication

```bash
uipath auth
```

This command opens a browser for authentication and creates/updates your `.env` file with the proper credentials.

### Initialize a Project

```bash
uipath init
```

Running `uipath init` will process the agent definitions in the `pydantic_ai.json` file and create the corresponding `entry-points.json` file needed for deployment.

For more details on the configuration format, see the [UiPath configuration specifications](https://github.com/UiPath/uipath-python/blob/main/specs/README.md).

### Debug a Project

```bash
uipath run AGENT [INPUT]
```

Executes the agent with the provided JSON input arguments.

### Package a Project

```bash
uipath pack
```

Packages your project into a `.nupkg` file that can be deployed to UiPath.

**Note:** Your `pyproject.toml` must include:

- A description field (avoid characters: &, <, >, ", ', ;)
- Author information

Example:

```toml
description = "Your package description"
authors = [{name = "Your Name", email = "your.email@example.com"}]
```

### Publish a Package

```bash
uipath publish
```

Publishes the most recently created package to your UiPath Orchestrator.

## Project Structure

To properly use the CLI for packaging and publishing, your project should include:

- A `pyproject.toml` file with project metadata
- A `pydantic_ai.json` file with your agent definitions (e.g., `"agents": {"agent": "main.py:agent"}`)
- A `entry-points.json` file (generated by `uipath init`)
- A `bindings.json` file (generated by `uipath init`) to configure resource overrides
- Any Python files needed for your automation

## Development

### Developer Tools

Check out [uipath-dev](https://github.com/uipath/uipath-dev-python) - an interactive application for building, testing, and debugging UiPath Python runtimes, agents, and automation scripts.

### Setting Up a Development Environment

Please read our [contribution guidelines](https://github.com/UiPath/uipath-integrations-python/blob/main/packages/uipath-pydantic-ai/CONTRIBUTING.md) before submitting a pull request.

### Special Thanks

A huge thank-you to the open-source community and the maintainers of the libraries that make this project possible:

- [PydanticAI](https://github.com/pydantic/pydantic-ai) for providing a powerful, type-safe framework for building AI agents.
- [OpenInference](https://github.com/Arize-ai/openinference) for observability and instrumentation support.
- [Pydantic](https://github.com/pydantic/pydantic) for reliable, typed configuration and validation.
97 changes: 97 additions & 0 deletions packages/uipath-pydantic-ai/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
[project]
name = "uipath-pydantic-ai"
version = "0.0.1"
description = "Python SDK that enables developers to build and deploy PydanticAI agents to the UiPath Cloud Platform"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"pydantic-ai>=1.63.0, <2.0.0",
"openinference-instrumentation-pydantic-ai>=0.1.12",
"uipath>=2.10.2, <2.11.0",
"uipath-runtime>=0.9.2, <0.10.0",
]
classifiers = [
"Intended Audience :: Developers",
"Topic :: Software Development :: Build Tools",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
maintainers = [
{ name = "Cristian Pufu", email = "cristian.pufu@uipath.com" }
]

[project.entry-points."uipath.middlewares"]
register = "uipath_pydantic_ai.middlewares:register_middleware"

[project.entry-points."uipath.runtime.factories"]
pydantic-ai = "uipath_pydantic_ai.runtime:register_runtime_factory"

[project.urls]
Homepage = "https://uipath.com"
Repository = "https://github.com/UiPath/uipath-integrations-python"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[dependency-groups]
dev = [
"mypy>=1.14.1",
"ruff>=0.9.4",
"pytest>=7.4.0",
"pytest-cov>=4.1.0",
"pytest-mock>=3.11.1",
"pre-commit>=4.1.0",
"pytest-asyncio>=1.0.0",
]

[tool.ruff]
line-length = 88
indent-width = 4

[tool.ruff.lint]
select = ["E", "F", "B", "I"]

[tool.ruff.lint.per-file-ignores]
"*" = ["E501"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.mypy]
plugins = [
"pydantic.mypy"
]
exclude = [
"samples/.*",
"testcases/.*"
]
follow_imports = "silent"
warn_redundant_casts = true
warn_unused_ignores = false
disallow_any_generics = true
check_untyped_defs = true
no_implicit_reexport = true
disallow_untyped_defs = false

[[tool.mypy.overrides]]
module = "pydantic_ai"
ignore_missing_imports = true
ignore_errors = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = "test_*.py"
addopts = "-ra -q"
asyncio_default_fixture_loop_scope = "function"
asyncio_mode = "auto"

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