@clude/sdk 3.2.0 → 3.3.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/dist/cli/index.js +2107 -414
- package/dist/mcp/local-store.d.ts +74 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +1941 -253
- package/dist/sdk/cortex-v2.d.ts +120 -0
- package/dist/sdk/cortex.d.ts +63 -0
- package/dist/sdk/http-transport.d.ts +14 -0
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +2005 -378
- package/dist/sdk/memory-types.d.ts +321 -0
- package/dist/sdk/sdk-mode.d.ts +1 -0
- package/dist/sdk/shared-constants.d.ts +53 -0
- package/dist/sdk/types.d.ts +47 -0
- package/package.json +16 -23
- package/supabase-schema.sql +169 -12
package/supabase-schema.sql
CHANGED
|
@@ -89,14 +89,47 @@ CREATE TABLE IF NOT EXISTS memories (
|
|
|
89
89
|
compacted_into TEXT, -- hash_id of the memory this was compacted into
|
|
90
90
|
encrypted BOOLEAN DEFAULT FALSE, -- whether content is client-side encrypted
|
|
91
91
|
encryption_pubkey TEXT, -- Solana pubkey that encrypted this memory
|
|
92
|
+
provider_delegated BOOLEAN DEFAULT TRUE, -- envelope: provider may read while delegated; revoke flips to FALSE (encryption §7)
|
|
93
|
+
summary_ciphertext TEXT, -- secretbox(summary) — populated on revoke (§9)
|
|
94
|
+
embedding_ciphertext TEXT, -- secretbox(embedding) — populated on revoke (§9)
|
|
92
95
|
owner_wallet TEXT, -- Solana pubkey of the memory owner
|
|
93
96
|
event_date TIMESTAMPTZ DEFAULT NULL, -- explicit event date extracted from content (temporal indexing)
|
|
94
97
|
event_date_precision TEXT DEFAULT NULL CHECK (event_date_precision IN ('day', 'week', 'month', 'year')),
|
|
95
98
|
ts_summary tsvector GENERATED ALWAYS AS (
|
|
96
|
-
setweight(to_tsvector('english', COALESCE(summary, '')), 'A')
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
setweight(to_tsvector('english', COALESCE(summary, '')), 'A')
|
|
100
|
+
) STORED, -- summary-only lexemes; content lexemes live in content_tokens (encryption §9)
|
|
101
|
+
content_tokens tsvector, -- content lexemes, app-maintained via set_memory_content_tokens; cleared on revoke
|
|
102
|
+
-- Memory 3.0 Phase 1 (migration 044): bi-temporal validity + provenance (all nullable, inert until MEMORY_RECONCILE)
|
|
103
|
+
valid_from TIMESTAMPTZ, -- fact lifetime start (defaults to created_at at reconcile time)
|
|
104
|
+
invalid_at TIMESTAMPTZ, -- NULL = currently valid; set = superseded/retired (never DELETE)
|
|
105
|
+
superseded_by TEXT, -- hash_id of the memory that replaced this one
|
|
106
|
+
fact_key TEXT, -- (entity, attribute) reconciliation key
|
|
107
|
+
extractor_version TEXT, -- provenance: which extractor produced this
|
|
108
|
+
extraction_confidence REAL, -- 0..1 extractor confidence
|
|
109
|
+
source_turn_ref JSONB, -- pointer back to the source conversation turn
|
|
110
|
+
hash_id_v2 TEXT -- 16-byte server-minted id (dual identity; legacy hash_id untouched)
|
|
99
111
|
);
|
|
112
|
+
-- Phase 1 hot-path indexes: recall filters to currently-valid rows; reconciliation groups by fact_key.
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_memories_valid ON memories(id) WHERE invalid_at IS NULL;
|
|
114
|
+
CREATE INDEX IF NOT EXISTS idx_memories_fact_key ON memories(fact_key) WHERE fact_key IS NOT NULL;
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_memories_hash_id_v2 ON memories(hash_id_v2) WHERE hash_id_v2 IS NOT NULL;
|
|
116
|
+
|
|
117
|
+
-- Memory 3.0 Phase 1 (migration 044): the C2 durable write outbox — replaces the
|
|
118
|
+
-- fire-and-forget embed/link/extract triad (errors were silently swallowed).
|
|
119
|
+
CREATE TABLE IF NOT EXISTS memory_write_jobs (
|
|
120
|
+
id BIGSERIAL PRIMARY KEY,
|
|
121
|
+
memory_id BIGINT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
|
|
122
|
+
job_type TEXT NOT NULL CHECK (job_type IN ('embed', 'link', 'extract', 'reconcile', 'backfill_v2')),
|
|
123
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running', 'done', 'failed')),
|
|
124
|
+
attempts INT NOT NULL DEFAULT 0,
|
|
125
|
+
next_retry_at TIMESTAMPTZ DEFAULT NOW(),
|
|
126
|
+
last_error TEXT,
|
|
127
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
128
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
129
|
+
);
|
|
130
|
+
CREATE INDEX IF NOT EXISTS idx_write_jobs_claim ON memory_write_jobs(status, next_retry_at)
|
|
131
|
+
WHERE status IN ('pending', 'failed');
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_write_jobs_memory ON memory_write_jobs(memory_id);
|
|
100
133
|
|
|
101
134
|
-- Memory fragments: granular vector decomposition for precision retrieval
|
|
102
135
|
-- Each memory is split into semantic fragments (summary, content chunks, tag context)
|
|
@@ -110,6 +143,37 @@ CREATE TABLE IF NOT EXISTS memory_fragments (
|
|
|
110
143
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
111
144
|
);
|
|
112
145
|
|
|
146
|
+
-- ============================================================
|
|
147
|
+
-- ENCRYPTION (PMP memory encryption-at-rest — see migration 021,
|
|
148
|
+
-- docs/pmp/memory-encryption-design.md §9). Owner-held envelope encryption.
|
|
149
|
+
-- ============================================================
|
|
150
|
+
|
|
151
|
+
-- Owner public-key registry. No private keys, ever.
|
|
152
|
+
CREATE TABLE IF NOT EXISTS encryption_keys (
|
|
153
|
+
owner_wallet TEXT PRIMARY KEY,
|
|
154
|
+
x25519_pubkey TEXT NOT NULL,
|
|
155
|
+
verifier_ct TEXT NOT NULL, -- secretbox("clude-key-verifier-v1") under derived key (H2)
|
|
156
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
157
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
-- Per-memory wrapped DEKs. Wrap = sealed box; wrap_pubkey is the ephemeral sender pubkey.
|
|
161
|
+
CREATE TABLE IF NOT EXISTS memory_dek_wraps (
|
|
162
|
+
memory_id BIGINT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
|
|
163
|
+
recipient TEXT NOT NULL, -- 'owner' | 'provider' | 'title_holder'
|
|
164
|
+
wrapped_dek TEXT NOT NULL, -- base64(nonce || box(DEK))
|
|
165
|
+
wrap_pubkey TEXT NOT NULL, -- base64 ephemeral sender X25519 pubkey
|
|
166
|
+
holder_wallet TEXT, -- (034) names the title_holder; NULL for owner/provider
|
|
167
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
168
|
+
CONSTRAINT memory_dek_wraps_recipient_chk CHECK (recipient IN ('owner', 'provider', 'title_holder')),
|
|
169
|
+
CONSTRAINT memory_dek_wraps_holder_chk CHECK ((recipient = 'title_holder') = (holder_wallet IS NOT NULL))
|
|
170
|
+
);
|
|
171
|
+
-- (036) holder-aware uniqueness: one owner + one provider per memory (NULLS NOT DISTINCT), and one
|
|
172
|
+
-- title_holder per (memory, holder) so a title sale's seller + buyer wraps coexist (RT7 additive).
|
|
173
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uq_dek_wraps_identity
|
|
174
|
+
ON memory_dek_wraps (memory_id, recipient, holder_wallet) NULLS NOT DISTINCT;
|
|
175
|
+
CREATE INDEX IF NOT EXISTS idx_dek_wraps_memory ON memory_dek_wraps(memory_id);
|
|
176
|
+
|
|
113
177
|
-- Dream logs: consolidation, reflection, emergence sessions
|
|
114
178
|
CREATE TABLE IF NOT EXISTS dream_logs (
|
|
115
179
|
id BIGSERIAL PRIMARY KEY,
|
|
@@ -133,6 +197,8 @@ CREATE INDEX IF NOT EXISTS idx_memories_evidence ON memories USING GIN(evidence_
|
|
|
133
197
|
CREATE INDEX IF NOT EXISTS idx_memories_owner ON memories(owner_wallet);
|
|
134
198
|
CREATE INDEX IF NOT EXISTS idx_memories_event_date ON memories(event_date) WHERE event_date IS NOT NULL;
|
|
135
199
|
CREATE INDEX IF NOT EXISTS idx_memories_ts_summary ON memories USING GIN (ts_summary);
|
|
200
|
+
CREATE INDEX IF NOT EXISTS idx_memories_content_tokens ON memories USING GIN (content_tokens);
|
|
201
|
+
CREATE INDEX IF NOT EXISTS idx_memories_delegated ON memories(provider_delegated) WHERE encrypted = TRUE;
|
|
136
202
|
|
|
137
203
|
-- Vector similarity indexes (HNSW for fast approximate nearest neighbor)
|
|
138
204
|
CREATE INDEX IF NOT EXISTS idx_memories_embedding ON memories USING hnsw (embedding vector_cosine_ops);
|
|
@@ -168,7 +234,11 @@ BEGIN
|
|
|
168
234
|
AND m.decay_factor >= min_decay
|
|
169
235
|
AND (filter_types IS NULL OR m.memory_type = ANY(filter_types))
|
|
170
236
|
AND (filter_user IS NULL OR m.related_user = filter_user)
|
|
171
|
-
AND (
|
|
237
|
+
AND (
|
|
238
|
+
filter_owner IS NULL
|
|
239
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
240
|
+
OR m.owner_wallet = filter_owner
|
|
241
|
+
)
|
|
172
242
|
AND (filter_tags IS NULL OR m.tags && filter_tags)
|
|
173
243
|
AND (1 - (m.embedding <=> query_embedding)) > match_threshold
|
|
174
244
|
ORDER BY m.embedding <=> query_embedding
|
|
@@ -201,7 +271,11 @@ BEGIN
|
|
|
201
271
|
AND m.decay_factor >= min_decay
|
|
202
272
|
AND (filter_types IS NULL OR m.memory_type = ANY(filter_types))
|
|
203
273
|
AND (filter_user IS NULL OR m.related_user = filter_user)
|
|
204
|
-
AND (
|
|
274
|
+
AND (
|
|
275
|
+
filter_owner IS NULL
|
|
276
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
277
|
+
OR m.owner_wallet = filter_owner
|
|
278
|
+
)
|
|
205
279
|
AND (filter_tags IS NULL OR m.tags && filter_tags)
|
|
206
280
|
AND (1 - (m.embedding <=> query_embedding)) > match_threshold
|
|
207
281
|
AND (start_date IS NULL OR COALESCE(m.event_date, m.created_at) >= start_date)
|
|
@@ -213,6 +287,66 @@ $$;
|
|
|
213
287
|
|
|
214
288
|
-- BM25-ranked full-text search using tsvector/tsquery (Exp 8)
|
|
215
289
|
-- Replaces ilike-based keyword search with stemming and TF-IDF ranking.
|
|
290
|
+
-- Populate content_tokens from a transient plaintext arg (PostgREST can't express to_tsvector inline).
|
|
291
|
+
-- setweight 'B' mirrors the old combined ts_summary weighting (summary 'A' > content 'B').
|
|
292
|
+
CREATE OR REPLACE FUNCTION set_memory_content_tokens(p_memory_id bigint, p_text text)
|
|
293
|
+
RETURNS void LANGUAGE sql AS $$
|
|
294
|
+
UPDATE memories
|
|
295
|
+
SET content_tokens = CASE
|
|
296
|
+
WHEN p_text IS NULL OR p_text = '' THEN NULL
|
|
297
|
+
ELSE setweight(to_tsvector('english', p_text), 'B')
|
|
298
|
+
END
|
|
299
|
+
WHERE id = p_memory_id;
|
|
300
|
+
$$;
|
|
301
|
+
|
|
302
|
+
-- Atomic revoke: clear plaintext + drop the provider wrap in one transaction (encryption §7).
|
|
303
|
+
CREATE OR REPLACE FUNCTION revoke_memory(p_memory_id bigint, p_summary_ct text, p_embedding_ct text)
|
|
304
|
+
RETURNS void LANGUAGE plpgsql AS $$
|
|
305
|
+
BEGIN
|
|
306
|
+
UPDATE memories SET
|
|
307
|
+
summary = '',
|
|
308
|
+
summary_ciphertext = p_summary_ct,
|
|
309
|
+
embedding = NULL,
|
|
310
|
+
embedding_ciphertext = NULLIF(p_embedding_ct, ''),
|
|
311
|
+
content_tokens = NULL,
|
|
312
|
+
provider_delegated = false
|
|
313
|
+
WHERE id = p_memory_id;
|
|
314
|
+
DELETE FROM memory_dek_wraps WHERE memory_id = p_memory_id AND recipient = 'provider';
|
|
315
|
+
-- Fragment parity (migration 043): fragments hold plaintext + live embeddings,
|
|
316
|
+
-- which kept revoked memories findable through the fragment lane.
|
|
317
|
+
DELETE FROM memory_fragments WHERE memory_id = p_memory_id;
|
|
318
|
+
END;
|
|
319
|
+
$$;
|
|
320
|
+
|
|
321
|
+
-- Atomic re-delegate (encryption §7) — inverse of revoke_memory. Restores plaintext
|
|
322
|
+
-- summary/embedding, rebuilds content_tokens via the canonical builder, clears ciphertext
|
|
323
|
+
-- cols, sets provider_delegated=true, (re-)inserts the provider wrap. Caller passes decrypted
|
|
324
|
+
-- plaintext (it holds the validated DEK); plaintext is transient, not stored beyond columns.
|
|
325
|
+
CREATE OR REPLACE FUNCTION redelegate_memory(
|
|
326
|
+
p_memory_id bigint,
|
|
327
|
+
p_summary text,
|
|
328
|
+
p_embedding text,
|
|
329
|
+
p_content text,
|
|
330
|
+
p_wrapped_dek text,
|
|
331
|
+
p_wrap_pubkey text
|
|
332
|
+
)
|
|
333
|
+
RETURNS void LANGUAGE plpgsql AS $$
|
|
334
|
+
BEGIN
|
|
335
|
+
UPDATE memories SET
|
|
336
|
+
summary = p_summary,
|
|
337
|
+
summary_ciphertext = NULL,
|
|
338
|
+
embedding = NULLIF(p_embedding, '')::vector,
|
|
339
|
+
embedding_ciphertext = NULL,
|
|
340
|
+
provider_delegated = true
|
|
341
|
+
WHERE id = p_memory_id;
|
|
342
|
+
PERFORM set_memory_content_tokens(p_memory_id, p_content);
|
|
343
|
+
INSERT INTO memory_dek_wraps (memory_id, recipient, wrapped_dek, wrap_pubkey)
|
|
344
|
+
VALUES (p_memory_id, 'provider', p_wrapped_dek, p_wrap_pubkey)
|
|
345
|
+
ON CONFLICT (memory_id, recipient) DO UPDATE
|
|
346
|
+
SET wrapped_dek = EXCLUDED.wrapped_dek, wrap_pubkey = EXCLUDED.wrap_pubkey;
|
|
347
|
+
END;
|
|
348
|
+
$$;
|
|
349
|
+
|
|
216
350
|
CREATE OR REPLACE FUNCTION bm25_search_memories(
|
|
217
351
|
search_query text,
|
|
218
352
|
match_count int DEFAULT 20,
|
|
@@ -231,11 +365,17 @@ BEGIN
|
|
|
231
365
|
RETURN;
|
|
232
366
|
END IF;
|
|
233
367
|
RETURN QUERY
|
|
234
|
-
SELECT m.id,
|
|
368
|
+
SELECT m.id,
|
|
369
|
+
(ts_rank_cd(COALESCE(m.ts_summary, ''::tsvector), tsquery_val, 32)
|
|
370
|
+
+ ts_rank_cd(COALESCE(m.content_tokens, ''::tsvector), tsquery_val, 32))::float AS rank
|
|
235
371
|
FROM memories m
|
|
236
|
-
WHERE m.ts_summary @@ tsquery_val
|
|
372
|
+
WHERE (m.ts_summary @@ tsquery_val OR m.content_tokens @@ tsquery_val)
|
|
237
373
|
AND m.decay_factor >= min_decay
|
|
238
|
-
AND (
|
|
374
|
+
AND (
|
|
375
|
+
filter_owner IS NULL
|
|
376
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
377
|
+
OR m.owner_wallet = filter_owner
|
|
378
|
+
)
|
|
239
379
|
AND (filter_types IS NULL OR m.memory_type = ANY(filter_types))
|
|
240
380
|
AND (filter_tags IS NULL OR m.tags && filter_tags)
|
|
241
381
|
ORDER BY rank DESC
|
|
@@ -262,6 +402,7 @@ CREATE TABLE IF NOT EXISTS memory_links (
|
|
|
262
402
|
'follows', -- temporal sequence
|
|
263
403
|
'relates', -- general semantic association
|
|
264
404
|
'resolves', -- contradiction resolution outcome
|
|
405
|
+
'supersedes', -- decisive replacement: new fact overrides an older one (Memory 3.0 C1, migration 044)
|
|
265
406
|
'happens_before', -- temporal ordering
|
|
266
407
|
'happens_after', -- temporal ordering
|
|
267
408
|
'concurrent_with' -- temporal co-occurrence
|
|
@@ -300,7 +441,11 @@ LANGUAGE sql AS $$
|
|
|
300
441
|
WHERE ml.source_id = ANY(seed_ids)
|
|
301
442
|
AND ml.target_id != ALL(seed_ids)
|
|
302
443
|
AND ml.strength >= min_strength
|
|
303
|
-
AND (
|
|
444
|
+
AND (
|
|
445
|
+
filter_owner IS NULL
|
|
446
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
447
|
+
OR m.owner_wallet = filter_owner
|
|
448
|
+
)
|
|
304
449
|
UNION
|
|
305
450
|
SELECT DISTINCT ON (ml.source_id, ml.link_type)
|
|
306
451
|
ml.source_id AS memory_id,
|
|
@@ -312,7 +457,11 @@ LANGUAGE sql AS $$
|
|
|
312
457
|
WHERE ml.target_id = ANY(seed_ids)
|
|
313
458
|
AND ml.source_id != ALL(seed_ids)
|
|
314
459
|
AND ml.strength >= min_strength
|
|
315
|
-
AND (
|
|
460
|
+
AND (
|
|
461
|
+
filter_owner IS NULL
|
|
462
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
463
|
+
OR m.owner_wallet = filter_owner
|
|
464
|
+
)
|
|
316
465
|
ORDER BY strength DESC
|
|
317
466
|
LIMIT max_results;
|
|
318
467
|
$$;
|
|
@@ -411,7 +560,9 @@ CREATE OR REPLACE FUNCTION match_memory_fragments(
|
|
|
411
560
|
query_embedding vector(1024),
|
|
412
561
|
match_threshold float DEFAULT 0.3,
|
|
413
562
|
match_count int DEFAULT 10,
|
|
414
|
-
filter_owner text DEFAULT NULL
|
|
563
|
+
filter_owner text DEFAULT NULL,
|
|
564
|
+
min_decay float DEFAULT 0.0,
|
|
565
|
+
filter_types text[] DEFAULT NULL
|
|
415
566
|
)
|
|
416
567
|
RETURNS TABLE (memory_id bigint, max_similarity float)
|
|
417
568
|
LANGUAGE plpgsql AS $$
|
|
@@ -422,7 +573,13 @@ BEGIN
|
|
|
422
573
|
JOIN memories m ON m.id = f.memory_id
|
|
423
574
|
WHERE f.embedding IS NOT NULL
|
|
424
575
|
AND (1 - (f.embedding <=> query_embedding)) > match_threshold
|
|
425
|
-
AND
|
|
576
|
+
AND m.decay_factor >= min_decay
|
|
577
|
+
AND (filter_types IS NULL OR m.memory_type = ANY(filter_types))
|
|
578
|
+
AND (
|
|
579
|
+
filter_owner IS NULL
|
|
580
|
+
OR (filter_owner = '__BOT_OWN__' AND m.owner_wallet IS NULL)
|
|
581
|
+
OR m.owner_wallet = filter_owner
|
|
582
|
+
)
|
|
426
583
|
GROUP BY f.memory_id
|
|
427
584
|
ORDER BY max_similarity DESC
|
|
428
585
|
LIMIT match_count;
|