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-agent-framework:
name: Lint uipath-agent-framework
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-agent-framework")' > /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-agent-framework"
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-agent-framework/.python-version"

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

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

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

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

skip-lint:
name: Skip Lint (Custom Version Testing)
runs-on: ubuntu-latest
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 || 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 || 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 @@ -178,3 +178,52 @@ jobs:
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-google-adk
run: uv run pytest

test-agent-framework:
name: Test (uipath-agent-framework, ${{ 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-agent-framework")' > /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-agent-framework"

- 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-agent-framework
run: uv sync --all-extras --python ${{ matrix.python-version }}

- name: Run tests
if: steps.check.outputs.skip != 'true'
working-directory: packages/uipath-agent-framework
run: uv run pytest
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ All packages extend the [UiPath Python SDK](https://github.com/UiPath/uipath-pyt
|---|---|---|---|
| [LlamaIndex](https://www.llamaindex.ai/) | [![PyPI](https://img.shields.io/pypi/v/uipath-llamaindex)](https://pypi.org/project/uipath-llamaindex/) | [![Downloads](https://img.shields.io/pypi/dm/uipath-llamaindex.svg)](https://pypi.org/project/uipath-llamaindex/) | [README](packages/uipath-llamaindex/README.md) · [Docs](https://uipath.github.io/uipath-python/llamaindex/quick_start/) · [Samples](packages/uipath-llamaindex/samples/) |
| [OpenAI Agents](https://github.com/openai/openai-agents-python) | [![PyPI](https://img.shields.io/pypi/v/uipath-openai-agents)](https://pypi.org/project/uipath-openai-agents/) | [![Downloads](https://img.shields.io/pypi/dm/uipath-openai-agents.svg)](https://pypi.org/project/uipath-openai-agents/) | [README](packages/uipath-openai-agents/README.md) · [Docs](https://uipath.github.io/uipath-python/openai-agents/quick_start/) · [Samples](packages/uipath-openai-agents/samples/) |
| [Google ADK](https://github.com/google/adk-python) | [![PyPI](https://img.shields.io/pypi/v/uipath-google-adk)](https://pypi.org/project/uipath-google-adk/) | [![Downloads](https://img.shields.io/pypi/dm/uipath-google-adk.svg)](https://pypi.org/project/uipath-google-adk/) | [README](packages/uipath-google-adk/README.md) · [Docs](https://uipath.github.io/uipath-python/google-adk/quick_start/) · [Samples](packages/uipath-google-adk/samples/) |
| [Google ADK](https://github.com/google/adk-python) | [![PyPI](https://img.shields.io/pypi/v/uipath-google-adk)](https://pypi.org/project/uipath-google-adk/) | [![Downloads](https://img.shields.io/pypi/dm/uipath-google-adk.svg)](https://pypi.org/project/uipath-google-adk/) | [README](packages/uipath-google-adk/README.md) · [Samples](packages/uipath-google-adk/samples/) |
| [Microsoft Agent Framework](https://github.com/microsoft/agent-framework) | [![PyPI](https://img.shields.io/pypi/v/uipath-agent-framework)](https://pypi.org/project/uipath-agent-framework/) | [![Downloads](https://img.shields.io/pypi/dm/uipath-agent-framework.svg)](https://pypi.org/project/uipath-agent-framework/) | [README](packages/uipath-agent-framework/README.md) · [Samples](packages/uipath-agent-framework/samples/) |


## Structure
Expand All @@ -22,7 +23,8 @@ uipath-integrations-python/
└── packages/
├── uipath-llamaindex/ # LlamaIndex runtime
├── uipath-openai-agents/ # OpenAI Agents runtime
└── uipath-google-adk/ # Google ADK runtime
├── uipath-google-adk/ # Google ADK runtime
└── uipath-agent-framework/ # Microsoft Agent Framework runtime
```

## Development
Expand Down
1 change: 1 addition & 0 deletions packages/uipath-agent-framework/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
131 changes: 131 additions & 0 deletions packages/uipath-agent-framework/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# UiPath Agent Framework Python SDK

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

A Python SDK that enables developers to build and deploy [Agent Framework](https://github.com/microsoft/agent-framework) 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-agent-framework/samples) to see the SDK in action.

## Requirements

- Python 3.11 or higher
- UiPath Automation Cloud account

## Installation

```bash
pip install uipath-agent-framework
```

using `uv`:

```bash
uv add uipath-agent-framework
```

For Anthropic model support:

```bash
pip install 'uipath-agent-framework[anthropic]'
```

## 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 Agent Framework 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 `agent_framework.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
- An `agent_framework.json` file with your agent definitions (e.g., `"agents": {"agent": "main.py:agent"}`)
- An `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 terminal 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/packages/uipath-agent-framework/blob/main/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:

- [Agent Framework](https://github.com/microsoft/agent-framework) for providing a flexible 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.
113 changes: 113 additions & 0 deletions packages/uipath-agent-framework/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
[project]
name = "uipath-agent-framework"
version = "0.0.1"
description = "Python SDK that enables developers to build and deploy Microsoft Agent Framework agents to the UiPath Cloud Platform"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"agent-framework-core>=1.0.0b260212",
"openinference-instrumentation-agent-framework>=0.1.0",
"uipath>=2.8.41, <2.9.0",
"uipath-runtime>=0.9.0, <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.optional-dependencies]
anthropic = ["anthropic>=0.43.0", "agent-framework-anthropic>=1.0.0b260212"]

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

[project.entry-points."uipath.runtime.factories"]
agent-framework = "uipath_agent_framework.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.19.1",
"ruff>=0.15.1",
"pytest>=9.0.2",
"pytest-cov>=7.0.0",
"pytest-mock>=3.15.1",
"pre-commit>=4.5.1",
"pytest-asyncio>=1.3.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 = "agent_framework.*"
ignore_missing_imports = true
ignore_errors = true

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

[[tool.mypy.overrides]]
module = "agent_framework_anthropic.*"
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]
prerelease = "allow"

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