2727 UiPathErrorCategory ,
2828 UiPathErrorCode ,
2929)
30- from uipath .runtime .events import UiPathRuntimeStateEvent
3130
3231from .._utils ._config import McpServer
3332from ._context import UiPathServerType
@@ -153,85 +152,23 @@ async def stream(
153152 input : dict [str , Any ] | None = None ,
154153 options : UiPathStreamOptions | None = None ,
155154 ) -> AsyncGenerator [UiPathRuntimeEvent , None ]:
156- """Stream execution events from MCP server runtime in real-time .
155+ """Stream execution for MCP server runtime.
157156
158- Yields state events at key lifecycle points (initialization, registration,
159- connection, sessions) and finally yields the runtime result.
160-
161- Args:
162- input: Optional input dictionary (unused for MCP servers).
163- options: Optional stream options.
164-
165- Yields:
166- UiPathRuntimeStateEvent: State updates during server lifecycle.
167- UiPathRuntimeResult: Final result when server stops.
168-
169- Raises:
170- UiPathMcpRuntimeError: If execution fails.
157+ MCP servers don't emit intermediate events, so this just yields the final result.
171158 """
172- # Queue for real-time event streaming
173- # None is used as sentinel to signal completion
174- event_queue : asyncio .Queue [UiPathRuntimeEvent | None ] = asyncio .Queue ()
175- run_exception : list [Exception ] = []
176-
177- async def run_with_queue () -> None :
178- try :
179- result = await self ._run_server (event_queue = event_queue )
180- await event_queue .put (result )
181- except Exception as e :
182- run_exception .append (e )
183- finally :
184- await event_queue .put (None ) # Signal completion
185-
186- # Start the server task
187- run_task = asyncio .create_task (run_with_queue ())
188-
189- try :
190- # Consume events from queue in real-time
191- while True :
192- event = await event_queue .get ()
193- if event is None :
194- break
195- yield event
196- finally :
197- # Ensure the run task is properly awaited
198- if not run_task .done ():
199- run_task .cancel ()
200- try :
201- await run_task
202- except asyncio .CancelledError :
203- pass
159+ result = await self ._run_server ()
160+ yield result
204161
205- # Re-raise any exception from the run task
206- if run_exception :
207- raise run_exception [0 ]
208-
209- async def _run_server (
210- self ,
211- event_queue : asyncio .Queue [UiPathRuntimeEvent | None ] | None = None ,
212- ) -> UiPathRuntimeResult :
162+ async def _run_server (self ) -> UiPathRuntimeResult :
213163 """Core server execution logic.
214164
215- Args:
216- event_queue: Optional queue to push state events for real-time streaming.
217-
218165 Returns:
219166 UiPathRuntimeResult with execution results.
220167
221168 Raises:
222169 UiPathMcpRuntimeError: If execution fails.
223170 """
224-
225- async def emit_state (node_name : str , payload : dict [str , Any ]) -> None :
226- if event_queue :
227- event = UiPathRuntimeStateEvent (
228- payload = payload ,
229- node_name = node_name ,
230- )
231- await event_queue .put (event )
232-
233171 try :
234- await emit_state ("initializing" , {"status" : "validating_auth" })
235172
236173 # Validate authentication configuration
237174 self ._validate_auth ()
@@ -262,11 +199,6 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
262199
263200 logger .info (f"Folder key: { self ._folder_key } " )
264201
265- await emit_state (
266- "initializing" ,
267- {"status" : "folder_resolved" , "folder_key" : self ._folder_key },
268- )
269-
270202 with tracer .start_as_current_span (self .slug ) as root_span :
271203 root_span .set_attribute ("runtime_id" , self ._runtime_id )
272204 root_span .set_attribute ("command" , str (self ._server .command ))
@@ -290,26 +222,13 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
290222 self ._signalr_client .on_open (self ._handle_signalr_open )
291223 self ._signalr_client .on_close (self ._handle_signalr_close )
292224
293- await emit_state ("registering" , {"status" : "registering_server" })
294-
295225 # Register the local server with UiPath MCP Server
296226 await self ._register ()
297227
298- await emit_state (
299- "registered" ,
300- {
301- "status" : "server_registered" ,
302- "slug" : self .slug ,
303- "server_type" : self .server_type .value ,
304- },
305- )
306-
307228 run_task = asyncio .create_task (self ._signalr_client .run ())
308229 cancel_task = asyncio .create_task (self ._cancel_event .wait ())
309230 self ._keep_alive_task = asyncio .create_task (self ._keep_alive ())
310231
311- await emit_state ("running" , {"status" : "server_running" })
312-
313232 try :
314233 # Wait for either the run to complete or cancellation
315234 done , pending = await asyncio .wait (
@@ -334,8 +253,6 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
334253 if self ._session_output :
335254 output_result ["content" ] = self ._session_output
336255
337- await emit_state ("completed" , {"status" : "server_stopped" })
338-
339256 return UiPathRuntimeResult (
340257 output = output_result ,
341258 status = UiPathRuntimeStatus .SUCCESSFUL ,
0 commit comments