Skip to content

Conversation

@apetraru-uipath
Copy link
Contributor

@apetraru-uipath apetraru-uipath commented Dec 23, 2025

Integration Tests for Agent Guardrails

Overview

Adds comprehensive integration tests for agent guardrails, verifying proper invocation and enforcement at Agent, LLM, and Tool scopes.

Guardrails Tested

Built-in Validators

  • PII Detection (Agent, LLM & Tool scopes) - Detects Email, Address, Person with 0.5 threshold
  • Prompt Injection (LLM scope) - Detects malicious prompts with 0.5 threshold

Custom Deterministic Guardrails

  • Filter Action - Removes input_phrase field when containing "donkey"
  • Block Action - Blocks tool execution when input contains "forbidden"

Actions Tested

  • Block Action - Stops execution at Agent, LLM, or Tool scope
  • Filter Action - Removes fields from outputs
  • Escalate Action (HITL) - Triggers human approval with both approval and rejection flows

@apetraru-uipath apetraru-uipath force-pushed the chore/tests_for_guardrails branch 6 times, most recently from 3876794 to f260a25 Compare December 29, 2025 08:26
def mock_guardrails_service():
"""Mock the guardrails service to avoid HTTP errors in tests."""

class MockGuardrailValidationResult(BaseModel):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this new class? Cann't we use the GuardrailValidationResult class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I will delete this mock class

"enabledForEvals": true,
"selector": {
"scopes": ["Tool"],
"matchNames": ["Agent _ Sentence Analyzer"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the correct tool name? with spaces?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've downloaded the uis archive and in agent.json the tool names are always with spaces:
Screenshot 2025-12-29 at 15 18 18

We can double check, I know that I had to change the input files agent.json to have tools original names.

)

# Block Guardrail for Tool - blocks if input matches forbidden pattern
# Note: Using CONTAINS operator as MATCHES_REGEX has issues with the current implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this note about? What exactly is not working with CONTAINS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was an issue with Regex matching, probably it was under development at the time I added the tests.
I will add a test specifically for regex, to check if it works as expected

guardrails = build_guardrails_with_actions(
[
custom_filter_guardrail,
pii_detection_guardrail,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give them more explicit names, where to include the scope and action? Like block_agent_pii_detection_guardrail and so on...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this. Moreover, I changed how agent is constructed for each test case so that we have only one guardrail configured for the agent per test

]


# Define guardrails programmatically (matching the uipath.json configuration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to pass guardrails in the joke_agent_uipath.json file? I see that they are not in sync anyway so it looks like it doesn't matter to have them there as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the approach to have in joke_agent_uipath.json a template and to select the guardrails at each test.
I prefer to have that agent template configuration in a file instead of inline-ing it into every test case

# Setup files
with open("joke_agent_with_guardrails.py", "w", encoding="utf-8") as f:
f.write(joke_agent_script)
with open("uipath.json", "w", encoding="utf-8") as f:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What file do we use exacly here? "uipath.json"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, we only use joke_agent_with_guardrails.py and langgraph.json. I will update the setup.


if not has_tool_message:
# First call: return tool call WITH "donkey" in the sentence
return AIMessage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand the real value of these tests, since we mock the model responses. How will these tests protect us in case the model response change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope of those tests (at first version) is to protect us against internal changes (someone updates something in guardrails code). My first intention was to mock any external interactions.

I can check (in another PR) if I can use a real LLM.... but those I see them as tests that are checking if external tools are working as required by us.

@apetraru-uipath apetraru-uipath force-pushed the chore/tests_for_guardrails branch from f260a25 to 3ceef2c Compare December 29, 2025 14:39
Add comprehensive integration tests for guardrails at different scopes:
- Agent-level guardrails (PII detection)
- LLM-level guardrails (Prompt injection)
- Tool-level guardrails (Filter, Block, and PII detection)

Tests verify that guardrails are properly invoked and block/filter as expected.
@apetraru-uipath apetraru-uipath force-pushed the chore/tests_for_guardrails branch from 3ceef2c to 052c5cf Compare December 29, 2025 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants