import asyncio
import os
import sys
from agents import Runner
from agents.run import RunConfig
from agents.sandbox import SandboxAgent, SandboxRunConfig
from declaw.openai import (
DeclawSandboxClient,
DeclawSandboxClientOptions,
PIIConfig,
PIIHandler,
SecurityPolicy,
)
USER_GOAL = (
"Our customer is Alice (email: alice@acme.com, SSN 123-45-6789). "
"Write her case details to /workspace/case.txt, then tell me the byte count."
)
async def main() -> None:
# --- Layer 1: anonymize the prompt before it reaches the model ---
pii = PIIHandler()
(anonymized_goal,), rmap = pii.anonymize([USER_GOAL])
print("original goal:")
print(" ", USER_GOAL)
print("anonymized goal (what the LLM sees):")
print(" ", anonymized_goal)
print(f"redaction map entries: {len(rmap)}")
# --- Layer 2: sandbox with edge-proxy PII scanning ---
options = DeclawSandboxClientOptions(
template="base",
timeout=180,
security=SecurityPolicy(
pii=PIIConfig(
enabled=True,
action="redact",
rehydrate_response=True, # keep the sandbox program's view intact
),
),
)
client = DeclawSandboxClient()
session = await client.create(options=options)
try:
agent = SandboxAgent(
name="pii-demo",
model="gpt-5.4",
instructions="You are a customer-ops agent. Use the bash tool as instructed.",
)
result = await Runner.run(
agent,
anonymized_goal,
run_config=RunConfig(sandbox=SandboxRunConfig(session=session)),
)
# Rehydrate the model's output so downstream customer-facing
# code sees the original PII again.
final = pii.deanonymize(result.final_output, rmap)
print("\n== final (rehydrated) ==")
print(final)
finally:
await client.delete(session)
if __name__ == "__main__":
asyncio.run(main())