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
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