Database Adapters
Persistence and session storage
Database Adapters
Database adapters provide persistence for conversations, sessions, and agent state.
Available Adapters
| Adapter | Description |
|---|---|
SqliteDbAdapter | Durable SQLite session store — full DbAdapter contract |
MemoryDbAdapter | In-process Maps — ephemeral session store |
SQLiteAdapter | Legacy low-level SQLite transport (degrades to a Map) |
UpstashRedisAdapter | Upstash Redis key/value transport |
MemoryRedisAdapter | In-memory Redis-compatible |
NeonPostgresAdapter | Neon PostgreSQL key/value transport |
MemoryPostgresAdapter | In-memory PostgreSQL-compatible |
PostgresSessionStorage | PostgreSQL session storage |
SqliteDbAdapter
SqliteDbAdapter implements the full DbAdapter contract (sessions, messages, runs, tool calls, traces, spans) on a real SQLite file, so a session written by one process is readable by the next. It is what db("sqlite:./data.db") returns.
import { db } from 'praisonai';
// Recommended URL-style entry point
const adapter = db('sqlite:./data.db');
await adapter.saveMessage({
sessionId: 'session-123',
role: 'user',
content: 'Hello',
});
// Last 50 messages for the session, chronological order
const messages = await adapter.getMessages('session-123', 50);createSqliteDbAdapter({ filename }) (or new SqliteDbAdapter({ filename })) remains available for direct construction:
import { createSqliteDbAdapter } from 'praisonai';
const adapter = createSqliteDbAdapter({ filename: './data.db' });Driver probe order
Two drivers back the adapter, tried in order. Opening the file is part of loading — better-sqlite3‘s ABI failure only surfaces at new Database(...), so a driver is “loaded” only once a connection actually opens.
better-sqlite3— the declared dependency. A native module compiled against one Node ABI; run under a mismatched Node major it throwsERR_DLOPEN_FAILED.node:sqlite— Node’s built-in SQLite (Node ≥ 22.5). No native build, same on-disk format, so a file written by either driver reads in the other.
Pin the choice with PRAISONAI_SQLITE_DRIVER=better-sqlite3|node or the driver constructor option.
No memory fallback
If neither driver can open the file, every operation rejects with a message naming what each driver did and how to fix it. It never degrades to an in-process Map — a persistence layer that quietly stops persisting is the bug this adapter exists to fix.
Incompatible-schema diagnostic
On open, the adapter verifies each required table’s columns. A file written with an incompatible table shape (for example, one created by the legacy SQLiteAdapter below) is diagnosed immediately rather than deferring the failure into the first INSERT:
SQLite file "./data.db" already has a "messages" table with an incompatible
shape (missing: run_id, tool_call_id). It was most likely written by the
low-level SQLiteAdapter in "praisonai/db/sqlite", whose tables differ.
Point db("sqlite:...") at a different file, or migrate that one.SQLite (legacy low-level adapter)
import { createSQLiteAdapter } from 'praisonai';
const db = createSQLiteAdapter({
filename: './data.db'
});
await db.saveMessage({ role: 'user', content: 'Hello' });
const messages = await db.getMessages();Redis (Upstash)
import { createUpstashRedis } from 'praisonai';
const redis = createUpstashRedis({
url: process.env.UPSTASH_REDIS_URL,
token: process.env.UPSTASH_REDIS_TOKEN
});PostgreSQL (Neon)
import { createNeonPostgres, createPostgresSessionStorage } from 'praisonai';
const pg = createNeonPostgres({
connectionString: process.env.DATABASE_URL
});
const sessions = createPostgresSessionStorage({
connectionString: process.env.DATABASE_URL
});CLI Usage
praisonai-ts db info
praisonai-ts db adapters --json