from upsonic import Agent, Task
from upsonic.safety_engine.base import RuleBase, ActionBase, Policy
from upsonic.safety_engine.models import PolicyInput, RuleOutput, PolicyOutput
import re
class ProjectCodeRule(RuleBase):
name = "Project Code Rule"
description = "Detects internal project codes"
language = "en"
def __init__(self, options=None):
super().__init__(options)
self.pattern = r'\b[A-Z]{2,4}-\d{3,5}\b'
def process(self, policy_input: PolicyInput) -> RuleOutput:
text = " ".join(policy_input.input_texts or [])
matches = re.findall(self.pattern, text)
if not matches:
return RuleOutput(
confidence=0.0,
content_type="SAFE",
details="No project codes found"
)
return RuleOutput(
confidence=1.0,
content_type="PROJECT_CODE",
details=f"Found {len(matches)} project codes",
triggered_keywords=matches
)
class ProjectCodeAction(ActionBase):
name = "Project Code Action"
description = "Redacts project codes"
language = "en"
def action(self, rule_result: RuleOutput) -> PolicyOutput:
if rule_result.confidence >= 0.8:
return self.replace_triggered_keywords("[PROJECT-CODE]")
return self.allow_content()
project_policy = Policy(
name="Project Code Policy",
description="Protects internal project codes",
rule=ProjectCodeRule(),
action=ProjectCodeAction(),
apply_to_description=True,
apply_to_context=True,
apply_to_system_prompt=False,
)
agent = Agent(
model="anthropic/claude-sonnet-4-6",
agent_policy=project_policy,
debug=True
)
task = Task("The issue is in ABC-1234 and XYZ-5678")
result = agent.print_do(task)
print(result)