diff --git a/pyproject.toml b/pyproject.toml index 98c7dff..c5cc7e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-runtime" -version = "0.3.1" +version = "0.3.2" 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/debug/runtime.py b/src/uipath/runtime/debug/runtime.py index b621c6d..b671645 100644 --- a/src/uipath/runtime/debug/runtime.py +++ b/src/uipath/runtime/debug/runtime.py @@ -188,20 +188,25 @@ async def _stream_and_debug( final_result ) + interrupt_id = final_result.trigger.interrupt_id + assert interrupt_id is not None + resume_data: dict[str, Any] | None = None try: + trigger_data: dict[str, Any] | None = None if ( final_result.trigger.trigger_type == UiPathResumeTriggerType.API ): - resume_data = ( + trigger_data = ( await self.debug_bridge.wait_for_resume() ) else: - resume_data = await self._poll_trigger( + trigger_data = await self._poll_trigger( final_result.trigger, self.delegate.trigger_manager, ) + resume_data = {interrupt_id: trigger_data} except UiPathDebugQuitError: final_result = UiPathRuntimeResult( status=UiPathRuntimeStatus.SUCCESSFUL, diff --git a/src/uipath/runtime/resumable/runtime.py b/src/uipath/runtime/resumable/runtime.py index d12b93c..d94e7e2 100644 --- a/src/uipath/runtime/resumable/runtime.py +++ b/src/uipath/runtime/resumable/runtime.py @@ -115,12 +115,30 @@ async def _restore_resume_input( Returns: Input to use for resume: {interrupt_id: resume_data, ...} """ + # Fetch all triggers from storage + triggers = await self.storage.get_triggers(self.runtime_id) + # If user provided explicit input, use it if input is not None: + if triggers: + if len(triggers) == 1: + # Single trigger - just delete it + await self.storage.delete_trigger(self.runtime_id, triggers[0]) + else: + # Multiple triggers - match by interrupt_id + found = False + for trigger in triggers: + if trigger.interrupt_id in input: + await self.storage.delete_trigger(self.runtime_id, trigger) + found = True + if not found: + logger.warning( + f"Multiple triggers detected but none match the provided input. " + f"Please specify which trigger to resume by {{interrupt_id: value}}. " + f"Available interrupt_ids: {[t.interrupt_id for t in triggers]}." + ) return input - # Fetch all triggers from storage - triggers = await self.storage.get_triggers(self.runtime_id) if not triggers: return None @@ -184,9 +202,7 @@ async def _handle_suspension( if suspended_result.triggers: await self.storage.save_triggers(self.runtime_id, suspended_result.triggers) - - # Backward compatibility: set single trigger directly - if len(suspended_result.triggers) == 1: + # Backward compatibility: set single trigger directly suspended_result.trigger = suspended_result.triggers[0] return suspended_result diff --git a/uv.lock b/uv.lock index d2cdd92..1a20a4d 100644 --- a/uv.lock +++ b/uv.lock @@ -1005,7 +1005,7 @@ wheels = [ [[package]] name = "uipath-runtime" -version = "0.3.1" +version = "0.3.2" source = { editable = "." } dependencies = [ { name = "uipath-core" },