uipath-core 0.1.4__py3-none-any.whl → 0.1.5__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.
@@ -10,10 +10,14 @@ from ._evaluators import (
10
10
  evaluate_word_rule,
11
11
  )
12
12
  from .guardrails import (
13
+ AllFieldsSelector,
14
+ ApplyTo,
13
15
  BooleanRule,
14
16
  DeterministicGuardrail,
17
+ FieldSource,
15
18
  GuardrailValidationResult,
16
19
  NumberRule,
20
+ SpecificFieldsSelector,
17
21
  UniversalRule,
18
22
  WordRule,
19
23
  )
@@ -27,6 +31,16 @@ class DeterministicGuardrailsService(BaseModel):
27
31
  guardrail: DeterministicGuardrail,
28
32
  ) -> GuardrailValidationResult:
29
33
  """Evaluate deterministic guardrail rules against input data (pre-execution)."""
34
+ # Check if guardrail contains any output-dependent rules
35
+ has_output_rule = self._has_output_dependent_rule(guardrail, [ApplyTo.OUTPUT])
36
+
37
+ # If guardrail has output-dependent rules, skip evaluation in pre-execution
38
+ # Output rules will be evaluated during post-execution
39
+ if has_output_rule:
40
+ return GuardrailValidationResult(
41
+ validation_passed=True,
42
+ reason="Guardrail contains output-dependent rules that will be evaluated during post-execution",
43
+ )
30
44
  return self._evaluate_deterministic_guardrail(
31
45
  input_data=input_data,
32
46
  output_data={},
@@ -41,12 +55,61 @@ class DeterministicGuardrailsService(BaseModel):
41
55
  guardrail: DeterministicGuardrail,
42
56
  ) -> GuardrailValidationResult:
43
57
  """Evaluate deterministic guardrail rules against input and output data."""
58
+ # Check if guardrail contains any output-dependent rules
59
+ has_output_rule = self._has_output_dependent_rule(
60
+ guardrail, [ApplyTo.OUTPUT, ApplyTo.INPUT_AND_OUTPUT]
61
+ )
62
+
63
+ # If guardrail has no output-dependent rules, skip post-execution evaluation
64
+ # Only input rules exist and they should have been evaluated during pre-execution
65
+ if not has_output_rule:
66
+ return GuardrailValidationResult(
67
+ validation_passed=True,
68
+ reason="Guardrail contains only input-dependent rules that were evaluated during pre-execution",
69
+ )
70
+
44
71
  return self._evaluate_deterministic_guardrail(
45
72
  input_data=input_data,
46
73
  output_data=output_data,
47
74
  guardrail=guardrail,
48
75
  )
49
76
 
77
+ @staticmethod
78
+ def _has_output_dependent_rule(
79
+ guardrail: DeterministicGuardrail,
80
+ universal_rules_apply_to_values: list[ApplyTo],
81
+ ) -> bool:
82
+ """Check if at least one rule EXCLUSIVELY requires output data.
83
+
84
+ Args:
85
+ guardrail: The guardrail to check
86
+ universal_rules_apply_to_values: List of ApplyTo values to consider as output-dependent for UniversalRules.
87
+
88
+ Returns:
89
+ True if at least one rule exclusively depends on output data, False otherwise.
90
+ """
91
+ for rule in guardrail.rules:
92
+ # UniversalRule: only return True if it applies to values in universal_rules_apply_to_values
93
+ if isinstance(rule, UniversalRule):
94
+ if rule.apply_to in universal_rules_apply_to_values:
95
+ return True
96
+ # Rules with field_selector
97
+ elif isinstance(rule, (WordRule, NumberRule, BooleanRule)):
98
+ field_selector = rule.field_selector
99
+ # AllFieldsSelector applies to both input and output, not exclusively output
100
+ # SpecificFieldsSelector: only return True if at least one field has OUTPUT source
101
+ if isinstance(field_selector, SpecificFieldsSelector):
102
+ if field_selector.fields and any(
103
+ field.source == FieldSource.OUTPUT
104
+ for field in field_selector.fields
105
+ ):
106
+ return True
107
+ elif isinstance(field_selector, AllFieldsSelector):
108
+ if FieldSource.OUTPUT in field_selector.sources:
109
+ return True
110
+
111
+ return False
112
+
50
113
  @staticmethod
51
114
  def _evaluate_deterministic_guardrail(
52
115
  input_data: dict[str, Any],
@@ -120,23 +120,25 @@ def get_fields_from_selector(
120
120
  fields: list[tuple[Any, FieldReference]] = []
121
121
 
122
122
  if isinstance(field_selector, AllFieldsSelector):
123
- # For "all" selector, we need to collect all fields from both input and output
123
+ # For "all" selector, we need to collect all fields from the specified sources
124
124
  # This is a simplified implementation - in practice, you might want to
125
125
  # recursively collect all nested fields
126
- for key, value in input_data.items():
127
- fields.append(
128
- (
129
- value,
130
- FieldReference(path=key, source=FieldSource.INPUT),
126
+ if FieldSource.INPUT in field_selector.sources:
127
+ for key, value in input_data.items():
128
+ fields.append(
129
+ (
130
+ value,
131
+ FieldReference(path=key, source=FieldSource.INPUT),
132
+ )
131
133
  )
132
- )
133
- for key, value in output_data.items():
134
- fields.append(
135
- (
136
- value,
137
- FieldReference(path=key, source=FieldSource.OUTPUT),
134
+ if FieldSource.OUTPUT in field_selector.sources:
135
+ for key, value in output_data.items():
136
+ fields.append(
137
+ (
138
+ value,
139
+ FieldReference(path=key, source=FieldSource.OUTPUT),
140
+ )
138
141
  )
139
- )
140
142
  elif isinstance(field_selector, SpecificFieldsSelector):
141
143
  # For specific fields, extract values based on field references
142
144
  for field_ref in field_selector.fields:
@@ -59,6 +59,7 @@ class AllFieldsSelector(BaseModel):
59
59
  """All fields selector."""
60
60
 
61
61
  selector_type: Literal["all"] = Field(alias="$selectorType")
62
+ sources: list[FieldSource]
62
63
 
63
64
  model_config = ConfigDict(populate_by_name=True, extra="allow")
64
65
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-core
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: UiPath Core abstractions
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-core-python
@@ -15,9 +15,9 @@ uipath/core/chat/tool.py,sha256=6e5pyX3hOWM5fIzr_fdG49Mbzz6XzJD3nsmha-yGa2k,2308
15
15
  uipath/core/errors/__init__.py,sha256=gjxdLibZ0fjwgzPuLJY04P8dIX9rbSM2wQ97jP34ucE,278
16
16
  uipath/core/errors/errors.py,sha256=5LajjuTfNW82ju07wT5mD3tXk0S-Ju7OqJqQpPN0F6g,486
17
17
  uipath/core/guardrails/__init__.py,sha256=baH9Vj8f6spKOpxv3dUl5UKg-LWthaoZ0RidtlFjyEQ,956
18
- uipath/core/guardrails/_deterministic_guardrails_service.py,sha256=3WGcgpyUIvTXBvheEXjX-XguytxquWJkBevrVeM2tcc,2841
19
- uipath/core/guardrails/_evaluators.py,sha256=5llj14Xh1mzREh8JC9LjsymGsuGrz8x6Sv6K5s4P1sE,14446
20
- uipath/core/guardrails/guardrails.py,sha256=X2EVZVhD2PSXmfudgLdPB9ccsyqfPWESzuOzH9MGCrg,4703
18
+ uipath/core/guardrails/_deterministic_guardrails_service.py,sha256=4Z0U2lf6O5VFMPxcU3AzvvzUXNEhAr7r7bPgM0qkaV0,5773
19
+ uipath/core/guardrails/_evaluators.py,sha256=oeO7rUyXWkE430EO12ltUqFYCb65hbCYrOK9DTFZzTM,14615
20
+ uipath/core/guardrails/guardrails.py,sha256=pq-Z0Jo0d4DDskczSd_L0FeqhPQ1V6H7vqisecZz0gk,4734
21
21
  uipath/core/tracing/__init__.py,sha256=1XNLYZ4J76XkRrizGO486mS6yxzVXUbrldpvxTyJe3E,483
22
22
  uipath/core/tracing/_utils.py,sha256=FiCFGOFa4czruhlSF87Q5Q4jX9KKPHZiw8k14K7W5v4,6636
23
23
  uipath/core/tracing/decorators.py,sha256=ag_MFwZ0TywrhbpLKqQwF1guvRA9sYiItxao5LN9_Iw,10942
@@ -25,7 +25,7 @@ uipath/core/tracing/exporters.py,sha256=FClouEEQfk3F8J7G_NFoarDJM3R0-gA5jUxA5xRH
25
25
  uipath/core/tracing/processors.py,sha256=R_652rtjPmfpUtaXoIcmfZrRZylVXFRNwjOmJUUxOQw,1408
26
26
  uipath/core/tracing/span_utils.py,sha256=WYBrd6ZbawAs7r1Js-Zvo9_8GzkD9LhHNOls00bK_xI,12235
27
27
  uipath/core/tracing/trace_manager.py,sha256=51rscJcepkTK4bWoCZdE-DFc9wt2F-aSuFBaSXmkHl0,3130
28
- uipath_core-0.1.4.dist-info/METADATA,sha256=z8rkXBn1096teW-f17J-a5QNegco4Qm02xWVvutjwQQ,938
29
- uipath_core-0.1.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
30
- uipath_core-0.1.4.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
31
- uipath_core-0.1.4.dist-info/RECORD,,
28
+ uipath_core-0.1.5.dist-info/METADATA,sha256=aZ5u-csm-87FrIskvqMU6VAVP9R8W-cDJgdUo-ZRzos,938
29
+ uipath_core-0.1.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
30
+ uipath_core-0.1.5.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
31
+ uipath_core-0.1.5.dist-info/RECORD,,