> ## Documentation Index
> Fetch the complete documentation index at: https://agentcontrol-abhi-agent-control-auth-contract-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain SQL Agent with Agent Control

> SQL injection protection with LangChain integration.

This example demonstrates integrating Agent Control with a LangChain SQL agent to block dangerous SQL operations.

## Setup

### 1. Start the Agent Control Server (for remote execution)

**IMPORTANT: You must start/restart the server to load the SQL evaluator!**

```bash theme={null}
# Kill any old servers
pkill -f "uvicorn agent_control_server"

# Start the server
make server-run
# OR: uv run --package agent-control-server uvicorn agent_control_server.main:app --port 8000
```

**Verify evaluators are loaded:**

```bash theme={null}
curl http://localhost:8000/api/v1/evaluators | python -m json.tool
# Should show: {"sql": {"name": "sql", "version": "1.0.0", ...}, ...}
```

### 2. Set OpenAI API Key

```bash theme={null}
export OPENAI_API_KEY="your-key-here"
```

### 3. Install pre-reqs

```bash theme={null}
cd examples/langchain
uv pip install -e . --upgrade
```

### 4. Setup SQL Controls (One-Time)

```bash theme={null}
uv run setup_sql_controls.py
```

This creates:

* SQL safety control (blocks DROP, DELETE, TRUNCATE, ALTER, GRANT)
* Policy with the control
* Assigns policy to the SQL agent

> For local execution, create the control with `execution: "sdk"` in
> `setup_sql_controls.py` (see `sql_control_data_sdk`) and enable
> `AGENT_CONTROL_LOCAL_EVAL=true` when running the agent.

## Running the Example

```bash theme={null}
uv run sql_agent_protection.py
```

### Local vs Remote Control Execution

**Remote (server-side) controls**:

* Default mode
* Requires running the Agent Control server
* Uses `@control()` to call `/api/v1/evaluation` on the server

**Local (SDK-side) controls**:

* Set `AGENT_CONTROL_LOCAL_EVAL=true`
* Controls must be configured with `execution: "sdk"`
* Uses `agent_control.check_evaluation_with_local(...)` before executing the tool

Example:

```bash theme={null}
export AGENT_CONTROL_LOCAL_EVAL=true
uv run sql_agent_protection.py
```

### Expected Behavior

**Safe Query (SELECT with LIMIT):**

```text theme={null}
✅ Safety check passed for: SELECT * FROM Track LIMIT 3
[Query executes successfully]
```

**Dangerous Query (DROP TABLE):**

```text theme={null}
✗ Execution blocked!
Error: Control evaluation failed...
[Query is blocked, table is NOT dropped]
```

## How It Works

### 1. The `@control()` Decorator

```python theme={null}
async def _execute_query(query: str):
    return query_tool.invoke(query)

# Set tool name (required for tool step detection)
_execute_query.name = "sql_db_query"
_execute_query.tool_name = "sql_db_query"

# Apply decorators
safe_query_tool = tool(
    "sql_db_query",
    description="Execute SQL query with safety checks"
)(control()(_execute_query))
```

### 2. Automatic Tool Call Detection

The `@control()` decorator:

1. Detects this is a tool (via `name` attribute)
2. Creates a `Step` payload with `type="tool"`, `name`, and `input`
3. Sends to server for evaluation **before** execution
4. Blocks execution if control triggers deny action

### 3. SQL Control Execution

The SQL is evaluated using the `sql` evaluator:

* Parses the query
* Checks for blocked operations (DROP, DELETE, etc.)
* Validates LIMIT clauses
* Returns deny/observe decision

### 4. Fail-Safe Error Handling

If the control check fails with an error:

* ✅ Execution is BLOCKED (fail-safe)
* ✅ RuntimeError is raised
* ❌ Query never executes

## Troubleshooting

### "Evaluator 'sql' not found"

**Cause:** Server was started before evaluators were installed, or using old code.

**Fix:**

```bash theme={null}
# Kill old server
pkill -f "uvicorn agent_control_server"

# Restart server
cd server && make run
```

### "Policy 'sql-protection-policy' already exists"

**Cause:** Setup script was run multiple times.

**Fix:** Either delete the policy via the API or use a different name in `setup_sql_controls.py`.

### DROP TABLE still executes

**Causes:**

1. Server not running or evaluators not loaded (remote mode)
2. Control not assigned to agent's policy
3. Control data missing/invalid (control not returned to agent)
4. Local mode enabled but control is still `execution: "server"`

**Fix:**

1. Restart server with `make run`
2. Re-run `setup_sql_controls.py`
3. Verify decorator code is up-to-date

## Architecture

```text theme={null}
LangChain Agent
    ↓
@tool("sql_db_query")  ← Marks as LangChain tool
@control()            ← Applies server-side validation
    ↓
Step Payload: {
  "type": "tool",
  "name": "sql_db_query",
  "input": {"query": "DROP TABLE..."}
}
    ↓
Agent Control Server
    ↓
SQL Evaluator Execution
    ↓
DENY (blocks DROP) or PASS (safe query)
    ↓
Back to Decorator
    ↓
Raise ControlViolationError (DENY) or Execute (PASS)
```

## Files

* `sql_agent_protection.py` - Main SQL agent with `@control()` decorator
* `setup_sql_controls.py` - One-time setup script for controls/policy
* `pyproject.toml` - Dependencies and configuration
* `README.md` - This file

## Key Security Features

1. **Fail-Safe by Default**: Errors block execution
2. **Server-Side Validation**: Remote controls enforced centrally
3. **SDK-Side Validation**: Local controls run before tool execution
4. **Automatic Detection**: Decorator auto-detects tool vs LLM calls

## Source Code

View the complete example with all scripts and setup instructions:

[`LangChain SQL Agent Example`](https://github.com/agentcontrol/agent-control/tree/main/examples/langchain)
