Skip to content

Commit 47d9dcf

Browse files
feat(guardrails): add HarmfulContent, IntellectualProperty, UserPromptAttacks middlewares [AL-372] (#751)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 71e583a commit 47d9dcf

File tree

20 files changed

+1021
-190
lines changed

20 files changed

+1021
-190
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[project]
22
name = "uipath-langchain"
3-
version = "0.9.25"
3+
version = "0.9.26"
44
description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
88
"uipath>=2.10.29, <2.11.0",
99
"uipath-core>=0.5.2, <0.6.0",
10-
"uipath-platform>=0.1.24, <0.2.0",
10+
"uipath-platform>=0.1.25, <0.2.0",
1111
"uipath-runtime>=0.10.0, <0.11.0",
1212
"langgraph>=1.0.0, <2.0.0",
1313
"langchain-core>=1.2.11, <2.0.0",

samples/joke-agent-decorator/graph.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@
2323
GuardrailAction,
2424
GuardrailExclude,
2525
GuardrailExecutionStage,
26+
HarmfulContentEntity,
27+
HarmfulContentValidator,
28+
IntellectualPropertyValidator,
2629
LogAction,
2730
LoggingSeverityLevel,
2831
PIIDetectionEntity,
2932
PIIValidator,
30-
PromptInjectionValidator,
33+
UserPromptAttacksValidator,
3134
guardrail,
3235
)
33-
from uipath_langchain.guardrails.enums import PIIDetectionEntityType
36+
from uipath_langchain.guardrails.enums import (
37+
HarmfulContentEntityType,
38+
IntellectualPropertyEntityType,
39+
PIIDetectionEntityType,
40+
)
3441

3542
logger = logging.getLogger(__name__)
3643

@@ -145,11 +152,19 @@ def format_joke_for_display(
145152

146153

147154
@guardrail(
148-
validator=PromptInjectionValidator(threshold=0.5),
155+
validator=UserPromptAttacksValidator(),
149156
action=BlockAction(),
150-
name="LLM Prompt Injection Detection",
157+
name="LLM User Prompt Attacks Detection",
151158
stage=GuardrailExecutionStage.PRE,
152159
)
160+
@guardrail(
161+
validator=IntellectualPropertyValidator(
162+
entities=[IntellectualPropertyEntityType.TEXT],
163+
),
164+
action=LogAction(severity_level=LoggingSeverityLevel.WARNING),
165+
name="LLM Intellectual Property Detection",
166+
stage=GuardrailExecutionStage.POST,
167+
)
153168
@guardrail(
154169
validator=pii_email,
155170
action=LogAction(severity_level=LoggingSeverityLevel.WARNING),
@@ -243,6 +258,14 @@ def analyze_joke_syntax(joke: str) -> str:
243258
# ---------------------------------------------------------------------------
244259

245260

261+
@guardrail(
262+
validator=HarmfulContentValidator(
263+
entities=[HarmfulContentEntity(HarmfulContentEntityType.VIOLENCE, threshold=2)],
264+
),
265+
action=BlockAction(),
266+
name="Agent Harmful Content Detection",
267+
stage=GuardrailExecutionStage.PRE,
268+
)
246269
@guardrail(
247270
validator=PIIValidator(
248271
entities=[PIIDetectionEntity(PIIDetectionEntityType.PERSON, threshold=0.5)],

samples/joke-agent-decorator/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "joke-agent-decorator"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
description = "Joke generating agent that creates family-friendly jokes based on a topic - using decorator-based guardrails"
55
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath-langchain>=0.9.20, <0.10.0",
8+
"uipath-langchain>=0.9.26, <0.10.0",
99
"uipath>2.7.0",
1010
]
1111

samples/joke-agent/graph.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,43 @@
33
from langchain.agents import create_agent
44
from langchain_core.messages import HumanMessage
55
from langchain_core.tools import tool
6-
from langgraph.constants import START, END
6+
from langgraph.constants import END, START
77
from langgraph.graph import StateGraph
8+
from middleware import CustomFilterAction, LoggingMiddleware
89
from pydantic import BaseModel
910
from uipath.core.guardrails import GuardrailScope
1011

11-
from middleware import CustomFilterAction, LoggingMiddleware
1212
from uipath_langchain.chat import UiPathChat
1313
from uipath_langchain.guardrails import (
1414
BlockAction,
15-
PIIDetectionEntity,
1615
GuardrailExecutionStage,
16+
HarmfulContentEntity,
1717
LogAction,
18+
PIIDetectionEntity,
1819
UiPathDeterministicGuardrailMiddleware,
20+
UiPathHarmfulContentMiddleware,
21+
UiPathIntellectualPropertyMiddleware,
1922
UiPathPIIDetectionMiddleware,
20-
UiPathPromptInjectionMiddleware,
23+
UiPathUserPromptAttacksMiddleware,
2124
)
2225
from uipath_langchain.guardrails.actions import LoggingSeverityLevel
23-
from uipath_langchain.guardrails.enums import PIIDetectionEntityType
26+
from uipath_langchain.guardrails.enums import (
27+
HarmfulContentEntityType,
28+
IntellectualPropertyEntityType,
29+
PIIDetectionEntityType,
30+
)
2431

2532

2633
# Define input schema for the agent
2734
class Input(BaseModel):
2835
"""Input schema for the joke agent."""
36+
2937
topic: str
3038

3139

3240
class Output(BaseModel):
3341
"""Output schema for the joke agent."""
42+
3443
joke: str
3544

3645

@@ -57,6 +66,7 @@ def analyze_joke_syntax(joke: str) -> str:
5766

5867
return f"Words number: {word_count}\nLetters: {letter_count}"
5968

69+
6070
# System prompt based on agent1.json
6171
SYSTEM_PROMPT = """You are an AI assistant designed to generate family-friendly jokes. Your process is as follows:
6272
@@ -104,12 +114,25 @@ def analyze_joke_syntax(joke: str) -> str:
104114
tools=[analyze_joke_syntax],
105115
enabled_for_evals=False,
106116
),
107-
*UiPathPromptInjectionMiddleware(
108-
name="Prompt Injection Detection",
117+
*UiPathUserPromptAttacksMiddleware(
118+
name="User Prompt Attacks Detection",
109119
action=BlockAction(),
110-
threshold=0.5,
111120
enabled_for_evals=False,
112121
),
122+
*UiPathHarmfulContentMiddleware(
123+
name="Harmful Content Detection",
124+
scopes=[GuardrailScope.AGENT, GuardrailScope.LLM],
125+
action=BlockAction(),
126+
entities=[
127+
HarmfulContentEntity(HarmfulContentEntityType.VIOLENCE, threshold=2),
128+
],
129+
),
130+
*UiPathIntellectualPropertyMiddleware(
131+
name="Intellectual Property Detection",
132+
scopes=[GuardrailScope.LLM],
133+
action=LogAction(severity_level=LoggingSeverityLevel.WARNING),
134+
entities=[IntellectualPropertyEntityType.TEXT],
135+
),
113136
# Custom FilterAction example: demonstrates how developers can implement their own actions
114137
*UiPathDeterministicGuardrailMiddleware(
115138
tools=[analyze_joke_syntax],
@@ -142,7 +165,7 @@ def analyze_joke_syntax(joke: str) -> str:
142165
),
143166
stage=GuardrailExecutionStage.POST,
144167
name="Joke Content Always Filter",
145-
)
168+
),
146169
],
147170
)
148171

@@ -152,7 +175,9 @@ async def joke_node(state: Input) -> Output:
152175
"""Convert topic to messages, call agent, and extract joke."""
153176
# Convert topic to messages format
154177
messages = [
155-
HumanMessage(content=f"Generate a family-friendly joke based on the topic: {state.topic}")
178+
HumanMessage(
179+
content=f"Generate a family-friendly joke based on the topic: {state.topic}"
180+
)
156181
]
157182

158183
# Call the agent with messages

samples/joke-agent/pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[project]
22
name = "joke-agent"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
description = "Joke generating agent that creates family-friendly jokes based on a topic"
55
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath-langchain",
9-
"uipath",
8+
"uipath-langchain>=0.9.26, <0.10.0",
9+
"uipath>2.7.0",
1010
]
1111

1212
[dependency-groups]

src/uipath_langchain/guardrails/__init__.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,31 @@
1313
GuardrailExecutionStage,
1414
GuardrailTargetAdapter,
1515
GuardrailValidatorBase,
16+
HarmfulContentEntity,
17+
HarmfulContentEntityType,
18+
HarmfulContentValidator,
19+
IntellectualPropertyEntityType,
20+
IntellectualPropertyValidator,
1621
LogAction,
1722
LoggingSeverityLevel,
1823
PIIDetectionEntity,
1924
PIIDetectionEntityType,
2025
PIIValidator,
2126
PromptInjectionValidator,
2227
RuleFunction,
28+
UserPromptAttacksValidator,
2329
guardrail,
2430
register_guardrail_adapter,
2531
)
2632

2733
from ._langchain_adapter import LangChainGuardrailAdapter
2834
from .middlewares import (
2935
UiPathDeterministicGuardrailMiddleware,
36+
UiPathHarmfulContentMiddleware,
37+
UiPathIntellectualPropertyMiddleware,
3038
UiPathPIIDetectionMiddleware,
3139
UiPathPromptInjectionMiddleware,
40+
UiPathUserPromptAttacksMiddleware,
3241
)
3342

3443
# Auto-register the LangChain adapter so @guardrail knows how to wrap
@@ -40,11 +49,17 @@
4049
"guardrail",
4150
# Validators
4251
"GuardrailValidatorBase",
52+
"HarmfulContentValidator",
53+
"IntellectualPropertyValidator",
4354
"PIIValidator",
4455
"PromptInjectionValidator",
56+
"UserPromptAttacksValidator",
4557
"CustomValidator",
4658
"RuleFunction",
4759
# Models & enums
60+
"HarmfulContentEntity",
61+
"HarmfulContentEntityType",
62+
"IntellectualPropertyEntityType",
4863
"PIIDetectionEntity",
4964
"PIIDetectionEntityType",
5065
"GuardrailExecutionStage",
@@ -60,9 +75,12 @@
6075
# Adapter registry
6176
"GuardrailTargetAdapter",
6277
"register_guardrail_adapter",
63-
# Middlewares (unchanged)
78+
# Middlewares
79+
"UiPathHarmfulContentMiddleware",
80+
"UiPathIntellectualPropertyMiddleware",
6481
"UiPathPIIDetectionMiddleware",
6582
"UiPathPromptInjectionMiddleware",
83+
"UiPathUserPromptAttacksMiddleware",
6684
"UiPathDeterministicGuardrailMiddleware",
6785
# Re-exports for backwards compat
6886
"AgentGuardrailSeverityLevel",

src/uipath_langchain/guardrails/enums.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@
33
from uipath.core.guardrails import GuardrailScope
44
from uipath.platform.guardrails.decorators import (
55
GuardrailExecutionStage,
6+
HarmfulContentEntityType,
7+
IntellectualPropertyEntityType,
68
PIIDetectionEntityType,
79
)
810

9-
__all__ = ["GuardrailScope", "PIIDetectionEntityType", "GuardrailExecutionStage"]
11+
__all__ = [
12+
"GuardrailScope",
13+
"HarmfulContentEntityType",
14+
"IntellectualPropertyEntityType",
15+
"PIIDetectionEntityType",
16+
"GuardrailExecutionStage",
17+
]

src/uipath_langchain/guardrails/middlewares/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@
44
RuleFunction,
55
UiPathDeterministicGuardrailMiddleware,
66
)
7+
from .harmful_content import UiPathHarmfulContentMiddleware
8+
from .intellectual_property import UiPathIntellectualPropertyMiddleware
79
from .pii_detection import UiPathPIIDetectionMiddleware
810
from .prompt_injection import UiPathPromptInjectionMiddleware
11+
from .user_prompt_attacks import UiPathUserPromptAttacksMiddleware
912

1013
__all__ = [
1114
"RuleFunction",
1215
"UiPathDeterministicGuardrailMiddleware",
16+
"UiPathHarmfulContentMiddleware",
17+
"UiPathIntellectualPropertyMiddleware",
1318
"UiPathPIIDetectionMiddleware",
1419
"UiPathPromptInjectionMiddleware",
20+
"UiPathUserPromptAttacksMiddleware",
1521
]

0 commit comments

Comments
 (0)