diff --git a/pyproject.toml b/pyproject.toml index 1da4e28..a8a6bae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-runtime" -version = "0.0.22" +version = "0.0.23" 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" diff --git a/src/uipath/runtime/result.py b/src/uipath/runtime/result.py index 333c1b2..e46e768 100644 --- a/src/uipath/runtime/result.py +++ b/src/uipath/runtime/result.py @@ -21,7 +21,7 @@ class UiPathRuntimeStatus(str, Enum): class UiPathRuntimeResult(UiPathRuntimeEvent): """Result of an execution with status and optional error information.""" - output: dict[str, Any] | BaseModel | None = None + output: dict[str, Any] | BaseModel | str | None = None status: UiPathRuntimeStatus = UiPathRuntimeStatus.SUCCESSFUL trigger: UiPathResumeTrigger | None = None error: UiPathErrorContract | None = None @@ -32,6 +32,7 @@ class UiPathRuntimeResult(UiPathRuntimeEvent): def to_dict(self) -> dict[str, Any]: """Convert to dictionary format for output.""" + output_data: dict[str, Any] | str if self.output is None: output_data = {} elif isinstance(self.output, BaseModel): diff --git a/src/uipath/runtime/resumable/runtime.py b/src/uipath/runtime/resumable/runtime.py index be4b8b1..b2a0809 100644 --- a/src/uipath/runtime/resumable/runtime.py +++ b/src/uipath/runtime/resumable/runtime.py @@ -68,9 +68,7 @@ async def execute( result = await self.delegate.execute(input, options=options) # If suspended, create and persist trigger - await self._handle_suspension(result) - - return result + return await self._handle_suspension(result) async def stream( self, @@ -90,18 +88,16 @@ async def stream( if options and options.resume: input = await self._restore_resume_input(input) - # Stream from delegate final_result: UiPathRuntimeResult | None = None async for event in self.delegate.stream(input, options=options): - yield event - - # Capture final result if isinstance(event, UiPathRuntimeResult): final_result = event + else: + yield event # If suspended, create and persist trigger if final_result: - await self._handle_suspension(final_result) + yield await self._handle_suspension(final_result) async def _restore_resume_input( self, input: dict[str, Any] | None @@ -128,7 +124,9 @@ async def _restore_resume_input( return resume_data - async def _handle_suspension(self, result: UiPathRuntimeResult) -> None: + async def _handle_suspension( + self, result: UiPathRuntimeResult + ) -> UiPathRuntimeResult: """Create and persist resume trigger if execution was suspended. Args: @@ -136,19 +134,25 @@ async def _handle_suspension(self, result: UiPathRuntimeResult) -> None: """ # Only handle suspensions if result.status != UiPathRuntimeStatus.SUSPENDED: - return + return result # Check if trigger already exists in result if result.trigger: await self.storage.save_trigger(result.trigger) - return + return result + + suspended_result = UiPathRuntimeResult( + status=UiPathRuntimeStatus.SUSPENDED, + ) if result.output: - trigger = await self.trigger_manager.create_trigger(result.output) + suspended_result.trigger = await self.trigger_manager.create_trigger( + result.output + ) - result.trigger = trigger + await self.storage.save_trigger(suspended_result.trigger) - await self.storage.save_trigger(trigger) + return suspended_result async def get_schema(self) -> UiPathRuntimeSchema: """Passthrough schema from delegate runtime.""" diff --git a/uv.lock b/uv.lock index 0f5288e..5fd19ed 100644 --- a/uv.lock +++ b/uv.lock @@ -938,7 +938,7 @@ wheels = [ [[package]] name = "uipath-runtime" -version = "0.0.22" +version = "0.0.23" source = { editable = "." } dependencies = [ { name = "uipath-core" },