Skip to content

Commit 9fe38e1

Browse files
authored
Merge pull request #59 from UiPath/fix/resumable_debug
fix: local debug with resumable runtimes
2 parents 85f82fc + f251573 commit 9fe38e1

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
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: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,20 +188,25 @@ async def _stream_and_debug(
188188
final_result
189189
)
190190

191+
interrupt_id = final_result.trigger.interrupt_id
192+
assert interrupt_id is not None
193+
191194
resume_data: dict[str, Any] | None = None
192195
try:
196+
trigger_data: dict[str, Any] | None = None
193197
if (
194198
final_result.trigger.trigger_type
195199
== UiPathResumeTriggerType.API
196200
):
197-
resume_data = (
201+
trigger_data = (
198202
await self.debug_bridge.wait_for_resume()
199203
)
200204
else:
201-
resume_data = await self._poll_trigger(
205+
trigger_data = await self._poll_trigger(
202206
final_result.trigger,
203207
self.delegate.trigger_manager,
204208
)
209+
resume_data = {interrupt_id: trigger_data}
205210
except UiPathDebugQuitError:
206211
final_result = UiPathRuntimeResult(
207212
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)