Source Code:
src/gaia/database/mixin.pyDatabaseMixin provides SQLite database access for GAIA agents. It uses Python’s
built-in sqlite3 module with zero external dependencies, making it lightweight and
fast.
Two Approaches
1. DatabaseAgent (Recommended for prototyping)
UseDatabaseAgent when you want the LLM to have direct database access:
db_query, db_insert, db_update, db_delete, db_tables, db_schema
db_query is read-only, and db_update/db_delete take structured conditions rather than a WHERE string — see LLM-facing tools vs. the Python API.
LLM-facing tools vs. the Python API
The mixin methods and the auto-registered tools sit at different trust levels, and deliberately have different shapes.update()/delete() interpolate where into the statement, so it must be a literal you wrote. Never build it from LLM output or end-user input — bind untrusted values through :param placeholders inside a literal fragment instead:
Conditions are combined with
AND. There is no OR and no nesting — an AND chain of allowlisted predicates can only narrow the row set, which is what makes OR 1=1-style payloads unrepresentable. If an agent genuinely needs OR, expose a domain-specific tool that runs the query you intend rather than widening the generic one.
An empty condition list is rejected unless you pass all_rows=True, so a full-table update or delete is always deliberate:
where as a JSON array, data as a JSON object, and all_rows
as "true"/"false". Only those exact spellings — an ambiguous value like
"yes" raises rather than being guessed at.
Malformed input raises ValueError naming the offending value and the rule, which the agent loop surfaces to the model so it can correct itself.
These tools still give the LLM read and write access to every table in the database — there is no per-table authorization. Point
db_path at a database holding only what the agent should be able to change, or override _register_db_tools() to expose domain-specific operations.Composing with Other Mixins
DatabaseAgent can be extended with additional mixins for more capabilities:
2. DatabaseMixin (Recommended for production)
UseDatabaseMixin when you want to expose domain-specific tools:
API Reference
Initialization
CRUD Operations
insert, update, and delete interpolate the table name — and insert/update the data keys — into the SQL, so all of them must be bare identifiers matching [A-Za-z_][A-Za-z0-9_]*; anything else raises ValueError. Quoted or non-ASCII identifiers that SQLite would otherwise accept are rejected. Empty data and a blank where raise as well, rather than producing a malformed statement.
Schema & Transactions
Examples
Basic CRUD
Transactions
Use transactions when multiple operations must succeed or fail together:Schema Initialization
Best Practices
Use Parameterized Queries
Always use:param placeholders to prevent SQL injection and syntax errors:
query_readonly().
Initialize Schema Once
Checktable_exists() before creating tables to avoid errors on restart:
Use Transactions for Related Operations
Ensure data consistency by wrapping related operations in a transaction:Close on Shutdown
Callclose_db() when the agent is done (optional but clean):
Complete Example: Notes Agent
A simple but complete agent that manages notes:Testing Your Agent
Use thetemp_db fixture for isolated tests: