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-langchain"
version = "0.18.54"
version = "0.18.55"
description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
dependencies = [
"uipath>=2.14.45, <2.15.0",
"uipath-core>=0.5.33, <0.6.0",
"uipath-core>=0.5.34, <0.6.0",
"uipath-platform>=0.2.43, <0.3.0",
"uipath-runtime>=0.13.5, <0.14.0",
"uipath-llm-client>=1.22.0, <1.23.0",
Expand Down
10 changes: 9 additions & 1 deletion src/uipath_langchain/agent/guardrails/guardrail_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,17 @@ def _create_validation_command(
)

if guardrail_result.result == GuardrailValidationResultType.VALIDATION_FAILED:
details = guardrail_result.reason
# The guardrail could not be evaluated (fail-closed); say so instead of
# reporting the provider error as a violation.
if guardrail_result.error_type is not None:
details = (
f"Guardrail could not be evaluated "
f"({guardrail_result.error_type.value}): {guardrail_result.reason}"
)
inner_state = {
"guardrail_validation_result": False,
"guardrail_validation_details": guardrail_result.reason,
"guardrail_validation_details": details,
"guardrail_flagged_file_names": flagged_file_names,
"guardrail_attachments": sent_attachments,
}
Expand Down
37 changes: 37 additions & 0 deletions tests/agent/guardrails/test_guardrail_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from _pytest.monkeypatch import MonkeyPatch
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, ToolMessage
from uipath.core.guardrails import (
GuardrailValidationErrorType,
GuardrailValidationResult,
GuardrailValidationResultType,
)
Expand Down Expand Up @@ -661,6 +662,42 @@ def test_create_validation_command_failure(self):
}
}

@pytest.mark.parametrize(
"error_type",
[
GuardrailValidationErrorType.PROVIDER_ERROR,
GuardrailValidationErrorType.INTERNAL_ERROR,
GuardrailValidationErrorType.RATE_LIMIT_EXCEEDED,
],
)
def test_create_validation_command_error_routes_to_failure_with_labelled_details(
self, error_type: GuardrailValidationErrorType
):
"""A guardrail that could not be evaluated still fails closed, with labelled details."""
from uipath_langchain.agent.guardrails.guardrail_nodes import (
_create_validation_command,
)

result = GuardrailValidationResult(
result=GuardrailValidationResultType.VALIDATION_FAILED,
reason="`temperature` is deprecated for this model.",
error_type=error_type,
)
command = _create_validation_command(result, "success_node", "failure_node")

assert command.goto == "failure_node"
assert command.update == {
"inner_state": {
"guardrail_validation_result": False,
"guardrail_validation_details": (
f"Guardrail could not be evaluated ({error_type.value}): "
"`temperature` is deprecated for this model."
),
"guardrail_flagged_file_names": None,
"guardrail_attachments": None,
}
}

def test_create_validation_command_success_with_span_id(self):
"""Test validation command includes guardrail_span_id when span_id is present."""
from uipath_langchain.agent.guardrails.guardrail_nodes import (
Expand Down
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading