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
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

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath-runtime"
version = "0.11.8"
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"
Expand Down
47 changes: 46 additions & 1 deletion src/uipath/runtime/resumable/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from uipath.core.triggers import UiPathResumeTrigger

from uipath.runtime.errors import UiPathRuntimeError
from uipath.runtime.errors.codes import UiPathErrorCode
from uipath.runtime.storage import UiPathRuntimeStorageProtocol


Expand Down Expand Up @@ -34,6 +36,20 @@
"""
...

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
"""
...

async def delete_trigger(
self, runtime_id: str, trigger: UiPathResumeTrigger
) -> None:
Expand All @@ -46,7 +62,8 @@
Raises:
Exception: If deletion operation fails
"""
...
# TODO: Remove this compatibility alias in the next minor version.

Check warning on line 65 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 @@ -63,6 +80,34 @@
Returns:
UiPathResumeTrigger ready to be persisted

Raises:
UiPathRuntimeError: If trigger creation fails
"""
# TODO: Remove this compatibility alias in the next minor version.

Check warning on line 86 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=AZ82K3xfyomRfTbE-kbr&open=AZ82K3xfyomRfTbE-kbr&pullRequest=138
triggers = await self.create_triggers(suspend_value)
if len(triggers) != 1:
raise UiPathRuntimeError(
code=UiPathErrorCode.CREATE_RESUME_TRIGGER_ERROR,
title="Unexpected resume trigger count",
detail=(
"create_trigger() cannot return multiple resume triggers. "
"Use create_triggers() instead."
),
)
return triggers[0]

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
"""
Expand Down
Loading
Loading