feat(core): implement full memory pipeline (#11)
This commit was merged in pull request #11.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
-- Enable pgvector extension
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
||||
-- Event log — source of truth for all memory
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
project VARCHAR NOT NULL,
|
||||
query_id VARCHAR NOT NULL,
|
||||
run_id VARCHAR NOT NULL,
|
||||
turn INT NOT NULL,
|
||||
event_type VARCHAR NOT NULL, -- "ingest", "gate_update", "gate_exit", "synthesis"
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
data JSONB NOT NULL,
|
||||
UNIQUE(project, query_id, run_id, turn)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_events_project_query ON events(project, query_id);
|
||||
CREATE INDEX idx_events_run ON events(run_id);
|
||||
CREATE INDEX idx_events_type ON events(event_type);
|
||||
|
||||
-- L0: Evidence chunks (raw, with source reference)
|
||||
CREATE TABLE IF NOT EXISTS chunks_l0 (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL,
|
||||
query_id VARCHAR NOT NULL,
|
||||
source VARCHAR NOT NULL, -- "pi", "claude", "transcript"
|
||||
content TEXT NOT NULL,
|
||||
tokens INT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chunks_l0_project_query ON chunks_l0(project, query_id);
|
||||
|
||||
-- L1: Per-query memories (one per standing query, up to 1024 tokens)
|
||||
CREATE TABLE IF NOT EXISTS memories_l1 (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL,
|
||||
query_id VARCHAR NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
tokens INT NOT NULL,
|
||||
embedding vector(768), -- nomic-embed-text-v2-moe
|
||||
chunks_seen INT NOT NULL,
|
||||
chunks_used INT NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
run_id VARCHAR NOT NULL,
|
||||
UNIQUE(project, query_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_memories_l1_project ON memories_l1(project);
|
||||
CREATE INDEX idx_memories_l1_embedding ON memories_l1 USING ivfflat (embedding vector_cosine_ops);
|
||||
|
||||
-- L1 -> L0 provenance (which evidence chunks produced this memory)
|
||||
CREATE TABLE IF NOT EXISTS l1_l0_edges (
|
||||
l1_id UUID REFERENCES memories_l1(id) ON DELETE CASCADE,
|
||||
l0_id UUID REFERENCES chunks_l0(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (l1_id, l0_id)
|
||||
);
|
||||
|
||||
-- L2: Project synthesis (one per project, up to 1024 tokens)
|
||||
CREATE TABLE IF NOT EXISTS memories_l2 (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL UNIQUE,
|
||||
content TEXT NOT NULL,
|
||||
tokens INT NOT NULL,
|
||||
embedding vector(768),
|
||||
l1_count INT NOT NULL, -- how many L1 memories were used
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
run_id VARCHAR NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_memories_l2_project ON memories_l2(project);
|
||||
CREATE INDEX idx_memories_l2_embedding ON memories_l2 USING ivfflat (embedding vector_cosine_ops);
|
||||
|
||||
-- L2 -> L1 provenance (which L1 memories produced this synthesis)
|
||||
CREATE TABLE IF NOT EXISTS l2_l1_edges (
|
||||
l2_id UUID REFERENCES memories_l2(id) ON DELETE CASCADE,
|
||||
l1_id UUID REFERENCES memories_l1(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (l2_id, l1_id)
|
||||
);
|
||||
|
||||
-- Reference corpus (not gated, used in queries)
|
||||
CREATE TABLE IF NOT EXISTS reference_corpus (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL,
|
||||
name VARCHAR NOT NULL, -- doc name or skill name
|
||||
content TEXT NOT NULL,
|
||||
embedding vector(768),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(project, name)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_corpus_project ON reference_corpus(project);
|
||||
CREATE INDEX idx_corpus_embedding ON reference_corpus USING ivfflat (embedding vector_cosine_ops);
|
||||
|
||||
-- Ingest jobs (async queue)
|
||||
CREATE TABLE IF NOT EXISTS ingest_jobs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL,
|
||||
ingest_id VARCHAR NOT NULL UNIQUE,
|
||||
status VARCHAR NOT NULL DEFAULT 'pending', -- pending, processing, done, failed
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
started_at TIMESTAMP,
|
||||
completed_at TIMESTAMP,
|
||||
error TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_ingest_jobs_project ON ingest_jobs(project);
|
||||
CREATE INDEX idx_ingest_jobs_status ON ingest_jobs(status);
|
||||
|
||||
-- Skills extracted from memories
|
||||
CREATE TABLE IF NOT EXISTS skills (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
project VARCHAR NOT NULL,
|
||||
name VARCHAR NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
when_to_use TEXT,
|
||||
examples TEXT,
|
||||
l1_source UUID NOT NULL REFERENCES memories_l1(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(project, name)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_skills_project ON skills(project);
|
||||
Reference in New Issue
Block a user