feat: add suspend/resume support for RPA invocations in evaluations #1083
+254
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implements the suspend/resume pattern for RPA process invocations within the evaluation runtime. When a LangGraph agent calls
interrupt(InvokeProcess(...)), the runtime now correctly:This enables evaluations to pause while waiting for external RPA jobs to complete, then resume with the job results.
Architecture
Flow Overview
```
Agent Execution → LangGraph interrupt() → Functions Runtime Detection
↓
Create UiPathResumeTrigger
↓
Return SUSPENDED status
↓
Evaluation Runtime (skip evaluators)
↓
Publish suspended event to bus
↓
Serverless Executor (poll job)
↓
Resume with job results
```
Key Components
1. Functions Runtime (
src/uipath/functions/runtime.py)_detect_langgraph_interrupt()__interrupt__field in agent outputInvokeProcessobject from interruptUiPathResumeTriggerwith job metadataexecute()to check interrupts and return SUSPENDED status2. Evaluation Runtime (
src/uipath/_cli/_evals/_runtime.py)agentExecutionOutputwith trigger dataEvalRunUpdatedEventwith suspended state3. Test Agent (
samples/event-trigger/test_suspend_resume_agent.py)MemorySavercheckpointer (required for interrupts)__interrupt__fieldChanges Made
Files Modified
src/uipath/functions/runtime.pysrc/uipath/_cli/_evals/_runtime.pysamples/event-trigger/test_suspend_resume_agent.pyDetailed Changes
Functions Runtime
Evaluation Runtime
Testing Instructions
Prerequisites
Test 1: Direct Runtime Execution
Test the functions runtime directly to verify interrupt detection:
Expected Output:
Test 2: Evaluation Runtime
Test the complete evaluation flow:
Expected JSON Structure:
{ "evaluationSetName": "Suspend Resume Test", "evaluationSetResults": [{ "evaluationName": "Basic suspend test", "evaluationRunResults": [], "agentExecutionOutput": { "result": { "status": "suspended", "trigger": { "trigger_type": "JOB", "item_key": "job-<uuid>", "folder_path": "Shared", "payload": { "process_name": "TestProcess", "input_arguments": {...} } } } } }] }Test 3: Check Logs
Verify proper logging throughout the flow:
Expected Log Messages:
Detected LangGraph interrupt - suspending execution for process: TestProcessEvaluation execution suspended for eval 'Basic suspend test'SUSPENDEDVerification Checklist
Before approving this PR, verify:
__interrupt__fieldSUSPENDEDstatus with proper triggeragentExecutionOutputis populated in JSON outputIntegration with Serverless Executor
The serverless executor (external component) will:
SUSPENDEDstatus fromagentExecutionOutputThis PR provides the agent-side infrastructure. The serverless executor changes are separate.
Related Work
UiPathResumableRuntimeimplementationTechnical Notes
Why Check for
__interrupt__Field?LangGraph's
interrupt()function only creates the__interrupt__field when:MemorySaver)Our runtime must detect this field to distinguish suspended executions from normal completions.
Why Skip Evaluators?
When an evaluation suspends:
Why Populate agentExecutionOutput?
The serverless executor needs to:
Without
agentExecutionOutput, the executor wouldn't know how to resume the evaluation.Next Steps
After merging this PR:
Dev Tag
This PR introduces new functionality that needs testing before release. Tag:
v2.5.0-dev.suspend-resume