mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-24 01:11:10 +00:00
* feat: scan past sessions for skill proposals * feat(ui): add progressive skill history scans * fix(ui): keep skill history scans synchronized * refactor: split skill history scan ownership * style: fix mock helper formatting * style: format skill history scan * build: refresh skill history schema baselines * build: refresh plugin SDK baseline after rebase * perf(ui): keep startup request budget bounded * fix(skills): satisfy history scan integration gates * fix(ui): bound control ui startup chunks * build: refresh plugin SDK API baseline * build(ui): refresh self-learning translation memory * refactor(ui): split skill workshop state * fix(ci): refresh skill workshop gates * fix(ci): satisfy skill history lint * build: refresh plugin SDK baseline after main rebase
316 lines
9.9 KiB
SQL
316 lines
9.9 KiB
SQL
CREATE TABLE IF NOT EXISTS schema_meta (
|
|
meta_key TEXT NOT NULL PRIMARY KEY,
|
|
role TEXT NOT NULL,
|
|
schema_version INTEGER NOT NULL,
|
|
agent_id TEXT,
|
|
app_version TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
session_key TEXT NOT NULL,
|
|
session_scope TEXT NOT NULL DEFAULT 'conversation' CHECK (session_scope IN ('conversation', 'shared-main', 'group', 'channel')),
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
transcript_updated_at INTEGER DEFAULT NULL,
|
|
transcript_observed_at INTEGER DEFAULT NULL,
|
|
session_entry_provenance INTEGER NOT NULL DEFAULT 0 CHECK (session_entry_provenance IN (0, 1)),
|
|
acp_owned INTEGER NOT NULL DEFAULT 0 CHECK (acp_owned IN (0, 1)),
|
|
plugin_owner_id TEXT,
|
|
hook_external_content_source TEXT CHECK (hook_external_content_source IS NULL OR hook_external_content_source IN ('gmail', 'webhook')),
|
|
started_at INTEGER,
|
|
ended_at INTEGER,
|
|
status TEXT CHECK (status IS NULL OR status IN ('running', 'done', 'failed', 'killed', 'timeout')),
|
|
chat_type TEXT CHECK (chat_type IS NULL OR chat_type IN ('direct', 'group', 'channel')),
|
|
channel TEXT,
|
|
account_id TEXT,
|
|
primary_conversation_id TEXT,
|
|
model_provider TEXT,
|
|
model TEXT,
|
|
agent_harness_id TEXT,
|
|
parent_session_key TEXT,
|
|
spawned_by TEXT,
|
|
display_name TEXT,
|
|
FOREIGN KEY (primary_conversation_id) REFERENCES conversations(conversation_id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_sessions_updated_at
|
|
ON sessions(updated_at DESC, session_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_sessions_created_at
|
|
ON sessions(created_at DESC, session_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_sessions_conversation
|
|
ON sessions(primary_conversation_id, updated_at DESC, session_id)
|
|
WHERE primary_conversation_id IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS session_routes (
|
|
session_key TEXT NOT NULL PRIMARY KEY,
|
|
session_id TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_session_routes_session_id
|
|
ON session_routes(session_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS conversations (
|
|
conversation_id TEXT NOT NULL PRIMARY KEY,
|
|
channel TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
kind TEXT NOT NULL CHECK (kind IN ('direct', 'group', 'channel')),
|
|
peer_id TEXT NOT NULL,
|
|
parent_conversation_id TEXT,
|
|
thread_id TEXT,
|
|
native_channel_id TEXT,
|
|
native_direct_user_id TEXT,
|
|
label TEXT,
|
|
metadata_json TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_conversations_lookup
|
|
ON conversations(channel, account_id, kind, peer_id, thread_id);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_conversations_identity
|
|
ON conversations(
|
|
channel,
|
|
account_id,
|
|
kind,
|
|
peer_id,
|
|
IFNULL(parent_conversation_id, ''),
|
|
IFNULL(thread_id, '')
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_conversations_updated
|
|
ON conversations(updated_at DESC, conversation_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS session_conversations (
|
|
session_id TEXT NOT NULL,
|
|
conversation_id TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'primary' CHECK (role IN ('primary', 'participant', 'related')),
|
|
first_seen_at INTEGER NOT NULL,
|
|
last_seen_at INTEGER NOT NULL,
|
|
PRIMARY KEY (session_id, conversation_id, role),
|
|
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
FOREIGN KEY (conversation_id) REFERENCES conversations(conversation_id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_session_conversations_conversation
|
|
ON session_conversations(conversation_id, last_seen_at DESC, session_id);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_session_conversations_primary
|
|
ON session_conversations(session_id)
|
|
WHERE role = 'primary';
|
|
|
|
CREATE TABLE IF NOT EXISTS session_entries (
|
|
session_key TEXT NOT NULL PRIMARY KEY,
|
|
session_id TEXT NOT NULL,
|
|
entry_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
status TEXT CHECK (status IS NULL OR status IN ('running', 'done', 'failed', 'killed', 'timeout')),
|
|
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_session_entries_updated_at
|
|
ON session_entries(updated_at DESC, session_key);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_session_entries_session_updated
|
|
ON session_entries(session_id, updated_at DESC, session_key);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_session_entries_status
|
|
ON session_entries(status, session_key)
|
|
WHERE status IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS transcript_events (
|
|
session_id TEXT NOT NULL,
|
|
seq INTEGER NOT NULL,
|
|
event_json TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
PRIMARY KEY (session_id, seq),
|
|
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS trajectory_runtime_events (
|
|
session_id TEXT NOT NULL,
|
|
seq INTEGER NOT NULL,
|
|
run_id TEXT,
|
|
event_json TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
PRIMARY KEY (session_id, seq),
|
|
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_trajectory_runtime_run
|
|
ON trajectory_runtime_events(session_id, run_id, seq)
|
|
WHERE run_id IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS transcript_event_identities (
|
|
session_id TEXT NOT NULL,
|
|
event_id TEXT NOT NULL,
|
|
seq INTEGER NOT NULL,
|
|
event_type TEXT,
|
|
parent_id TEXT,
|
|
message_idempotency_key TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
PRIMARY KEY (session_id, event_id),
|
|
FOREIGN KEY (session_id, seq) REFERENCES transcript_events(session_id, seq) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_transcript_message_idempotency
|
|
ON transcript_event_identities(session_id, message_idempotency_key)
|
|
WHERE message_idempotency_key IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_transcript_event_parent
|
|
ON transcript_event_identities(session_id, parent_id)
|
|
WHERE parent_id IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_transcript_event_sequence
|
|
ON transcript_event_identities(session_id, event_type, seq DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS cache_entries (
|
|
scope TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
value_json TEXT,
|
|
blob BLOB,
|
|
expires_at INTEGER,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (scope, key)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_cache_expiry
|
|
ON cache_entries(scope, expires_at, key)
|
|
WHERE expires_at IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_cache_updated
|
|
ON cache_entries(scope, updated_at DESC, key);
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_profile_store (
|
|
store_key TEXT NOT NULL PRIMARY KEY,
|
|
store_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_profile_state (
|
|
state_key TEXT NOT NULL PRIMARY KEY,
|
|
state_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS memory_index_meta (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS memory_index_sources (
|
|
id INTEGER PRIMARY KEY,
|
|
path TEXT NOT NULL,
|
|
source TEXT NOT NULL DEFAULT 'memory',
|
|
hash TEXT NOT NULL,
|
|
mtime INTEGER NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
UNIQUE (path, source)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS memory_index_chunks (
|
|
id TEXT PRIMARY KEY,
|
|
path TEXT NOT NULL,
|
|
source TEXT NOT NULL DEFAULT 'memory',
|
|
start_line INTEGER NOT NULL,
|
|
end_line INTEGER NOT NULL,
|
|
hash TEXT NOT NULL,
|
|
model TEXT NOT NULL,
|
|
text TEXT NOT NULL,
|
|
embedding TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS memory_embedding_cache (
|
|
provider TEXT NOT NULL,
|
|
model TEXT NOT NULL,
|
|
provider_key TEXT NOT NULL,
|
|
hash TEXT NOT NULL,
|
|
embedding TEXT NOT NULL,
|
|
dims INTEGER,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (provider, model, provider_key, hash)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS memory_index_state (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
revision INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS session_transcript_index_state (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
indexed_seq INTEGER NOT NULL,
|
|
leaf_event_id TEXT,
|
|
needs_rebuild INTEGER NOT NULL DEFAULT 0,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE VIRTUAL TABLE IF NOT EXISTS session_transcript_fts USING fts5(
|
|
text,
|
|
session_id UNINDEXED,
|
|
message_id UNINDEXED,
|
|
role UNINDEXED,
|
|
timestamp UNINDEXED,
|
|
tokenize = 'unicode61 remove_diacritics 2'
|
|
);
|
|
|
|
INSERT OR IGNORE INTO memory_index_state (id, revision) VALUES (1, 0);
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_sources_revision_after_insert
|
|
AFTER INSERT ON memory_index_sources
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_sources_revision_after_update
|
|
AFTER UPDATE ON memory_index_sources
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_sources_revision_after_delete
|
|
AFTER DELETE ON memory_index_sources
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_chunks_revision_after_insert
|
|
AFTER INSERT ON memory_index_chunks
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_chunks_revision_after_update
|
|
AFTER UPDATE ON memory_index_chunks
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE TRIGGER IF NOT EXISTS memory_index_chunks_revision_after_delete
|
|
AFTER DELETE ON memory_index_chunks
|
|
BEGIN
|
|
UPDATE memory_index_state SET revision = revision + 1 WHERE id = 1;
|
|
END;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_memory_embedding_cache_updated_at
|
|
ON memory_embedding_cache(updated_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_memory_index_sources_source
|
|
ON memory_index_sources(source);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_memory_index_chunks_path_source
|
|
ON memory_index_chunks(path, source);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_memory_index_chunks_path
|
|
ON memory_index_chunks(path);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_memory_index_chunks_source
|
|
ON memory_index_chunks(source);
|