Skip to content

Commit 8ea31ee

Browse files
committed
fix: local debug with resumable runtimes
1 parent 85f82fc commit 8ea31ee

File tree

4 files changed

+28
-10
lines changed

4 files changed

+28
-10
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-runtime"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
description = "Runtime abstractions and interfaces for building agents and automation scripts in the UiPath ecosystem"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

src/uipath/runtime/debug/runtime.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,21 +187,23 @@ async def _stream_and_debug(
187187
await self.debug_bridge.emit_execution_suspended(
188188
final_result
189189
)
190-
190+
interrupt_id = final_result.trigger.interrupt_id
191191
resume_data: dict[str, Any] | None = None
192192
try:
193+
trigger_data: dict[str, Any] | None = None
193194
if (
194195
final_result.trigger.trigger_type
195196
== UiPathResumeTriggerType.API
196197
):
197-
resume_data = (
198+
trigger_data = (
198199
await self.debug_bridge.wait_for_resume()
199200
)
200201
else:
201-
resume_data = await self._poll_trigger(
202+
trigger_data = await self._poll_trigger(
202203
final_result.trigger,
203204
self.delegate.trigger_manager,
204205
)
206+
resume_data = {interrupt_id: trigger_data}
205207
except UiPathDebugQuitError:
206208
final_result = UiPathRuntimeResult(
207209
status=UiPathRuntimeStatus.SUCCESSFUL,

src/uipath/runtime/resumable/runtime.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,30 @@ async def _restore_resume_input(
115115
Returns:
116116
Input to use for resume: {interrupt_id: resume_data, ...}
117117
"""
118+
# Fetch all triggers from storage
119+
triggers = await self.storage.get_triggers(self.runtime_id)
120+
118121
# If user provided explicit input, use it
119122
if input is not None:
123+
if triggers:
124+
if len(triggers) == 1:
125+
# Single trigger - just delete it
126+
await self.storage.delete_trigger(self.runtime_id, triggers[0])
127+
else:
128+
# Multiple triggers - match by interrupt_id
129+
found = False
130+
for trigger in triggers:
131+
if trigger.interrupt_id in input:
132+
await self.storage.delete_trigger(self.runtime_id, trigger)
133+
found = True
134+
if not found:
135+
logger.warning(
136+
f"Multiple triggers detected but none match the provided input. "
137+
f"Please specify which trigger to resume by {{interrupt_id: value}}. "
138+
f"Available interrupt_ids: {[t.interrupt_id for t in triggers]}, "
139+
)
120140
return input
121141

122-
# Fetch all triggers from storage
123-
triggers = await self.storage.get_triggers(self.runtime_id)
124142
if not triggers:
125143
return None
126144

@@ -184,9 +202,7 @@ async def _handle_suspension(
184202

185203
if suspended_result.triggers:
186204
await self.storage.save_triggers(self.runtime_id, suspended_result.triggers)
187-
188-
# Backward compatibility: set single trigger directly
189-
if len(suspended_result.triggers) == 1:
205+
# Backward compatibility: set single trigger directly
190206
suspended_result.trigger = suspended_result.triggers[0]
191207

192208
return suspended_result

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)