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
49 changes: 36 additions & 13 deletions examples/agent_control_demo/demo_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,8 @@ async def test_scenario(name: str, func, input_text: str):
print(f"\n❌ ERROR: {e}")


async def run_demo():
"""Run the demo scenarios."""
logger.info("Starting agent control demo")
print("\n" + "=" * 60)
print("AGENT CONTROL DEMO: Running Agent")
print("=" * 60)

# Initialize the agent
print(f"\n🤖 Initializing agent: {AGENT_NAME}")
print(f" Server: {SERVER_URL}")

def initialize_demo_agent() -> bool:
"""Initialize the demo agent and print actionable failure guidance."""
try:
logger.info(f"Initializing agent: {AGENT_NAME}")
agent_control.init(
Expand All @@ -165,14 +156,18 @@ async def run_demo():
server_url=SERVER_URL,
)
logger.info("Agent initialized successfully")
return True
except Exception as e:
logger.error(f"Failed to initialize agent: {e}")
print(f"\n❌ Failed to initialize agent: {e}")
print("\nMake sure:")
print(" 1. Server is running: cd server && make run")
print(" 2. Controls are created: python setup_controls.py")
return
return False


async def run_demo_scenarios() -> None:
"""Run the scripted demo scenarios."""
# ==========================================================================
# Test 1: Safe chat message
# ==========================================================================
Expand Down Expand Up @@ -236,7 +231,9 @@ async def run_demo():
"Get user info" # Will generate response with SSN
)

# Summary

def print_demo_summary() -> None:
"""Print the final demo summary."""
logger.info("All demo scenarios completed")
print("\n" + "=" * 60)
print("DEMO COMPLETE!")
Expand All @@ -254,5 +251,31 @@ async def run_demo():
""")


async def run_demo_session() -> None:
"""Initialize the agent and run the scripted demo."""
if not initialize_demo_agent():
return

await run_demo_scenarios()
print_demo_summary()


async def run_demo() -> None:
"""Run the demo scenarios."""
logger.info("Starting agent control demo")
print("\n" + "=" * 60)
print("AGENT CONTROL DEMO: Running Agent")
print("=" * 60)

# Initialize the agent
print(f"\n🤖 Initializing agent: {AGENT_NAME}")
print(f" Server: {SERVER_URL}")

try:
await run_demo_session()
finally:
await agent_control.ashutdown()


if __name__ == "__main__":
asyncio.run(run_demo())
57 changes: 38 additions & 19 deletions examples/crewai/content_agent_protection.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@
AGENT_NAME = "crew-ai-customer-support"
AGENT_DESCRIPTION = "Customer support crew with PII protection and access controls"

# Initialize Agent Control
server_url = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")

agent_control.init(
agent_name=AGENT_NAME,
agent_description=AGENT_DESCRIPTION,
server_url=server_url,
)

def initialize_agent_control() -> None:
"""Initialize the SDK once for this example process."""
current_agent = agent_control.current_agent()
if current_agent is not None and current_agent.agent_name == AGENT_NAME:
return

agent_control.init(
agent_name=AGENT_NAME,
agent_description=AGENT_DESCRIPTION,
server_url=server_url,
)

# --- Define CrewAI Guardrails for Quality Validation ---

Expand Down Expand Up @@ -511,7 +517,8 @@ def verify_setup():
return False


def main():
def print_demo_intro() -> None:
"""Print the demo header and description."""
print("=" * 60)
print("CrewAI Customer Support: Agent Control + Guardrails")
print("=" * 60)
Expand All @@ -520,29 +527,34 @@ def main():
print("work together to ensure both safe AND high-quality responses.")
print()

# Verify setup

def verify_prerequisites() -> bool:
"""Validate server setup and required environment variables."""
print("\n" + "="*60)
print("SETUP VERIFICATION")
print("="*60)

if not verify_setup():
print("\n❌ Setup verification failed. Please fix the issues above.")
return
return False

# Check API key
if not os.getenv("OPENAI_API_KEY"):
print("\n❌ Error: OPENAI_API_KEY not set")
print("Please set: export OPENAI_API_KEY='your-key-here'")
return
return False

print("\n✅ Setup verified! Starting demos...\n")
return True

# Create crew and final output validator

def run_demo_session() -> None:
"""Initialize the SDK and run the CrewAI demo scenarios."""
initialize_agent_control()

print("\n✅ Setup verified! Starting demos...\n")
print("Creating customer support crew with multi-layer protection...")
crew = create_support_crew()
validate_final_output = create_final_output_validator()

# --- Scenario 1: Unauthorized Access Attempt (Agent Control PRE-execution) ---
print("\n" + "="*50)
print("SCENARIO 1: Unauthorized Access (Agent Control PRE)")
print("="*50)
Expand All @@ -559,7 +571,6 @@ def main():
print("\n💡 Explanation: Agent Control blocks security violations immediately.")
print(" No retries because unauthorized access is non-negotiable.")

# --- Scenario 2: PII Leakage in Response (Agent Control POST-execution) ---
print("\n" + "="*50)
print("SCENARIO 2: PII Leakage (Agent Control POST)")
print("="*50)
Expand All @@ -576,7 +587,6 @@ def main():
print("\n💡 Explanation: Agent Control blocks PII violations immediately.")
print(" No retries because PII leakage is a compliance violation.")

# --- Scenario 2.5: Poor Quality Response (CrewAI Guardrails with Retry) ---
print("\n" + "="*50)
print("SCENARIO 2.5: Quality Issues (CrewAI Guardrails)")
print("="*50)
Expand All @@ -601,7 +611,6 @@ def main():
print(" - Friendly tone (LLM-based)")
print(" - Useful information (LLM-based)")

# --- Scenario 3: Final Output Validation (Catches Unprotected Tool PII) ---
print("\n" + "="*50)
print("SCENARIO 3: Final Output Validation - Catches PII from Unprotected Tool")
print("="*50)
Expand All @@ -616,7 +625,6 @@ def main():
print("- Final output validation catches the PII and blocks it")
print()

# Create separate crew for Scenario 3 with unprotected tool
print("Creating Scenario 3 crew with unprotected customer info tool...")
scenario3_crew = create_scenario3_crew()

Expand All @@ -631,7 +639,6 @@ def main():

print("\n[Validating Final Output]")
try:
# Validate the final crew output for PII
validated_output = validate_final_output(str(result3))
print("\n📝 Result (Validated - No PII):")
print(validated_output)
Expand Down Expand Up @@ -677,5 +684,17 @@ def main():
""")


def main():
print_demo_intro()

if not verify_prerequisites():
return

try:
run_demo_session()
finally:
agent_control.shutdown()


if __name__ == "__main__":
main()
44 changes: 28 additions & 16 deletions examples/customer_support_agent/run_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@
import logging
import os
import sys
from typing import TYPE_CHECKING

import agent_control
from agent_control import AgentControlClient, agents, controls

if TYPE_CHECKING:
from support_agent import CustomerSupportAgent

# Configure logging to see SDK debug output
logging.basicConfig(
level=logging.INFO,
Expand Down Expand Up @@ -68,7 +73,7 @@ async def reset_agent():
async with AgentControlClient(base_url=server_url) as client:
# Check if agent exists
try:
await agents.get_agent(client, agent_name)
await agents.get_agent(client, AGENT_NAME)
logger.debug("Agent exists, proceeding with reset")
except Exception as e:
if "404" in str(e):
Expand All @@ -93,7 +98,7 @@ async def reset_agent():
try:
remove_result = await agents.remove_agent_control(
client,
agent_name,
AGENT_NAME,
control_id,
)
if remove_result.get("removed_direct_association"):
Expand All @@ -104,7 +109,7 @@ async def reset_agent():
logger.debug(
"Error removing direct control %s from %s: %s",
control_id,
agent_name,
AGENT_NAME,
e,
)

Expand Down Expand Up @@ -244,7 +249,7 @@ async def run_interactive(agent: CustomerSupportAgent):
print("Usage: /comprehensive [customer_id] <message>")
print("Example: /comprehensive C001 I need help with a refund")
else:
print(f"Running comprehensive support flow (multi-span)...")
print("Running comprehensive support flow (multi-span)...")
if customer_id:
print(f" Customer: {customer_id}")
print(f" Message: {message}")
Expand Down Expand Up @@ -292,7 +297,13 @@ async def run_interactive(agent: CustomerSupportAgent):
response = await agent.chat(user_input)
print(f"Agent: {response}")

print()

async def run_demo_mode(agent: CustomerSupportAgent, automated: bool) -> None:
"""Run the selected demo mode."""
if automated:
await run_automated_tests(agent)
else:
await run_interactive(agent)


async def run_safe_tests(agent: CustomerSupportAgent):
Expand Down Expand Up @@ -609,19 +620,20 @@ def main():
asyncio.run(reset_agent())
return

# Create agent instance (this triggers SDK initialization)
logger.info("Initializing customer support agent")
agent = get_agent()
logger.info("Agent initialized successfully")
try:
# Create agent instance (this triggers SDK initialization)
logger.info("Initializing customer support agent")
agent = get_agent()
logger.info("Agent initialized successfully")

# Run appropriate mode
mode = "automated" if (args.automated or args.mode == "automated") else "interactive"
logger.info(f"Starting demo in {mode} mode")
# Run appropriate mode
automated = args.automated or args.mode == "automated"
mode = "automated" if automated else "interactive"
logger.info(f"Starting demo in {mode} mode")

if args.automated or args.mode == "automated":
asyncio.run(run_automated_tests(agent))
else:
asyncio.run(run_interactive(agent))
asyncio.run(run_demo_mode(agent, automated=automated))
finally:
agent_control.shutdown()


if __name__ == "__main__":
Expand Down
Loading
Loading