11"""Debug runtime implementation."""
22
33import logging
4- from typing import Any , Generic , TypeVar
4+ from typing import Any , AsyncGenerator , Generic , TypeVar
55
66from uipath .runtime import (
77 UiPathBaseRuntime ,
88 UiPathBreakpointResult ,
99 UiPathRuntimeContext ,
10+ UiPathRuntimeEvent ,
1011 UiPathRuntimeResult ,
1112 UiPathRuntimeStatus ,
1213 UiPathStreamNotSupportedError ,
@@ -46,7 +47,7 @@ async def execute(self, input: dict[str, Any]) -> UiPathRuntimeResult:
4647 result : UiPathRuntimeResult
4748 # Try to stream events from inner runtime
4849 try :
49- result = await self ._stream_and_debug (self . delegate , input )
50+ result = await self ._stream_and_debug (input )
5051 except UiPathStreamNotSupportedError :
5152 # Fallback to regular execute if streaming not supported
5253 logger .debug (
@@ -71,9 +72,38 @@ async def execute(self, input: dict[str, Any]) -> UiPathRuntimeResult:
7172 )
7273 raise
7374
74- async def _stream_and_debug (
75- self , inner_runtime : T , input : dict [str , Any ]
76- ) -> UiPathRuntimeResult :
75+ async def stream (
76+ self ,
77+ input : dict [str , Any ],
78+ ) -> AsyncGenerator [UiPathRuntimeEvent , None ]:
79+ """Stream events from inner runtime and handle debug interactions."""
80+ async for event in self .delegate .stream (input ):
81+ if isinstance (event , UiPathRuntimeStateEvent ):
82+ # Move these to constructor and remove from context
83+ if self .context :
84+ breakpoints = self .context .breakpoints
85+ else :
86+ breakpoints = None
87+ hit_breakpoint = False
88+
89+ if breakpoints == "*" :
90+ hit_breakpoint = True
91+ elif isinstance (breakpoints , list ) and event .node_name in breakpoints :
92+ hit_breakpoint = True
93+
94+ if hit_breakpoint :
95+ yield UiPathBreakpointResult (
96+ breakpoint_node = event .node_name ,
97+ breakpoint_type = "before" ,
98+ next_nodes = event .next_nodes ,
99+ current_state = {"node" : event .node_name },
100+ )
101+ else :
102+ yield event
103+ else :
104+ yield event
105+
106+ async def _stream_and_debug (self , input : dict [str , Any ]) -> UiPathRuntimeResult :
77107 """Stream events from inner runtime and handle debug interactions."""
78108 final_result : UiPathRuntimeResult
79109 execution_completed = False
@@ -84,10 +114,10 @@ async def _stream_and_debug(
84114 # Keep streaming until execution completes (not just paused at breakpoint)
85115 while not execution_completed :
86116 # Update breakpoints from debug bridge
87- if inner_runtime .context is not None :
88- inner_runtime .context .breakpoints = self .debug_bridge .get_breakpoints ()
117+ if self . delegate .context is not None :
118+ self . delegate .context .breakpoints = self .debug_bridge .get_breakpoints ()
89119 # Stream events from inner runtime
90- async for event in inner_runtime .stream (input ):
120+ async for event in self .stream (input ):
91121 # Handle final result
92122 if isinstance (event , UiPathRuntimeResult ):
93123 final_result = event
@@ -99,8 +129,8 @@ async def _stream_and_debug(
99129 await self .debug_bridge .emit_breakpoint_hit (event )
100130 await self .debug_bridge .wait_for_resume ()
101131
102- if inner_runtime .context is not None :
103- inner_runtime .context .resume = True
132+ if self . delegate .context is not None :
133+ self . delegate .context .resume = True
104134
105135 except UiPathDebugQuitError :
106136 final_result = UiPathRuntimeResult (
0 commit comments