- schema/canonical.sql: 29 tables across 3 databases, CHECK constraints, foreign keys, 13 indexes, WAL mode, schema_version tracking - tools/validate-schema.ts: applies DDL to in-memory SQLite, extracts PRAGMA table_info + sqlite_master metadata as JSON - tools/migrate-db.ts: CLI for Tauri→Electrobun data migration with atomic transaction, version fencing, INSERT OR IGNORE - docs/SWITCHING.md: migration guide with prerequisites and troubleshooting
299 lines
10 KiB
SQL
299 lines
10 KiB
SQL
-- canonical.sql — Authoritative DDL for all AGOR SQLite databases.
|
|
-- Both Tauri (Rust) and Electrobun (Bun) stacks MUST match this schema.
|
|
-- DBs: settings.db, btmsg.db, search.db. See docs/SWITCHING.md.
|
|
|
|
PRAGMA journal_mode = WAL;
|
|
PRAGMA foreign_keys = ON;
|
|
PRAGMA busy_timeout = 5000;
|
|
|
|
-- ── VERSION TRACKING ──────────────────────────────────────────────────
|
|
-- Schema version fence. One row per database file.
|
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
version INTEGER NOT NULL,
|
|
migration_source TEXT, -- e.g. 'tauri', 'electrobun', 'migrate-db'
|
|
migration_timestamp TEXT -- ISO-8601 when last migrated
|
|
);
|
|
|
|
-- ── settings.db TABLES ────────────────────────────────────────────────
|
|
|
|
-- Key-value application settings (theme, fonts, shell, cwd, etc.)
|
|
CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT NOT NULL);
|
|
|
|
-- Project configurations stored as JSON blobs.
|
|
CREATE TABLE IF NOT EXISTS projects (id TEXT PRIMARY KEY, config TEXT NOT NULL);
|
|
|
|
-- Workspace groups (sidebar tabs).
|
|
CREATE TABLE IF NOT EXISTS groups (
|
|
id TEXT PRIMARY KEY, name TEXT NOT NULL,
|
|
icon TEXT NOT NULL, position INTEGER NOT NULL
|
|
);
|
|
|
|
-- User-created custom themes.
|
|
CREATE TABLE IF NOT EXISTS custom_themes (
|
|
id TEXT PRIMARY KEY, name TEXT NOT NULL,
|
|
palette TEXT NOT NULL -- JSON blob (color map)
|
|
);
|
|
|
|
-- User-customized keyboard shortcuts.
|
|
CREATE TABLE IF NOT EXISTS keybindings (id TEXT PRIMARY KEY, chord TEXT NOT NULL);
|
|
|
|
-- Agent sessions per project (provider-agnostic).
|
|
CREATE TABLE IF NOT EXISTS agent_sessions (
|
|
project_id TEXT NOT NULL,
|
|
session_id TEXT PRIMARY KEY,
|
|
provider TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'idle'
|
|
CHECK (status IN ('idle','running','error','stopped','completed')),
|
|
cost_usd REAL NOT NULL DEFAULT 0,
|
|
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
model TEXT NOT NULL DEFAULT '',
|
|
error TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_agent_sessions_project ON agent_sessions(project_id);
|
|
|
|
-- Individual agent messages within a session.
|
|
CREATE TABLE IF NOT EXISTS agent_messages (
|
|
session_id TEXT NOT NULL,
|
|
msg_id TEXT NOT NULL,
|
|
role TEXT NOT NULL,
|
|
content TEXT NOT NULL DEFAULT '',
|
|
tool_name TEXT,
|
|
tool_input TEXT,
|
|
timestamp INTEGER NOT NULL,
|
|
cost_usd REAL NOT NULL DEFAULT 0,
|
|
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (session_id, msg_id),
|
|
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_agent_messages_session ON agent_messages(session_id, timestamp);
|
|
|
|
-- Historical session metrics (cost, tokens, turns) per project.
|
|
CREATE TABLE IF NOT EXISTS session_metrics (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id TEXT NOT NULL,
|
|
session_id TEXT NOT NULL,
|
|
start_time INTEGER NOT NULL,
|
|
end_time INTEGER NOT NULL,
|
|
peak_tokens INTEGER DEFAULT 0,
|
|
turn_count INTEGER DEFAULT 0,
|
|
tool_call_count INTEGER DEFAULT 0,
|
|
cost_usd REAL DEFAULT 0,
|
|
model TEXT,
|
|
status TEXT NOT NULL,
|
|
error_message TEXT
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_session_metrics_project ON session_metrics(project_id);
|
|
|
|
-- Session anchors — preserved turns surviving compaction.
|
|
CREATE TABLE IF NOT EXISTS session_anchors (
|
|
id TEXT PRIMARY KEY,
|
|
project_id TEXT NOT NULL,
|
|
message_id TEXT NOT NULL,
|
|
anchor_type TEXT NOT NULL
|
|
CHECK (anchor_type IN ('auto','pinned','promoted')),
|
|
content TEXT NOT NULL,
|
|
estimated_tokens INTEGER NOT NULL,
|
|
turn_index INTEGER NOT NULL DEFAULT 0,
|
|
created_at INTEGER NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_session_anchors_project ON session_anchors(project_id);
|
|
|
|
-- Remote relay machine connections.
|
|
CREATE TABLE IF NOT EXISTS remote_machines (
|
|
id TEXT PRIMARY KEY,
|
|
label TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
token TEXT NOT NULL,
|
|
auto_connect INTEGER NOT NULL DEFAULT 0,
|
|
spki_pins TEXT NOT NULL DEFAULT '[]', -- JSON array of SPKI hashes
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
-- Legacy v2 layout state (single-row).
|
|
CREATE TABLE IF NOT EXISTS layout_state (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
preset TEXT NOT NULL DEFAULT '1-col', pane_ids TEXT NOT NULL DEFAULT '[]'
|
|
);
|
|
|
|
-- Legacy v2 terminal sessions.
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id TEXT PRIMARY KEY,
|
|
type TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
shell TEXT,
|
|
cwd TEXT,
|
|
args TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
last_used_at INTEGER NOT NULL,
|
|
group_name TEXT DEFAULT '',
|
|
project_id TEXT DEFAULT ''
|
|
);
|
|
|
|
-- SSH connection profiles.
|
|
CREATE TABLE IF NOT EXISTS ssh_sessions (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
host TEXT NOT NULL,
|
|
port INTEGER NOT NULL DEFAULT 22,
|
|
username TEXT NOT NULL,
|
|
key_file TEXT DEFAULT '',
|
|
folder TEXT DEFAULT '',
|
|
color TEXT DEFAULT '#89b4fa',
|
|
created_at INTEGER NOT NULL,
|
|
last_used_at INTEGER NOT NULL
|
|
);
|
|
|
|
-- ── btmsg.db TABLES — inter-agent messaging & task board ──────────────
|
|
|
|
-- Registered agents (Tier 1 management + Tier 2 project).
|
|
CREATE TABLE IF NOT EXISTS agents (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
role TEXT NOT NULL,
|
|
group_id TEXT NOT NULL,
|
|
tier INTEGER NOT NULL DEFAULT 2,
|
|
model TEXT,
|
|
cwd TEXT,
|
|
system_prompt TEXT,
|
|
status TEXT DEFAULT 'stopped',
|
|
last_active_at TEXT,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- Agent-to-agent visibility ACL.
|
|
CREATE TABLE IF NOT EXISTS contacts (
|
|
agent_id TEXT NOT NULL, contact_id TEXT NOT NULL,
|
|
PRIMARY KEY (agent_id, contact_id)
|
|
);
|
|
|
|
-- Direct messages between agents.
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id TEXT PRIMARY KEY,
|
|
from_agent TEXT NOT NULL,
|
|
to_agent TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
read INTEGER DEFAULT 0,
|
|
reply_to TEXT,
|
|
group_id TEXT NOT NULL,
|
|
sender_group_id TEXT,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent, read);
|
|
CREATE INDEX IF NOT EXISTS idx_messages_from ON messages(from_agent);
|
|
|
|
-- Broadcast channels within a group.
|
|
CREATE TABLE IF NOT EXISTS channels (
|
|
id TEXT PRIMARY KEY, name TEXT NOT NULL, group_id TEXT NOT NULL,
|
|
created_by TEXT NOT NULL, created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- Channel membership (many-to-many).
|
|
CREATE TABLE IF NOT EXISTS channel_members (
|
|
channel_id TEXT NOT NULL, agent_id TEXT NOT NULL,
|
|
joined_at TEXT DEFAULT (datetime('now')),
|
|
PRIMARY KEY (channel_id, agent_id)
|
|
);
|
|
|
|
-- Messages posted to channels.
|
|
CREATE TABLE IF NOT EXISTS channel_messages (
|
|
id TEXT PRIMARY KEY,
|
|
channel_id TEXT NOT NULL,
|
|
from_agent TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_channel_messages ON channel_messages(channel_id, created_at);
|
|
|
|
-- Agent liveness heartbeats (unix epoch seconds).
|
|
CREATE TABLE IF NOT EXISTS heartbeats (agent_id TEXT PRIMARY KEY, timestamp INTEGER NOT NULL);
|
|
|
|
-- Undeliverable messages (recipient not found, etc.)
|
|
CREATE TABLE IF NOT EXISTS dead_letter_queue (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
from_agent TEXT NOT NULL,
|
|
to_agent TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
error TEXT NOT NULL,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- Audit trail for agent actions.
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
agent_id TEXT NOT NULL,
|
|
event_type TEXT NOT NULL,
|
|
detail TEXT NOT NULL,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- Per-session message acknowledgment (prevents re-processing).
|
|
CREATE TABLE IF NOT EXISTS seen_messages (
|
|
session_id TEXT NOT NULL, message_id TEXT NOT NULL,
|
|
seen_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
PRIMARY KEY (session_id, message_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_seen_messages_session ON seen_messages(session_id);
|
|
|
|
-- Kanban task board.
|
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
id TEXT PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
description TEXT DEFAULT '',
|
|
status TEXT DEFAULT 'todo'
|
|
CHECK (status IN ('todo','progress','review','done','blocked')),
|
|
priority TEXT DEFAULT 'medium'
|
|
CHECK (priority IN ('low','medium','high')),
|
|
assigned_to TEXT,
|
|
created_by TEXT NOT NULL,
|
|
group_id TEXT NOT NULL,
|
|
parent_task_id TEXT,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
updated_at TEXT DEFAULT (datetime('now')),
|
|
version INTEGER DEFAULT 1 -- optimistic locking
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_group ON tasks(group_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
|
|
-- Task discussion comments.
|
|
CREATE TABLE IF NOT EXISTS task_comments (
|
|
id TEXT PRIMARY KEY,
|
|
task_id TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_task_comments_task ON task_comments(task_id);
|
|
|
|
-- ── search.db TABLES — FTS5 full-text search ─────────────────────────
|
|
|
|
-- Agent message search index.
|
|
CREATE VIRTUAL TABLE IF NOT EXISTS search_messages USING fts5(
|
|
session_id,
|
|
role,
|
|
content,
|
|
timestamp
|
|
);
|
|
|
|
-- Task search index.
|
|
CREATE VIRTUAL TABLE IF NOT EXISTS search_tasks USING fts5(
|
|
task_id,
|
|
title,
|
|
description,
|
|
status,
|
|
assigned_to
|
|
);
|
|
|
|
-- Inter-agent message search index.
|
|
CREATE VIRTUAL TABLE IF NOT EXISTS search_btmsg USING fts5(
|
|
message_id,
|
|
from_agent,
|
|
to_agent,
|
|
content,
|
|
channel_name
|
|
);
|