2727 UiPathErrorCategory ,
2828 UiPathErrorCode ,
2929)
30- from uipath .runtime .events import UiPathRuntimeStateEvent
3130
3231from .._utils ._config import McpServer
3332from ._context import UiPathServerType
@@ -153,86 +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
204-
205- # Re-raise any exception from the run task
206- if run_exception :
207- raise run_exception [0 ]
159+ result = await self ._run_server ()
160+ yield result
208161
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" })
235-
236172 # Validate authentication configuration
237173 self ._validate_auth ()
238174
@@ -262,11 +198,6 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
262198
263199 logger .info (f"Folder key: { self ._folder_key } " )
264200
265- await emit_state (
266- "initializing" ,
267- {"status" : "folder_resolved" , "folder_key" : self ._folder_key },
268- )
269-
270201 with tracer .start_as_current_span (self .slug ) as root_span :
271202 root_span .set_attribute ("runtime_id" , self ._runtime_id )
272203 root_span .set_attribute ("command" , str (self ._server .command ))
@@ -290,26 +221,13 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
290221 self ._signalr_client .on_open (self ._handle_signalr_open )
291222 self ._signalr_client .on_close (self ._handle_signalr_close )
292223
293- await emit_state ("registering" , {"status" : "registering_server" })
294-
295224 # Register the local server with UiPath MCP Server
296225 await self ._register ()
297226
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-
307227 run_task = asyncio .create_task (self ._signalr_client .run ())
308228 cancel_task = asyncio .create_task (self ._cancel_event .wait ())
309229 self ._keep_alive_task = asyncio .create_task (self ._keep_alive ())
310230
311- await emit_state ("running" , {"status" : "server_running" })
312-
313231 try :
314232 # Wait for either the run to complete or cancellation
315233 done , pending = await asyncio .wait (
@@ -334,8 +252,6 @@ async def emit_state(node_name: str, payload: dict[str, Any]) -> None:
334252 if self ._session_output :
335253 output_result ["content" ] = self ._session_output
336254
337- await emit_state ("completed" , {"status" : "server_stopped" })
338-
339255 return UiPathRuntimeResult (
340256 output = output_result ,
341257 status = UiPathRuntimeStatus .SUCCESSFUL ,
0 commit comments