engram-sdk 0.1.1 → 0.1.2

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/hosted.js CHANGED
@@ -1,144 +1,321 @@
1
1
  #!/usr/bin/env node
2
+ import { createServer } from 'node:http';
3
+ import { mkdirSync } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { Vault } from './vault.js';
6
+ import { GeminiEmbeddings } from './embeddings.js';
7
+ import { AccountStore, PLAN_LIMITS } from './accounts.js';
2
8
  // ============================================================
3
- // Engram Hosted API — Multi-tenant server
9
+ // Engram Hosted — Multi-Tenant API Server
4
10
  // ============================================================
5
- //
6
- // Wraps createEngramServer with:
7
- // - Dynamic API key provisioning (POST /v1/keys)
8
- // - Per-user SQLite vaults on a persistent volume
9
- // - Admin endpoints for key management
10
- //
11
- // ENV:
12
- // ENGRAM_DATA_DIR — vault storage dir (default: /data)
13
- // ENGRAM_ADMIN_KEY — admin key for provisioning
14
- // ENGRAM_HOST — bind address (default: 0.0.0.0)
15
- // ENGRAM_PORT — port (default: 3800)
16
- // ENGRAM_LLM_PROVIDER gemini|openai (shared across tenants)
17
- // ENGRAM_LLM_API_KEY — LLM key (or GEMINI_API_KEY)
18
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
19
- import { join } from 'node:path';
20
- import { randomUUID } from 'node:crypto';
21
- import { createEngramServer } from './server.js';
22
- const DATA_DIR = process.env.ENGRAM_DATA_DIR ?? '/data';
23
- const ADMIN_KEY = process.env.ENGRAM_ADMIN_KEY ?? '';
24
- const PORT = parseInt(process.env.PORT ?? process.env.ENGRAM_PORT ?? '3800', 10);
25
- const HOST = process.env.ENGRAM_HOST ?? '0.0.0.0';
26
- const LLM_PROVIDER = process.env.ENGRAM_LLM_PROVIDER;
27
- const LLM_API_KEY = process.env.ENGRAM_LLM_API_KEY ?? process.env.GEMINI_API_KEY;
28
- const LLM_MODEL = process.env.ENGRAM_LLM_MODEL;
29
- const EMBEDDING_MODEL = process.env.ENGRAM_EMBEDDING_MODEL;
30
- const KEYS_PATH = join(DATA_DIR, 'keys.json');
31
- function loadKeys() {
32
- if (!existsSync(KEYS_PATH))
33
- return {};
34
- try {
35
- return JSON.parse(readFileSync(KEYS_PATH, 'utf-8'));
36
- }
37
- catch {
38
- return {};
11
+ const PORT = parseInt(process.env.PORT ?? '3800', 10);
12
+ const HOST = process.env.HOST ?? '0.0.0.0';
13
+ const GEMINI_API_KEY = process.env.GEMINI_API_KEY ?? '';
14
+ const ADMIN_KEY = process.env.ADMIN_KEY ?? '';
15
+ const VAULTS_DIR = process.env.VAULTS_DIR ?? './vaults';
16
+ const ACCOUNTS_DB = process.env.ACCOUNTS_DB ?? './accounts.db';
17
+ const vaultCache = new Map();
18
+ const EVICT_MS = 30 * 60 * 1000;
19
+ function getVault(accountId) {
20
+ const cached = vaultCache.get(accountId);
21
+ if (cached) {
22
+ cached.lastAccess = Date.now();
23
+ return cached.vault;
39
24
  }
25
+ const dbPath = path.join(VAULTS_DIR, `${accountId}.db`);
26
+ const embedder = GEMINI_API_KEY ? new GeminiEmbeddings(GEMINI_API_KEY) : undefined;
27
+ const vault = new Vault({ owner: accountId, dbPath }, embedder);
28
+ vaultCache.set(accountId, { vault, lastAccess: Date.now() });
29
+ return vault;
40
30
  }
41
- function saveKeys(keys) {
42
- mkdirSync(DATA_DIR, { recursive: true });
43
- writeFileSync(KEYS_PATH, JSON.stringify(keys, null, 2));
44
- }
31
+ // Evict idle vaults every 5 minutes
32
+ setInterval(async () => {
33
+ const now = Date.now();
34
+ for (const [id, cached] of vaultCache) {
35
+ if (now - cached.lastAccess > EVICT_MS) {
36
+ vaultCache.delete(id);
37
+ await cached.vault.close().catch(() => { });
38
+ }
39
+ }
40
+ }, 5 * 60 * 1000);
45
41
  // ============================================================
46
- // Build vault configs from stored keys
42
+ // Helpers
47
43
  // ============================================================
48
- function keyToVaultConfig(record) {
49
- const dbPath = join(DATA_DIR, 'vaults', `${record.owner}.db`);
50
- mkdirSync(join(DATA_DIR, 'vaults'), { recursive: true });
51
- return {
52
- owner: record.owner,
53
- dbPath,
54
- agentId: 'hosted',
55
- ...(LLM_PROVIDER && LLM_API_KEY ? {
56
- llm: {
57
- provider: LLM_PROVIDER,
58
- apiKey: LLM_API_KEY,
59
- model: LLM_MODEL,
60
- embeddingModel: EMBEDDING_MODEL,
61
- }
62
- } : {}),
63
- };
44
+ async function readBody(req) {
45
+ const chunks = [];
46
+ for await (const chunk of req) {
47
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
48
+ }
49
+ return Buffer.concat(chunks).toString('utf-8');
50
+ }
51
+ function json(res, status, data) {
52
+ res.writeHead(status, { 'Content-Type': 'application/json' });
53
+ res.end(JSON.stringify(data));
54
+ }
55
+ function errorResponse(res, status, message) {
56
+ json(res, status, { error: message });
57
+ }
58
+ function rateLimitResponse(res, type, limit, used, resetAt) {
59
+ res.writeHead(429, { 'Content-Type': 'application/json' });
60
+ res.end(JSON.stringify({
61
+ error: 'rate_limit_exceeded',
62
+ message: `Monthly ${type} limit reached (${used}/${limit})`,
63
+ limit,
64
+ used,
65
+ resetAt,
66
+ upgradeUrl: 'https://engram.fyi/pricing',
67
+ }));
68
+ }
69
+ const routes = [];
70
+ function route(method, pathStr, handler) {
71
+ const paramNames = [];
72
+ const re = pathStr.replace(/:(\w+)/g, (_, n) => { paramNames.push(n); return '([^/]+)'; });
73
+ routes.push({ method, pattern: new RegExp(`^${re}$`), paramNames, handler, auth: 'user' });
74
+ }
75
+ function publicRoute(method, pathStr, handler) {
76
+ const paramNames = [];
77
+ const re = pathStr.replace(/:(\w+)/g, (_, n) => { paramNames.push(n); return '([^/]+)'; });
78
+ routes.push({ method, pattern: new RegExp(`^${re}$`), paramNames, handler, auth: 'none' });
64
79
  }
65
- // Load existing keys and build the vaults map
66
- const keys = loadKeys();
67
- const vaults = {};
68
- for (const [apiKey, record] of Object.entries(keys)) {
69
- vaults[apiKey] = keyToVaultConfig(record);
80
+ function adminRoute(method, pathStr, handler) {
81
+ const paramNames = [];
82
+ const re = pathStr.replace(/:(\w+)/g, (_, n) => { paramNames.push(n); return '([^/]+)'; });
83
+ routes.push({ method, pattern: new RegExp(`^${re}$`), paramNames, handler: null, auth: 'admin', adminHandler: handler });
70
84
  }
71
85
  // ============================================================
72
- // Provision endpoint — injected before the core server starts
86
+ // User Routes
73
87
  // ============================================================
74
- // We'll intercept /v1/keys before delegating to the core server
75
- // by wrapping the HTTP server's request handler
76
- const coreSrv = createEngramServer({
77
- port: PORT,
78
- host: HOST,
79
- vaults,
88
+ route('POST', '/v1/memories', async (req, res, { account, vault }) => {
89
+ const check = accountStore.checkLimit(account, 'memory');
90
+ if (!check.allowed)
91
+ return rateLimitResponse(res, 'memory', check.limit, check.used, check.resetAt);
92
+ const body = JSON.parse(await readBody(req));
93
+ const memory = vault.remember(body);
94
+ accountStore.trackUsage(account.id, 'memory');
95
+ json(res, 201, memory);
80
96
  });
81
- // Monkey-patch the underlying http server to intercept admin routes
82
- const origHandler = coreSrv.server.listeners('request')[0];
83
- coreSrv.server.removeAllListeners('request');
84
- coreSrv.server.on('request', async (req, res) => {
97
+ route('GET', '/v1/memories/recall', async (req, res, { account, vault }) => {
98
+ const check = accountStore.checkLimit(account, 'recall');
99
+ if (!check.allowed)
100
+ return rateLimitResponse(res, 'recall', check.limit, check.used, check.resetAt);
85
101
  const url = new URL(req.url, `http://${req.headers.host}`);
86
- // Key provisioning
87
- if (url.pathname === '/v1/keys' && req.method === 'POST') {
88
- const auth = req.headers.authorization;
89
- if (!ADMIN_KEY || auth !== `Bearer ${ADMIN_KEY}`) {
90
- res.writeHead(401, { 'Content-Type': 'application/json' });
91
- res.end(JSON.stringify({ error: 'Unauthorized' }));
92
- return;
93
- }
94
- const chunks = [];
95
- for await (const chunk of req)
96
- chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
97
- const body = JSON.parse(Buffer.concat(chunks).toString('utf-8'));
98
- const owner = body.owner;
99
- const email = body.email;
100
- if (!owner) {
101
- res.writeHead(400, { 'Content-Type': 'application/json' });
102
- res.end(JSON.stringify({ error: 'owner is required' }));
103
- return;
104
- }
105
- const apiKey = `engram_${randomUUID().replace(/-/g, '')}`;
106
- const record = { apiKey, owner, email, createdAt: new Date().toISOString() };
107
- // Register in both the keys store and the live vaults map
108
- keys[apiKey] = record;
109
- vaults[apiKey] = keyToVaultConfig(record);
110
- saveKeys(keys);
111
- res.writeHead(201, { 'Content-Type': 'application/json' });
112
- res.end(JSON.stringify({ apiKey, owner, message: 'Use Authorization: Bearer ' + apiKey }));
113
- return;
102
+ const context = url.searchParams.get('context');
103
+ if (!context)
104
+ return errorResponse(res, 400, 'context query parameter is required');
105
+ const input = { context };
106
+ for (const [k, parse] of [['entities', (v) => v.split(',')], ['topics', (v) => v.split(',')], ['types', (v) => v.split(',')], ['limit', (v) => parseInt(v, 10)]]) {
107
+ const v = url.searchParams.get(k);
108
+ if (v)
109
+ input[k] = parse(v);
114
110
  }
115
- // List keys (admin)
116
- if (url.pathname === '/v1/keys' && req.method === 'GET') {
117
- const auth = req.headers.authorization;
118
- if (!ADMIN_KEY || auth !== `Bearer ${ADMIN_KEY}`) {
119
- res.writeHead(401, { 'Content-Type': 'application/json' });
120
- res.end(JSON.stringify({ error: 'Unauthorized' }));
121
- return;
122
- }
123
- const sanitized = Object.values(keys).map(k => ({
124
- owner: k.owner, email: k.email, createdAt: k.createdAt,
125
- apiKey: k.apiKey.slice(0, 12) + '...',
126
- }));
127
- res.writeHead(200, { 'Content-Type': 'application/json' });
128
- res.end(JSON.stringify({ keys: sanitized, count: sanitized.length }));
129
- return;
111
+ const memories = await vault.recall(input);
112
+ accountStore.trackUsage(account.id, 'recall');
113
+ json(res, 200, { memories, count: memories.length });
114
+ });
115
+ route('POST', '/v1/memories/recall', async (req, res, { account, vault }) => {
116
+ const check = accountStore.checkLimit(account, 'recall');
117
+ if (!check.allowed)
118
+ return rateLimitResponse(res, 'recall', check.limit, check.used, check.resetAt);
119
+ const body = JSON.parse(await readBody(req));
120
+ const memories = await vault.recall(body);
121
+ accountStore.trackUsage(account.id, 'recall');
122
+ json(res, 200, { memories, count: memories.length });
123
+ });
124
+ route('DELETE', '/v1/memories/:id', (req, res, { account, vault, params }) => {
125
+ const url = new URL(req.url, `http://${req.headers.host}`);
126
+ const hard = url.searchParams.get('hard') === 'true';
127
+ vault.forget(params.id, hard);
128
+ accountStore.decrementMemories(account.id);
129
+ json(res, 200, { deleted: params.id, hard });
130
+ });
131
+ route('GET', '/v1/memories/:id/neighbors', (req, res, { vault, params }) => {
132
+ const url = new URL(req.url, `http://${req.headers.host}`);
133
+ const depth = parseInt(url.searchParams.get('depth') ?? '1', 10);
134
+ const memories = vault.neighbors(params.id, depth);
135
+ json(res, 200, { memories, count: memories.length });
136
+ });
137
+ route('POST', '/v1/consolidate', async (req, res, { account, vault }) => {
138
+ const check = accountStore.checkLimit(account, 'consolidation');
139
+ if (!check.allowed)
140
+ return rateLimitResponse(res, 'consolidation', check.limit, check.used, check.resetAt);
141
+ const report = await vault.consolidate();
142
+ accountStore.trackUsage(account.id, 'consolidation');
143
+ json(res, 200, report);
144
+ });
145
+ route('GET', '/v1/stats', (req, res, { vault }) => {
146
+ json(res, 200, vault.stats());
147
+ });
148
+ route('GET', '/v1/entities', (req, res, { vault }) => {
149
+ const entities = vault.entities();
150
+ json(res, 200, { entities, count: entities.length });
151
+ });
152
+ route('GET', '/v1/account', (req, res, { account }) => {
153
+ const limits = PLAN_LIMITS[account.plan];
154
+ json(res, 200, {
155
+ id: account.id,
156
+ email: account.email,
157
+ plan: account.plan,
158
+ createdAt: account.createdAt,
159
+ usage: {
160
+ memoriesStored: account.memoriesStored,
161
+ recallsThisMonth: account.recallsThisMonth,
162
+ consolidationsThisMonth: account.consolidationsThisMonth,
163
+ usageResetAt: account.usageResetAt,
164
+ },
165
+ limits,
166
+ });
167
+ });
168
+ publicRoute('GET', '/health', (req, res) => {
169
+ json(res, 200, { status: 'ok', version: '0.1.0', timestamp: new Date().toISOString() });
170
+ });
171
+ // ============================================================
172
+ // Admin Routes
173
+ // ============================================================
174
+ adminRoute('POST', '/admin/accounts', async (req, res) => {
175
+ const body = JSON.parse(await readBody(req));
176
+ if (!body.email)
177
+ return errorResponse(res, 400, 'email is required');
178
+ const plan = body.plan ?? 'free';
179
+ if (!['free', 'growth', 'pro', 'enterprise'].includes(plan))
180
+ return errorResponse(res, 400, 'invalid plan');
181
+ try {
182
+ const account = accountStore.createAccount(body.email, plan);
183
+ json(res, 201, account);
184
+ }
185
+ catch (e) {
186
+ if (e.message?.includes('UNIQUE'))
187
+ return errorResponse(res, 409, 'account with this email already exists');
188
+ throw e;
130
189
  }
131
- // Everything else → core server
132
- origHandler(req, res);
133
190
  });
134
- // Start
135
- coreSrv.listen().then(() => {
136
- console.log(` Mode: hosted (multi-tenant)`);
137
- console.log(` Data: ${DATA_DIR}`);
138
- console.log(` Tenants: ${Object.keys(keys).length}`);
139
- if (!ADMIN_KEY)
140
- console.warn(' ⚠️ No ENGRAM_ADMIN_KEY — key provisioning disabled');
191
+ adminRoute('GET', '/admin/accounts', (req, res) => {
192
+ json(res, 200, accountStore.listAccounts());
141
193
  });
142
- process.on('SIGINT', () => { saveKeys(keys); process.exit(0); });
143
- process.on('SIGTERM', () => { saveKeys(keys); process.exit(0); });
194
+ adminRoute('GET', '/admin/accounts/:id', (req, res, params) => {
195
+ const account = accountStore.getAccountById(params.id);
196
+ if (!account)
197
+ return errorResponse(res, 404, 'account not found');
198
+ json(res, 200, account);
199
+ });
200
+ // ============================================================
201
+ // Server
202
+ // ============================================================
203
+ let accountStore;
204
+ function startServer() {
205
+ mkdirSync(VAULTS_DIR, { recursive: true });
206
+ accountStore = new AccountStore(ACCOUNTS_DB);
207
+ if (!ADMIN_KEY) {
208
+ console.error('ERROR: ADMIN_KEY environment variable is required');
209
+ process.exit(1);
210
+ }
211
+ const server = createServer(async (req, res) => {
212
+ const start = Date.now();
213
+ let status = 200;
214
+ // CORS
215
+ res.setHeader('Access-Control-Allow-Origin', '*');
216
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
217
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
218
+ if (req.method === 'OPTIONS') {
219
+ res.writeHead(204);
220
+ res.end();
221
+ return;
222
+ }
223
+ const url = new URL(req.url, `http://${req.headers.host}`);
224
+ const pathname = url.pathname;
225
+ try {
226
+ for (const r of routes) {
227
+ if (req.method !== r.method)
228
+ continue;
229
+ const match = pathname.match(r.pattern);
230
+ if (!match)
231
+ continue;
232
+ const params = {};
233
+ r.paramNames.forEach((n, i) => { params[n] = match[i + 1]; });
234
+ if (r.auth === 'none') {
235
+ await r.handler(req, res, { account: null, vault: null, params });
236
+ status = res.statusCode;
237
+ log(req, pathname, status, start);
238
+ return;
239
+ }
240
+ if (r.auth === 'admin') {
241
+ const authHeader = req.headers.authorization;
242
+ if (!authHeader?.startsWith('Bearer ') || authHeader.slice(7) !== ADMIN_KEY) {
243
+ status = 401;
244
+ errorResponse(res, 401, 'Invalid or missing admin key');
245
+ log(req, pathname, status, start);
246
+ return;
247
+ }
248
+ await r.adminHandler(req, res, params);
249
+ status = res.statusCode;
250
+ log(req, pathname, status, start);
251
+ return;
252
+ }
253
+ // User auth
254
+ const authHeader = req.headers.authorization;
255
+ if (!authHeader?.startsWith('Bearer ')) {
256
+ status = 401;
257
+ json(res, 401, { error: 'unauthorized', message: 'Missing Authorization header. Use: Authorization: Bearer eng_live_xxxxx' });
258
+ log(req, pathname, status, start);
259
+ return;
260
+ }
261
+ const apiKey = authHeader.slice(7);
262
+ const account = accountStore.getAccountByKey(apiKey);
263
+ if (!account) {
264
+ status = 401;
265
+ json(res, 401, { error: 'unauthorized', message: 'Invalid API key' });
266
+ log(req, pathname, status, start);
267
+ return;
268
+ }
269
+ const vault = getVault(account.id);
270
+ await r.handler(req, res, { account, vault, params });
271
+ status = res.statusCode;
272
+ log(req, pathname, status, start);
273
+ return;
274
+ }
275
+ status = 404;
276
+ errorResponse(res, 404, `Not found: ${req.method} ${pathname}`);
277
+ log(req, pathname, status, start);
278
+ }
279
+ catch (err) {
280
+ status = 500;
281
+ console.error(`Error handling ${req.method} ${pathname}:`, err);
282
+ errorResponse(res, 500, err.message ?? 'Internal server error');
283
+ log(req, pathname, status, start);
284
+ }
285
+ });
286
+ server.listen(PORT, HOST, () => {
287
+ console.log(`🧠 Engram Hosted API`);
288
+ console.log(`✓ Accounts database ready`);
289
+ if (GEMINI_API_KEY)
290
+ console.log(`✓ Gemini embeddings configured`);
291
+ else
292
+ console.log(`⚠ No GEMINI_API_KEY — semantic search disabled`);
293
+ console.log(`✓ Listening on http://${HOST}:${PORT}`);
294
+ console.log();
295
+ console.log(`Admin key: ${ADMIN_KEY.slice(0, 12)}...`);
296
+ console.log(`Create accounts: POST /admin/accounts -d '{"email":"user@co.com","plan":"growth"}'`);
297
+ });
298
+ // Graceful shutdown
299
+ const shutdown = async () => {
300
+ console.log('\nShutting down...');
301
+ const closes = [...vaultCache.values()].map(c => c.vault.close().catch(() => { }));
302
+ await Promise.allSettled(closes);
303
+ vaultCache.clear();
304
+ accountStore.close();
305
+ server.close(() => process.exit(0));
306
+ };
307
+ process.on('SIGINT', shutdown);
308
+ process.on('SIGTERM', shutdown);
309
+ }
310
+ function log(req, path, status, start) {
311
+ const ms = Date.now() - start;
312
+ console.log(`${new Date().toISOString()} ${req.method} ${path} ${status} ${ms}ms`);
313
+ }
314
+ // ============================================================
315
+ // CLI Entry Point
316
+ // ============================================================
317
+ if (process.argv[1]?.endsWith('hosted.ts') || process.argv[1]?.endsWith('hosted.js')) {
318
+ startServer();
319
+ }
320
+ export { startServer };
144
321
  //# sourceMappingURL=hosted.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted.js","sourceRoot":"","sources":["../src/hosted.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hosted.js","sourceRoot":"","sources":["../src/hosted.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * temporal.ts — Temporal Intelligence for Engram
3
+ *
4
+ * Handles fact supersession detection and recency-aware scoring.
5
+ * This module addresses the core weakness exposed by Letta's
6
+ * core-memory-update benchmark: when facts change over time,
7
+ * Engram needs to know which version is current.
8
+ *
9
+ * Three strategies (implement in order):
10
+ *
11
+ * 1. Contradiction detection at write time
12
+ * When a new memory is stored, check if it contradicts an
13
+ * existing memory about the same entity+topic. If so, mark
14
+ * the old one as `superseded` and link them with an edge.
15
+ *
16
+ * 2. Recency boost in recall scoring
17
+ * Add a time-decay multiplier so newer memories score higher
18
+ * when content similarity is close. Small effect, but helps
19
+ * break ties in favor of recent information.
20
+ *
21
+ * 3. Temporal spreading activation
22
+ * Weight graph edges by recency — when an entity activates
23
+ * connected memories, more recent connections fire stronger.
24
+ *
25
+ * Target: improve Letta core-memory-update from 41.9% → 65%+
26
+ *
27
+ * @module temporal
28
+ */
29
+ import type { Memory } from './types.js';
30
+ export interface ContradictionResult {
31
+ /** The new memory that triggered the check */
32
+ newMemoryId: string;
33
+ /** The old memory that was superseded */
34
+ oldMemoryId: string;
35
+ /** Shared entities between the two memories */
36
+ sharedEntities: string[];
37
+ /** Shared topics */
38
+ sharedTopics: string[];
39
+ /** Confidence that this is a genuine contradiction (0-1) */
40
+ confidence: number;
41
+ /** Brief explanation of what changed */
42
+ explanation: string;
43
+ }
44
+ export interface RecencyBoostConfig {
45
+ /** Whether recency boost is enabled (default: true) */
46
+ enabled: boolean;
47
+ /** Max boost factor for brand-new memories (default: 0.15) */
48
+ maxBoost: number;
49
+ /** Half-life in days — after this many days, boost is halved (default: 7) */
50
+ halfLifeDays: number;
51
+ }
52
+ export interface TemporalConfig {
53
+ /** Enable contradiction detection at write time */
54
+ detectContradictions: boolean;
55
+ /** Enable recency boost in recall scoring */
56
+ recencyBoost: RecencyBoostConfig;
57
+ /** Minimum entity overlap to consider contradiction (default: 1) */
58
+ minEntityOverlap: number;
59
+ /** Minimum similarity for contradiction candidate (default: 0.75) */
60
+ contradictionSimilarityThreshold: number;
61
+ }
62
+ export declare const DEFAULT_TEMPORAL_CONFIG: TemporalConfig;
63
+ /**
64
+ * Check if two memories contradict each other.
65
+ *
66
+ * Heuristic approach (no LLM call):
67
+ * - Must share at least one entity
68
+ * - Must share at least one topic OR have high semantic similarity
69
+ * - Content must differ meaningfully (not just rephrasing)
70
+ *
71
+ * For higher accuracy, pass to LLM for verification.
72
+ */
73
+ export declare function findContradictionCandidates(newMemory: Memory, existingMemories: Memory[], config?: TemporalConfig): Memory[];
74
+ /**
75
+ * Use LLM to verify if two memories genuinely contradict each other.
76
+ *
77
+ * Returns null if no contradiction, or a ContradictionResult if confirmed.
78
+ *
79
+ * TODO: Implement with Gemini call
80
+ */
81
+ export declare function verifyContradiction(newMemory: Memory, oldMemory: Memory, llmCall: (prompt: string) => Promise<string>): Promise<ContradictionResult | null>;
82
+ /**
83
+ * Calculate a recency boost for a memory based on its age.
84
+ *
85
+ * Uses exponential decay: boost = maxBoost * 2^(-age/halfLife)
86
+ *
87
+ * Examples (with defaults: maxBoost=0.15, halfLife=7 days):
88
+ * - Created today: +0.15
89
+ * - Created 7 days ago: +0.075
90
+ * - Created 14 days ago: +0.0375
91
+ * - Created 30 days ago: +0.009 (negligible)
92
+ *
93
+ * This is additive to the recall score, not multiplicative.
94
+ * It's small enough to not override strong semantic matches,
95
+ * but large enough to break ties between competing facts.
96
+ */
97
+ export declare function calculateRecencyBoost(memory: Memory, config?: RecencyBoostConfig, now?: Date): number;
98
+ /**
99
+ * Weight a graph edge by recency of the connected memory.
100
+ *
101
+ * When spreading activation traverses the memory graph,
102
+ * edges to more recent memories carry more activation energy.
103
+ *
104
+ * This naturally surfaces the latest version of a fact when
105
+ * multiple memories about the same entity exist.
106
+ *
107
+ * TODO: Integrate with vault.ts spreading activation
108
+ */
109
+ export declare function temporalEdgeWeight(baseWeight: number, targetMemory: Memory, halfLifeDays?: number, now?: Date): number;
110
+ //# sourceMappingURL=temporal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../src/temporal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIzC,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,oBAAoB;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,6CAA6C;IAC7C,YAAY,EAAE,kBAAkB,CAAC;IACjC,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,gCAAgC,EAAE,MAAM,CAAC;CAC1C;AAED,eAAO,MAAM,uBAAuB,EAAE,cASrC,CAAC;AAIF;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EAAE,EAC1B,MAAM,GAAE,cAAwC,GAC/C,MAAM,EAAE,CA4BV;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAC3C,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA8CrC;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,kBAAyD,EACjE,GAAG,GAAE,IAAiB,GACrB,MAAM,CAWR;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,YAAY,GAAE,MAAW,EACzB,GAAG,GAAE,IAAiB,GACrB,MAAM,CAMR"}