Database Schema
Distri uses SQLite for local storage. The database is created at .distri/distri.db when you run distri serve or execute agents.
Connecting to the Database
sqlite3 .distri/distri.db
Or use any SQLite client (DB Browser, TablePlus, etc.).
Core Tables
threads
Conversation contexts that persist across messages.
CREATE TABLE threads (
id TEXT PRIMARY KEY NOT NULL,
agent_id TEXT NOT NULL,
title TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
message_count INTEGER NOT NULL DEFAULT 0,
last_message TEXT,
metadata TEXT NOT NULL, -- JSON
attributes TEXT NOT NULL, -- JSON
external_id TEXT -- For linking to your system
);
Example queries:
-- List all threads for an agent
SELECT id, title, message_count, created_at
FROM threads
WHERE agent_id = 'assistant'
ORDER BY updated_at DESC;
-- Find threads by external ID (your user/session ID)
SELECT * FROM threads WHERE external_id = 'user_123';
-- Get thread metadata
SELECT id, json_extract(metadata, '$.user_name') as user_name
FROM threads;
tasks
Individual agent invocations within a thread.
CREATE TABLE tasks (
id TEXT PRIMARY KEY NOT NULL,
thread_id TEXT NOT NULL,
parent_task_id TEXT, -- For nested tasks
status TEXT NOT NULL, -- pending, running, completed, failed
created_at BIGINT NOT NULL, -- Unix timestamp ms
updated_at BIGINT NOT NULL
);
Example queries:
-- Get all tasks for a thread
SELECT id, status, datetime(created_at/1000, 'unixepoch') as created
FROM tasks
WHERE thread_id = 'thread_abc123';
-- Find failed tasks
SELECT t.id, th.title, t.status
FROM tasks t
JOIN threads th ON t.thread_id = th.id
WHERE t.status = 'failed';
task_messages
Messages exchanged during task execution (user messages, assistant responses, tool calls).
CREATE TABLE task_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL,
kind TEXT NOT NULL, -- message, tool_call, tool_result, etc.
payload TEXT NOT NULL, -- JSON content
created_at BIGINT NOT NULL -- Unix timestamp ms
);
Example queries:
-- Get conversation history for a task
SELECT kind, payload, datetime(created_at/1000, 'unixepoch') as time
FROM task_messages
WHERE task_id = 'task_xyz'
ORDER BY created_at;
-- Extract message text from payload
SELECT
kind,
json_extract(payload, '$.content') as content
FROM task_messages
WHERE task_id = 'task_xyz';
-- Count messages by type
SELECT kind, COUNT(*) as count
FROM task_messages
GROUP BY kind;
session_entries
Key-value storage scoped to a thread. Used by agents to maintain state.
CREATE TABLE session_entries (
thread_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL, -- JSON
expiry TIMESTAMP, -- Optional TTL
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
PRIMARY KEY(thread_id, key)
);
Example queries:
-- Get all session data for a thread
SELECT key, value FROM session_entries
WHERE thread_id = 'thread_abc123';
-- Get specific session value
SELECT json_extract(value, '$') as data
FROM session_entries
WHERE thread_id = 'thread_abc123' AND key = 'user_preferences';
secrets
Environment variables and API keys stored by the server.
CREATE TABLE secrets (
id TEXT PRIMARY KEY NOT NULL,
key TEXT NOT NULL UNIQUE,
value TEXT NOT NULL, -- Encrypted
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
Example queries:
-- List all secret keys (values are encrypted)
SELECT key, updated_at FROM secrets;
agent_configs
Registered agent configurations.
CREATE TABLE agent_configs (
name TEXT PRIMARY KEY NOT NULL,
config TEXT NOT NULL, -- JSON agent definition
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
Example queries:
-- List all registered agents
SELECT name, updated_at FROM agent_configs;
-- Get agent configuration
SELECT json_extract(config, '$.description') as description
FROM agent_configs
WHERE name = 'assistant';
prompt_templates
Reusable prompt templates.
CREATE TABLE prompt_templates (
id TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
template TEXT NOT NULL,
description TEXT,
version TEXT,
source TEXT NOT NULL DEFAULT 'user',
is_system INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
Supporting Tables
scratchpad_entries
Intermediate agent thinking and planning data.
CREATE TABLE scratchpad_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
thread_id TEXT NOT NULL,
task_id TEXT NOT NULL,
parent_task_id TEXT,
entry TEXT NOT NULL, -- JSON
entry_type TEXT,
timestamp BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL
);
memory_entries
Long-term memory storage per user.
CREATE TABLE memory_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
content TEXT NOT NULL, -- JSON
created_at TIMESTAMP NOT NULL
);
external_tool_calls
Tracking external tool invocations (for async tools).
CREATE TABLE external_tool_calls (
id TEXT PRIMARY KEY NOT NULL,
request TEXT NOT NULL, -- JSON request payload
response TEXT, -- JSON response payload
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
integrations
OAuth and external service integrations.
CREATE TABLE integrations (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
provider TEXT NOT NULL,
session_data TEXT, -- JSON
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
expires_at TIMESTAMP
);
Useful Queries
Export conversation as JSON
SELECT json_group_array(
json_object(
'kind', kind,
'content', json_extract(payload, '$.content'),
'time', datetime(created_at/1000, 'unixepoch')
)
) as conversation
FROM task_messages
WHERE task_id = 'task_xyz'
ORDER BY created_at;
Analytics: Messages per day
SELECT
date(created_at/1000, 'unixepoch') as day,
COUNT(*) as messages
FROM task_messages
GROUP BY day
ORDER BY day DESC
LIMIT 30;
Find threads with specific session data
SELECT t.id, t.title, se.value
FROM threads t
JOIN session_entries se ON t.id = se.thread_id
WHERE se.key = 'user_tier'
AND json_extract(se.value, '$') = 'premium';
Backup & Migration
Backup
sqlite3 .distri/distri.db ".backup backup.db"
Export to SQL
sqlite3 .distri/distri.db ".dump" > backup.sql
Restore
sqlite3 new.db < backup.sql
Next Steps
- Self-Hosted Setup — Installation guide
- Agent Definition — Full configuration options