@@ -147,6 +147,7 @@ async def test_invoke_calls_processes_invoke_async(
147147 attachments = [],
148148 parent_span_id = None ,
149149 parent_operation_id = None ,
150+ run_as_me = None ,
150151 )
151152
152153 @pytest .mark .asyncio
@@ -358,3 +359,97 @@ async def test_span_context_defaults_to_none_when_empty(
358359
359360 call_kwargs = mock_client .processes .invoke_async .call_args [1 ]
360361 assert call_kwargs ["parent_span_id" ] is None
362+
363+
364+ class TestProcessToolRunAsMe :
365+ """Test RunAsMe propagation passed top-down from tool factory."""
366+
367+ @pytest .mark .asyncio
368+ @patch ("uipath_langchain._utils.durable_interrupt.decorator.interrupt" )
369+ @patch ("uipath_langchain.agent.tools.process_tool.UiPath" )
370+ async def test_run_as_me_true_passed_to_invoke (
371+ self ,
372+ mock_uipath_class ,
373+ mock_interrupt ,
374+ process_resource ,
375+ ):
376+ """Test RunAsMe=True is forwarded to invoke_async when set."""
377+ mock_job = MagicMock (spec = Job )
378+ mock_job .key = "job-key"
379+ mock_job .folder_key = "folder-key"
380+
381+ mock_resumed_job = MagicMock (spec = Job )
382+ mock_resumed_job .state = "successful"
383+
384+ mock_client = MagicMock ()
385+ mock_client .processes .invoke_async = AsyncMock (return_value = mock_job )
386+ mock_client .jobs .extract_output_async = AsyncMock (return_value = None )
387+ mock_uipath_class .return_value = mock_client
388+
389+ mock_interrupt .return_value = mock_resumed_job
390+
391+ tool = create_process_tool (process_resource , run_as_me = True )
392+ await tool .ainvoke ({})
393+
394+ call_kwargs = mock_client .processes .invoke_async .call_args [1 ]
395+ assert call_kwargs ["run_as_me" ] is True
396+
397+ @pytest .mark .asyncio
398+ @patch ("uipath_langchain._utils.durable_interrupt.decorator.interrupt" )
399+ @patch ("uipath_langchain.agent.tools.process_tool.UiPath" )
400+ async def test_run_as_me_false_sends_none (
401+ self ,
402+ mock_uipath_class ,
403+ mock_interrupt ,
404+ process_resource ,
405+ ):
406+ """Test RunAsMe=None when run_as_me=False (default)."""
407+ mock_job = MagicMock (spec = Job )
408+ mock_job .key = "job-key"
409+ mock_job .folder_key = "folder-key"
410+
411+ mock_resumed_job = MagicMock (spec = Job )
412+ mock_resumed_job .state = "successful"
413+
414+ mock_client = MagicMock ()
415+ mock_client .processes .invoke_async = AsyncMock (return_value = mock_job )
416+ mock_client .jobs .extract_output_async = AsyncMock (return_value = None )
417+ mock_uipath_class .return_value = mock_client
418+
419+ mock_interrupt .return_value = mock_resumed_job
420+
421+ tool = create_process_tool (process_resource , run_as_me = False )
422+ await tool .ainvoke ({})
423+
424+ call_kwargs = mock_client .processes .invoke_async .call_args [1 ]
425+ assert call_kwargs ["run_as_me" ] is None
426+
427+ @pytest .mark .asyncio
428+ @patch ("uipath_langchain._utils.durable_interrupt.decorator.interrupt" )
429+ @patch ("uipath_langchain.agent.tools.process_tool.UiPath" )
430+ async def test_run_as_me_default_sends_none (
431+ self ,
432+ mock_uipath_class ,
433+ mock_interrupt ,
434+ process_resource ,
435+ ):
436+ """Test RunAsMe=None when run_as_me not specified (default)."""
437+ mock_job = MagicMock (spec = Job )
438+ mock_job .key = "job-key"
439+ mock_job .folder_key = "folder-key"
440+
441+ mock_resumed_job = MagicMock (spec = Job )
442+ mock_resumed_job .state = "successful"
443+
444+ mock_client = MagicMock ()
445+ mock_client .processes .invoke_async = AsyncMock (return_value = mock_job )
446+ mock_client .jobs .extract_output_async = AsyncMock (return_value = None )
447+ mock_uipath_class .return_value = mock_client
448+
449+ mock_interrupt .return_value = mock_resumed_job
450+
451+ tool = create_process_tool (process_resource )
452+ await tool .ainvoke ({})
453+
454+ call_kwargs = mock_client .processes .invoke_async .call_args [1 ]
455+ assert call_kwargs ["run_as_me" ] is None
0 commit comments