Daita Logo

from_db Guardrails

Production guardrails for Agent.from_db(), including read-only mode, SQL validation, access controls, result limits, and repair guidance.

#Read-Only By Default

All built-in modes default to read-only database access:

python
agent = await Agent.from_db(
    "postgresql://user:pass@host/db",
    read_only=True,
)

Read-only mode omits db_execute and rejects mutating SQL in query tools.

#Enabling Writes

Only enable writes for agents that are explicitly meant to mutate data:

python
writer = await Agent.from_db(
    "postgresql://user:pass@host/db",
    read_only=False,
)

Even with writes enabled, keep table restrictions and database permissions narrow.

#SQL Validation

from_db() validates SQL before execution. Validation can reject:

  • empty SQL
  • multiple statements
  • mutating statements in read-only mode
  • non-read statements sent to read query tools
  • references to unknown tables or columns
  • blocked tables or columns
  • tables outside an allowlist

Agents receive structured repair guidance instead of repeatedly executing invalid SQL.

#Table and Column Controls

Use allowlists and blocklists for production deployments:

python
agent = await Agent.from_db(
    "postgresql://user:pass@host/db",
    allowed_tables=["orders", "customers", "products"],
    blocked_columns=["email", "phone", "address"],
)

allowed_tables is restrictive: any table outside the list is rejected. blocked_tables and blocked_columns reject known-sensitive objects.

#Result Limits

python
agent = await Agent.from_db(
    "postgresql://user:pass@host/db",
    query_default_limit=25,
    query_max_rows=100,
    query_max_chars=25000,
    query_timeout=30,
)
  • query_default_limit is added when SQL omits LIMIT.
  • query_max_rows caps returned rows.
  • query_max_chars caps serialized result size.
  • query_timeout caps tool execution time.

#Tool Result Compaction

DB results are compacted before being appended to model context. Large row sets, long strings, large JSON cells, and noisy payload columns can be summarized or omitted.

python
from daita.agents.db.config import ToolResultPolicy
 
agent = await Agent.from_db(
    "postgresql://user:pass@host/db",
    tool_result_policy=ToolResultPolicy(
        max_result_tokens=800,
        max_rows_inline=8,
        max_cell_chars=160,
        omitted_column_patterns=["*_payload", "*_context", "trace_data"],
    ),
)

#Repair Guidance

When SQL fails preflight, the agent can receive:

  • error type
  • unknown tables
  • missing columns
  • candidate tables and columns
  • suggested next tool
  • instruction not to retry the same SQL

This is meant to push the agent toward db_search_schema, db_inspect_table, db_find_join_path, or db_plan_query before retrying.

#Production Checklist

  • Keep read_only=True unless writes are required.
  • Use allowed_tables for narrow business-facing agents.
  • Use blocked_columns for PII or secrets.
  • Set query_timeout for external-facing workflows.
  • Use mode="governed" for safer defaults.
  • Add business definitions with prompt.
  • Inspect agent.describe()["db"]["query_policy"] before deployment.