Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4c363ad
feat: cut over to optional multi-policy and direct agent controls
lan17 Feb 23, 2026
a071c84
fix: make agent control removal non-destructive and drop sdk aliases
lan17 Feb 23, 2026
c68872a
feat: expose control usage counts and refresh docs
lan17 Feb 23, 2026
08757f9
fix: clarify agent control removal and cleanup failed add flow
lan17 Feb 23, 2026
ae45dc2
chore: regenerate ts sdk and ui api types
lan17 Feb 23, 2026
e10636b
chore(ui): apply prettier formatting
lan17 Feb 23, 2026
998f596
test(ui): align control removal and usage table specs
lan17 Feb 23, 2026
c285d44
fix: harden agent association semantics and add coverage
lan17 Feb 23, 2026
840a9db
fix: address review findings in server filters and control-store hooks
lan17 Feb 23, 2026
1b583e7
chore: regenerate typescript sdk for updated agent policy docs
lan17 Feb 23, 2026
dad5118
test: add behavioral coverage for policy/direct control invariants
lan17 Feb 23, 2026
44088a9
update_readme
lan17 Feb 24, 2026
eaf6ba6
docs(ui): remove policy wording from docs and user-facing UI copy
lan17 Feb 25, 2026
df82155
Merge remote-tracking branch 'origin/main' into lev/sc-54639
lan17 Feb 25, 2026
c012721
fix(server): remove stale agent.policy_id check
lan17 Feb 26, 2026
f4245c6
test(server): use policies route in overwrite conflict test
lan17 Feb 26, 2026
7ee3d48
fix(server): rebase agent policy m2m migration to squashed schema
lan17 Feb 26, 2026
944b5bb
Merge remote-tracking branch 'origin/main' into lev/sc-54639
lan17 Feb 27, 2026
ed2caf0
Merge remote-tracking branch 'origin/main' into lev/sc-54639
lan17 Mar 2, 2026
e5240c7
fix: repair post-merge test and typing regressions
lan17 Mar 2, 2026
eec9cbd
fix: restore name-native agent identity from main
lan17 Mar 2, 2026
ee9daa0
fix: drop stale agent_uuid references
lan17 Mar 2, 2026
f8c23a5
chore: eliminate remaining agent_id references
lan17 Mar 2, 2026
4f75200
fix(ui/examples): align agent control flows with policy-based APIs
lan17 Mar 2, 2026
1bd3acb
fix(server): restore agent policy/control association semantics
lan17 Mar 2, 2026
186c3ef
fix: restore multi-policy and direct-control integrations
lan17 Mar 2, 2026
4499d30
fix: restore python convenience associations and demo reset semantics
lan17 Mar 3, 2026
15eca02
docs: align control association wording across sdk and examples
lan17 Mar 3, 2026
e5f5411
fix!: remove AgentSummary policy_id and align direct-control docs/tests
lan17 Mar 3, 2026
ac59b04
test: add multi-policy additive coverage and fix server docs
lan17 Mar 3, 2026
9a66aef
fix: address multi-policy review findings and test gaps
lan17 Mar 3, 2026
7bc1808
fix: stabilize sdk-ts CI generate checks
lan17 Mar 3, 2026
51abe38
refactor(examples): remove policy-based association flows
lan17 Mar 3, 2026
da28bb8
fix: address latest PR review threads
lan17 Mar 3, 2026
f219705
fix: resolve ui and sdk-ts-ci CI failures
lan17 Mar 3, 2026
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
75 changes: 47 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

**Runtime guardrails for AI agents — configurable, extensible, and production-ready.**

AI agents interact with users, tools, and external systems in unpredictable ways. **Agent Control** provides an extensible, policy-based runtime layer that evaluates inputs and outputs against configurable rules — blocking prompt injections, PII leakage, and other risks without modifying your agent's code.
AI agents interact with users, tools, and external systems in unpredictable ways. **Agent Control** provides an extensible, control-based runtime layer that evaluates inputs and outputs against configurable rules — blocking prompt injections, PII leakage, and other risks without modifying your agent's code.

![Agent Control Architecture](docs/images/Architecture.png)

Expand All @@ -23,15 +23,15 @@ Traditional guardrails embedded inside your agent code have critical limitations
**Agent Control gives you runtime control over what your agents can and cannot do:**
- **For developers:** Centralize safety logic and adapt to emerging threats instantly without redeployment
- **For non-technical teams:** Intuitive UI to configure and monitor agent safety without touching code
- **For organizations:** Reusable policies across agents with comprehensive audit trails
- **For organizations:** Reusable controls across agents with comprehensive audit trails

---

## Key Features

- **Safety Without Code Changes** — Add guardrails with a `@control()` decorator
- **Runtime Configuration** — Update controls instantly via API or UI without having to re-deploy your agentic applications
- **Centralized Policies** — Define controls once, apply to multiple agents
- **Centralized Controls** — Define controls once, apply to multiple agents
- **Web Dashboard** — Visual interface for managing agents, controls, and viewing analytics
- **Pluggable Evaluators** — Built-in (regex, list matching, Luna-2 AI) or custom evaluators
- **Fail-Safe Defaults** — Deny controls fail closed on error with configurable error handling
Expand Down Expand Up @@ -119,12 +119,16 @@ cd agent-control
# Install dependencies
make sync

# Start server (automatically starts Postgres + runs migrations + starts server)
# Start PostgreSQL database
cd server && docker-compose up -d && cd ..

# Run database migrations
make server-alembic-upgrade

# Start the Agent Control server
make server-run
```

> 💡 **First time?** The command above handles everything: starts Postgres, runs migrations, and starts the server. Migrations are idempotent - safe to run multiple times.

**Server is now running at `http://localhost:8000`** ✅

> 💡 **Verify it's working:** Open http://localhost:8000/health in your browser - you should see `{"status": "ok"}`
Expand Down Expand Up @@ -155,16 +159,16 @@ Create controls to protect your agent's operations:
# setup.py - Run once to configure everything
import asyncio
from datetime import datetime, UTC
from agent_control import AgentControlClient, controls, policies, agents
from agent_control import AgentControlClient, controls, agents
from agent_control_models import Agent

async def setup():
async with AgentControlClient() as client: # Defaults to localhost:8000
# 1. Register agent first (required before assigning policy)
# 1. Register agent first
agent = Agent(
# Your agent's UUID
agent_name="550e8400-e29b-41d4-a716-446655440000",
agent_name="My Chatbot",
agent_description="My Chatbot",
agent_created_at=datetime.now(UTC).isoformat()
)
await agents.register_agent(client, agent, steps=[])
Expand All @@ -185,26 +189,15 @@ async def setup():
"action": {"decision": "deny"}
}
)
# 3. Create policy
policy = await policies.create_policy(client, name="production-policy")

# 4. Add control to policy
await policies.add_control_to_policy(
client,
policy_id=policy["policy_id"],
control_id=control["control_id"]
)

# 5. Assign policy to agent
await policies.assign_policy_to_agent(
# 3. Associate control directly with agent
await agents.add_agent_control(
client,
agent_name=AGENT_ID,
policy_id=policy["policy_id"]
agent_name=agent.agent_name,
control_id=control["control_id"],
)

print("✅ Setup complete!")
print(f" Control ID: {control['control_id']}")
print(f" Policy ID: {policy['policy_id']}")

asyncio.run(setup())
```
Expand All @@ -231,8 +224,8 @@ from agent_control import control, ControlViolationError

# Initialize your agent
agent_control.init(
agent_name="My Chatbot",
agent_name="550e8400-e29b-41d4-a716-446655440000"
agent_name="550e8400-e29b-41d4-a716-446655440000", # Agent identifier (UUID recommended)
agent_description="My Chatbot",
)

# Protect any function (like LLM calls)
Expand Down Expand Up @@ -289,6 +282,28 @@ uv run my_agent.py

> **💡 Pro Tip:** Start with simple regex controls, then graduate to AI-powered evaluators for complex safety checks!

### 5. Assign Controls

Controls can be associated directly with agents. An agent's **active controls** are the controls currently linked to that agent.

**Direct controls** — attach individual controls to an agent:

```bash
# Add a control directly to an agent
curl -X POST http://localhost:8000/api/v1/agents/support-agent-v1/controls/3

# Remove a direct control
curl -X DELETE http://localhost:8000/api/v1/agents/support-agent-v1/controls/3
```

**List all active controls**:

```bash
curl http://localhost:8000/api/v1/agents/support-agent-v1/controls
```

> Controls are optional. An agent can operate with no controls configured.

---

## Configuration
Expand All @@ -299,7 +314,7 @@ uv run my_agent.py
|----------|---------|-------------|
| `AGENT_CONTROL_URL` | `http://localhost:8000` | Server URL for SDK |
| `AGENT_CONTROL_API_KEY` | — | API key for authentication (if enabled) |
| `DATABASE_URL` or `DB_URL` | `postgresql+psycopg://agent_control:agent_control@localhost:5432/agent_control` | Database connection string (`DATABASE_URL` preferred for Docker, `DB_URL` for local dev. SQLite: `sqlite+aiosqlite:///./agent_control.db`) |
| `DB_URL` | `postgresql+psycopg://agent_control:agent_control@localhost:5432/agent_control` | Database connection string (SQLite: `sqlite+aiosqlite:///./agent_control.db`) |
| `GALILEO_API_KEY` | — | Required for Luna-2 AI evaluator |

### Server Configuration
Expand Down Expand Up @@ -334,8 +349,9 @@ Agent Control is built as a monorepo with these components:
┌──────────────────────────────────────────────────────────────────┐
│ Agent Control Server │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Controls │ │ Policies │ │ Evaluators │ │ Agents │ │
│ │ Controls │ │Control Link│ │ Evaluators │ │ Agents │ │
│ │ API │ │ API │ │ Registry │ │ API │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Expand All @@ -353,6 +369,7 @@ Agent Control is built as a monorepo with these components:
| Package | Description |
|:--------|:------------|
| `agent-control-sdk` | Python SDK with `@control()` decorator |
| `agent-control` (npm) | TypeScript SDK (generated from OpenAPI) |
| `agent-control-server` | FastAPI server with Control Management API |
| `agent-control-engine` | Core evaluation logic and evaluator system |
| `agent-control-models` | Shared Pydantic v2 models |
Expand All @@ -368,10 +385,12 @@ Agent Control is built as a monorepo with these components:
```
agent-control/
├── sdks/python/ # Python SDK (agent-control)
├── sdks/typescript/ # TypeScript SDK (generated)
├── server/ # FastAPI server (agent-control-server)
├── engine/ # Evaluation engine (agent-control-engine)
├── models/ # Shared models (agent-control-models)
├── evaluators/ # Evaluator implementations (agent-control-evaluators)
├── ui/ # Next.js web dashboard
└── examples/ # Usage examples
```

Expand Down
21 changes: 9 additions & 12 deletions docs/OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Runtime guardrails for AI agents — configurable, extensible, and production-ready.**

Agent Control provides a policy-based control layer that sits between your AI agents and the outside world. It evaluates inputs and outputs against configurable rules, blocking harmful content, prompt injections, PII leakage, and other risks — all without changing your agent's code.
Agent Control provides a control-based runtime layer that sits between your AI agents and the outside world. It evaluates inputs and outputs against configurable rules, blocking harmful content, prompt injections, PII leakage, and other risks — all without changing your agent's code.

---

Expand Down Expand Up @@ -57,15 +57,12 @@ A **Control Set** is a named group of related controls. Use them to organize con
| `compliance-controls` | block-pii, block-phi, audit-logging |
| `quality-controls` | check-hallucination, verify-sources |

### 📜 Policies
### 🔗 Control Associations

A **Policy** combines one or more Control Sets and is assigned to agents. Policies let you:
- Reuse control sets across multiple agents
- Version and audit your safety rules
- Apply different policies to different environments (dev/staging/prod)
Controls can be linked directly to agents and reused across multiple agents. This keeps rollout and tuning fast without redeploying application code.

```
Policy → Control Sets → Controls → Agents
Controls → Agents
```

### 🎯 Selectors
Expand Down Expand Up @@ -335,14 +332,14 @@ async def chat(message: str) -> str:
Update controls without redeploying your application. Critical for:
- Responding to emerging threats
- Tuning thresholds based on real-world data
- A/B testing different safety policies
- A/B testing different safety controls

### 🎯 Centralized Policy Management
Define controls once, apply them to multiple agents. Security teams can manage policies independently from development teams.
### 🎯 Centralized Control Management
Define controls once, apply them to multiple agents. Security teams can manage controls independently from development teams.

```
┌─────────────────────────────────────────────────────┐
Policy
Control Collection
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Control Set │ │ Control Set │ │ Control Set │ │
│ │ (Safety) │ │ (Compliance)│ │ (Quality) │ │
Expand Down Expand Up @@ -398,7 +395,7 @@ Choose how to handle failures:
┌──────────────────────────────────────────────────────────────────┐
│ Agent Control Server │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Controls │ │ Policies │ │ Evaluators │ │ Agents │ │
│ │ Controls │ │Control Link│ │ Evaluators │ │ Agents │ │
│ │ API │ │ API │ │ Registry │ │ API │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Expand Down
53 changes: 15 additions & 38 deletions docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This document provides comprehensive technical reference for Agent Control. Each

## Introduction

Agent Control provides a policy-based control layer that sits between your AI agents and the outside world. It evaluates inputs and outputs against configurable rules, blocking harmful content, prompt injections, PII leakage, and other risks.
Agent Control provides a control-based runtime layer that sits between your AI agents and the outside world. It evaluates inputs and outputs against configurable rules, blocking harmful content, prompt injections, PII leakage, and other risks.

### Why Agent Control?

Expand Down Expand Up @@ -64,16 +64,12 @@ Example: *"If the output contains an SSN pattern, block the response."*
}
```

### Policies
### Control Associations

A **Policy** is a named collection of controls assigned to agents. Policies enable you to:

- Reuse control sets across multiple agents
- Version and audit your safety rules
- Apply different policies to different environments (dev/staging/prod)
Controls can be assigned directly to agents and reused across multiple agents.

```
Policy → Controls → Agents
Controls → Agents
```

### Check Stages
Expand Down Expand Up @@ -252,7 +248,7 @@ graph TB

### Agent Initialization
1. **Agent Registration**: Agent initializes with `agent_control.init()`, registering with the server
2. **Policy Assignment**: Server returns the agent's assigned policy and active controls
2. **Control Resolution**: Server returns the agent's active controls

### Control Execution Flow
1. **Function Invocation**: User calls a function decorated with `@control()`
Expand Down Expand Up @@ -590,8 +586,8 @@ The Python SDK provides decorator-based protection and programmatic control mana
import agent_control

agent_control.init(
agent_name="my-agent", # Required: human-readable name
agent_name="550e8400-e29b-41d4-a716-446655440000", # Required: UUID
agent_name="my-agent", # Required: unique identifier
agent_description="My Agent", # Optional: human-readable description
server_url="http://localhost:8000", # Optional: defaults to env var
policy_refresh_interval_seconds=60, # Optional: set 0 to disable background refresh
steps=[ # Optional: register available steps
Expand All @@ -605,12 +601,12 @@ agent_control.init(
)
```

When enabled, background refresh fetches controls via `GET /agents/{agent_id}/controls`.
When enabled, background refresh fetches controls via `GET /agents/{agent_name}/controls`.
Refresh failures are fail-open: the SDK keeps the last successful local cache snapshot.

### The @control Decorator

The `@control()` decorator applies server-side policies to any function.
The `@control()` decorator applies server-side controls to any function.

```python
from agent_control import control
Expand All @@ -632,7 +628,6 @@ async def chat(message: str) -> str:

**Parameters**:

- `policy` (str, optional): Policy name for documentation purposes. The agent's assigned policy is automatically used.
- `step_name` (str, optional): Custom name for this step. If not provided, uses the function name. Useful for:
- Overriding auto-detected names when they don't match your control configuration
- Applying the same controls to functions with different names
Expand Down Expand Up @@ -779,22 +774,14 @@ async with AgentControlClient() as client:
| `agent_control.get_control()` | Get control by ID |
| `agent_control.update_control()` | Update control properties |
| `agent_control.delete_control()` | Delete a control |
| `agent_control.add_control_to_policy()` | Add control to policy |
| `agent_control.remove_control_from_policy()` | Remove control from policy |
| `agent_control.list_policy_controls()` | List controls in a policy |

**Policy management** (via `agent_control.policies` module):

| Function | Description |
|----------|-------------|
| `policies.create_policy()` | Create a new policy |
| `policies.assign_policy_to_agent()` | Assign policy to agent |
| `agent_control.add_control_to_agent()` | Add control to agent |
| `agent_control.remove_control_from_agent()` | Remove control from agent |

---

## Server API

The Agent Control server exposes a RESTful API for managing agents, controls, and policies.
The Agent Control server exposes a RESTful API for managing agents and controls.

### Base URL

Expand All @@ -811,9 +798,8 @@ Default: `http://localhost:8000/api/v1`
| `GET` | `/agents/{agent_name}` | Get agent details |
| `PATCH` | `/agents/{agent_name}` | Update agent |
| `GET` | `/agents/{agent_name}/controls` | List controls for agent |
| `GET` | `/agents/{agent_name}/policy` | Get agent's policy |
| `POST` | `/agents/{agent_name}/policy/{policy_id}` | Assign policy |
| `DELETE` | `/agents/{agent_name}/policy` | Remove policy |
| `POST` | `/agents/{agent_name}/controls/{control_id}` | Add control to agent |
| `DELETE` | `/agents/{agent_name}/controls/{control_id}` | Remove control from agent |

**Controls**:

Expand All @@ -825,15 +811,6 @@ Default: `http://localhost:8000/api/v1`
| `PATCH` | `/controls/{control_id}` | Update control |
| `DELETE` | `/controls/{control_id}` | Delete control |

**Policies**:

| Method | Endpoint | Description |
|--------|----------|-------------|
| `PUT` | `/policies` | Create policy |
| `GET` | `/policies/{policy_id}/controls` | List controls in policy |
| `POST` | `/policies/{policy_id}/controls/{control_id}` | Add control to policy |
| `DELETE` | `/policies/{policy_id}/controls/{control_id}` | Remove control |

**System**:

| Method | Endpoint | Description |
Expand Down Expand Up @@ -928,7 +905,7 @@ Agent Control supports multiple API keys for zero-downtime rotation:
| `DB_PASSWORD` | `agent_control` | Database password |
| `DB_DATABASE` | `agent_control` | Database name |
| `DB_DRIVER` | `psycopg` | Database driver |
| `DATABASE_URL` or `DB_URL` | — | Full database URL (overrides above). `DATABASE_URL` is preferred for Docker environments. |
| `DB_URL` | — | Full database URL (overrides above) |

**Authentication**:

Expand Down
Loading
Loading