Files
cleveragents-core/docs/reference/database_handler.md
T
HAL9000 18d00c04c4
CI / lint (pull_request) Failing after 1m15s
CI / quality (pull_request) Successful in 1m21s
CI / typecheck (pull_request) Successful in 1m34s
CI / security (pull_request) Successful in 1m37s
CI / coverage (pull_request) Has been skipped
CI / unit_tests (pull_request) Failing after 1m37s
CI / docker (pull_request) Has been skipped
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 26s
CI / push-validation (pull_request) Successful in 19s
CI / e2e_tests (pull_request) Successful in 3m20s
CI / integration_tests (pull_request) Successful in 4m32s
CI / status-check (pull_request) Failing after 3s
fix(skills): implement multi-scope agent skill discovery for global, project, and local tiers
Implements AgentSkillDiscovery class to support discovering Agent Skills from
multiple configured directories across three scopes (global, project, local).
Handles name collisions with precedence: local > project > global.

Adds comprehensive BDD test coverage for multi-scope discovery scenarios including:
- Global-only, project-only, and local-only discovery
- Combined discovery from all scopes
- Name collision resolution with proper precedence
- Non-existent and empty scope directory handling
- Multiple skills in same scope discovery

ISSUES CLOSED: #9369
2026-05-06 19:55:22 +00:00

5.9 KiB

Database Resource Handler

The DatabaseResourceHandler manages database resources within the CleverAgents resource model. It supports four database types (postgres, mysql, sqlite, duckdb) and implements the full ResourceHandler protocol including CRUD operations and checkpoint/rollback methods.

Introduced in v3.7.0 (issues #1241, #836) as part of the ResourceHandler Protocol Completion epic (#825).

Module: cleveragents.resource.handlers.database


Supported Resource Types

Type Kind Sandbox Strategy Connection
sqlite physical transaction_rollback File path
postgres physical transaction_rollback Host/port/dbname or connection string
mysql physical transaction_rollback Host/port/dbname or connection string
duckdb physical transaction_rollback File path or in-memory

All types are user-addable via agents resource add.

CLI Arguments

SQLite / DuckDB:

Argument Type Required Description
--path string Yes Path to the database file

PostgreSQL / MySQL:

Argument Type Required Description
--connection-string string No Full connection string (overrides individual args)
--host string No Database server hostname (default: localhost)
--port integer No Database server port
--dbname string No Database name
--user string No Database user
--password string No Database password (masked in logs)

Content CRUD Methods

All methods raise ValueError if the resource has no location.

read(*, resource, path="") → Content

Returns the database schema or connection information.

Database type Behaviour
SQLite Queries sqlite_master for tables, views, and indexes; returns DDL as UTF-8 text
Remote (postgres, mysql, duckdb) Returns a connection-info summary with credentials masked

The path argument is ignored for database resources (schema is always read).

write(*, resource, path, data) → WriteResult

Executes SQL statements against the database.

Database type Behaviour
SQLite Executes the SQL in data (decoded as UTF-8) using executescript()
Remote Returns WriteResult(success=False, message="not supported")

delete(*, resource, path="") → DeleteResult

Drops a table from the database.

Database type Behaviour
SQLite Executes DROP TABLE IF EXISTS <path>
Remote Returns DeleteResult(success=False, message="not supported")

If path is empty, returns a failure result (no-op rather than dropping all tables).

list_children(*, resource) → list[str]

Lists the tables and views in the database.

Database type Behaviour
SQLite Queries sqlite_master for tables and views; returns their names
Remote Returns []

diff(*, resource, other_location) → DiffResult

Compares the schema of this database against another location by content hash.

Both sides are read via read(). If both sides are absent (empty content), the EMPTY_CONTENT_HASH sentinel is used and the result is no_change=True.


Checkpoint Methods

Checkpoints allow the plan execution engine to save and restore database state during the Apply phase.

create_checkpoint(*, resource) → CheckpointResult

Creates a savepoint in the database.

Database type Behaviour
SQLite Opens a connection, executes SAVEPOINT <id>, and holds the connection open
Remote Returns a content-hash-based checkpoint (no actual savepoint)

The returned CheckpointResult.checkpoint_id is used to identify the savepoint for rollback_to().

rollback_to(*, resource, checkpoint_id) → RollbackResult

Rolls back to a previously created savepoint.

Database type Behaviour
SQLite Executes ROLLBACK TO SAVEPOINT <id> and closes the held connection
Remote Returns RollbackResult(success=False, message="not supported")

If checkpoint_id is not found (e.g. the process restarted), returns a failure result rather than raising.


Error Handling

All methods handle errors gracefully:

  • SQLite errors are caught and returned as failure results with the error message in metadata["error"].
  • Credentials in connection strings are masked using cleveragents.shared.redaction.mask_database_url() before appearing in logs or error messages.
  • No unhandled exceptions propagate from CRUD or checkpoint methods.

CLI Usage

# Add a SQLite database resource
agents resource add sqlite local/my-db --path /path/to/db.sqlite

# Add a PostgreSQL database resource
agents resource add postgres local/pg-db \
    --host localhost --port 5432 --dbname myapp --user admin

# Add using a full connection string
agents resource add postgres local/pg-db \
    --connection-string "postgresql://admin:secret@localhost:5432/myapp"

# List database resources
agents resource list --type sqlite

# Show database details
agents resource show local/my-db

Architecture Notes

DatabaseResourceHandler extends BaseResourceHandler and uses the transaction_rollback sandbox strategy. SQLite checkpoints hold an open sqlite3.Connection with an active SAVEPOINT in the _sqlite_checkpoints dict (keyed by checkpoint ID). The connection is closed when rollback_to() is called or when the handler is garbage collected.