uipath 2.1.111__py3-none-any.whl → 2.1.113__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of uipath might be problematic. Click here for more details.
- uipath/_cli/_debug/_bridge.py +194 -33
- uipath/_cli/_debug/_runtime.py +6 -2
- uipath/_cli/_evals/_models/_output.py +22 -8
- uipath/_cli/_evals/_runtime.py +21 -8
- uipath/_cli/_runtime/_contracts.py +3 -1
- uipath/_resources/SDK_REFERENCE.md +5 -5
- uipath/_services/documents_service.py +279 -107
- uipath/models/documents.py +28 -2
- {uipath-2.1.111.dist-info → uipath-2.1.113.dist-info}/METADATA +1 -1
- {uipath-2.1.111.dist-info → uipath-2.1.113.dist-info}/RECORD +13 -13
- {uipath-2.1.111.dist-info → uipath-2.1.113.dist-info}/WHEEL +0 -0
- {uipath-2.1.111.dist-info → uipath-2.1.113.dist-info}/entry_points.txt +0 -0
- {uipath-2.1.111.dist-info → uipath-2.1.113.dist-info}/licenses/LICENSE +0 -0
uipath/_cli/_debug/_bridge.py
CHANGED
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
import os
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
6
|
from enum import Enum
|
|
7
|
-
from typing import Any, Dict, List, Optional, Set
|
|
7
|
+
from typing import Any, Dict, List, Literal, Optional, Set
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
from pysignalr.client import SignalRClient
|
|
@@ -123,7 +123,7 @@ class UiPathDebugBridge(ABC):
|
|
|
123
123
|
pass
|
|
124
124
|
|
|
125
125
|
@abstractmethod
|
|
126
|
-
def get_breakpoints(self) -> List[str]:
|
|
126
|
+
def get_breakpoints(self) -> List[str] | Literal["*"]:
|
|
127
127
|
"""Get nodes to suspend execution at.
|
|
128
128
|
|
|
129
129
|
Returns:
|
|
@@ -220,7 +220,7 @@ class ConsoleDebugBridge(UiPathDebugBridge):
|
|
|
220
220
|
"""Print error."""
|
|
221
221
|
self.console.print()
|
|
222
222
|
self.console.print("[red]─" * 40)
|
|
223
|
-
self.console.print(
|
|
223
|
+
self.console.print("[red]✗ Error[/red]")
|
|
224
224
|
self.console.print("[red]─" * 40)
|
|
225
225
|
|
|
226
226
|
# Truncate very long errors
|
|
@@ -228,7 +228,7 @@ class ConsoleDebugBridge(UiPathDebugBridge):
|
|
|
228
228
|
if len(error) > 500:
|
|
229
229
|
error_display = error[:500] + "\n[dim]... (truncated)"
|
|
230
230
|
|
|
231
|
-
self.console.print(f"[
|
|
231
|
+
self.console.print(f"[red]{error_display}[/red]")
|
|
232
232
|
self.console.print("[red]─" * 40)
|
|
233
233
|
|
|
234
234
|
async def wait_for_resume(self) -> Any:
|
|
@@ -252,21 +252,14 @@ class ConsoleDebugBridge(UiPathDebugBridge):
|
|
|
252
252
|
# These commands don't resume execution, loop again
|
|
253
253
|
continue
|
|
254
254
|
|
|
255
|
-
# Reset step modes if continuing
|
|
256
|
-
if command_result["command"] == DebugCommand.CONTINUE:
|
|
257
|
-
self.state.step_mode = False
|
|
258
|
-
|
|
259
|
-
if command_result["command"] == DebugCommand.QUIT:
|
|
260
|
-
raise DebuggerQuitException("User requested exit")
|
|
261
|
-
|
|
262
255
|
# Commands that resume execution: CONTINUE, STEP
|
|
263
256
|
self.console.print()
|
|
264
257
|
return command_result
|
|
265
258
|
|
|
266
|
-
def get_breakpoints(self) -> List[str]:
|
|
259
|
+
def get_breakpoints(self) -> List[str] | Literal["*"]:
|
|
267
260
|
"""Get nodes to suspend execution at."""
|
|
268
261
|
if self.state.step_mode:
|
|
269
|
-
return
|
|
262
|
+
return "*" # Suspend at all nodes
|
|
270
263
|
return list(self.state.breakpoints) # Only suspend at breakpoints
|
|
271
264
|
|
|
272
265
|
def _parse_command(self, user_input: str) -> Dict[str, Any]:
|
|
@@ -283,6 +276,7 @@ class ConsoleDebugBridge(UiPathDebugBridge):
|
|
|
283
276
|
args = parts[1:] if len(parts) > 1 else []
|
|
284
277
|
|
|
285
278
|
if cmd in ["c", "continue"]:
|
|
279
|
+
self.state.step_mode = False
|
|
286
280
|
return {"command": DebugCommand.CONTINUE, "args": None}
|
|
287
281
|
|
|
288
282
|
elif cmd in ["s", "step"]:
|
|
@@ -318,7 +312,7 @@ class ConsoleDebugBridge(UiPathDebugBridge):
|
|
|
318
312
|
}
|
|
319
313
|
|
|
320
314
|
elif cmd in ["q", "quit", "exit"]:
|
|
321
|
-
raise
|
|
315
|
+
raise DebuggerQuitException("User requested exit")
|
|
322
316
|
|
|
323
317
|
elif cmd in ["h", "help", "?"]:
|
|
324
318
|
self._print_help()
|
|
@@ -465,26 +459,75 @@ class SignalRDebugBridge(UiPathDebugBridge):
|
|
|
465
459
|
self._client = SignalRClient(self.hub_url, headers=all_headers)
|
|
466
460
|
|
|
467
461
|
# Register event handlers
|
|
468
|
-
self._client.on("
|
|
462
|
+
self._client.on("Start", self._handle_start)
|
|
463
|
+
self._client.on("Resume", self._handle_resume)
|
|
464
|
+
self._client.on("Step", self._handle_step)
|
|
465
|
+
self._client.on("AddBreakpoints", self._handle_add_breakpoints)
|
|
466
|
+
self._client.on("RemoveBreakpoints", self._handle_remove_breakpoints)
|
|
467
|
+
self._client.on("Quit", self._handle_quit)
|
|
469
468
|
self._client.on_open(self._handle_open)
|
|
470
469
|
self._client.on_close(self._handle_close)
|
|
471
470
|
self._client.on_error(self._handle_error)
|
|
472
471
|
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
self._run_task = asyncio.create_task(self._client.run())
|
|
473
|
+
|
|
474
|
+
async def cleanup_run_task() -> str:
|
|
475
|
+
error_message = (
|
|
476
|
+
"Failed to establish WebSocket connection within 10s timeout"
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
if self._run_task:
|
|
480
|
+
if not self._run_task.done():
|
|
481
|
+
self._run_task.cancel()
|
|
482
|
+
try:
|
|
483
|
+
await self._run_task
|
|
484
|
+
except asyncio.CancelledError:
|
|
485
|
+
pass # Expected on cancel
|
|
486
|
+
except Exception as task_error:
|
|
487
|
+
error_msg = str(task_error).strip()
|
|
488
|
+
error_detail = f": {error_msg}" if error_msg else ""
|
|
489
|
+
return f"{error_message}: {type(task_error).__name__}{error_detail}"
|
|
490
|
+
|
|
491
|
+
return error_message
|
|
492
|
+
|
|
493
|
+
try:
|
|
494
|
+
# Wait for connection with timeout
|
|
495
|
+
await asyncio.wait_for(self._connected_event.wait(), timeout=10.0)
|
|
496
|
+
except asyncio.TimeoutError as e:
|
|
497
|
+
# Clean up on timeout
|
|
498
|
+
raise RuntimeError(await cleanup_run_task()) from e
|
|
499
|
+
except Exception:
|
|
500
|
+
# Clean up on any other error
|
|
501
|
+
await cleanup_run_task()
|
|
502
|
+
raise
|
|
475
503
|
|
|
476
|
-
#
|
|
477
|
-
|
|
504
|
+
# Check if run_task failed
|
|
505
|
+
if self._run_task.done():
|
|
506
|
+
exception = self._run_task.exception()
|
|
507
|
+
if exception:
|
|
508
|
+
raise exception
|
|
478
509
|
|
|
479
510
|
async def disconnect(self) -> None:
|
|
480
511
|
"""Close SignalR connection."""
|
|
481
|
-
if
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
512
|
+
if not self._client:
|
|
513
|
+
return
|
|
514
|
+
|
|
515
|
+
# Cancel the run task first
|
|
516
|
+
if self._run_task and not self._run_task.done():
|
|
517
|
+
self._run_task.cancel()
|
|
518
|
+
try:
|
|
519
|
+
await self._run_task
|
|
520
|
+
except (Exception, asyncio.CancelledError):
|
|
521
|
+
pass
|
|
522
|
+
|
|
523
|
+
# Try to close the client cleanly
|
|
524
|
+
try:
|
|
525
|
+
if hasattr(self._client, "_transport"):
|
|
526
|
+
transport = self._client._transport
|
|
527
|
+
if transport and hasattr(transport, "_ws") and transport._ws:
|
|
485
528
|
await transport._ws.close()
|
|
486
|
-
|
|
487
|
-
|
|
529
|
+
except Exception as e:
|
|
530
|
+
logger.warning(f"Error closing SignalR WebSocket: {e}")
|
|
488
531
|
|
|
489
532
|
async def emit_execution_started(self, execution_id: str, **kwargs) -> None:
|
|
490
533
|
"""Send execution started event."""
|
|
@@ -541,6 +584,9 @@ class SignalRDebugBridge(UiPathDebugBridge):
|
|
|
541
584
|
error: str,
|
|
542
585
|
) -> None:
|
|
543
586
|
"""Send execution error event."""
|
|
587
|
+
if not self._connected_event.is_set():
|
|
588
|
+
return
|
|
589
|
+
|
|
544
590
|
logger.error(f"Execution error: {execution_id} - {error}")
|
|
545
591
|
await self._send(
|
|
546
592
|
"OnExecutionError",
|
|
@@ -558,24 +604,139 @@ class SignalRDebugBridge(UiPathDebugBridge):
|
|
|
558
604
|
logger.info("Resume command received")
|
|
559
605
|
return self._resume_data
|
|
560
606
|
|
|
561
|
-
def get_breakpoints(self) -> List[str]:
|
|
607
|
+
def get_breakpoints(self) -> List[str] | Literal["*"]:
|
|
562
608
|
"""Get nodes to suspend execution at."""
|
|
563
609
|
if self.state.step_mode:
|
|
564
|
-
return
|
|
610
|
+
return "*" # Suspend at all nodes
|
|
565
611
|
return list(self.state.breakpoints) # Only suspend at breakpoints
|
|
566
612
|
|
|
567
|
-
async def _send(self,
|
|
568
|
-
"""Send message to SignalR hub.
|
|
613
|
+
async def _send(self, event_name: str, data: Dict[str, Any]) -> None:
|
|
614
|
+
"""Send message to SignalR hub via SendCommand.
|
|
615
|
+
|
|
616
|
+
Args:
|
|
617
|
+
event_name: The event/command name (e.g., "OnExecutionStarted")
|
|
618
|
+
data: The data payload to send
|
|
619
|
+
"""
|
|
569
620
|
if not self._client:
|
|
570
621
|
raise RuntimeError("SignalR client not connected")
|
|
622
|
+
try:
|
|
623
|
+
# Wrap the event in SendCommand protocol
|
|
624
|
+
# Server expects: SendCommand(event_name, json_string_of_data)
|
|
625
|
+
data_json = json.dumps(data)
|
|
626
|
+
arguments: list[Any] = [event_name, data_json]
|
|
627
|
+
await self._client.send(method="SendCommand", arguments=arguments)
|
|
628
|
+
logger.debug(f"Sent command: {event_name} with data: {data}")
|
|
629
|
+
except Exception as e:
|
|
630
|
+
logger.error(f"Error sending command {event_name} to SignalR hub: {e}")
|
|
631
|
+
|
|
632
|
+
async def _handle_start(self, args: list[Any]) -> None:
|
|
633
|
+
"""Handle Start command from SignalR server.
|
|
571
634
|
|
|
572
|
-
|
|
635
|
+
Args:
|
|
636
|
+
args: List containing command arguments, typically [dict_with_args]
|
|
637
|
+
"""
|
|
638
|
+
logger.info(f"Start command received with args: {args}")
|
|
639
|
+
if not args or len(args) == 0:
|
|
640
|
+
logger.warning("Start command received with empty args.")
|
|
641
|
+
return
|
|
642
|
+
|
|
643
|
+
command_args = args[0] if isinstance(args[0], dict) else {}
|
|
644
|
+
self.state.breakpoints = set(command_args.get("breakpoints", []))
|
|
645
|
+
step_mode = command_args.get("enableStepMode", False)
|
|
646
|
+
self.state.step_mode = step_mode
|
|
573
647
|
|
|
574
648
|
async def _handle_resume(self, args: list[Any]) -> None:
|
|
575
|
-
"""Handle
|
|
576
|
-
|
|
577
|
-
|
|
649
|
+
"""Handle Resume command from SignalR server.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
args: List containing command arguments
|
|
653
|
+
"""
|
|
654
|
+
logger.info(f"Resume command received with args: {args}")
|
|
655
|
+
command_args = args[0] if args and len(args) > 0 else {}
|
|
656
|
+
|
|
657
|
+
if self._resume_event:
|
|
658
|
+
self._resume_data = command_args
|
|
578
659
|
self._resume_event.set()
|
|
660
|
+
logger.info("Resume event set")
|
|
661
|
+
else:
|
|
662
|
+
logger.warning("Resume command received but no resume event is waiting")
|
|
663
|
+
|
|
664
|
+
async def _handle_step(self, args: list[Any]) -> None:
|
|
665
|
+
"""Handle Step command from SignalR server.
|
|
666
|
+
|
|
667
|
+
Args:
|
|
668
|
+
args: List containing command arguments
|
|
669
|
+
"""
|
|
670
|
+
logger.info(f"Step command received with args: {args}")
|
|
671
|
+
self.state.step_mode = True
|
|
672
|
+
logger.info("Step mode enabled")
|
|
673
|
+
|
|
674
|
+
async def _handle_add_breakpoints(self, args: list[Any]) -> None:
|
|
675
|
+
"""Handle AddBreakpoints command from SignalR server.
|
|
676
|
+
|
|
677
|
+
Args:
|
|
678
|
+
args: List containing command arguments with breakpoints list
|
|
679
|
+
"""
|
|
680
|
+
logger.info(f"AddBreakpoints command received with args: {args}")
|
|
681
|
+
if not args or len(args) == 0:
|
|
682
|
+
logger.warning("AddBreakpoints command received with empty args.")
|
|
683
|
+
return
|
|
684
|
+
|
|
685
|
+
command_args = args[0] if isinstance(args[0], dict) else {}
|
|
686
|
+
break_points = command_args.get("breakpoints", [])
|
|
687
|
+
|
|
688
|
+
for bp in break_points:
|
|
689
|
+
node_name = (
|
|
690
|
+
bp.get("node", {}).get("name")
|
|
691
|
+
if isinstance(bp.get("node"), dict)
|
|
692
|
+
else None
|
|
693
|
+
)
|
|
694
|
+
if node_name:
|
|
695
|
+
self.state.add_breakpoint(node_name)
|
|
696
|
+
logger.info(f"Breakpoint set at: {node_name}")
|
|
697
|
+
else:
|
|
698
|
+
logger.warning(f"Breakpoint command received without node name: {bp}")
|
|
699
|
+
|
|
700
|
+
async def _handle_remove_breakpoints(self, args: list[Any]) -> None:
|
|
701
|
+
"""Handle RemoveBreakpoints command from SignalR server.
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
args: List containing command arguments with breakpoints list
|
|
705
|
+
"""
|
|
706
|
+
logger.info(f"RemoveBreakpoints command received with args: {args}")
|
|
707
|
+
if not args or len(args) == 0:
|
|
708
|
+
self.state.clear_all_breakpoints()
|
|
709
|
+
logger.info("All breakpoints cleared")
|
|
710
|
+
return
|
|
711
|
+
|
|
712
|
+
command_args = args[0] if isinstance(args[0], dict) else {}
|
|
713
|
+
break_points = command_args.get("breakpoints", [])
|
|
714
|
+
|
|
715
|
+
if not break_points:
|
|
716
|
+
self.state.clear_all_breakpoints()
|
|
717
|
+
logger.info("All breakpoints cleared")
|
|
718
|
+
else:
|
|
719
|
+
for bp in break_points:
|
|
720
|
+
node_name = (
|
|
721
|
+
bp.get("node", {}).get("name")
|
|
722
|
+
if isinstance(bp.get("node"), dict)
|
|
723
|
+
else None
|
|
724
|
+
)
|
|
725
|
+
if node_name:
|
|
726
|
+
self.state.remove_breakpoint(node_name)
|
|
727
|
+
logger.info(f"Breakpoint removed: {node_name}")
|
|
728
|
+
|
|
729
|
+
async def _handle_quit(self, args: list[Any]) -> None:
|
|
730
|
+
"""Handle Quit command from SignalR server.
|
|
731
|
+
|
|
732
|
+
Args:
|
|
733
|
+
args: List containing command arguments
|
|
734
|
+
"""
|
|
735
|
+
if args:
|
|
736
|
+
logger.info(f"Quit command received from server with args: {args}")
|
|
737
|
+
else:
|
|
738
|
+
logger.info("Quit command received from server")
|
|
739
|
+
raise DebuggerQuitException("Quit command received from server")
|
|
579
740
|
|
|
580
741
|
async def _handle_open(self) -> None:
|
|
581
742
|
"""Handle SignalR connection open."""
|
uipath/_cli/_debug/_runtime.py
CHANGED
|
@@ -35,6 +35,7 @@ class UiPathDebugRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
35
35
|
self.context: UiPathRuntimeContext = context
|
|
36
36
|
self.factory: UiPathRuntimeFactory[T, C] = factory
|
|
37
37
|
self.debug_bridge: UiPathDebugBridge = debug_bridge
|
|
38
|
+
self.execution_id: str = context.job_id or "default"
|
|
38
39
|
self._inner_runtime: Optional[T] = None
|
|
39
40
|
|
|
40
41
|
@classmethod
|
|
@@ -57,7 +58,7 @@ class UiPathDebugRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
57
58
|
raise RuntimeError("Failed to create inner runtime")
|
|
58
59
|
|
|
59
60
|
await self.debug_bridge.emit_execution_started(
|
|
60
|
-
execution_id=self.
|
|
61
|
+
execution_id=self.execution_id
|
|
61
62
|
)
|
|
62
63
|
|
|
63
64
|
# Try to stream events from inner runtime
|
|
@@ -78,8 +79,11 @@ class UiPathDebugRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
78
79
|
|
|
79
80
|
except Exception as e:
|
|
80
81
|
# Emit execution error
|
|
82
|
+
self.context.result = UiPathRuntimeResult(
|
|
83
|
+
status=UiPathRuntimeStatus.FAULTED,
|
|
84
|
+
)
|
|
81
85
|
await self.debug_bridge.emit_execution_error(
|
|
82
|
-
execution_id=self.
|
|
86
|
+
execution_id=self.execution_id,
|
|
83
87
|
error=str(e),
|
|
84
88
|
)
|
|
85
89
|
raise
|
|
@@ -8,7 +8,11 @@ from pydantic.alias_generators import to_camel
|
|
|
8
8
|
from pydantic_core import core_schema
|
|
9
9
|
|
|
10
10
|
from uipath._cli._runtime._contracts import UiPathRuntimeResult
|
|
11
|
-
from uipath.eval.models.models import
|
|
11
|
+
from uipath.eval.models.models import (
|
|
12
|
+
EvaluationResult,
|
|
13
|
+
ScoreType,
|
|
14
|
+
TrajectoryEvaluationTrace,
|
|
15
|
+
)
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
class UiPathEvalRunExecutionOutput(BaseModel):
|
|
@@ -22,6 +26,22 @@ class UiPathEvalRunExecutionOutput(BaseModel):
|
|
|
22
26
|
result: UiPathRuntimeResult
|
|
23
27
|
|
|
24
28
|
|
|
29
|
+
class UiPathSerializableEvalRunExecutionOutput(BaseModel):
|
|
30
|
+
execution_time: float
|
|
31
|
+
trace: TrajectoryEvaluationTrace
|
|
32
|
+
result: UiPathRuntimeResult
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def convert_eval_execution_output_to_serializable(
|
|
36
|
+
output: UiPathEvalRunExecutionOutput,
|
|
37
|
+
) -> UiPathSerializableEvalRunExecutionOutput:
|
|
38
|
+
return UiPathSerializableEvalRunExecutionOutput(
|
|
39
|
+
execution_time=output.execution_time,
|
|
40
|
+
result=output.result,
|
|
41
|
+
trace=TrajectoryEvaluationTrace.from_readable_spans(output.spans),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
25
45
|
class EvaluationResultDto(BaseModel):
|
|
26
46
|
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
|
|
27
47
|
|
|
@@ -67,19 +87,13 @@ class EvaluationRunResultDto(BaseModel):
|
|
|
67
87
|
evaluator_id: str
|
|
68
88
|
result: EvaluationResultDto
|
|
69
89
|
|
|
70
|
-
@model_serializer(mode="wrap")
|
|
71
|
-
def serialize_model(self, serializer, info):
|
|
72
|
-
data = serializer(self)
|
|
73
|
-
if isinstance(data, dict):
|
|
74
|
-
data.pop("evaluatorId", None)
|
|
75
|
-
return data
|
|
76
|
-
|
|
77
90
|
|
|
78
91
|
class EvaluationRunResult(BaseModel):
|
|
79
92
|
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
|
|
80
93
|
|
|
81
94
|
evaluation_name: str
|
|
82
95
|
evaluation_run_results: List[EvaluationRunResultDto]
|
|
96
|
+
agent_execution_output: Optional[UiPathSerializableEvalRunExecutionOutput] = None
|
|
83
97
|
|
|
84
98
|
@property
|
|
85
99
|
def score(self) -> float:
|
uipath/_cli/_evals/_runtime.py
CHANGED
|
@@ -38,6 +38,7 @@ from .._runtime._contracts import (
|
|
|
38
38
|
)
|
|
39
39
|
from .._runtime._logging import ExecutionLogHandler
|
|
40
40
|
from .._utils._eval_set import EvalHelpers
|
|
41
|
+
from ..models.runtime_schema import Entrypoint
|
|
41
42
|
from ._evaluator_factory import EvaluatorFactory
|
|
42
43
|
from ._models._evaluation_set import (
|
|
43
44
|
AnyEvaluationItem,
|
|
@@ -53,6 +54,7 @@ from ._models._output import (
|
|
|
53
54
|
EvaluationRunResultDto,
|
|
54
55
|
UiPathEvalOutput,
|
|
55
56
|
UiPathEvalRunExecutionOutput,
|
|
57
|
+
convert_eval_execution_output_to_serializable,
|
|
56
58
|
)
|
|
57
59
|
from ._span_collection import ExecutionSpanCollector
|
|
58
60
|
from .mocks.mocks import (
|
|
@@ -147,6 +149,7 @@ class UiPathEvalContext(UiPathRuntimeContext):
|
|
|
147
149
|
workers: Optional[int] = 1
|
|
148
150
|
eval_set: Optional[str] = None
|
|
149
151
|
eval_ids: Optional[List[str]] = None
|
|
152
|
+
verbose: bool = False
|
|
150
153
|
|
|
151
154
|
|
|
152
155
|
class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
@@ -173,6 +176,15 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
173
176
|
|
|
174
177
|
self.logs_exporter: ExecutionLogsExporter = ExecutionLogsExporter()
|
|
175
178
|
self.execution_id = str(uuid.uuid4())
|
|
179
|
+
self.entrypoint: Optional[Entrypoint] = None
|
|
180
|
+
|
|
181
|
+
async def get_entrypoint(self):
|
|
182
|
+
if not self.entrypoint:
|
|
183
|
+
temp_runtime = self.factory.new_runtime(
|
|
184
|
+
entrypoint=self.context.entrypoint, runtime_dir=os.getcwd()
|
|
185
|
+
)
|
|
186
|
+
self.entrypoint = await temp_runtime.get_entrypoint()
|
|
187
|
+
return self.entrypoint
|
|
176
188
|
|
|
177
189
|
@classmethod
|
|
178
190
|
def from_eval_context(
|
|
@@ -187,13 +199,6 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
187
199
|
if self.context.eval_set is None:
|
|
188
200
|
raise ValueError("eval_set must be provided for evaluation runs")
|
|
189
201
|
|
|
190
|
-
# Get entrypoint from a temporary runtime
|
|
191
|
-
temp_context = self.factory.new_context(
|
|
192
|
-
entrypoint=self.context.entrypoint, runtime_dir=os.getcwd()
|
|
193
|
-
)
|
|
194
|
-
temp_runtime = self.factory.from_context(temp_context)
|
|
195
|
-
self.entrypoint = await temp_runtime.get_entrypoint()
|
|
196
|
-
|
|
197
202
|
event_bus = self.event_bus
|
|
198
203
|
|
|
199
204
|
# Load eval set (path is already resolved in cli_eval.py)
|
|
@@ -360,6 +365,12 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
360
365
|
|
|
361
366
|
try:
|
|
362
367
|
agent_execution_output = await self.execute_runtime(eval_item, execution_id)
|
|
368
|
+
if self.context.verbose:
|
|
369
|
+
evaluation_run_results.agent_execution_output = (
|
|
370
|
+
convert_eval_execution_output_to_serializable(
|
|
371
|
+
agent_execution_output
|
|
372
|
+
)
|
|
373
|
+
)
|
|
363
374
|
evaluation_item_results: list[EvalItemResult] = []
|
|
364
375
|
|
|
365
376
|
for evaluator in evaluators:
|
|
@@ -477,7 +488,9 @@ class UiPathEvalRuntime(UiPathBaseRuntime, Generic[T, C]):
|
|
|
477
488
|
self, eval_item: AnyEvaluationItem
|
|
478
489
|
) -> AnyEvaluationItem:
|
|
479
490
|
"""Use LLM to generate a mock input for an evaluation item."""
|
|
480
|
-
generated_input = await generate_llm_input(
|
|
491
|
+
generated_input = await generate_llm_input(
|
|
492
|
+
eval_item, (await self.get_entrypoint()).input
|
|
493
|
+
)
|
|
481
494
|
updated_eval_item = eval_item.model_copy(update={"inputs": generated_input})
|
|
482
495
|
return updated_eval_item
|
|
483
496
|
|
|
@@ -382,7 +382,7 @@ class UiPathRuntimeContext(BaseModel):
|
|
|
382
382
|
log_handler: Optional[logging.Handler] = None
|
|
383
383
|
chat_handler: Optional[UiPathConversationHandler] = None
|
|
384
384
|
is_conversational: Optional[bool] = None
|
|
385
|
-
breakpoints: Optional[List[str]] = None
|
|
385
|
+
breakpoints: Optional[List[str] | Literal["*"]] = None
|
|
386
386
|
|
|
387
387
|
model_config = {"arbitrary_types_allowed": True, "extra": "allow"}
|
|
388
388
|
|
|
@@ -536,6 +536,7 @@ class UiPathRuntimeError(UiPathBaseRuntimeError):
|
|
|
536
536
|
title: str,
|
|
537
537
|
detail: str,
|
|
538
538
|
category: UiPathErrorCategory = UiPathErrorCategory.UNKNOWN,
|
|
539
|
+
status: Optional[int] = None,
|
|
539
540
|
prefix: str = "Python",
|
|
540
541
|
include_traceback: bool = True,
|
|
541
542
|
):
|
|
@@ -544,6 +545,7 @@ class UiPathRuntimeError(UiPathBaseRuntimeError):
|
|
|
544
545
|
title=title,
|
|
545
546
|
detail=detail,
|
|
546
547
|
category=category,
|
|
548
|
+
status=status,
|
|
547
549
|
prefix=prefix,
|
|
548
550
|
include_traceback=include_traceback,
|
|
549
551
|
)
|
|
@@ -127,19 +127,19 @@ Documents service
|
|
|
127
127
|
# Create a validation action for a document based on the extraction response. More details about validation actions can be found in the [official documentation](https://docs.uipath.com/ixp/automation-cloud/latest/user-guide/validating-extractions).
|
|
128
128
|
sdk.documents.create_validation_action(action_title: str, action_priority: <enum 'ActionPriority, action_catalog: str, action_folder: str, storage_bucket_name: str, storage_bucket_directory_path: str, extraction_response: uipath.models.documents.ExtractionResponse) -> uipath.models.documents.ValidationAction
|
|
129
129
|
|
|
130
|
-
#
|
|
130
|
+
# Asynchronous version of the [`create_validation_action`][uipath._services.documents_service.DocumentsService.create_validation_action] method.
|
|
131
131
|
sdk.documents.create_validation_action_async(action_title: str, action_priority: <enum 'ActionPriority, action_catalog: str, action_folder: str, storage_bucket_name: str, storage_bucket_directory_path: str, extraction_response: uipath.models.documents.ExtractionResponse) -> uipath.models.documents.ValidationAction
|
|
132
132
|
|
|
133
133
|
# Extract predicted data from a document using an IXP project.
|
|
134
|
-
sdk.documents.extract(project_name: str, tag: str, file: Union[IO[bytes], bytes, str, NoneType]=None, file_path: Optional[str]=None) -> uipath.models.documents.ExtractionResponse
|
|
134
|
+
sdk.documents.extract(project_name: str, tag: str, file: Union[IO[bytes], bytes, str, NoneType]=None, file_path: Optional[str]=None, project_type: <enum 'ProjectType="IXP", document_type_name: Optional[str]=None) -> typing.Union[uipath.models.documents.ExtractionResponse, uipath.models.documents.ExtractionResponseIXP]
|
|
135
135
|
|
|
136
|
-
# Asynchronously
|
|
137
|
-
sdk.documents.extract_async(project_name: str, tag: str, file: Union[IO[bytes], bytes, str, NoneType]=None, file_path: Optional[str]=None) -> uipath.models.documents.ExtractionResponse
|
|
136
|
+
# Asynchronously version of the [`extract`][uipath._services.documents_service.DocumentsService.extract] method.
|
|
137
|
+
sdk.documents.extract_async(project_name: str, tag: str, file: Union[IO[bytes], bytes, str, NoneType]=None, file_path: Optional[str]=None, project_type: <enum 'ProjectType="IXP", document_type_name: Optional[str]=None) -> typing.Union[uipath.models.documents.ExtractionResponse, uipath.models.documents.ExtractionResponseIXP]
|
|
138
138
|
|
|
139
139
|
# Get the result of a validation action.
|
|
140
140
|
sdk.documents.get_validation_result(validation_action: uipath.models.documents.ValidationAction) -> uipath.models.documents.ValidatedResult
|
|
141
141
|
|
|
142
|
-
#
|
|
142
|
+
# Asynchronous version of the [`get_validation_result`][uipath._services.documents_service.DocumentsService.get_validation_result] method.
|
|
143
143
|
sdk.documents.get_validation_result_async(validation_action: uipath.models.documents.ValidationAction) -> uipath.models.documents.ValidatedResult
|
|
144
144
|
|
|
145
145
|
```
|