Skip to content

Commit 1fb671c

Browse files
authored
Merge pull request #1 from UiPath/fix/initial
add basic structure
2 parents 4ef1cbc + 221b522 commit 1fb671c

14 files changed

Lines changed: 411 additions & 0 deletions

.editorconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; https://editorconfig.org/
2+
3+
root = true
4+
5+
[*]
6+
indent_style = space
7+
indent_size = 4
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
end_of_line = lf
11+
charset = utf-8
12+
13+
[*.{json,toml,yml}]
14+
indent_size = 2

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.9.6
4+
hooks:
5+
- id: ruff
6+
args: [ --fix ]
7+
- id: ruff-format

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10

CONTRIBUTING.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Contributing to UiPath SDK
2+
3+
## Local Development Setup
4+
5+
### Prerequisites
6+
7+
1. **Install Python 3.13**:
8+
- Download and install Python 3.13 from the official [Python website](https://www.python.org/downloads/)
9+
- Verify the installation by running:
10+
```sh
11+
python3.13 --version
12+
```
13+
14+
Alternative: [mise](https://mise.jdx.dev/lang/python.html)
15+
16+
2. **Install [uv](https://docs.astral.sh/uv/)**:
17+
```sh
18+
pip install uv
19+
```
20+
21+
3. **Create a virtual environment in the current working directory**:
22+
```sh
23+
uv venv
24+
```
25+
26+
4. **Install dependencies**:
27+
```sh
28+
uv sync --all-extras
29+
```
30+
31+
See `just --list` for linting, formatting and build commands.
32+
33+
34+
### Use SDK Locally
35+
1. Create a folder on your own device `mkdir project; cd project`
36+
2. Initialize the python project `uv` `uv init . --python 3.10`
37+
3. Obtain the project path `PATH_TO_SDK=/Users/YOU_USER/uipath-mcp-python/uipath-mcp`
38+
4. Install the sdk in editable mode `uv add --editable ${PATH_TO_SDK}`
39+
40+
:information_source: Instead of cloning the project into `.venv/lib/python3.10/site-packages/uipath-mcp`, this mode creates a file named `_uipath-mcp.pth` inside `.venv/lib/python3.10/site-packages`. This file contains the value of `PATH_TO_SDK`, which is added to `sys.path`—the list of directories where python searches for packages. (Run `python -c 'import sys; print(sys.path)'` to see the entries.)
41+
42+

pyproject.toml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
[project]
2+
name = "uipath-llama"
3+
version = "0.0.1"
4+
description = "UiPath Llama SDK"
5+
readme = { file = "README.md", content-type = "text/markdown" }
6+
requires-python = ">=3.10"
7+
dependencies = [
8+
"uipath>=2.0.56",
9+
]
10+
classifiers = [
11+
"Development Status :: 3 - Alpha",
12+
"Intended Audience :: Developers",
13+
"Topic :: Software Development :: Build Tools",
14+
"Programming Language :: Python :: 3.10",
15+
"Programming Language :: Python :: 3.11",
16+
"Programming Language :: Python :: 3.12",
17+
]
18+
maintainers = [
19+
{ name = "Marius Cosareanu", email = "marius.cosareanu@uipath.com" },
20+
{ name = "Cristian Pufu", email = "cristian.pufu@uipath.com" }
21+
]
22+
23+
[project.entry-points."uipath.middlewares"]
24+
register = "uipath_llama.middlewares:register_middleware"
25+
26+
[project.urls]
27+
Homepage = "https://uipath.com"
28+
Repository = "https://github.com/UiPath/uipath-llama-python"
29+
30+
[build-system]
31+
requires = ["hatchling"]
32+
build-backend = "hatchling.build"
33+
34+
[dependency-groups]
35+
dev = [
36+
"mypy>=1.14.1",
37+
"ruff>=0.9.4",
38+
"pytest>=7.4.0",
39+
"pytest-cov>=4.1.0",
40+
"pytest-mock>=3.11.1",
41+
"pre-commit>=4.1.0",
42+
"numpy>=1.24.0",
43+
]
44+
45+
[tool.ruff]
46+
line-length = 88
47+
indent-width = 4
48+
49+
[tool.ruff.lint]
50+
select = ["E", "F", "B", "I"]
51+
52+
[tool.ruff.lint.per-file-ignores]
53+
"*" = ["E501"]
54+
55+
[tool.ruff.format]
56+
quote-style = "double"
57+
indent-style = "space"
58+
skip-magic-trailing-comma = false
59+
line-ending = "auto"
60+
61+
[tool.mypy]
62+
plugins = [
63+
"pydantic.mypy"
64+
]
65+
66+
follow_imports = "silent"
67+
warn_redundant_casts = true
68+
warn_unused_ignores = true
69+
disallow_any_generics = true
70+
check_untyped_defs = true
71+
no_implicit_reexport = true
72+
73+
disallow_untyped_defs = false
74+
75+
[tool.pytest.ini_options]
76+
testpaths = ["tests"]
77+
python_files = "test_*.py"
78+
addopts = "-ra -q"
79+
80+

src/uipath_llama/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .middlewares import register_middleware
2+
3+
__all__ = ["register_middleware"]

src/uipath_llama/_cli/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__all__: list[str] = []
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import Optional
2+
3+
from uipath._cli._runtime._contracts import UiPathRuntimeContext
4+
5+
from .._utils._config import LlamaConfig
6+
7+
8+
class UiPathLlamaRuntimeContext(UiPathRuntimeContext):
9+
"""Context information passed throughout the runtime execution."""
10+
11+
config: Optional[LlamaConfig] = None
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import Optional
2+
3+
from uipath._cli._runtime._contracts import UiPathErrorCategory, UiPathRuntimeError
4+
5+
6+
class UiPathLlamaRuntimeError(UiPathRuntimeError):
7+
"""Custom exception for Llama runtime errors with structured error information."""
8+
9+
def __init__(
10+
self,
11+
code: str,
12+
title: str,
13+
detail: str,
14+
category: UiPathErrorCategory = UiPathErrorCategory.UNKNOWN,
15+
status: Optional[int] = None,
16+
):
17+
super().__init__(code, title, detail, category, status, prefix="Llama")
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import logging
2+
from typing import Optional
3+
4+
from uipath import UiPath
5+
from uipath._cli._runtime._contracts import (
6+
UiPathBaseRuntime,
7+
UiPathErrorCategory,
8+
UiPathRuntimeResult,
9+
)
10+
from uipath.tracing import wait_for_tracers
11+
12+
from ._context import UiPathLlamaRuntimeContext
13+
from ._exception import UiPathLlamaRuntimeError
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
class UiPathLlamaRuntime(UiPathBaseRuntime):
19+
"""
20+
A runtime class for hosting UiPath Llama agents.
21+
"""
22+
23+
def __init__(self, context: UiPathLlamaRuntimeContext):
24+
super().__init__(context)
25+
self.context: UiPathLlamaRuntimeContext = context
26+
self._uipath = UiPath()
27+
28+
async def execute(self) -> Optional[UiPathRuntimeResult]:
29+
"""
30+
Start the Llama agent runtime.
31+
32+
Returns:
33+
Dictionary with execution results
34+
35+
Raises:
36+
UiPathLlamaRuntimeError: If execution fails
37+
"""
38+
await self.validate()
39+
40+
try:
41+
a = 2
42+
43+
except Exception as e:
44+
if isinstance(e, UiPathLlamaRuntimeError):
45+
raise
46+
detail = f"Error: {str(e)}"
47+
raise UiPathLlamaRuntimeError(
48+
"EXECUTION_ERROR",
49+
"Llama Runtime execution failed",
50+
detail,
51+
UiPathErrorCategory.USER,
52+
) from e
53+
finally:
54+
wait_for_tracers()
55+
56+
async def validate(self) -> None:
57+
"""Validate runtime inputs and load Llama agent configuration."""
58+
pass
59+
60+
async def cleanup(self) -> None:
61+
"""Clean up all resources."""
62+
pass

0 commit comments

Comments
 (0)