@withone/mem 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Mem Database Schema
3
+ * https://mem.now
4
+ *
5
+ * Two tables:
6
+ * - mem_records: All memories
7
+ * - mem_links: Relationships between records
8
+ */
9
+ export declare const SCHEMA_VERSION = "1.0.0";
10
+ export declare const SCHEMA_SQL = "\n-- =============================================================================\n-- Mem: Memory for AI Agents\n-- https://mem.now\n-- Version: 1.0.0\n-- =============================================================================\n\n-- Enable required extensions\nCREATE EXTENSION IF NOT EXISTS vector;\nCREATE EXTENSION IF NOT EXISTS pg_trgm;\n\n-- =============================================================================\n-- RECORDS: All memories\n-- =============================================================================\n\nCREATE TABLE IF NOT EXISTS mem_records (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n type TEXT NOT NULL, -- user-defined (note, decision, preference, etc.)\n data JSONB NOT NULL, -- flexible structure\n tags TEXT[],\n embedding vector(1536),\n searchable_text TEXT,\n searchable tsvector GENERATED ALWAYS AS (\n to_tsvector('english', COALESCE(searchable_text, ''))\n ) STORED,\n\n -- Relevance scoring\n weight INTEGER NOT NULL DEFAULT 5 CHECK (weight BETWEEN 1 AND 10),\n access_count INTEGER NOT NULL DEFAULT 0,\n last_accessed_at TIMESTAMPTZ,\n status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),\n\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n);\n\n-- =============================================================================\n-- LINKS: Relationships between records\n-- =============================================================================\n\nCREATE TABLE IF NOT EXISTS mem_links (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n from_id UUID NOT NULL REFERENCES mem_records(id) ON DELETE CASCADE,\n to_id UUID NOT NULL REFERENCES mem_records(id) ON DELETE CASCADE,\n relation TEXT NOT NULL,\n bidirectional BOOLEAN NOT NULL DEFAULT false, -- true = traversable both ways\n metadata JSONB,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n UNIQUE(from_id, to_id, relation)\n);\n\n-- =============================================================================\n-- INDEXES\n-- =============================================================================\n\nCREATE INDEX IF NOT EXISTS idx_mem_records_type ON mem_records(type);\nCREATE INDEX IF NOT EXISTS idx_mem_records_tags ON mem_records USING GIN(tags);\nCREATE INDEX IF NOT EXISTS idx_mem_records_data ON mem_records USING GIN(data);\nCREATE INDEX IF NOT EXISTS idx_mem_records_searchable ON mem_records USING GIN(searchable);\nCREATE INDEX IF NOT EXISTS idx_mem_records_status ON mem_records(status);\nCREATE INDEX IF NOT EXISTS idx_mem_records_relevance ON mem_records(\n status, weight DESC, access_count DESC, last_accessed_at DESC NULLS LAST\n);\n\nCREATE INDEX IF NOT EXISTS idx_mem_links_from ON mem_links(from_id);\nCREATE INDEX IF NOT EXISTS idx_mem_links_to ON mem_links(to_id);\nCREATE INDEX IF NOT EXISTS idx_mem_links_relation ON mem_links(relation);\nCREATE INDEX IF NOT EXISTS idx_mem_links_from_relation ON mem_links(from_id, relation);\nCREATE INDEX IF NOT EXISTS idx_mem_links_to_relation ON mem_links(to_id, relation);\nCREATE INDEX IF NOT EXISTS idx_mem_links_bidirectional ON mem_links(bidirectional) WHERE bidirectional = true;\n\n-- =============================================================================\n-- SCHEMA METADATA\n-- =============================================================================\n\nCREATE TABLE IF NOT EXISTS mem_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n);\n\nINSERT INTO mem_meta (key, value) VALUES ('version', '1.0.0')\nON CONFLICT (key) DO UPDATE SET value = '1.0.0', updated_at = NOW();\n";
11
+ export declare const VECTOR_INDEX_SQL = "\nDO $$\nBEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_mem_records_embedding') THEN\n CREATE INDEX idx_mem_records_embedding ON mem_records USING hnsw(embedding vector_cosine_ops);\n END IF;\nEND $$;\n";
12
+ export declare const FUNCTIONS_SQL = "\n-- =============================================================================\n-- HYBRID SEARCH\n-- Combines semantic similarity with full-text search using RRF\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_hybrid_search(\n query_text TEXT,\n query_embedding vector(1536),\n match_count INT DEFAULT 10,\n filter_type TEXT DEFAULT NULL,\n full_text_weight FLOAT DEFAULT 0.3,\n semantic_weight FLOAT DEFAULT 0.7,\n rrf_k INT DEFAULT 50,\n include_archived BOOLEAN DEFAULT FALSE\n)\nRETURNS TABLE (\n id UUID,\n type TEXT,\n data JSONB,\n tags TEXT[],\n fts_rank FLOAT,\n semantic_rank FLOAT,\n combined_score FLOAT\n)\nLANGUAGE plpgsql\nAS $$\nBEGIN\n RETURN QUERY\n WITH fts_results AS (\n SELECT\n r.id,\n ROW_NUMBER() OVER (ORDER BY ts_rank_cd(r.searchable, websearch_to_tsquery('english', query_text)) DESC) AS rank\n FROM mem_records r\n WHERE r.searchable @@ websearch_to_tsquery('english', query_text)\n AND (filter_type IS NULL OR r.type = filter_type)\n AND (include_archived OR r.status = 'active')\n LIMIT match_count * 2\n ),\n semantic_results AS (\n SELECT\n r.id,\n ROW_NUMBER() OVER (ORDER BY r.embedding <=> query_embedding) AS rank\n FROM mem_records r\n WHERE r.embedding IS NOT NULL\n AND (filter_type IS NULL OR r.type = filter_type)\n AND (include_archived OR r.status = 'active')\n ORDER BY r.embedding <=> query_embedding\n LIMIT match_count * 2\n ),\n combined AS (\n SELECT\n COALESCE(fts.id, sem.id) AS id,\n COALESCE(1.0 / (rrf_k + fts.rank), 0.0) AS fts_score,\n COALESCE(1.0 / (rrf_k + sem.rank), 0.0) AS sem_score\n FROM fts_results fts\n FULL OUTER JOIN semantic_results sem ON fts.id = sem.id\n )\n SELECT\n r.id,\n r.type,\n r.data,\n r.tags,\n c.fts_score::FLOAT AS fts_rank,\n c.sem_score::FLOAT AS semantic_rank,\n (c.fts_score * full_text_weight + c.sem_score * semantic_weight)::FLOAT AS combined_score\n FROM combined c\n JOIN mem_records r ON r.id = c.id\n ORDER BY (c.fts_score * full_text_weight + c.sem_score * semantic_weight) DESC\n LIMIT match_count;\nEND;\n$$;\n\n-- =============================================================================\n-- RELEVANCE SCORING\n-- Combines: weight (40%), access frequency (30%), recency (30%)\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_calculate_relevance(\n p_weight INTEGER,\n p_access_count INTEGER,\n p_last_accessed_at TIMESTAMPTZ,\n p_created_at TIMESTAMPTZ,\n max_access_count INTEGER DEFAULT 100\n)\nRETURNS FLOAT\nLANGUAGE plpgsql\nAS $$\nDECLARE\n weight_score FLOAT;\n access_score FLOAT;\n recency_score FLOAT;\n days_since_access FLOAT;\nBEGIN\n -- Normalize weight to 0-1 (weight is 1-10)\n weight_score := (p_weight - 1) / 9.0;\n\n -- Normalize access count to 0-1 (capped at max_access_count)\n access_score := LEAST(p_access_count::FLOAT / max_access_count, 1.0);\n\n -- Calculate recency score (1.0 for today, decays over 30 days to 0.1)\n IF p_last_accessed_at IS NOT NULL THEN\n days_since_access := EXTRACT(EPOCH FROM (NOW() - p_last_accessed_at)) / 86400.0;\n recency_score := GREATEST(1.0 - (days_since_access / 30.0) * 0.9, 0.1);\n ELSE\n -- Never accessed, use created_at with lower base score\n days_since_access := EXTRACT(EPOCH FROM (NOW() - p_created_at)) / 86400.0;\n recency_score := GREATEST(0.5 - (days_since_access / 60.0) * 0.4, 0.1);\n END IF;\n\n -- Combine scores: weight 40%, access 30%, recency 30%\n RETURN (weight_score * 0.4) + (access_score * 0.3) + (recency_score * 0.3);\nEND;\n$$;\n\n-- =============================================================================\n-- CONTEXT: Get most relevant records for startup\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_get_context(\n match_count INT DEFAULT 20,\n filter_types TEXT[] DEFAULT NULL\n)\nRETURNS TABLE (\n id UUID,\n type TEXT,\n data JSONB,\n tags TEXT[],\n weight INTEGER,\n access_count INTEGER,\n relevance_score FLOAT\n)\nLANGUAGE plpgsql\nAS $$\nBEGIN\n RETURN QUERY\n SELECT\n r.id,\n r.type,\n r.data,\n r.tags,\n r.weight,\n r.access_count,\n mem_calculate_relevance(r.weight, r.access_count, r.last_accessed_at, r.created_at)::FLOAT AS relevance_score\n FROM mem_records r\n WHERE r.status = 'active'\n AND (filter_types IS NULL OR r.type = ANY(filter_types))\n ORDER BY mem_calculate_relevance(r.weight, r.access_count, r.last_accessed_at, r.created_at) DESC\n LIMIT match_count;\nEND;\n$$;\n\n-- =============================================================================\n-- ACCESS TRACKING\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_increment_access(record_ids UUID[])\nRETURNS VOID\nLANGUAGE plpgsql\nAS $$\nBEGIN\n UPDATE mem_records\n SET\n access_count = access_count + 1,\n last_accessed_at = NOW()\n WHERE id = ANY(record_ids);\nEND;\n$$;\n\n-- =============================================================================\n-- ARCHIVE / UNARCHIVE\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_archive(record_ids UUID[])\nRETURNS INTEGER\nLANGUAGE plpgsql\nAS $$\nDECLARE\n affected INTEGER;\nBEGIN\n UPDATE mem_records\n SET status = 'archived', updated_at = NOW()\n WHERE id = ANY(record_ids) AND status = 'active';\n GET DIAGNOSTICS affected = ROW_COUNT;\n RETURN affected;\nEND;\n$$;\n\nCREATE OR REPLACE FUNCTION mem_unarchive(record_ids UUID[])\nRETURNS INTEGER\nLANGUAGE plpgsql\nAS $$\nDECLARE\n affected INTEGER;\nBEGIN\n UPDATE mem_records\n SET status = 'active', updated_at = NOW()\n WHERE id = ANY(record_ids) AND status = 'archived';\n GET DIAGNOSTICS affected = ROW_COUNT;\n RETURN affected;\nEND;\n$$;\n\n-- =============================================================================\n-- FLUSH: Reset access count\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_flush(record_ids UUID[])\nRETURNS INTEGER\nLANGUAGE plpgsql\nAS $$\nDECLARE\n affected INTEGER;\nBEGIN\n UPDATE mem_records\n SET\n access_count = 0,\n last_accessed_at = NULL,\n updated_at = NOW()\n WHERE id = ANY(record_ids);\n GET DIAGNOSTICS affected = ROW_COUNT;\n RETURN affected;\nEND;\n$$;\n\n-- =============================================================================\n-- GRAPH TRAVERSAL\n-- Respects bidirectional flag\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_get_record_with_links(record_id UUID)\nRETURNS JSONB\nLANGUAGE sql\nAS $$\n SELECT jsonb_build_object(\n 'id', r.id,\n 'type', r.type,\n 'data', r.data,\n 'tags', r.tags,\n 'weight', r.weight,\n 'access_count', r.access_count,\n 'status', r.status,\n 'created_at', r.created_at,\n 'updated_at', r.updated_at,\n 'outgoing', COALESCE((\n SELECT jsonb_agg(jsonb_build_object(\n 'relation', l.relation,\n 'bidirectional', l.bidirectional,\n 'metadata', l.metadata,\n 'record', jsonb_build_object(\n 'id', linked.id,\n 'type', linked.type,\n 'data', linked.data\n )\n ))\n FROM mem_links l\n JOIN mem_records linked ON linked.id = l.to_id\n WHERE l.from_id = r.id\n ), '[]'::jsonb),\n 'incoming', COALESCE((\n SELECT jsonb_agg(jsonb_build_object(\n 'relation', l.relation,\n 'bidirectional', l.bidirectional,\n 'metadata', l.metadata,\n 'record', jsonb_build_object(\n 'id', linked.id,\n 'type', linked.type,\n 'data', linked.data\n )\n ))\n FROM mem_links l\n JOIN mem_records linked ON linked.id = l.from_id\n WHERE l.to_id = r.id\n ), '[]'::jsonb)\n )\n FROM mem_records r\n WHERE r.id = record_id;\n$$;\n\nCREATE OR REPLACE FUNCTION mem_get_linked(\n record_id UUID,\n relation_type TEXT DEFAULT NULL,\n direction TEXT DEFAULT 'outgoing'\n)\nRETURNS TABLE (\n id UUID,\n type TEXT,\n data JSONB,\n relation TEXT,\n bidirectional BOOLEAN,\n link_metadata JSONB\n)\nLANGUAGE sql\nAS $$\n -- Outgoing links (from this record to others)\n SELECT\n r.id,\n r.type,\n r.data,\n l.relation,\n l.bidirectional,\n l.metadata\n FROM mem_links l\n JOIN mem_records r ON r.id = l.to_id\n WHERE l.from_id = record_id\n AND (relation_type IS NULL OR l.relation = relation_type)\n AND (direction = 'outgoing' OR direction = 'both')\n\n UNION ALL\n\n -- Incoming links (from others to this record)\n -- Only include if bidirectional=true OR direction includes incoming\n SELECT\n r.id,\n r.type,\n r.data,\n l.relation,\n l.bidirectional,\n l.metadata\n FROM mem_links l\n JOIN mem_records r ON r.id = l.from_id\n WHERE l.to_id = record_id\n AND (relation_type IS NULL OR l.relation = relation_type)\n AND (\n direction = 'incoming'\n OR direction = 'both'\n OR l.bidirectional = true\n );\n$$;\n\n-- =============================================================================\n-- LINK OPERATIONS\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_create_link(\n from_record_id UUID,\n to_record_id UUID,\n relation_type TEXT,\n is_bidirectional BOOLEAN DEFAULT false,\n link_metadata JSONB DEFAULT NULL\n)\nRETURNS UUID\nLANGUAGE plpgsql\nAS $$\nDECLARE\n link_id UUID;\nBEGIN\n INSERT INTO mem_links (from_id, to_id, relation, bidirectional, metadata)\n VALUES (from_record_id, to_record_id, relation_type, is_bidirectional, link_metadata)\n ON CONFLICT (from_id, to_id, relation) DO UPDATE\n SET bidirectional = is_bidirectional,\n metadata = COALESCE(link_metadata, mem_links.metadata)\n RETURNING id INTO link_id;\n RETURN link_id;\nEND;\n$$;\n\nCREATE OR REPLACE FUNCTION mem_remove_link(\n from_record_id UUID,\n to_record_id UUID,\n relation_type TEXT\n)\nRETURNS BOOLEAN\nLANGUAGE plpgsql\nAS $$\nBEGIN\n DELETE FROM mem_links\n WHERE from_id = from_record_id\n AND to_id = to_record_id\n AND relation = relation_type;\n RETURN FOUND;\nEND;\n$$;\n\n-- =============================================================================\n-- TRIGGERS\n-- =============================================================================\n\nCREATE OR REPLACE FUNCTION mem_extract_searchable_text(record_type TEXT, record_data JSONB)\nRETURNS TEXT\nLANGUAGE plpgsql\nAS $$\nBEGIN\n -- Generic extraction: concatenate all string values\n RETURN (SELECT string_agg(value::TEXT, ' ')\n FROM jsonb_each_text(record_data)\n WHERE value IS NOT NULL AND value != '');\nEND;\n$$;\n\nCREATE OR REPLACE FUNCTION mem_records_trigger()\nRETURNS TRIGGER\nLANGUAGE plpgsql\nAS $$\nBEGIN\n NEW.searchable_text := mem_extract_searchable_text(NEW.type, NEW.data);\n NEW.updated_at := NOW();\n RETURN NEW;\nEND;\n$$;\n\nDROP TRIGGER IF EXISTS mem_records_before_upsert ON mem_records;\nCREATE TRIGGER mem_records_before_upsert\nBEFORE INSERT OR UPDATE ON mem_records\nFOR EACH ROW\nEXECUTE FUNCTION mem_records_trigger();\n";
13
+ export declare function getMigrationSQL(): string;
14
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,UAAU,0qHAmFtB,CAAC;AAGF,eAAO,MAAM,gBAAgB,oPAO5B,CAAC;AAEF,eAAO,MAAM,aAAa,k6XAsZzB,CAAC;AAGF,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
package/dist/schema.js ADDED
@@ -0,0 +1,514 @@
1
+ /**
2
+ * Mem Database Schema
3
+ * https://mem.now
4
+ *
5
+ * Two tables:
6
+ * - mem_records: All memories
7
+ * - mem_links: Relationships between records
8
+ */
9
+ export const SCHEMA_VERSION = "1.0.0";
10
+ export const SCHEMA_SQL = `
11
+ -- =============================================================================
12
+ -- Mem: Memory for AI Agents
13
+ -- https://mem.now
14
+ -- Version: ${SCHEMA_VERSION}
15
+ -- =============================================================================
16
+
17
+ -- Enable required extensions
18
+ CREATE EXTENSION IF NOT EXISTS vector;
19
+ CREATE EXTENSION IF NOT EXISTS pg_trgm;
20
+
21
+ -- =============================================================================
22
+ -- RECORDS: All memories
23
+ -- =============================================================================
24
+
25
+ CREATE TABLE IF NOT EXISTS mem_records (
26
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
27
+ type TEXT NOT NULL, -- user-defined (note, decision, preference, etc.)
28
+ data JSONB NOT NULL, -- flexible structure
29
+ tags TEXT[],
30
+ embedding vector(1536),
31
+ searchable_text TEXT,
32
+ searchable tsvector GENERATED ALWAYS AS (
33
+ to_tsvector('english', COALESCE(searchable_text, ''))
34
+ ) STORED,
35
+
36
+ -- Relevance scoring
37
+ weight INTEGER NOT NULL DEFAULT 5 CHECK (weight BETWEEN 1 AND 10),
38
+ access_count INTEGER NOT NULL DEFAULT 0,
39
+ last_accessed_at TIMESTAMPTZ,
40
+ status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),
41
+
42
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
43
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
44
+ );
45
+
46
+ -- =============================================================================
47
+ -- LINKS: Relationships between records
48
+ -- =============================================================================
49
+
50
+ CREATE TABLE IF NOT EXISTS mem_links (
51
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
52
+ from_id UUID NOT NULL REFERENCES mem_records(id) ON DELETE CASCADE,
53
+ to_id UUID NOT NULL REFERENCES mem_records(id) ON DELETE CASCADE,
54
+ relation TEXT NOT NULL,
55
+ bidirectional BOOLEAN NOT NULL DEFAULT false, -- true = traversable both ways
56
+ metadata JSONB,
57
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
58
+ UNIQUE(from_id, to_id, relation)
59
+ );
60
+
61
+ -- =============================================================================
62
+ -- INDEXES
63
+ -- =============================================================================
64
+
65
+ CREATE INDEX IF NOT EXISTS idx_mem_records_type ON mem_records(type);
66
+ CREATE INDEX IF NOT EXISTS idx_mem_records_tags ON mem_records USING GIN(tags);
67
+ CREATE INDEX IF NOT EXISTS idx_mem_records_data ON mem_records USING GIN(data);
68
+ CREATE INDEX IF NOT EXISTS idx_mem_records_searchable ON mem_records USING GIN(searchable);
69
+ CREATE INDEX IF NOT EXISTS idx_mem_records_status ON mem_records(status);
70
+ CREATE INDEX IF NOT EXISTS idx_mem_records_relevance ON mem_records(
71
+ status, weight DESC, access_count DESC, last_accessed_at DESC NULLS LAST
72
+ );
73
+
74
+ CREATE INDEX IF NOT EXISTS idx_mem_links_from ON mem_links(from_id);
75
+ CREATE INDEX IF NOT EXISTS idx_mem_links_to ON mem_links(to_id);
76
+ CREATE INDEX IF NOT EXISTS idx_mem_links_relation ON mem_links(relation);
77
+ CREATE INDEX IF NOT EXISTS idx_mem_links_from_relation ON mem_links(from_id, relation);
78
+ CREATE INDEX IF NOT EXISTS idx_mem_links_to_relation ON mem_links(to_id, relation);
79
+ CREATE INDEX IF NOT EXISTS idx_mem_links_bidirectional ON mem_links(bidirectional) WHERE bidirectional = true;
80
+
81
+ -- =============================================================================
82
+ -- SCHEMA METADATA
83
+ -- =============================================================================
84
+
85
+ CREATE TABLE IF NOT EXISTS mem_meta (
86
+ key TEXT PRIMARY KEY,
87
+ value TEXT NOT NULL,
88
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
89
+ );
90
+
91
+ INSERT INTO mem_meta (key, value) VALUES ('version', '${SCHEMA_VERSION}')
92
+ ON CONFLICT (key) DO UPDATE SET value = '${SCHEMA_VERSION}', updated_at = NOW();
93
+ `;
94
+ // Vector index (created separately)
95
+ export const VECTOR_INDEX_SQL = `
96
+ DO $$
97
+ BEGIN
98
+ IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_mem_records_embedding') THEN
99
+ CREATE INDEX idx_mem_records_embedding ON mem_records USING hnsw(embedding vector_cosine_ops);
100
+ END IF;
101
+ END $$;
102
+ `;
103
+ export const FUNCTIONS_SQL = `
104
+ -- =============================================================================
105
+ -- HYBRID SEARCH
106
+ -- Combines semantic similarity with full-text search using RRF
107
+ -- =============================================================================
108
+
109
+ CREATE OR REPLACE FUNCTION mem_hybrid_search(
110
+ query_text TEXT,
111
+ query_embedding vector(1536),
112
+ match_count INT DEFAULT 10,
113
+ filter_type TEXT DEFAULT NULL,
114
+ full_text_weight FLOAT DEFAULT 0.3,
115
+ semantic_weight FLOAT DEFAULT 0.7,
116
+ rrf_k INT DEFAULT 50,
117
+ include_archived BOOLEAN DEFAULT FALSE
118
+ )
119
+ RETURNS TABLE (
120
+ id UUID,
121
+ type TEXT,
122
+ data JSONB,
123
+ tags TEXT[],
124
+ fts_rank FLOAT,
125
+ semantic_rank FLOAT,
126
+ combined_score FLOAT
127
+ )
128
+ LANGUAGE plpgsql
129
+ AS $$
130
+ BEGIN
131
+ RETURN QUERY
132
+ WITH fts_results AS (
133
+ SELECT
134
+ r.id,
135
+ ROW_NUMBER() OVER (ORDER BY ts_rank_cd(r.searchable, websearch_to_tsquery('english', query_text)) DESC) AS rank
136
+ FROM mem_records r
137
+ WHERE r.searchable @@ websearch_to_tsquery('english', query_text)
138
+ AND (filter_type IS NULL OR r.type = filter_type)
139
+ AND (include_archived OR r.status = 'active')
140
+ LIMIT match_count * 2
141
+ ),
142
+ semantic_results AS (
143
+ SELECT
144
+ r.id,
145
+ ROW_NUMBER() OVER (ORDER BY r.embedding <=> query_embedding) AS rank
146
+ FROM mem_records r
147
+ WHERE r.embedding IS NOT NULL
148
+ AND (filter_type IS NULL OR r.type = filter_type)
149
+ AND (include_archived OR r.status = 'active')
150
+ ORDER BY r.embedding <=> query_embedding
151
+ LIMIT match_count * 2
152
+ ),
153
+ combined AS (
154
+ SELECT
155
+ COALESCE(fts.id, sem.id) AS id,
156
+ COALESCE(1.0 / (rrf_k + fts.rank), 0.0) AS fts_score,
157
+ COALESCE(1.0 / (rrf_k + sem.rank), 0.0) AS sem_score
158
+ FROM fts_results fts
159
+ FULL OUTER JOIN semantic_results sem ON fts.id = sem.id
160
+ )
161
+ SELECT
162
+ r.id,
163
+ r.type,
164
+ r.data,
165
+ r.tags,
166
+ c.fts_score::FLOAT AS fts_rank,
167
+ c.sem_score::FLOAT AS semantic_rank,
168
+ (c.fts_score * full_text_weight + c.sem_score * semantic_weight)::FLOAT AS combined_score
169
+ FROM combined c
170
+ JOIN mem_records r ON r.id = c.id
171
+ ORDER BY (c.fts_score * full_text_weight + c.sem_score * semantic_weight) DESC
172
+ LIMIT match_count;
173
+ END;
174
+ $$;
175
+
176
+ -- =============================================================================
177
+ -- RELEVANCE SCORING
178
+ -- Combines: weight (40%), access frequency (30%), recency (30%)
179
+ -- =============================================================================
180
+
181
+ CREATE OR REPLACE FUNCTION mem_calculate_relevance(
182
+ p_weight INTEGER,
183
+ p_access_count INTEGER,
184
+ p_last_accessed_at TIMESTAMPTZ,
185
+ p_created_at TIMESTAMPTZ,
186
+ max_access_count INTEGER DEFAULT 100
187
+ )
188
+ RETURNS FLOAT
189
+ LANGUAGE plpgsql
190
+ AS $$
191
+ DECLARE
192
+ weight_score FLOAT;
193
+ access_score FLOAT;
194
+ recency_score FLOAT;
195
+ days_since_access FLOAT;
196
+ BEGIN
197
+ -- Normalize weight to 0-1 (weight is 1-10)
198
+ weight_score := (p_weight - 1) / 9.0;
199
+
200
+ -- Normalize access count to 0-1 (capped at max_access_count)
201
+ access_score := LEAST(p_access_count::FLOAT / max_access_count, 1.0);
202
+
203
+ -- Calculate recency score (1.0 for today, decays over 30 days to 0.1)
204
+ IF p_last_accessed_at IS NOT NULL THEN
205
+ days_since_access := EXTRACT(EPOCH FROM (NOW() - p_last_accessed_at)) / 86400.0;
206
+ recency_score := GREATEST(1.0 - (days_since_access / 30.0) * 0.9, 0.1);
207
+ ELSE
208
+ -- Never accessed, use created_at with lower base score
209
+ days_since_access := EXTRACT(EPOCH FROM (NOW() - p_created_at)) / 86400.0;
210
+ recency_score := GREATEST(0.5 - (days_since_access / 60.0) * 0.4, 0.1);
211
+ END IF;
212
+
213
+ -- Combine scores: weight 40%, access 30%, recency 30%
214
+ RETURN (weight_score * 0.4) + (access_score * 0.3) + (recency_score * 0.3);
215
+ END;
216
+ $$;
217
+
218
+ -- =============================================================================
219
+ -- CONTEXT: Get most relevant records for startup
220
+ -- =============================================================================
221
+
222
+ CREATE OR REPLACE FUNCTION mem_get_context(
223
+ match_count INT DEFAULT 20,
224
+ filter_types TEXT[] DEFAULT NULL
225
+ )
226
+ RETURNS TABLE (
227
+ id UUID,
228
+ type TEXT,
229
+ data JSONB,
230
+ tags TEXT[],
231
+ weight INTEGER,
232
+ access_count INTEGER,
233
+ relevance_score FLOAT
234
+ )
235
+ LANGUAGE plpgsql
236
+ AS $$
237
+ BEGIN
238
+ RETURN QUERY
239
+ SELECT
240
+ r.id,
241
+ r.type,
242
+ r.data,
243
+ r.tags,
244
+ r.weight,
245
+ r.access_count,
246
+ mem_calculate_relevance(r.weight, r.access_count, r.last_accessed_at, r.created_at)::FLOAT AS relevance_score
247
+ FROM mem_records r
248
+ WHERE r.status = 'active'
249
+ AND (filter_types IS NULL OR r.type = ANY(filter_types))
250
+ ORDER BY mem_calculate_relevance(r.weight, r.access_count, r.last_accessed_at, r.created_at) DESC
251
+ LIMIT match_count;
252
+ END;
253
+ $$;
254
+
255
+ -- =============================================================================
256
+ -- ACCESS TRACKING
257
+ -- =============================================================================
258
+
259
+ CREATE OR REPLACE FUNCTION mem_increment_access(record_ids UUID[])
260
+ RETURNS VOID
261
+ LANGUAGE plpgsql
262
+ AS $$
263
+ BEGIN
264
+ UPDATE mem_records
265
+ SET
266
+ access_count = access_count + 1,
267
+ last_accessed_at = NOW()
268
+ WHERE id = ANY(record_ids);
269
+ END;
270
+ $$;
271
+
272
+ -- =============================================================================
273
+ -- ARCHIVE / UNARCHIVE
274
+ -- =============================================================================
275
+
276
+ CREATE OR REPLACE FUNCTION mem_archive(record_ids UUID[])
277
+ RETURNS INTEGER
278
+ LANGUAGE plpgsql
279
+ AS $$
280
+ DECLARE
281
+ affected INTEGER;
282
+ BEGIN
283
+ UPDATE mem_records
284
+ SET status = 'archived', updated_at = NOW()
285
+ WHERE id = ANY(record_ids) AND status = 'active';
286
+ GET DIAGNOSTICS affected = ROW_COUNT;
287
+ RETURN affected;
288
+ END;
289
+ $$;
290
+
291
+ CREATE OR REPLACE FUNCTION mem_unarchive(record_ids UUID[])
292
+ RETURNS INTEGER
293
+ LANGUAGE plpgsql
294
+ AS $$
295
+ DECLARE
296
+ affected INTEGER;
297
+ BEGIN
298
+ UPDATE mem_records
299
+ SET status = 'active', updated_at = NOW()
300
+ WHERE id = ANY(record_ids) AND status = 'archived';
301
+ GET DIAGNOSTICS affected = ROW_COUNT;
302
+ RETURN affected;
303
+ END;
304
+ $$;
305
+
306
+ -- =============================================================================
307
+ -- FLUSH: Reset access count
308
+ -- =============================================================================
309
+
310
+ CREATE OR REPLACE FUNCTION mem_flush(record_ids UUID[])
311
+ RETURNS INTEGER
312
+ LANGUAGE plpgsql
313
+ AS $$
314
+ DECLARE
315
+ affected INTEGER;
316
+ BEGIN
317
+ UPDATE mem_records
318
+ SET
319
+ access_count = 0,
320
+ last_accessed_at = NULL,
321
+ updated_at = NOW()
322
+ WHERE id = ANY(record_ids);
323
+ GET DIAGNOSTICS affected = ROW_COUNT;
324
+ RETURN affected;
325
+ END;
326
+ $$;
327
+
328
+ -- =============================================================================
329
+ -- GRAPH TRAVERSAL
330
+ -- Respects bidirectional flag
331
+ -- =============================================================================
332
+
333
+ CREATE OR REPLACE FUNCTION mem_get_record_with_links(record_id UUID)
334
+ RETURNS JSONB
335
+ LANGUAGE sql
336
+ AS $$
337
+ SELECT jsonb_build_object(
338
+ 'id', r.id,
339
+ 'type', r.type,
340
+ 'data', r.data,
341
+ 'tags', r.tags,
342
+ 'weight', r.weight,
343
+ 'access_count', r.access_count,
344
+ 'status', r.status,
345
+ 'created_at', r.created_at,
346
+ 'updated_at', r.updated_at,
347
+ 'outgoing', COALESCE((
348
+ SELECT jsonb_agg(jsonb_build_object(
349
+ 'relation', l.relation,
350
+ 'bidirectional', l.bidirectional,
351
+ 'metadata', l.metadata,
352
+ 'record', jsonb_build_object(
353
+ 'id', linked.id,
354
+ 'type', linked.type,
355
+ 'data', linked.data
356
+ )
357
+ ))
358
+ FROM mem_links l
359
+ JOIN mem_records linked ON linked.id = l.to_id
360
+ WHERE l.from_id = r.id
361
+ ), '[]'::jsonb),
362
+ 'incoming', COALESCE((
363
+ SELECT jsonb_agg(jsonb_build_object(
364
+ 'relation', l.relation,
365
+ 'bidirectional', l.bidirectional,
366
+ 'metadata', l.metadata,
367
+ 'record', jsonb_build_object(
368
+ 'id', linked.id,
369
+ 'type', linked.type,
370
+ 'data', linked.data
371
+ )
372
+ ))
373
+ FROM mem_links l
374
+ JOIN mem_records linked ON linked.id = l.from_id
375
+ WHERE l.to_id = r.id
376
+ ), '[]'::jsonb)
377
+ )
378
+ FROM mem_records r
379
+ WHERE r.id = record_id;
380
+ $$;
381
+
382
+ CREATE OR REPLACE FUNCTION mem_get_linked(
383
+ record_id UUID,
384
+ relation_type TEXT DEFAULT NULL,
385
+ direction TEXT DEFAULT 'outgoing'
386
+ )
387
+ RETURNS TABLE (
388
+ id UUID,
389
+ type TEXT,
390
+ data JSONB,
391
+ relation TEXT,
392
+ bidirectional BOOLEAN,
393
+ link_metadata JSONB
394
+ )
395
+ LANGUAGE sql
396
+ AS $$
397
+ -- Outgoing links (from this record to others)
398
+ SELECT
399
+ r.id,
400
+ r.type,
401
+ r.data,
402
+ l.relation,
403
+ l.bidirectional,
404
+ l.metadata
405
+ FROM mem_links l
406
+ JOIN mem_records r ON r.id = l.to_id
407
+ WHERE l.from_id = record_id
408
+ AND (relation_type IS NULL OR l.relation = relation_type)
409
+ AND (direction = 'outgoing' OR direction = 'both')
410
+
411
+ UNION ALL
412
+
413
+ -- Incoming links (from others to this record)
414
+ -- Only include if bidirectional=true OR direction includes incoming
415
+ SELECT
416
+ r.id,
417
+ r.type,
418
+ r.data,
419
+ l.relation,
420
+ l.bidirectional,
421
+ l.metadata
422
+ FROM mem_links l
423
+ JOIN mem_records r ON r.id = l.from_id
424
+ WHERE l.to_id = record_id
425
+ AND (relation_type IS NULL OR l.relation = relation_type)
426
+ AND (
427
+ direction = 'incoming'
428
+ OR direction = 'both'
429
+ OR l.bidirectional = true
430
+ );
431
+ $$;
432
+
433
+ -- =============================================================================
434
+ -- LINK OPERATIONS
435
+ -- =============================================================================
436
+
437
+ CREATE OR REPLACE FUNCTION mem_create_link(
438
+ from_record_id UUID,
439
+ to_record_id UUID,
440
+ relation_type TEXT,
441
+ is_bidirectional BOOLEAN DEFAULT false,
442
+ link_metadata JSONB DEFAULT NULL
443
+ )
444
+ RETURNS UUID
445
+ LANGUAGE plpgsql
446
+ AS $$
447
+ DECLARE
448
+ link_id UUID;
449
+ BEGIN
450
+ INSERT INTO mem_links (from_id, to_id, relation, bidirectional, metadata)
451
+ VALUES (from_record_id, to_record_id, relation_type, is_bidirectional, link_metadata)
452
+ ON CONFLICT (from_id, to_id, relation) DO UPDATE
453
+ SET bidirectional = is_bidirectional,
454
+ metadata = COALESCE(link_metadata, mem_links.metadata)
455
+ RETURNING id INTO link_id;
456
+ RETURN link_id;
457
+ END;
458
+ $$;
459
+
460
+ CREATE OR REPLACE FUNCTION mem_remove_link(
461
+ from_record_id UUID,
462
+ to_record_id UUID,
463
+ relation_type TEXT
464
+ )
465
+ RETURNS BOOLEAN
466
+ LANGUAGE plpgsql
467
+ AS $$
468
+ BEGIN
469
+ DELETE FROM mem_links
470
+ WHERE from_id = from_record_id
471
+ AND to_id = to_record_id
472
+ AND relation = relation_type;
473
+ RETURN FOUND;
474
+ END;
475
+ $$;
476
+
477
+ -- =============================================================================
478
+ -- TRIGGERS
479
+ -- =============================================================================
480
+
481
+ CREATE OR REPLACE FUNCTION mem_extract_searchable_text(record_type TEXT, record_data JSONB)
482
+ RETURNS TEXT
483
+ LANGUAGE plpgsql
484
+ AS $$
485
+ BEGIN
486
+ -- Generic extraction: concatenate all string values
487
+ RETURN (SELECT string_agg(value::TEXT, ' ')
488
+ FROM jsonb_each_text(record_data)
489
+ WHERE value IS NOT NULL AND value != '');
490
+ END;
491
+ $$;
492
+
493
+ CREATE OR REPLACE FUNCTION mem_records_trigger()
494
+ RETURNS TRIGGER
495
+ LANGUAGE plpgsql
496
+ AS $$
497
+ BEGIN
498
+ NEW.searchable_text := mem_extract_searchable_text(NEW.type, NEW.data);
499
+ NEW.updated_at := NOW();
500
+ RETURN NEW;
501
+ END;
502
+ $$;
503
+
504
+ DROP TRIGGER IF EXISTS mem_records_before_upsert ON mem_records;
505
+ CREATE TRIGGER mem_records_before_upsert
506
+ BEFORE INSERT OR UPDATE ON mem_records
507
+ FOR EACH ROW
508
+ EXECUTE FUNCTION mem_records_trigger();
509
+ `;
510
+ // Full migration SQL (combines schema + vector index + functions)
511
+ export function getMigrationSQL() {
512
+ return `${SCHEMA_SQL}\n\n${VECTOR_INDEX_SQL}\n\n${FUNCTIONS_SQL}`;
513
+ }
514
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG;;;;cAIZ,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDA6E4B,cAAc;2CAC3B,cAAc;CACxD,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;CAO/B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsZ5B,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,eAAe;IAC7B,OAAO,GAAG,UAAU,OAAO,gBAAgB,OAAO,aAAa,EAAE,CAAC;AACpE,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Mem Type Definitions
3
+ */
4
+ export interface MemRecord {
5
+ id: string;
6
+ type: string;
7
+ data: Record<string, unknown>;
8
+ tags?: string[];
9
+ embedding?: number[];
10
+ searchable_text?: string;
11
+ weight: number;
12
+ access_count: number;
13
+ last_accessed_at?: string;
14
+ status: "active" | "archived";
15
+ created_at: string;
16
+ updated_at: string;
17
+ }
18
+ export interface MemLink {
19
+ id: string;
20
+ from_id: string;
21
+ to_id: string;
22
+ relation: string;
23
+ bidirectional: boolean;
24
+ metadata?: Record<string, unknown>;
25
+ created_at: string;
26
+ }
27
+ export interface MemRecordWithLinks extends MemRecord {
28
+ outgoing: Array<{
29
+ relation: string;
30
+ bidirectional: boolean;
31
+ metadata?: Record<string, unknown>;
32
+ record: {
33
+ id: string;
34
+ type: string;
35
+ data: Record<string, unknown>;
36
+ };
37
+ }>;
38
+ incoming: Array<{
39
+ relation: string;
40
+ bidirectional: boolean;
41
+ metadata?: Record<string, unknown>;
42
+ record: {
43
+ id: string;
44
+ type: string;
45
+ data: Record<string, unknown>;
46
+ };
47
+ }>;
48
+ }
49
+ export interface SearchResult {
50
+ id: string;
51
+ type: string;
52
+ data: Record<string, unknown>;
53
+ tags?: string[];
54
+ fts_rank: number;
55
+ semantic_rank: number;
56
+ combined_score: number;
57
+ }
58
+ export interface ContextResult {
59
+ id: string;
60
+ type: string;
61
+ data: Record<string, unknown>;
62
+ tags?: string[];
63
+ weight: number;
64
+ access_count: number;
65
+ relevance_score: number;
66
+ }
67
+ export interface AddRecordOptions {
68
+ tags?: string[];
69
+ weight?: number;
70
+ generateEmbedding?: boolean;
71
+ }
72
+ export interface UpdateRecordOptions {
73
+ tags?: string[];
74
+ regenerateEmbedding?: boolean;
75
+ }
76
+ export interface SearchOptions {
77
+ limit?: number;
78
+ type?: string;
79
+ ftsWeight?: number;
80
+ semanticWeight?: number;
81
+ includeArchived?: boolean;
82
+ trackAccess?: boolean;
83
+ }
84
+ export interface ContextOptions {
85
+ limit?: number;
86
+ types?: string[];
87
+ }
88
+ export interface LinkedOptions {
89
+ relation?: string;
90
+ direction?: "outgoing" | "incoming" | "both";
91
+ }
92
+ export interface LinkedRecord {
93
+ id: string;
94
+ type: string;
95
+ data: Record<string, unknown>;
96
+ relation: string;
97
+ bidirectional: boolean;
98
+ link_metadata?: Record<string, unknown>;
99
+ }
100
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Mem Type Definitions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}