Module: database
A plug-and-play database inspector — a psql-like console pane where the user (or
the agent) writes SQL and runs it against any connected database. It ships with a
pluggable driver layer so you can connect to several providers, and exposes the
dashboard's own local vector store as the built-in app connection.
Status: implemented — frontend in packages/core/src/modules/database/, backend in
backend/modules/database/.
What it does
- Connections — a named-connection store. The built-in
appconnection (the local vector store) is always present and read-only; you add your own connections for external databases. Connections persist in.data/connections.json. - SQL console — write SQL, run it with Run or Ctrl/Cmd+Enter, and get a
results grid with column headers, a status line (
N rows · M ms, truncation flag), and inline error output. Recent queries are kept in a history dropdown. A Read-only toggle restricts a run to a singleSELECT/WITH/EXPLAINstatement. - Schema sidebar — an introspected tree of tables → columns (with types and PK
markers). Click a table to drop a
SELECT * FROM <table> LIMIT 100into the editor. - No synthetic data — the pane only ever shows real rows returned from a real connection.
Providers & drivers
Each provider is a thin synchronous driver (backend/modules/database/drivers/) behind a
uniform test / run_query / introspect contract. Routes run drivers via
asyncio.to_thread so the (blocking) client libraries never stall the event loop. Client
libraries are imported lazily, so a missing optional dependency yields a clear error
rather than breaking boot.
| Provider | Driver | Dependency | Notes |
|---|---|---|---|
sqlite | sqlite_driver | stdlib | Backs the built-in app connection and any .sqlite/.db file. Registers the app's cosine_similarity() SQL function. |
postgres | postgres_driver | psycopg[binary] | Connect to any Postgres; pgvector vector columns and bytea blobs are summarized in the grid. |
duckdb | duckdb_driver | duckdb | Local analytical/columnar querying (file or in-memory). |
mysql | mysql_driver | pymysql | MySQL / MariaDB. |
Result cells are coerced to JSON-safe values: binary blobs and long numeric arrays
(embeddings, pgvector) are summarized (e.g. <1536 bytes>, [384 numbers]), and
dates/decimals are stringified.
The built-in app vector store
The dashboard's own data lives in a local SQLite file at .data/vector_store.db. It uses
a custom Python cosine_similarity(v1_bytes, v2_bytes) SQL function (registered via
sqlite3.Connection.create_function) for semantic search:
SELECT id, collection, text, metadata,
cosine_similarity(embedding, :query_emb) AS score
FROM documents
WHERE collection = :collection
ORDER BY score DESC LIMIT :limit
Because it's just the app connection, you can run ordinary SQL against it in the
console (SELECT id, collection FROM documents). Embeddings are generated by a tiered
pipeline (active agent provider → dedicated embedding model probe → deterministic local
hash fallback so it works offline) in embeddings.py. The same vector store backs
agent-commons matchmaking — see network.
Contributions to the Layout Shell
- Widget:
database.console— the connection bar + schema sidebar + SQL console. - Command:
database.open(Database: Open Console) — opens the console in the workspace center. - Settings:
database.defaultConnection(defaultapp) anddatabase.rowLimit(default1000), read live viauseSetting()— see settings.
Backend REST API
Mounted under /api/database.
| Method | Path | Description |
|---|---|---|
GET | /connections | List connections (built-in + saved, secrets redacted) and available providers. |
POST | /connections | Create a connection. |
PUT | /connections/{id} | Update a connection (built-in is read-only; omitted secrets are preserved). |
DELETE | /connections/{id} | Delete a saved connection. |
POST | /connections/test | Probe an unsaved connection (form still holds the password). |
POST | /connections/{id}/test | Probe a stored connection (server-side credentials). |
GET | /connections/{id}/schema | Introspected tables/columns. |
POST | /query | Run SQL against a connection. read_only rejects non-SELECT. Returns columns, rows, rowcount, elapsed_ms, truncated. |
GET | /status | App vector store stats + active embedding provider/model. |
POST | /pull | Stream an Ollama all-minilm embedding-model download (NDJSON). |
GET | /collections | App vector store collection names. |
GET | /documents | List app vector store documents (paginated, filterable). |
POST | /documents | Embed and upsert a document into the app vector store. |
DELETE | /documents/{id} | Delete a document by id. |
POST | /search | Semantic similarity search in an app vector store collection. |
Agent Tools
The widget registers these tools with the agent orchestrator:
| Tool Name | Description | Parameters | Side Effect |
|---|---|---|---|
database.listConnections | List connections the agent can query. | none | No |
database.describe | Schema (tables/columns) for a connection, so the agent writes correct SQL. | connection_id (str, opt) | No |
database.query | Run a read-only SELECT against a connection. | sql (str), connection_id (str, opt) | No |
database.execute | Run a writing statement (INSERT/UPDATE/DELETE/DDL); permission-gated. | sql (str), connection_id (str, opt) | Yes |
database.semanticSearch | Vector search a collection in the app vector store. | collection (str), text (str), limit (int, opt) | No |
Agent Context
The console exposes the active connection and its schema via useAgentContext() so the
agent can target the right database:
{
activeConnection: "app",
provider: "sqlite",
tables: [{ name: "documents", columns: ["id", "collection", "text", "embedding"] }]
}
Security
SQL execution is unsandboxed (consistent with the v1 trusted plugin posture). The agent's
database.query tool is read-only; writes go through database.execute, which is
side-effect gated. Connection credentials are stored as plaintext in the gitignored
.data/connections.json; encryption is a tracked follow-up.
Browser vs Desktop
Identical in both layouts — the frontend talks to the local FastAPI server, which owns the driver connections and the SQLite vector store.