Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[project]
name = "uipath"
version = "2.2.29"
version = "2.2.30"
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
dependencies = [
"uipath-runtime>=0.2.5, <0.3.0",
"uipath-core>=0.1.0, <0.2.0",
"uipath-core>=0.1.3, <0.2.0",
"click>=8.3.1",
"httpx>=0.28.1",
"pyjwt>=2.10.1",
Expand Down
85 changes: 82 additions & 3 deletions src/uipath/agent/models/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
from typing import Annotated, Any, Dict, List, Literal, Optional, Union

from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from uipath.core.guardrails import (
BaseGuardrail,
FieldReference,
FieldSelector,
UniversalRule,
)

from uipath.platform.connections import Connection
from uipath.platform.guardrails import (
BuiltInValidatorGuardrail,
CustomGuardrail,
FieldReference,
)


Expand Down Expand Up @@ -469,9 +473,84 @@ class AgentBuiltInValidatorGuardrail(BuiltInValidatorGuardrail):
)


class AgentCustomGuardrail(CustomGuardrail):
class AgentWordOperator(str, Enum):
"""Word operator enumeration."""

CONTAINS = "contains"
DOES_NOT_CONTAIN = "doesNotContain"
DOES_NOT_END_WITH = "doesNotEndWith"
DOES_NOT_EQUAL = "doesNotEqual"
DOES_NOT_START_WITH = "doesNotStartWith"
ENDS_WITH = "endsWith"
EQUALS = "equals"
IS_EMPTY = "isEmpty"
IS_NOT_EMPTY = "isNotEmpty"
MATCHES_REGEX = "matchesRegex"
STARTS_WITH = "startsWith"


class AgentWordRule(BaseModel):
"""Word rule model."""

rule_type: Literal["word"] = Field(alias="$ruleType")
field_selector: FieldSelector = Field(alias="fieldSelector")
operator: AgentWordOperator
value: str | None = None

model_config = ConfigDict(populate_by_name=True, extra="allow")


class AgentNumberOperator(str, Enum):
"""Number operator enumeration."""

DOES_NOT_EQUAL = "doesNotEqual"
EQUALS = "equals"
GREATER_THAN = "greaterThan"
GREATER_THAN_OR_EQUAL = "greaterThanOrEqual"
LESS_THAN = "lessThan"
LESS_THAN_OR_EQUAL = "lessThanOrEqual"


class AgentNumberRule(BaseModel):
"""Number rule model."""

rule_type: Literal["number"] = Field(alias="$ruleType")
field_selector: FieldSelector = Field(alias="fieldSelector")
operator: AgentNumberOperator
value: float

model_config = ConfigDict(populate_by_name=True, extra="allow")


class AgentBooleanOperator(str, Enum):
"""Boolean operator enumeration."""

EQUALS = "equals"


class AgentBooleanRule(BaseModel):
"""Boolean rule model."""

rule_type: Literal["boolean"] = Field(alias="$ruleType")
field_selector: FieldSelector = Field(alias="fieldSelector")
operator: AgentBooleanOperator
value: bool

model_config = ConfigDict(populate_by_name=True, extra="allow")


AgentRule = Annotated[
AgentWordRule | AgentNumberRule | AgentBooleanRule | UniversalRule,
Field(discriminator="rule_type"),
]


class AgentCustomGuardrail(BaseGuardrail):
"""Agent custom guardrail with action capabilities."""

guardrail_type: Literal["custom"] = Field(alias="$guardrailType")
rules: list[AgentRule]

action: GuardrailAction = Field(
..., description="Action to take when guardrail is triggered"
)
Expand Down
58 changes: 13 additions & 45 deletions src/uipath/platform/guardrails/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,30 @@
This module contains models related to UiPath Guardrails service.
"""

# 2.3.0 remove
from uipath.core.guardrails import (
BaseGuardrail,
DeterministicGuardrail,
GuardrailScope,
GuardrailValidationResult,
)

from ._guardrails_service import GuardrailsService
from .guardrails import (
AllFieldsSelector,
ApplyTo,
BaseGuardrail,
BooleanOperator,
BooleanRule,
BuiltInValidatorGuardrail,
CustomGuardrail,
EnumListParameterValue,
FieldReference,
FieldSelector,
FieldSource,
Guardrail,
GuardrailScope,
GuardrailSelector,
GuardrailType,
MapEnumParameterValue,
NumberOperator,
NumberParameterValue,
NumberRule,
Rule,
SelectorType,
SpecificFieldsSelector,
UniversalRule,
ValidatorParameter,
WordOperator,
WordRule,
)

__all__ = [
"GuardrailsService",
"FieldSource",
"ApplyTo",
"FieldReference",
"SelectorType",
"AllFieldsSelector",
"SpecificFieldsSelector",
"FieldSelector",
"BaseGuardrail",
"GuardrailType",
"Guardrail",
"BuiltInValidatorGuardrail",
"CustomGuardrail",
"WordOperator",
"WordRule",
"NumberOperator",
"NumberRule",
"BooleanOperator",
"BooleanRule",
"UniversalRule",
"Rule",
"ValidatorParameter",
"GuardrailType",
"BaseGuardrail",
"GuardrailScope",
"DeterministicGuardrail",
"GuardrailValidationResult",
"EnumListParameterValue",
"MapEnumParameterValue",
"NumberParameterValue",
"GuardrailScope",
"GuardrailSelector",
]
57 changes: 25 additions & 32 deletions src/uipath/platform/guardrails/_guardrails_service.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from typing import Any

from uipath.core.guardrails import GuardrailValidationResult

from ..._utils import Endpoint, RequestSpec
from ...tracing import traced
from ..common import BaseService, UiPathApiConfig, UiPathExecutionContext
from .guardrails import BuiltInValidatorGuardrail, Guardrail, GuardrailValidationResult
from .guardrails import BuiltInValidatorGuardrail


class GuardrailsService(BaseService):
Expand All @@ -29,43 +31,34 @@ def __init__(
def evaluate_guardrail(
self,
input_data: str | dict[str, Any],
guardrail: Guardrail,
guardrail: BuiltInValidatorGuardrail,
) -> GuardrailValidationResult:
"""Validate input text using the provided guardrail.

Args:
input_data: The text or structured data to validate. Dictionaries will be converted to a string before validation.
guardrail: A guardrail instance used for validation. Must be an instance of ``BuiltInValidatorGuardrail``. Custom guardrails are not supported.
guardrail: A guardrail instance used for validation.

Returns:
BuiltInGuardrailValidationResult: The outcome of the guardrail evaluation, containing whether validation passed and the reason.

Raises:
NotImplementedError: If a non-built-in guardrail is provided.
"""
if isinstance(guardrail, BuiltInValidatorGuardrail):
parameters = [
param.model_dump(by_alias=True)
for param in guardrail.validator_parameters
]
payload = {
"validator": guardrail.validator_type,
"input": input_data if isinstance(input_data, str) else str(input_data),
"parameters": parameters,
}
spec = RequestSpec(
method="POST",
endpoint=Endpoint("/agentsruntime_/api/execution/guardrails/validate"),
json=payload,
)
response = self.request(
spec.method,
url=spec.endpoint,
json=spec.json,
headers=spec.headers,
)
return GuardrailValidationResult.model_validate(response.json())
else:
raise NotImplementedError(
"Custom guardrail validation is not yet supported by the API."
)
parameters = [
param.model_dump(by_alias=True) for param in guardrail.validator_parameters
]
payload = {
"validator": guardrail.validator_type,
"input": input_data if isinstance(input_data, str) else str(input_data),
"parameters": parameters,
}
spec = RequestSpec(
method="POST",
endpoint=Endpoint("/agentsruntime_/api/execution/guardrails/validate"),
json=payload,
)
response = self.request(
spec.method,
url=spec.endpoint,
json=spec.json,
headers=spec.headers,
)
return GuardrailValidationResult.model_validate(response.json())
Loading
Loading