@mnexium/core 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.
- package/.env.example +37 -0
- package/README.md +37 -0
- package/docs/API.md +299 -0
- package/docs/BEHAVIOR.md +224 -0
- package/docs/OPERATIONS.md +116 -0
- package/docs/SETUP.md +239 -0
- package/package.json +22 -0
- package/scripts/e2e.lib.mjs +604 -0
- package/scripts/e2e.routes.mjs +32 -0
- package/scripts/e2e.sh +76 -0
- package/scripts/e2e.webapp.client.js +408 -0
- package/scripts/e2e.webapp.mjs +1065 -0
- package/sql/postgres/schema.sql +275 -0
- package/src/adapters/postgres/PostgresCoreStore.ts +1017 -0
- package/src/ai/memoryExtractionService.ts +265 -0
- package/src/ai/recallService.ts +442 -0
- package/src/ai/types.ts +11 -0
- package/src/contracts/storage.ts +137 -0
- package/src/contracts/types.ts +138 -0
- package/src/dev.ts +144 -0
- package/src/index.ts +15 -0
- package/src/providers/cerebras.ts +101 -0
- package/src/providers/openaiChat.ts +116 -0
- package/src/providers/openaiEmbedding.ts +52 -0
- package/src/server/createCoreServer.ts +1154 -0
- package/src/server/memoryEventBus.ts +57 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
-- CORE Postgres schema
|
|
2
|
+
-- Requires pgvector extension for embedding similarity.
|
|
3
|
+
|
|
4
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
5
|
+
|
|
6
|
+
-- Common updated_at trigger
|
|
7
|
+
CREATE OR REPLACE FUNCTION core_set_updated_at()
|
|
8
|
+
RETURNS trigger AS $$
|
|
9
|
+
BEGIN
|
|
10
|
+
NEW.updated_at = NOW();
|
|
11
|
+
RETURN NEW;
|
|
12
|
+
END;
|
|
13
|
+
$$ LANGUAGE plpgsql;
|
|
14
|
+
|
|
15
|
+
-- =====================================================================
|
|
16
|
+
-- Memories
|
|
17
|
+
-- =====================================================================
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
project_id TEXT NOT NULL,
|
|
22
|
+
subject_id TEXT NOT NULL,
|
|
23
|
+
text TEXT NOT NULL,
|
|
24
|
+
kind TEXT NOT NULL DEFAULT 'fact',
|
|
25
|
+
visibility TEXT NOT NULL DEFAULT 'private',
|
|
26
|
+
importance INTEGER NOT NULL DEFAULT 50 CHECK (importance BETWEEN 0 AND 100),
|
|
27
|
+
confidence DOUBLE PRECISION NOT NULL DEFAULT 0.8 CHECK (confidence >= 0 AND confidence <= 1),
|
|
28
|
+
is_temporal BOOLEAN NOT NULL DEFAULT FALSE,
|
|
29
|
+
tags TEXT[] NOT NULL DEFAULT '{}',
|
|
30
|
+
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
31
|
+
embedding VECTOR(1536),
|
|
32
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
33
|
+
superseded_by TEXT,
|
|
34
|
+
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
35
|
+
source_type TEXT NOT NULL DEFAULT 'explicit',
|
|
36
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
37
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
38
|
+
last_seen_at TIMESTAMPTZ,
|
|
39
|
+
seen_count INTEGER NOT NULL DEFAULT 0,
|
|
40
|
+
reinforcement_count INTEGER NOT NULL DEFAULT 0,
|
|
41
|
+
last_reinforced_at TIMESTAMPTZ
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
DO $$
|
|
45
|
+
BEGIN
|
|
46
|
+
IF NOT EXISTS (
|
|
47
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'memories_kind_check'
|
|
48
|
+
) THEN
|
|
49
|
+
ALTER TABLE memories
|
|
50
|
+
ADD CONSTRAINT memories_kind_check
|
|
51
|
+
CHECK (kind IN ('fact', 'preference', 'context', 'note', 'event', 'trait'));
|
|
52
|
+
END IF;
|
|
53
|
+
END $$;
|
|
54
|
+
|
|
55
|
+
DO $$
|
|
56
|
+
BEGIN
|
|
57
|
+
IF NOT EXISTS (
|
|
58
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'memories_visibility_check'
|
|
59
|
+
) THEN
|
|
60
|
+
ALTER TABLE memories
|
|
61
|
+
ADD CONSTRAINT memories_visibility_check
|
|
62
|
+
CHECK (visibility IN ('private', 'shared', 'public'));
|
|
63
|
+
END IF;
|
|
64
|
+
END $$;
|
|
65
|
+
|
|
66
|
+
DO $$
|
|
67
|
+
BEGIN
|
|
68
|
+
IF NOT EXISTS (
|
|
69
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'memories_status_check'
|
|
70
|
+
) THEN
|
|
71
|
+
ALTER TABLE memories
|
|
72
|
+
ADD CONSTRAINT memories_status_check
|
|
73
|
+
CHECK (status IN ('active', 'superseded'));
|
|
74
|
+
END IF;
|
|
75
|
+
END $$;
|
|
76
|
+
|
|
77
|
+
CREATE INDEX IF NOT EXISTS idx_memories_project_subject
|
|
78
|
+
ON memories(project_id, subject_id);
|
|
79
|
+
|
|
80
|
+
CREATE INDEX IF NOT EXISTS idx_memories_project_subject_active
|
|
81
|
+
ON memories(project_id, subject_id, status, is_deleted, created_at DESC);
|
|
82
|
+
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_memories_superseded
|
|
84
|
+
ON memories(project_id, subject_id, status, created_at DESC);
|
|
85
|
+
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_memories_text_trgm
|
|
87
|
+
ON memories USING gin (to_tsvector('english', text));
|
|
88
|
+
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_memories_embedding_ivfflat
|
|
90
|
+
ON memories USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
|
91
|
+
|
|
92
|
+
DROP TRIGGER IF EXISTS trg_memories_updated_at ON memories;
|
|
93
|
+
CREATE TRIGGER trg_memories_updated_at
|
|
94
|
+
BEFORE UPDATE ON memories
|
|
95
|
+
FOR EACH ROW
|
|
96
|
+
EXECUTE FUNCTION core_set_updated_at();
|
|
97
|
+
|
|
98
|
+
-- =====================================================================
|
|
99
|
+
-- Claims
|
|
100
|
+
-- =====================================================================
|
|
101
|
+
|
|
102
|
+
CREATE TABLE IF NOT EXISTS claims (
|
|
103
|
+
claim_id TEXT PRIMARY KEY,
|
|
104
|
+
project_id TEXT NOT NULL,
|
|
105
|
+
subject_id TEXT NOT NULL,
|
|
106
|
+
predicate TEXT NOT NULL,
|
|
107
|
+
object_value TEXT NOT NULL,
|
|
108
|
+
slot TEXT NOT NULL,
|
|
109
|
+
claim_type TEXT NOT NULL DEFAULT 'fact',
|
|
110
|
+
confidence DOUBLE PRECISION NOT NULL DEFAULT 0.8 CHECK (confidence >= 0 AND confidence <= 1),
|
|
111
|
+
importance DOUBLE PRECISION NOT NULL DEFAULT 0.5 CHECK (importance >= 0 AND importance <= 1),
|
|
112
|
+
tags TEXT[] NOT NULL DEFAULT '{}',
|
|
113
|
+
source_memory_id TEXT,
|
|
114
|
+
source_observation_id TEXT,
|
|
115
|
+
subject_entity TEXT NOT NULL DEFAULT 'self',
|
|
116
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
117
|
+
asserted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
118
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
119
|
+
retracted_at TIMESTAMPTZ,
|
|
120
|
+
retract_reason TEXT,
|
|
121
|
+
embedding VECTOR(1536),
|
|
122
|
+
valid_from TIMESTAMPTZ,
|
|
123
|
+
valid_until TIMESTAMPTZ,
|
|
124
|
+
CONSTRAINT fk_claim_source_memory
|
|
125
|
+
FOREIGN KEY (source_memory_id) REFERENCES memories(id) ON DELETE SET NULL
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
DO $$
|
|
129
|
+
BEGIN
|
|
130
|
+
IF NOT EXISTS (
|
|
131
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'claims_status_check'
|
|
132
|
+
) THEN
|
|
133
|
+
ALTER TABLE claims
|
|
134
|
+
ADD CONSTRAINT claims_status_check
|
|
135
|
+
CHECK (status IN ('active', 'retracted'));
|
|
136
|
+
END IF;
|
|
137
|
+
END $$;
|
|
138
|
+
|
|
139
|
+
CREATE INDEX IF NOT EXISTS idx_claims_project_subject
|
|
140
|
+
ON claims(project_id, subject_id);
|
|
141
|
+
|
|
142
|
+
CREATE INDEX IF NOT EXISTS idx_claims_project_subject_slot
|
|
143
|
+
ON claims(project_id, subject_id, slot, asserted_at DESC);
|
|
144
|
+
|
|
145
|
+
CREATE INDEX IF NOT EXISTS idx_claims_project_subject_predicate
|
|
146
|
+
ON claims(project_id, subject_id, predicate, asserted_at DESC);
|
|
147
|
+
|
|
148
|
+
CREATE INDEX IF NOT EXISTS idx_claims_status
|
|
149
|
+
ON claims(project_id, subject_id, status);
|
|
150
|
+
|
|
151
|
+
DROP TRIGGER IF EXISTS trg_claims_updated_at ON claims;
|
|
152
|
+
CREATE TRIGGER trg_claims_updated_at
|
|
153
|
+
BEFORE UPDATE ON claims
|
|
154
|
+
FOR EACH ROW
|
|
155
|
+
EXECUTE FUNCTION core_set_updated_at();
|
|
156
|
+
|
|
157
|
+
CREATE TABLE IF NOT EXISTS claim_assertions (
|
|
158
|
+
assertion_id TEXT PRIMARY KEY,
|
|
159
|
+
project_id TEXT NOT NULL,
|
|
160
|
+
subject_id TEXT NOT NULL,
|
|
161
|
+
claim_id TEXT NOT NULL REFERENCES claims(claim_id) ON DELETE CASCADE,
|
|
162
|
+
memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
|
|
163
|
+
predicate TEXT NOT NULL,
|
|
164
|
+
object_type TEXT NOT NULL DEFAULT 'string',
|
|
165
|
+
value_string TEXT,
|
|
166
|
+
value_number DOUBLE PRECISION,
|
|
167
|
+
value_date TIMESTAMPTZ,
|
|
168
|
+
value_json JSONB,
|
|
169
|
+
confidence DOUBLE PRECISION NOT NULL DEFAULT 0.8 CHECK (confidence >= 0 AND confidence <= 1),
|
|
170
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
171
|
+
first_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
172
|
+
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
DO $$
|
|
176
|
+
BEGIN
|
|
177
|
+
IF NOT EXISTS (
|
|
178
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'claim_assertions_object_type_check'
|
|
179
|
+
) THEN
|
|
180
|
+
ALTER TABLE claim_assertions
|
|
181
|
+
ADD CONSTRAINT claim_assertions_object_type_check
|
|
182
|
+
CHECK (object_type IN ('string', 'number', 'date', 'json'));
|
|
183
|
+
END IF;
|
|
184
|
+
END $$;
|
|
185
|
+
|
|
186
|
+
CREATE INDEX IF NOT EXISTS idx_claim_assertions_memory
|
|
187
|
+
ON claim_assertions(project_id, memory_id, last_seen_at DESC);
|
|
188
|
+
|
|
189
|
+
CREATE INDEX IF NOT EXISTS idx_claim_assertions_claim
|
|
190
|
+
ON claim_assertions(project_id, claim_id);
|
|
191
|
+
|
|
192
|
+
CREATE TABLE IF NOT EXISTS claim_edges (
|
|
193
|
+
edge_id BIGSERIAL PRIMARY KEY,
|
|
194
|
+
project_id TEXT NOT NULL,
|
|
195
|
+
subject_id TEXT NOT NULL,
|
|
196
|
+
from_claim_id TEXT NOT NULL REFERENCES claims(claim_id) ON DELETE CASCADE,
|
|
197
|
+
to_claim_id TEXT NOT NULL REFERENCES claims(claim_id) ON DELETE CASCADE,
|
|
198
|
+
edge_type TEXT NOT NULL,
|
|
199
|
+
weight DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
200
|
+
reason_code TEXT,
|
|
201
|
+
reason_text TEXT,
|
|
202
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
203
|
+
UNIQUE(project_id, from_claim_id, to_claim_id, edge_type)
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
DO $$
|
|
207
|
+
BEGIN
|
|
208
|
+
IF NOT EXISTS (
|
|
209
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'claim_edges_type_check'
|
|
210
|
+
) THEN
|
|
211
|
+
ALTER TABLE claim_edges
|
|
212
|
+
ADD CONSTRAINT claim_edges_type_check
|
|
213
|
+
CHECK (edge_type IN ('supersedes', 'supports', 'duplicates', 'related', 'retracts'));
|
|
214
|
+
END IF;
|
|
215
|
+
END $$;
|
|
216
|
+
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_claim_edges_from
|
|
218
|
+
ON claim_edges(project_id, from_claim_id, created_at DESC);
|
|
219
|
+
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_claim_edges_to
|
|
221
|
+
ON claim_edges(project_id, to_claim_id, created_at DESC);
|
|
222
|
+
|
|
223
|
+
CREATE TABLE IF NOT EXISTS slot_state (
|
|
224
|
+
project_id TEXT NOT NULL,
|
|
225
|
+
subject_id TEXT NOT NULL,
|
|
226
|
+
slot TEXT NOT NULL,
|
|
227
|
+
active_claim_id TEXT REFERENCES claims(claim_id) ON DELETE SET NULL,
|
|
228
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
229
|
+
replaced_by_claim_id TEXT,
|
|
230
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
231
|
+
PRIMARY KEY(project_id, subject_id, slot)
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
DO $$
|
|
235
|
+
BEGIN
|
|
236
|
+
IF NOT EXISTS (
|
|
237
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'slot_state_status_check'
|
|
238
|
+
) THEN
|
|
239
|
+
ALTER TABLE slot_state
|
|
240
|
+
ADD CONSTRAINT slot_state_status_check
|
|
241
|
+
CHECK (status IN ('active', 'superseded', 'retracted'));
|
|
242
|
+
END IF;
|
|
243
|
+
END $$;
|
|
244
|
+
|
|
245
|
+
CREATE INDEX IF NOT EXISTS idx_slot_state_subject
|
|
246
|
+
ON slot_state(project_id, subject_id, status, updated_at DESC);
|
|
247
|
+
|
|
248
|
+
-- =====================================================================
|
|
249
|
+
-- Recall events (audit/analytics for memory use)
|
|
250
|
+
-- =====================================================================
|
|
251
|
+
|
|
252
|
+
CREATE TABLE IF NOT EXISTS memory_recall_events (
|
|
253
|
+
event_id TEXT PRIMARY KEY,
|
|
254
|
+
project_id TEXT NOT NULL,
|
|
255
|
+
subject_id TEXT NOT NULL,
|
|
256
|
+
memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
|
|
257
|
+
memory_text TEXT NOT NULL DEFAULT '',
|
|
258
|
+
chat_id TEXT NOT NULL DEFAULT '',
|
|
259
|
+
message_index INTEGER NOT NULL DEFAULT 0,
|
|
260
|
+
chat_logged BOOLEAN NOT NULL DEFAULT TRUE,
|
|
261
|
+
similarity_score DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
262
|
+
request_type TEXT NOT NULL DEFAULT 'chat',
|
|
263
|
+
model TEXT NOT NULL DEFAULT '',
|
|
264
|
+
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
265
|
+
recalled_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
CREATE INDEX IF NOT EXISTS idx_memory_recall_by_chat
|
|
269
|
+
ON memory_recall_events(project_id, chat_id, recalled_at ASC);
|
|
270
|
+
|
|
271
|
+
CREATE INDEX IF NOT EXISTS idx_memory_recall_by_memory
|
|
272
|
+
ON memory_recall_events(project_id, memory_id, recalled_at DESC);
|
|
273
|
+
|
|
274
|
+
CREATE INDEX IF NOT EXISTS idx_memory_recall_by_subject
|
|
275
|
+
ON memory_recall_events(project_id, subject_id, recalled_at DESC);
|