Skip to content

Commit 2a557c8

Browse files
authored
Merge pull request #1066 from UiPath/fix/eval-sequential-runtime-isolation
fix: create isolated runtime per eval execution
2 parents 6c12b8e + bedb6d9 commit 2a557c8

3 files changed

Lines changed: 43 additions & 30 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath"
3-
version = "2.4.2"
3+
version = "2.4.3"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

src/uipath/_cli/_evals/_runtime.py

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -613,42 +613,55 @@ async def execute_runtime(
613613
"evalId": eval_item.id,
614614
"span_type": "eval",
615615
}
616-
execution_runtime = UiPathExecutionRuntime(
617-
delegate=runtime,
618-
trace_manager=self.trace_manager,
619-
log_handler=log_handler,
620-
execution_id=execution_id,
621-
span_attributes=attributes,
622-
)
623616

624-
start_time = time()
617+
# Create a new runtime with unique runtime_id for this eval execution.
618+
# This ensures each eval has its own LangGraph thread_id (clean state),
619+
# preventing message accumulation across eval runs.
620+
eval_runtime = None
625621
try:
626-
result = await execution_runtime.execute(
627-
input=eval_item.inputs,
622+
eval_runtime = await self.factory.new_runtime(
623+
entrypoint=self.context.entrypoint or "",
624+
runtime_id=execution_id,
628625
)
629-
except Exception as e:
626+
execution_runtime = UiPathExecutionRuntime(
627+
delegate=eval_runtime,
628+
trace_manager=self.trace_manager,
629+
log_handler=log_handler,
630+
execution_id=execution_id,
631+
span_attributes=attributes,
632+
)
633+
634+
start_time = time()
635+
try:
636+
result = await execution_runtime.execute(
637+
input=eval_item.inputs,
638+
)
639+
except Exception as e:
640+
end_time = time()
641+
spans, logs = self._get_and_clear_execution_data(execution_id)
642+
643+
raise EvaluationRuntimeException(
644+
spans=spans,
645+
logs=logs,
646+
root_exception=e,
647+
execution_time=end_time - start_time,
648+
) from e
649+
630650
end_time = time()
631651
spans, logs = self._get_and_clear_execution_data(execution_id)
632652

633-
raise EvaluationRuntimeException(
653+
if result is None:
654+
raise ValueError("Execution result cannot be None for eval runs")
655+
656+
return UiPathEvalRunExecutionOutput(
657+
execution_time=end_time - start_time,
634658
spans=spans,
635659
logs=logs,
636-
root_exception=e,
637-
execution_time=end_time - start_time,
638-
) from e
639-
640-
end_time = time()
641-
spans, logs = self._get_and_clear_execution_data(execution_id)
642-
643-
if result is None:
644-
raise ValueError("Execution result cannot be None for eval runs")
645-
646-
return UiPathEvalRunExecutionOutput(
647-
execution_time=end_time - start_time,
648-
spans=spans,
649-
logs=logs,
650-
result=result,
651-
)
660+
result=result,
661+
)
662+
finally:
663+
if eval_runtime is not None:
664+
await eval_runtime.dispose()
652665

653666
def _setup_execution_logging(
654667
self, eval_item_id: str

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)