Skip to content
Open
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
91 changes: 91 additions & 0 deletions .github/scripts/force-runtime-override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""Force cross-repo uv resolves to use the runtime wheel under test."""

from __future__ import annotations

import re
import sys
from pathlib import Path


def _quoted(value: str) -> str:
return '"' + value.replace("\\", "\\\\").replace('"', '\\"') + '"'


def _add_override(pyproject_path: Path, override: str) -> None:
text = pyproject_path.read_text()
quoted_override = _quoted(override)

if override in text:
return

tool_uv_match = re.search(
r"(?ms)^\[tool\.uv\]\n(?P<body>.*?)(?=^\[|\Z)",
text,
)
if not tool_uv_match:
text = (
text.rstrip()
+ f"\n\n[tool.uv]\noverride-dependencies = [{quoted_override}]\n"
)
pyproject_path.write_text(text)
return

body = tool_uv_match.group("body")
override_match = re.search(
r"(?ms)^override-dependencies\s*=\s*\[(?P<items>.*?)\]\s*",
body,
)
if override_match:
items = override_match.group("items").strip()
if quoted_override in items:
return

if items:
replacement = f"override-dependencies = [{items}, {quoted_override}]\n"
else:
replacement = f"override-dependencies = [{quoted_override}]\n"

body = (
body[: override_match.start()] + replacement + body[override_match.end() :]
)
else:
body = f"override-dependencies = [{quoted_override}]\n" + body

text = (
text[: tool_uv_match.start("body")] + body + text[tool_uv_match.end("body") :]
)
pyproject_path.write_text(text)


def main() -> None:
"""Add a local runtime wheel override to a pyproject and print the wheel path."""
if len(sys.argv) != 3:
print(
"usage: force-runtime-override.py <pyproject.toml> <runtime-wheel-dir>",
file=sys.stderr,
)
raise SystemExit(2)

pyproject_path = Path(sys.argv[1])
wheel_dir = Path(sys.argv[2])
wheels = sorted(wheel_dir.glob("uipath_runtime-*.whl"))
if not wheels:
print(f"no uipath-runtime wheel found in {wheel_dir}", file=sys.stderr)
raise SystemExit(1)
if len(wheels) > 1:
wheel_names = ", ".join(str(wheel) for wheel in wheels)
print(
f"expected one uipath-runtime wheel in {wheel_dir}, found: {wheel_names}",
file=sys.stderr,
)
raise SystemExit(1)

wheel = wheels[0].resolve()

_add_override(pyproject_path, f"uipath-runtime @ {wheel.as_uri()}")
print(wheel)


if __name__ == "__main__":
main()
14 changes: 10 additions & 4 deletions .github/workflows/test-uipath-langchain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-langchain-python
run: uv add ../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Run uipath-langchain tests
working-directory: uipath-langchain-python
Expand Down Expand Up @@ -89,7 +91,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-langchain-python
run: uv add ../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Run typecheck
working-directory: uipath-langchain-python
Expand Down Expand Up @@ -163,7 +167,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-langchain-python
run: uv add ../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Install dependencies
working-directory: uipath-langchain-python
Expand All @@ -182,8 +188,8 @@ jobs:
echo "Environment: ${{ matrix.environment }}"
echo "LLM: ${{ matrix.use_azure_chat && 'UiPathAzureChatOpenAI' || 'UiPathChat' }}"
echo "USE_AZURE_CHAT: ${{ matrix.use_azure_chat }}"
python ../../../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../../../uipath-runtime-python/dist

# Execute the testcase run script directly
bash run.sh
bash ../common/validate_output.sh

14 changes: 10 additions & 4 deletions .github/workflows/test-uipath.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-python/packages/uipath
run: uv add ../../../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../../../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../../../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Run uipath tests
working-directory: uipath-python/packages/uipath
Expand Down Expand Up @@ -89,7 +91,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-python/packages/uipath
run: uv add ../../../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../../../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../../../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Run typecheck
working-directory: uipath-python/packages/uipath
Expand Down Expand Up @@ -162,7 +166,9 @@ jobs:
- name: Update uipath-runtime version
shell: bash
working-directory: uipath-python/packages/uipath
run: uv add ../../../uipath-runtime-python/dist/*.whl --dev
run: |
runtime_wheel="$(python ../../../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../../../uipath-runtime-python/dist)"
uv add "$runtime_wheel" --dev

- name: Install dependencies
working-directory: uipath-python/packages/uipath
Expand All @@ -179,8 +185,8 @@ jobs:
run: |
echo "Running testcase: ${{ matrix.testcase }}"
echo "Environment: ${{ matrix.environment }}"
python ../../../../../uipath-runtime-python/.github/scripts/force-runtime-override.py pyproject.toml ../../../../../uipath-runtime-python/dist

# Execute the testcase run script directly
bash run.sh
bash ../common/validate_output.sh

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[project]
name = "uipath-runtime"
version = "0.11.5"
version = "0.12.0"
description = "Runtime abstractions and interfaces for building agents and automation scripts in the UiPath ecosystem"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
dependencies = [
"uipath-core>=0.5.26,<0.6.0",
"uipath-core>=0.5.27,<0.6.0",
]
classifiers = [
"Intended Audience :: Developers",
Expand Down
41 changes: 40 additions & 1 deletion src/uipath/runtime/resumable/protocols.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Module defining the protocol for resume trigger storage."""

import warnings
from typing import Any, Protocol

from uipath.core.triggers import UiPathResumeTrigger
Expand Down Expand Up @@ -34,6 +35,21 @@
"""
...

async def delete_triggers(
self, runtime_id: str, triggers: list[UiPathResumeTrigger]
) -> None:
"""Delete resume triggers from storage.

Args:
runtime_id: The runtime ID
triggers: The resume triggers to delete

Raises:
Exception: If deletion operation fails
"""
for trigger in triggers:
await self.delete_trigger(runtime_id, trigger)

async def delete_trigger(
self, runtime_id: str, trigger: UiPathResumeTrigger
) -> None:
Expand All @@ -46,7 +62,13 @@
Raises:
Exception: If deletion operation fails
"""
...
warnings.warn(
"delete_trigger() is deprecated; use delete_triggers() instead.",
DeprecationWarning,
stacklevel=2,
)
# TODO: Remove this compatibility alias in the next minor version.

Check warning on line 70 in src/uipath/runtime/resumable/protocols.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-runtime-python&issues=AZ8Ysv4Q5Nj1gAX0VWKK&open=AZ8Ysv4Q5Nj1gAX0VWKK&pullRequest=138
await self.delete_triggers(runtime_id, [trigger])


class UiPathResumeTriggerCreatorProtocol(Protocol):
Expand All @@ -68,6 +90,23 @@
"""
...

async def create_triggers(self, suspend_value: Any) -> list[UiPathResumeTrigger]:
"""Create resume triggers from a suspend value.

Most suspend values produce one trigger. Composite values may produce
multiple sibling triggers for the same interrupt.

Args:
suspend_value: The value that caused the suspension.

Returns:
UiPathResumeTrigger objects ready to be persisted.

Raises:
UiPathRuntimeError: If trigger creation fails
"""
return [await self.create_trigger(suspend_value)]


class UiPathResumeTriggerReaderProtocol(Protocol):
"""Protocol for reading resume triggers and converting them to runtime input."""
Expand Down
Loading
Loading