Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ import agent_control

agent_control.init(
agent_name="my-agent", # Required: human-readable name
agent_id="my-agent-v1", # Required: unique identifier
agent_id="550e8400-e29b-41d4-a716-446655440000", # Required: UUID
server_url="http://localhost:8000", # Optional: defaults to env var
steps=[ # Optional: register available steps
{
Expand Down
5 changes: 4 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ import agent_control
from agent_control import control, ControlViolationError

# Initialize agent (connects to server, loads policy)
agent_control.init(agent_name="my-bot", agent_id="bot-123")
agent_control.init(
agent_name="my-bot",
agent_id="550e8400-e29b-41d4-a716-446655440000",
)

# Apply the agent's assigned policy
@control()
Expand Down
3 changes: 1 addition & 2 deletions examples/agent_control_demo/demo_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

# Configuration
AGENT_NAME = "demo-chatbot"
AGENT_ID = "demo-chatbot-v1"
AGENT_ID = "672e50df-af4c-429f-965a-3d7f8262302f"
SERVER_URL = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")


Expand Down Expand Up @@ -258,4 +258,3 @@ async def run_demo():

if __name__ == "__main__":
asyncio.run(run_demo())

12 changes: 5 additions & 7 deletions examples/agent_control_demo/setup_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

# Configuration
AGENT_NAME = "demo-chatbot"
AGENT_ID = "demo-chatbot-v1"
AGENT_ID = "672e50df-af4c-429f-965a-3d7f8262302f"
SERVER_URL = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")


Expand All @@ -44,9 +44,8 @@ async def create_agent(client: AgentControlClient) -> str:
print("STEP 1: Creating Agent")
print("=" * 60)

# Generate a deterministic UUID from the agent ID
import uuid
agent_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID)
# Use the provided UUID for the agent
agent_uuid = UUID(AGENT_ID)

try:
response = await client.http_client.post(
Expand Down Expand Up @@ -440,9 +439,8 @@ async def main():
print(" cd server && make run")
return

# Generate agent UUID
import uuid
agent_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID))
# Use the provided UUID for verification
agent_uuid = AGENT_ID

# If verify-only mode, just run verification
if args.verify_only:
Expand Down
8 changes: 3 additions & 5 deletions examples/agent_control_demo/update_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@
import asyncio
import os
import sys
import uuid

# Add the SDK to path for development
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../sdks/python/src"))

from agent_control import AgentControlClient

# Configuration
AGENT_ID = "demo-chatbot-v1"
AGENT_ID = "672e50df-af4c-429f-965a-3d7f8262302f"
SERVER_URL = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")


Expand Down Expand Up @@ -156,8 +154,8 @@ async def main():
parser.add_argument("--status", action="store_true", help="Show current status")
args = parser.parse_args()

# Generate agent UUID
agent_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID))
# Use the provided UUID
agent_uuid = AGENT_ID

print("\n" + "=" * 60)
print("AGENT CONTROL DEMO: Update Controls")
Expand Down
2 changes: 1 addition & 1 deletion examples/crewai/content_agent_protection.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
# It's a dependency of agent_control so should be available

# --- Configuration ---
AGENT_ID = "support-crew-demo"
AGENT_ID = "989d84f0-9afe-4fb2-9e9e-e9d076271e29"
AGENT_NAME = "Customer Support Crew"
AGENT_DESCRIPTION = "Customer support crew with PII protection and access controls"

Expand Down
6 changes: 3 additions & 3 deletions examples/crewai/setup_content_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@

import asyncio
import os
import uuid
from uuid import UUID

from agent_control import Agent, AgentControlClient, agents, controls, policies

AGENT_ID = "support-crew-demo"
AGENT_ID = "989d84f0-9afe-4fb2-9e9e-e9d076271e29"
SERVER_URL = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")


async def setup_content_controls():
"""Create PII protection and unauthorized access controls, policy, and assign to agent."""
async with AgentControlClient(base_url=SERVER_URL) as client:
# 1. Register Agent
agent_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID)
agent_uuid = UUID(AGENT_ID)

agent = Agent(
agent_id=agent_uuid,
Expand Down
2 changes: 1 addition & 1 deletion examples/customer_support_agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ import agent_control

agent_control.init(
agent_name="Customer Support Agent",
agent_id="customer-support-agent",
agent_id="646d5dea-c2e6-4453-b446-7035482b38e4",
agent_description="AI-powered customer support assistant",
)
```
Expand Down
4 changes: 2 additions & 2 deletions examples/customer_support_agent/demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ setup_demo_controls() {
python setup_demo_controls.py
}

# Generate UUID5 from agent ID (matches Python's uuid.uuid5(uuid.NAMESPACE_DNS, agent_id))
# Agent UUID used by the demo (must match support_agent.py)
get_agent_uuid() {
python3 -c "import uuid; print(uuid.uuid5(uuid.NAMESPACE_DNS, 'customer-support-agent'))"
echo "646d5dea-c2e6-4453-b446-7035482b38e4"
}

show_observability_stats() {
Expand Down
9 changes: 3 additions & 6 deletions examples/customer_support_agent/run_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,13 @@
# Add parent directory to path for imports
sys.path.insert(0, str(__file__).rsplit("/", 2)[0])

# Agent ID used in support_agent.py
AGENT_ID = "customer-support-agent"
# Agent UUID used in support_agent.py
AGENT_ID = "646d5dea-c2e6-4453-b446-7035482b38e4"


async def reset_agent():
"""Reset the agent by removing its policy (which disconnects all controls)."""
import uuid

# Generate the same UUID5 that the SDK generates
agent_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID))
agent_uuid = AGENT_ID
server_url = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")

logger.info(f"Resetting agent '{AGENT_ID}' (UUID: {agent_uuid})")
Expand Down
8 changes: 3 additions & 5 deletions examples/customer_support_agent/setup_demo_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@

import asyncio
import os
import uuid

from agent_control import Agent, AgentControlClient, agents, controls, policies

# Same agent ID as in support_agent.py
AGENT_ID = "customer-support-agent"
AGENT_ID = "646d5dea-c2e6-4453-b446-7035482b38e4"
AGENT_NAME = "Customer Support Agent"
AGENT_DESCRIPTION = "AI-powered customer support assistant"

Expand Down Expand Up @@ -228,8 +226,8 @@

async def setup_demo(quiet: bool = False):
"""Set up the demo agent with controls."""
# Generate the same UUID5 that the SDK generates
agent_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID))
# Use the provided UUID (must match support_agent.py)
agent_uuid = AGENT_ID

async with AgentControlClient(base_url=SERVER_URL, timeout=30.0) as client:
# Check server health
Expand Down
2 changes: 1 addition & 1 deletion examples/customer_support_agent/support_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

agent_control.init(
agent_name="Customer Support Agent",
agent_id="customer-support-agent",
agent_id="646d5dea-c2e6-4453-b446-7035482b38e4",
agent_description="AI-powered customer support assistant that helps with inquiries, "
"searches knowledge bases, and creates support tickets.",
agent_version="1.0.0",
Expand Down
6 changes: 3 additions & 3 deletions examples/langchain/setup_sql_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import asyncio
import os
import pathlib
import uuid
from uuid import UUID

import requests

from agent_control import Agent, AgentControlClient, agents, controls, policies

AGENT_ID = "sql-agent-demo"
AGENT_ID = "edf66504-0db5-4ee8-9e09-3ef37bbb8faa"
SERVER_URL = os.getenv("AGENT_CONTROL_URL", "http://localhost:8000")


Expand Down Expand Up @@ -52,7 +52,7 @@ async def setup_sql_controls():
"""Create SQL control, policy, and assign to agent."""
async with AgentControlClient(base_url=SERVER_URL) as client:
# 1. Register Agent
agent_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, AGENT_ID)
agent_uuid = UUID(AGENT_ID)

agent = Agent(
agent_id=agent_uuid,
Expand Down
2 changes: 1 addition & 1 deletion examples/langchain/sql_agent_protection.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from langgraph.prebuilt import ToolNode

# --- Configuration ---
AGENT_ID = "sql-agent-demo"
AGENT_ID = "edf66504-0db5-4ee8-9e09-3ef37bbb8faa"
AGENT_NAME = "SQL Demo Agent"
AGENT_DESCRIPTION = "SQL agent with server-side controls"
USE_LOCAL_CONTROLS = os.getenv("AGENT_CONTROL_LOCAL_EVAL", "false").lower() == "true"
Expand Down
9 changes: 4 additions & 5 deletions models/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ from agent_control_models import Agent, Step
# Create an agent
agent = Agent(
agent_name="Customer Support Bot",
agent_id="support-bot-v1",
agent_id="550e8400-e29b-41d4-a716-446655440000",
agent_description="Handles customer inquiries",
agent_version="1.0.0"
)
Expand Down Expand Up @@ -129,7 +129,7 @@ Agent metadata and configuration.

**Fields:**
- `agent_name` (str): Human-readable agent name
- `agent_id` (str): Unique identifier
- `agent_id` (UUID): Unique identifier
- `agent_description` (Optional[str]): Agent description
- `agent_version` (Optional[str]): Agent version
- `tools` (Optional[List[str]]): List of available tools
Expand Down Expand Up @@ -198,7 +198,7 @@ from agent_control_models import Agent
# Create with validation
agent = Agent(
agent_name="My Agent",
agent_id="my-agent-v1"
agent_id="550e8400-e29b-41d4-a716-446655440000"
)

# Serialize to dict
Expand Down Expand Up @@ -243,7 +243,7 @@ from agent_control_models import Agent
# Add custom metadata
agent = Agent(
agent_name="Support Bot",
agent_id="support-v1",
agent_id="550e8400-e29b-41d4-a716-446655440000",
metadata={
"team": "customer-success",
"environment": "production",
Expand Down Expand Up @@ -291,4 +291,3 @@ uv run pytest
4. **Version carefully**: Model changes affect both server and SDK
5. **Document fields**: Use Field's `description` parameter
6. **Use Optional appropriately**: Mark optional fields clearly

10 changes: 7 additions & 3 deletions sdks/python/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ async with agent_control.AgentControlClient() as client:
)

# Get agent
agent_data = await agent_control.agents.get_agent(client, "agent-id")
agent_data = await agent_control.agents.get_agent(
client, "550e8400-e29b-41d4-a716-446655440000"
)
```

### `policies.py` - Policy Operations
Expand Down Expand Up @@ -259,11 +261,13 @@ High-level convenience functions are provided in `__init__.py` for common operat

```python
# Convenience: No need to manage client manually
agent_data = await agent_control.get_agent("agent-id")
agent_data = await agent_control.get_agent("550e8400-e29b-41d4-a716-446655440000")

# Equivalent module-first approach:
async with AgentControlClient() as client:
agent_data = await agent_control.agents.get_agent(client, "agent-id")
agent_data = await agent_control.agents.get_agent(
client, "550e8400-e29b-41d4-a716-446655440000"
)
```

### 4. API Stability
Expand Down
22 changes: 14 additions & 8 deletions sdks/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import agent_control
# Initialize at the base of your agent
agent_control.init(
agent_name="My Customer Service Bot",
agent_id="csbot-prod-v1"
agent_id="550e8400-e29b-41d4-a716-446655440000"
)

# Use the control decorator
Expand All @@ -36,7 +36,7 @@ import agent_control

agent_control.init(
agent_name="Customer Service Bot",
agent_id="csbot-prod-v1",
agent_id="550e8400-e29b-41d4-a716-446655440000",
agent_description="Handles customer inquiries and support",
agent_version="2.1.0",
server_url="http://localhost:8000",
Expand All @@ -53,7 +53,10 @@ agent_control.init(
One line to set up your agent with full protection:

```python
agent_control.init(agent_name="...", agent_id="...")
agent_control.init(
agent_name="...",
agent_id="550e8400-e29b-41d4-a716-446655440000",
)
```

This automatically:
Expand Down Expand Up @@ -87,7 +90,7 @@ async with AgentControlClient() as client:
# Evaluate a step
result = await agent_control.evaluation.check_evaluation(
client,
agent_uuid="your-agent-uuid",
agent_uuid="550e8400-e29b-41d4-a716-446655440000",
step={"type": "llm_inference", "input": "User input here"},
stage="pre"
)
Expand All @@ -114,7 +117,7 @@ from agent_control import control, ControlViolationError
# Initialize
agent_control.init(
agent_name="Customer Support Bot",
agent_id="support-bot-v1",
agent_id="550e8400-e29b-41d4-a716-446655440000",
agent_version="1.0.0"
)

Expand Down Expand Up @@ -155,7 +158,7 @@ asyncio.run(main())
```python
def init(
agent_name: str,
agent_id: str,
agent_id: str | UUID,
agent_description: Optional[str] = None,
agent_version: Optional[str] = None,
server_url: Optional[str] = None,
Expand All @@ -168,7 +171,7 @@ Initialize Agent Control with your agent's information.

**Parameters:**
- `agent_name`: Human-readable name
- `agent_id`: Unique identifier (user-defined)
- `agent_id`: UUID string (or UUID instance)
- `agent_description`: Optional description
- `agent_version`: Optional version string
- `server_url`: Optional server URL (defaults to `AGENT_CONTROL_URL` env var)
Expand Down Expand Up @@ -273,7 +276,10 @@ Basic usage:
import agent_control
from agent_control import control, ControlViolationError

agent_control.init(agent_name="...", agent_id="...")
agent_control.init(
agent_name="...",
agent_id="550e8400-e29b-41d4-a716-446655440000",
)

@control()
async def handle(message: str):
Expand Down
Loading
Loading