mem0ai 2.1.8 → 2.1.10
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/oss/index.d.mts +67 -2
- package/dist/oss/index.d.ts +67 -2
- package/dist/oss/index.js +571 -70
- package/dist/oss/index.js.map +1 -1
- package/dist/oss/index.mjs +568 -70
- package/dist/oss/index.mjs.map +1 -1
- package/package.json +17 -5
package/dist/oss/index.js
CHANGED
|
@@ -33,10 +33,13 @@ __export(index_exports, {
|
|
|
33
33
|
AnthropicLLM: () => AnthropicLLM,
|
|
34
34
|
EmbedderFactory: () => EmbedderFactory,
|
|
35
35
|
GroqLLM: () => GroqLLM,
|
|
36
|
+
HistoryManagerFactory: () => HistoryManagerFactory,
|
|
36
37
|
LLMFactory: () => LLMFactory,
|
|
37
38
|
Memory: () => Memory,
|
|
38
39
|
MemoryConfigSchema: () => MemoryConfigSchema,
|
|
39
40
|
MemoryVectorStore: () => MemoryVectorStore,
|
|
41
|
+
OllamaEmbedder: () => OllamaEmbedder,
|
|
42
|
+
OllamaLLM: () => OllamaLLM,
|
|
40
43
|
OpenAIEmbedder: () => OpenAIEmbedder,
|
|
41
44
|
OpenAILLM: () => OpenAILLM,
|
|
42
45
|
OpenAIStructuredLLM: () => OpenAIStructuredLLM,
|
|
@@ -47,7 +50,7 @@ __export(index_exports, {
|
|
|
47
50
|
module.exports = __toCommonJS(index_exports);
|
|
48
51
|
|
|
49
52
|
// src/oss/src/memory/index.ts
|
|
50
|
-
var
|
|
53
|
+
var import_uuid3 = require("uuid");
|
|
51
54
|
var import_crypto = require("crypto");
|
|
52
55
|
|
|
53
56
|
// src/oss/src/types/index.ts
|
|
@@ -90,7 +93,12 @@ var MemoryConfigSchema = import_zod.z.object({
|
|
|
90
93
|
config: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
|
|
91
94
|
}).optional(),
|
|
92
95
|
customPrompt: import_zod.z.string().optional()
|
|
93
|
-
}).optional()
|
|
96
|
+
}).optional(),
|
|
97
|
+
historyStore: import_zod.z.object({
|
|
98
|
+
provider: import_zod.z.string(),
|
|
99
|
+
config: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
|
|
100
|
+
}).optional(),
|
|
101
|
+
disableHistory: import_zod.z.boolean().optional()
|
|
94
102
|
});
|
|
95
103
|
|
|
96
104
|
// src/oss/src/embeddings/openai.ts
|
|
@@ -116,6 +124,60 @@ var OpenAIEmbedder = class {
|
|
|
116
124
|
}
|
|
117
125
|
};
|
|
118
126
|
|
|
127
|
+
// src/oss/src/embeddings/ollama.ts
|
|
128
|
+
var import_ollama = require("ollama");
|
|
129
|
+
|
|
130
|
+
// src/oss/src/utils/logger.ts
|
|
131
|
+
var logger = {
|
|
132
|
+
info: (message) => console.log(`[INFO] ${message}`),
|
|
133
|
+
error: (message) => console.error(`[ERROR] ${message}`),
|
|
134
|
+
debug: (message) => console.debug(`[DEBUG] ${message}`),
|
|
135
|
+
warn: (message) => console.warn(`[WARN] ${message}`)
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// src/oss/src/embeddings/ollama.ts
|
|
139
|
+
var OllamaEmbedder = class {
|
|
140
|
+
constructor(config) {
|
|
141
|
+
// Using this variable to avoid calling the Ollama server multiple times
|
|
142
|
+
this.initialized = false;
|
|
143
|
+
this.ollama = new import_ollama.Ollama({
|
|
144
|
+
host: config.url || "http://localhost:11434"
|
|
145
|
+
});
|
|
146
|
+
this.model = config.model || "nomic-embed-text:latest";
|
|
147
|
+
this.ensureModelExists().catch((err) => {
|
|
148
|
+
logger.error(`Error ensuring model exists: ${err}`);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async embed(text) {
|
|
152
|
+
try {
|
|
153
|
+
await this.ensureModelExists();
|
|
154
|
+
} catch (err) {
|
|
155
|
+
logger.error(`Error ensuring model exists: ${err}`);
|
|
156
|
+
}
|
|
157
|
+
const response = await this.ollama.embeddings({
|
|
158
|
+
model: this.model,
|
|
159
|
+
prompt: text
|
|
160
|
+
});
|
|
161
|
+
return response.embedding;
|
|
162
|
+
}
|
|
163
|
+
async embedBatch(texts) {
|
|
164
|
+
const response = await Promise.all(texts.map((text) => this.embed(text)));
|
|
165
|
+
return response;
|
|
166
|
+
}
|
|
167
|
+
async ensureModelExists() {
|
|
168
|
+
if (this.initialized) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
const local_models = await this.ollama.list();
|
|
172
|
+
if (!local_models.models.find((m) => m.name === this.model)) {
|
|
173
|
+
logger.info(`Pulling model ${this.model}...`);
|
|
174
|
+
await this.ollama.pull({ model: this.model });
|
|
175
|
+
}
|
|
176
|
+
this.initialized = true;
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
119
181
|
// src/oss/src/llms/openai.ts
|
|
120
182
|
var import_openai2 = __toESM(require("openai"));
|
|
121
183
|
var OpenAILLM = class {
|
|
@@ -1073,12 +1135,459 @@ var RedisDB = class {
|
|
|
1073
1135
|
}
|
|
1074
1136
|
};
|
|
1075
1137
|
|
|
1138
|
+
// src/oss/src/llms/ollama.ts
|
|
1139
|
+
var import_ollama2 = require("ollama");
|
|
1140
|
+
var OllamaLLM = class {
|
|
1141
|
+
constructor(config) {
|
|
1142
|
+
// Using this variable to avoid calling the Ollama server multiple times
|
|
1143
|
+
this.initialized = false;
|
|
1144
|
+
var _a;
|
|
1145
|
+
this.ollama = new import_ollama2.Ollama({
|
|
1146
|
+
host: ((_a = config.config) == null ? void 0 : _a.url) || "http://localhost:11434"
|
|
1147
|
+
});
|
|
1148
|
+
this.model = config.model || "llama3.1:8b";
|
|
1149
|
+
this.ensureModelExists().catch((err) => {
|
|
1150
|
+
logger.error(`Error ensuring model exists: ${err}`);
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
async generateResponse(messages, responseFormat, tools) {
|
|
1154
|
+
try {
|
|
1155
|
+
await this.ensureModelExists();
|
|
1156
|
+
} catch (err) {
|
|
1157
|
+
logger.error(`Error ensuring model exists: ${err}`);
|
|
1158
|
+
}
|
|
1159
|
+
const completion = await this.ollama.chat({
|
|
1160
|
+
model: this.model,
|
|
1161
|
+
messages: messages.map((msg) => {
|
|
1162
|
+
const role = msg.role;
|
|
1163
|
+
return {
|
|
1164
|
+
role,
|
|
1165
|
+
content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)
|
|
1166
|
+
};
|
|
1167
|
+
}),
|
|
1168
|
+
...(responseFormat == null ? void 0 : responseFormat.type) === "json_object" && { format: "json" },
|
|
1169
|
+
...tools && { tools, tool_choice: "auto" }
|
|
1170
|
+
});
|
|
1171
|
+
const response = completion.message;
|
|
1172
|
+
if (response.tool_calls) {
|
|
1173
|
+
return {
|
|
1174
|
+
content: response.content || "",
|
|
1175
|
+
role: response.role,
|
|
1176
|
+
toolCalls: response.tool_calls.map((call) => ({
|
|
1177
|
+
name: call.function.name,
|
|
1178
|
+
arguments: JSON.stringify(call.function.arguments)
|
|
1179
|
+
}))
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
return response.content || "";
|
|
1183
|
+
}
|
|
1184
|
+
async generateChat(messages) {
|
|
1185
|
+
try {
|
|
1186
|
+
await this.ensureModelExists();
|
|
1187
|
+
} catch (err) {
|
|
1188
|
+
logger.error(`Error ensuring model exists: ${err}`);
|
|
1189
|
+
}
|
|
1190
|
+
const completion = await this.ollama.chat({
|
|
1191
|
+
messages: messages.map((msg) => {
|
|
1192
|
+
const role = msg.role;
|
|
1193
|
+
return {
|
|
1194
|
+
role,
|
|
1195
|
+
content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)
|
|
1196
|
+
};
|
|
1197
|
+
}),
|
|
1198
|
+
model: this.model
|
|
1199
|
+
});
|
|
1200
|
+
const response = completion.message;
|
|
1201
|
+
return {
|
|
1202
|
+
content: response.content || "",
|
|
1203
|
+
role: response.role
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
async ensureModelExists() {
|
|
1207
|
+
if (this.initialized) {
|
|
1208
|
+
return true;
|
|
1209
|
+
}
|
|
1210
|
+
const local_models = await this.ollama.list();
|
|
1211
|
+
if (!local_models.models.find((m) => m.name === this.model)) {
|
|
1212
|
+
logger.info(`Pulling model ${this.model}...`);
|
|
1213
|
+
await this.ollama.pull({ model: this.model });
|
|
1214
|
+
}
|
|
1215
|
+
this.initialized = true;
|
|
1216
|
+
return true;
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
// src/oss/src/vector_stores/supabase.ts
|
|
1221
|
+
var import_supabase_js = require("@supabase/supabase-js");
|
|
1222
|
+
var SupabaseDB = class {
|
|
1223
|
+
constructor(config) {
|
|
1224
|
+
this.client = (0, import_supabase_js.createClient)(config.supabaseUrl, config.supabaseKey);
|
|
1225
|
+
this.tableName = config.tableName;
|
|
1226
|
+
this.embeddingColumnName = config.embeddingColumnName || "embedding";
|
|
1227
|
+
this.metadataColumnName = config.metadataColumnName || "metadata";
|
|
1228
|
+
this.initialize().catch((err) => {
|
|
1229
|
+
console.error("Failed to initialize Supabase:", err);
|
|
1230
|
+
throw err;
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
async initialize() {
|
|
1234
|
+
try {
|
|
1235
|
+
const testVector = Array(1536).fill(0);
|
|
1236
|
+
try {
|
|
1237
|
+
await this.client.from(this.tableName).delete().eq("id", "test_vector");
|
|
1238
|
+
} catch (error) {
|
|
1239
|
+
console.warn("No test vector to delete, safe to ignore.");
|
|
1240
|
+
}
|
|
1241
|
+
const { error: testError } = await this.client.from(this.tableName).insert({
|
|
1242
|
+
id: "test_vector",
|
|
1243
|
+
[this.embeddingColumnName]: testVector,
|
|
1244
|
+
[this.metadataColumnName]: {}
|
|
1245
|
+
}).select();
|
|
1246
|
+
if (testError) {
|
|
1247
|
+
console.error("Test insert error:", testError);
|
|
1248
|
+
throw new Error(
|
|
1249
|
+
`Vector operations failed. Please ensure:
|
|
1250
|
+
1. The vector extension is enabled
|
|
1251
|
+
2. The table "${this.tableName}" exists with correct schema
|
|
1252
|
+
3. The match_vectors function is created
|
|
1253
|
+
|
|
1254
|
+
RUN THE FOLLOWING SQL IN YOUR SUPABASE SQL EDITOR:
|
|
1255
|
+
|
|
1256
|
+
-- Enable the vector extension
|
|
1257
|
+
create extension if not exists vector;
|
|
1258
|
+
|
|
1259
|
+
-- Create the memories table
|
|
1260
|
+
create table if not exists memories (
|
|
1261
|
+
id text primary key,
|
|
1262
|
+
embedding vector(1536),
|
|
1263
|
+
metadata jsonb,
|
|
1264
|
+
created_at timestamp with time zone default timezone('utc', now()),
|
|
1265
|
+
updated_at timestamp with time zone default timezone('utc', now())
|
|
1266
|
+
);
|
|
1267
|
+
|
|
1268
|
+
-- Create the vector similarity search function
|
|
1269
|
+
create or replace function match_vectors(
|
|
1270
|
+
query_embedding vector(1536),
|
|
1271
|
+
match_count int,
|
|
1272
|
+
filter jsonb default '{}'::jsonb
|
|
1273
|
+
)
|
|
1274
|
+
returns table (
|
|
1275
|
+
id text,
|
|
1276
|
+
similarity float,
|
|
1277
|
+
metadata jsonb
|
|
1278
|
+
)
|
|
1279
|
+
language plpgsql
|
|
1280
|
+
as $$
|
|
1281
|
+
begin
|
|
1282
|
+
return query
|
|
1283
|
+
select
|
|
1284
|
+
id,
|
|
1285
|
+
similarity,
|
|
1286
|
+
metadata
|
|
1287
|
+
from memories
|
|
1288
|
+
where case
|
|
1289
|
+
when filter::text = '{}'::text then true
|
|
1290
|
+
else metadata @> filter
|
|
1291
|
+
end
|
|
1292
|
+
order by embedding <=> query_embedding
|
|
1293
|
+
limit match_count;
|
|
1294
|
+
end;
|
|
1295
|
+
$$;
|
|
1296
|
+
|
|
1297
|
+
See the SQL migration instructions in the code comments.`
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
await this.client.from(this.tableName).delete().eq("id", "test_vector");
|
|
1301
|
+
console.log("Connected to Supabase successfully");
|
|
1302
|
+
} catch (error) {
|
|
1303
|
+
console.error("Error during Supabase initialization:", error);
|
|
1304
|
+
throw error;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
async insert(vectors, ids, payloads) {
|
|
1308
|
+
try {
|
|
1309
|
+
const data = vectors.map((vector, idx) => ({
|
|
1310
|
+
id: ids[idx],
|
|
1311
|
+
[this.embeddingColumnName]: vector,
|
|
1312
|
+
[this.metadataColumnName]: {
|
|
1313
|
+
...payloads[idx],
|
|
1314
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1315
|
+
}
|
|
1316
|
+
}));
|
|
1317
|
+
const { error } = await this.client.from(this.tableName).insert(data);
|
|
1318
|
+
if (error) throw error;
|
|
1319
|
+
} catch (error) {
|
|
1320
|
+
console.error("Error during vector insert:", error);
|
|
1321
|
+
throw error;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
async search(query, limit = 5, filters) {
|
|
1325
|
+
try {
|
|
1326
|
+
const rpcQuery = {
|
|
1327
|
+
query_embedding: query,
|
|
1328
|
+
match_count: limit
|
|
1329
|
+
};
|
|
1330
|
+
if (filters) {
|
|
1331
|
+
rpcQuery.filter = filters;
|
|
1332
|
+
}
|
|
1333
|
+
const { data, error } = await this.client.rpc("match_vectors", rpcQuery);
|
|
1334
|
+
if (error) throw error;
|
|
1335
|
+
if (!data) return [];
|
|
1336
|
+
const results = data;
|
|
1337
|
+
return results.map((result) => ({
|
|
1338
|
+
id: result.id,
|
|
1339
|
+
payload: result.metadata,
|
|
1340
|
+
score: result.similarity
|
|
1341
|
+
}));
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
console.error("Error during vector search:", error);
|
|
1344
|
+
throw error;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
async get(vectorId) {
|
|
1348
|
+
try {
|
|
1349
|
+
const { data, error } = await this.client.from(this.tableName).select("*").eq("id", vectorId).single();
|
|
1350
|
+
if (error) throw error;
|
|
1351
|
+
if (!data) return null;
|
|
1352
|
+
return {
|
|
1353
|
+
id: data.id,
|
|
1354
|
+
payload: data[this.metadataColumnName]
|
|
1355
|
+
};
|
|
1356
|
+
} catch (error) {
|
|
1357
|
+
console.error("Error getting vector:", error);
|
|
1358
|
+
throw error;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
async update(vectorId, vector, payload) {
|
|
1362
|
+
try {
|
|
1363
|
+
const { error } = await this.client.from(this.tableName).update({
|
|
1364
|
+
[this.embeddingColumnName]: vector,
|
|
1365
|
+
[this.metadataColumnName]: {
|
|
1366
|
+
...payload,
|
|
1367
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1368
|
+
}
|
|
1369
|
+
}).eq("id", vectorId);
|
|
1370
|
+
if (error) throw error;
|
|
1371
|
+
} catch (error) {
|
|
1372
|
+
console.error("Error during vector update:", error);
|
|
1373
|
+
throw error;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
async delete(vectorId) {
|
|
1377
|
+
try {
|
|
1378
|
+
const { error } = await this.client.from(this.tableName).delete().eq("id", vectorId);
|
|
1379
|
+
if (error) throw error;
|
|
1380
|
+
} catch (error) {
|
|
1381
|
+
console.error("Error deleting vector:", error);
|
|
1382
|
+
throw error;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
async deleteCol() {
|
|
1386
|
+
try {
|
|
1387
|
+
const { error } = await this.client.from(this.tableName).delete().neq("id", "");
|
|
1388
|
+
if (error) throw error;
|
|
1389
|
+
} catch (error) {
|
|
1390
|
+
console.error("Error deleting collection:", error);
|
|
1391
|
+
throw error;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
async list(filters, limit = 100) {
|
|
1395
|
+
try {
|
|
1396
|
+
let query = this.client.from(this.tableName).select("*", { count: "exact" }).limit(limit);
|
|
1397
|
+
if (filters) {
|
|
1398
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
1399
|
+
query = query.eq(`${this.metadataColumnName}->>${key}`, value);
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
const { data, error, count } = await query;
|
|
1403
|
+
if (error) throw error;
|
|
1404
|
+
const results = data.map((item) => ({
|
|
1405
|
+
id: item.id,
|
|
1406
|
+
payload: item[this.metadataColumnName]
|
|
1407
|
+
}));
|
|
1408
|
+
return [results, count || 0];
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
console.error("Error listing vectors:", error);
|
|
1411
|
+
throw error;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
// src/oss/src/storage/SQLiteManager.ts
|
|
1417
|
+
var import_sqlite32 = __toESM(require("sqlite3"));
|
|
1418
|
+
var SQLiteManager = class {
|
|
1419
|
+
constructor(dbPath) {
|
|
1420
|
+
this.db = new import_sqlite32.default.Database(dbPath);
|
|
1421
|
+
this.init().catch(console.error);
|
|
1422
|
+
}
|
|
1423
|
+
async init() {
|
|
1424
|
+
await this.run(`
|
|
1425
|
+
CREATE TABLE IF NOT EXISTS memory_history (
|
|
1426
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1427
|
+
memory_id TEXT NOT NULL,
|
|
1428
|
+
previous_value TEXT,
|
|
1429
|
+
new_value TEXT,
|
|
1430
|
+
action TEXT NOT NULL,
|
|
1431
|
+
created_at TEXT,
|
|
1432
|
+
updated_at TEXT,
|
|
1433
|
+
is_deleted INTEGER DEFAULT 0
|
|
1434
|
+
)
|
|
1435
|
+
`);
|
|
1436
|
+
}
|
|
1437
|
+
async run(sql, params = []) {
|
|
1438
|
+
return new Promise((resolve, reject) => {
|
|
1439
|
+
this.db.run(sql, params, (err) => {
|
|
1440
|
+
if (err) reject(err);
|
|
1441
|
+
else resolve();
|
|
1442
|
+
});
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
async all(sql, params = []) {
|
|
1446
|
+
return new Promise((resolve, reject) => {
|
|
1447
|
+
this.db.all(sql, params, (err, rows) => {
|
|
1448
|
+
if (err) reject(err);
|
|
1449
|
+
else resolve(rows);
|
|
1450
|
+
});
|
|
1451
|
+
});
|
|
1452
|
+
}
|
|
1453
|
+
async addHistory(memoryId, previousValue, newValue, action, createdAt, updatedAt, isDeleted = 0) {
|
|
1454
|
+
await this.run(
|
|
1455
|
+
`INSERT INTO memory_history
|
|
1456
|
+
(memory_id, previous_value, new_value, action, created_at, updated_at, is_deleted)
|
|
1457
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1458
|
+
[
|
|
1459
|
+
memoryId,
|
|
1460
|
+
previousValue,
|
|
1461
|
+
newValue,
|
|
1462
|
+
action,
|
|
1463
|
+
createdAt,
|
|
1464
|
+
updatedAt,
|
|
1465
|
+
isDeleted
|
|
1466
|
+
]
|
|
1467
|
+
);
|
|
1468
|
+
}
|
|
1469
|
+
async getHistory(memoryId) {
|
|
1470
|
+
return this.all(
|
|
1471
|
+
"SELECT * FROM memory_history WHERE memory_id = ? ORDER BY id DESC",
|
|
1472
|
+
[memoryId]
|
|
1473
|
+
);
|
|
1474
|
+
}
|
|
1475
|
+
async reset() {
|
|
1476
|
+
await this.run("DROP TABLE IF EXISTS memory_history");
|
|
1477
|
+
await this.init();
|
|
1478
|
+
}
|
|
1479
|
+
close() {
|
|
1480
|
+
this.db.close();
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
// src/oss/src/storage/MemoryHistoryManager.ts
|
|
1485
|
+
var import_uuid = require("uuid");
|
|
1486
|
+
var MemoryHistoryManager = class {
|
|
1487
|
+
constructor() {
|
|
1488
|
+
this.memoryStore = /* @__PURE__ */ new Map();
|
|
1489
|
+
}
|
|
1490
|
+
async addHistory(memoryId, previousValue, newValue, action, createdAt, updatedAt, isDeleted = 0) {
|
|
1491
|
+
const historyEntry = {
|
|
1492
|
+
id: (0, import_uuid.v4)(),
|
|
1493
|
+
memory_id: memoryId,
|
|
1494
|
+
previous_value: previousValue,
|
|
1495
|
+
new_value: newValue,
|
|
1496
|
+
action,
|
|
1497
|
+
created_at: createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1498
|
+
updated_at: updatedAt || null,
|
|
1499
|
+
is_deleted: isDeleted
|
|
1500
|
+
};
|
|
1501
|
+
this.memoryStore.set(historyEntry.id, historyEntry);
|
|
1502
|
+
}
|
|
1503
|
+
async getHistory(memoryId) {
|
|
1504
|
+
return Array.from(this.memoryStore.values()).filter((entry) => entry.memory_id === memoryId).sort(
|
|
1505
|
+
(a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
1506
|
+
).slice(0, 100);
|
|
1507
|
+
}
|
|
1508
|
+
async reset() {
|
|
1509
|
+
this.memoryStore.clear();
|
|
1510
|
+
}
|
|
1511
|
+
close() {
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/oss/src/storage/SupabaseHistoryManager.ts
|
|
1517
|
+
var import_supabase_js2 = require("@supabase/supabase-js");
|
|
1518
|
+
var import_uuid2 = require("uuid");
|
|
1519
|
+
var SupabaseHistoryManager = class {
|
|
1520
|
+
constructor(config) {
|
|
1521
|
+
this.tableName = config.tableName || "memory_history";
|
|
1522
|
+
this.supabase = (0, import_supabase_js2.createClient)(config.supabaseUrl, config.supabaseKey);
|
|
1523
|
+
this.initializeSupabase().catch(console.error);
|
|
1524
|
+
}
|
|
1525
|
+
async initializeSupabase() {
|
|
1526
|
+
const { error } = await this.supabase.from(this.tableName).select("id").limit(1);
|
|
1527
|
+
if (error) {
|
|
1528
|
+
console.error(
|
|
1529
|
+
"Error: Table does not exist. Please run this SQL in your Supabase SQL Editor:"
|
|
1530
|
+
);
|
|
1531
|
+
console.error(`
|
|
1532
|
+
create table ${this.tableName} (
|
|
1533
|
+
id text primary key,
|
|
1534
|
+
memory_id text not null,
|
|
1535
|
+
previous_value text,
|
|
1536
|
+
new_value text,
|
|
1537
|
+
action text not null,
|
|
1538
|
+
created_at timestamp with time zone default timezone('utc', now()),
|
|
1539
|
+
updated_at timestamp with time zone,
|
|
1540
|
+
is_deleted integer default 0
|
|
1541
|
+
);
|
|
1542
|
+
`);
|
|
1543
|
+
throw error;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
async addHistory(memoryId, previousValue, newValue, action, createdAt, updatedAt, isDeleted = 0) {
|
|
1547
|
+
const historyEntry = {
|
|
1548
|
+
id: (0, import_uuid2.v4)(),
|
|
1549
|
+
memory_id: memoryId,
|
|
1550
|
+
previous_value: previousValue,
|
|
1551
|
+
new_value: newValue,
|
|
1552
|
+
action,
|
|
1553
|
+
created_at: createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1554
|
+
updated_at: updatedAt || null,
|
|
1555
|
+
is_deleted: isDeleted
|
|
1556
|
+
};
|
|
1557
|
+
const { error } = await this.supabase.from(this.tableName).insert(historyEntry);
|
|
1558
|
+
if (error) {
|
|
1559
|
+
console.error("Error adding history to Supabase:", error);
|
|
1560
|
+
throw error;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
async getHistory(memoryId) {
|
|
1564
|
+
const { data, error } = await this.supabase.from(this.tableName).select("*").eq("memory_id", memoryId).order("created_at", { ascending: false }).limit(100);
|
|
1565
|
+
if (error) {
|
|
1566
|
+
console.error("Error getting history from Supabase:", error);
|
|
1567
|
+
throw error;
|
|
1568
|
+
}
|
|
1569
|
+
return data || [];
|
|
1570
|
+
}
|
|
1571
|
+
async reset() {
|
|
1572
|
+
const { error } = await this.supabase.from(this.tableName).delete().neq("id", "");
|
|
1573
|
+
if (error) {
|
|
1574
|
+
console.error("Error resetting Supabase history:", error);
|
|
1575
|
+
throw error;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
close() {
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1076
1583
|
// src/oss/src/utils/factory.ts
|
|
1077
1584
|
var EmbedderFactory = class {
|
|
1078
1585
|
static create(provider, config) {
|
|
1079
1586
|
switch (provider.toLowerCase()) {
|
|
1080
1587
|
case "openai":
|
|
1081
1588
|
return new OpenAIEmbedder(config);
|
|
1589
|
+
case "ollama":
|
|
1590
|
+
return new OllamaEmbedder(config);
|
|
1082
1591
|
default:
|
|
1083
1592
|
throw new Error(`Unsupported embedder provider: ${provider}`);
|
|
1084
1593
|
}
|
|
@@ -1095,6 +1604,8 @@ var LLMFactory = class {
|
|
|
1095
1604
|
return new AnthropicLLM(config);
|
|
1096
1605
|
case "groq":
|
|
1097
1606
|
return new GroqLLM(config);
|
|
1607
|
+
case "ollama":
|
|
1608
|
+
return new OllamaLLM(config);
|
|
1098
1609
|
default:
|
|
1099
1610
|
throw new Error(`Unsupported LLM provider: ${provider}`);
|
|
1100
1611
|
}
|
|
@@ -1111,11 +1622,32 @@ var VectorStoreFactory = class {
|
|
|
1111
1622
|
case "redis":
|
|
1112
1623
|
return new RedisDB(config);
|
|
1113
1624
|
// Type assertion needed as config is extended
|
|
1625
|
+
case "supabase":
|
|
1626
|
+
return new SupabaseDB(config);
|
|
1627
|
+
// Type assertion needed as config is extended
|
|
1114
1628
|
default:
|
|
1115
1629
|
throw new Error(`Unsupported vector store provider: ${provider}`);
|
|
1116
1630
|
}
|
|
1117
1631
|
}
|
|
1118
1632
|
};
|
|
1633
|
+
var HistoryManagerFactory = class {
|
|
1634
|
+
static create(provider, config) {
|
|
1635
|
+
switch (provider.toLowerCase()) {
|
|
1636
|
+
case "sqlite":
|
|
1637
|
+
return new SQLiteManager(config.config.historyDbPath || ":memory:");
|
|
1638
|
+
case "supabase":
|
|
1639
|
+
return new SupabaseHistoryManager({
|
|
1640
|
+
supabaseUrl: config.config.supabaseUrl || "",
|
|
1641
|
+
supabaseKey: config.config.supabaseKey || "",
|
|
1642
|
+
tableName: config.config.tableName || "memory_history"
|
|
1643
|
+
});
|
|
1644
|
+
case "memory":
|
|
1645
|
+
return new MemoryHistoryManager();
|
|
1646
|
+
default:
|
|
1647
|
+
throw new Error(`Unsupported history store provider: ${provider}`);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
};
|
|
1119
1651
|
|
|
1120
1652
|
// src/oss/src/prompts/index.ts
|
|
1121
1653
|
function getFactRetrievalMessages(parsedMessages) {
|
|
@@ -1348,76 +1880,27 @@ function removeCodeBlocks(text) {
|
|
|
1348
1880
|
return text.replace(/```[^`]*```/g, "");
|
|
1349
1881
|
}
|
|
1350
1882
|
|
|
1351
|
-
// src/oss/src/storage/
|
|
1352
|
-
var
|
|
1353
|
-
|
|
1354
|
-
constructor(dbPath) {
|
|
1355
|
-
this.db = new import_sqlite32.default.Database(dbPath);
|
|
1356
|
-
this.init().catch(console.error);
|
|
1357
|
-
}
|
|
1358
|
-
async init() {
|
|
1359
|
-
await this.run(`
|
|
1360
|
-
CREATE TABLE IF NOT EXISTS memory_history (
|
|
1361
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1362
|
-
memory_id TEXT NOT NULL,
|
|
1363
|
-
previous_value TEXT,
|
|
1364
|
-
new_value TEXT,
|
|
1365
|
-
action TEXT NOT NULL,
|
|
1366
|
-
created_at TEXT,
|
|
1367
|
-
updated_at TEXT,
|
|
1368
|
-
is_deleted INTEGER DEFAULT 0
|
|
1369
|
-
)
|
|
1370
|
-
`);
|
|
1371
|
-
}
|
|
1372
|
-
async run(sql, params = []) {
|
|
1373
|
-
return new Promise((resolve, reject) => {
|
|
1374
|
-
this.db.run(sql, params, (err) => {
|
|
1375
|
-
if (err) reject(err);
|
|
1376
|
-
else resolve();
|
|
1377
|
-
});
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
async all(sql, params = []) {
|
|
1381
|
-
return new Promise((resolve, reject) => {
|
|
1382
|
-
this.db.all(sql, params, (err, rows) => {
|
|
1383
|
-
if (err) reject(err);
|
|
1384
|
-
else resolve(rows);
|
|
1385
|
-
});
|
|
1386
|
-
});
|
|
1883
|
+
// src/oss/src/storage/DummyHistoryManager.ts
|
|
1884
|
+
var DummyHistoryManager = class {
|
|
1885
|
+
constructor() {
|
|
1387
1886
|
}
|
|
1388
1887
|
async addHistory(memoryId, previousValue, newValue, action, createdAt, updatedAt, isDeleted = 0) {
|
|
1389
|
-
|
|
1390
|
-
`INSERT INTO memory_history
|
|
1391
|
-
(memory_id, previous_value, new_value, action, created_at, updated_at, is_deleted)
|
|
1392
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
1393
|
-
[
|
|
1394
|
-
memoryId,
|
|
1395
|
-
previousValue,
|
|
1396
|
-
newValue,
|
|
1397
|
-
action,
|
|
1398
|
-
createdAt,
|
|
1399
|
-
updatedAt,
|
|
1400
|
-
isDeleted
|
|
1401
|
-
]
|
|
1402
|
-
);
|
|
1888
|
+
return;
|
|
1403
1889
|
}
|
|
1404
1890
|
async getHistory(memoryId) {
|
|
1405
|
-
return
|
|
1406
|
-
"SELECT * FROM memory_history WHERE memory_id = ? ORDER BY id DESC",
|
|
1407
|
-
[memoryId]
|
|
1408
|
-
);
|
|
1891
|
+
return [];
|
|
1409
1892
|
}
|
|
1410
1893
|
async reset() {
|
|
1411
|
-
|
|
1412
|
-
await this.init();
|
|
1894
|
+
return;
|
|
1413
1895
|
}
|
|
1414
1896
|
close() {
|
|
1415
|
-
|
|
1897
|
+
return;
|
|
1416
1898
|
}
|
|
1417
1899
|
};
|
|
1418
1900
|
|
|
1419
1901
|
// src/oss/src/config/defaults.ts
|
|
1420
1902
|
var DEFAULT_MEMORY_CONFIG = {
|
|
1903
|
+
disableHistory: false,
|
|
1421
1904
|
version: "v1.1",
|
|
1422
1905
|
embedder: {
|
|
1423
1906
|
provider: "openai",
|
|
@@ -1455,7 +1938,12 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
1455
1938
|
}
|
|
1456
1939
|
}
|
|
1457
1940
|
},
|
|
1458
|
-
|
|
1941
|
+
historyStore: {
|
|
1942
|
+
provider: "sqlite",
|
|
1943
|
+
config: {
|
|
1944
|
+
historyDbPath: "memory.db"
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1459
1947
|
};
|
|
1460
1948
|
|
|
1461
1949
|
// src/oss/src/config/manager.ts
|
|
@@ -1492,6 +1980,11 @@ var ConfigManager = class {
|
|
|
1492
1980
|
...DEFAULT_MEMORY_CONFIG.graphStore,
|
|
1493
1981
|
...userConfig.graphStore
|
|
1494
1982
|
},
|
|
1983
|
+
historyStore: {
|
|
1984
|
+
...DEFAULT_MEMORY_CONFIG.historyStore,
|
|
1985
|
+
...userConfig.historyStore
|
|
1986
|
+
},
|
|
1987
|
+
disableHistory: userConfig.disableHistory || DEFAULT_MEMORY_CONFIG.disableHistory,
|
|
1495
1988
|
enableGraph: userConfig.enableGraph || DEFAULT_MEMORY_CONFIG.enableGraph
|
|
1496
1989
|
};
|
|
1497
1990
|
return MemoryConfigSchema.parse(mergedConfig);
|
|
@@ -1707,14 +2200,6 @@ function getDeleteMessages(existingMemoriesString, data, userId) {
|
|
|
1707
2200
|
];
|
|
1708
2201
|
}
|
|
1709
2202
|
|
|
1710
|
-
// src/oss/src/utils/logger.ts
|
|
1711
|
-
var logger = {
|
|
1712
|
-
info: (message) => console.log(`[INFO] ${message}`),
|
|
1713
|
-
error: (message) => console.error(`[ERROR] ${message}`),
|
|
1714
|
-
debug: (message) => console.debug(`[DEBUG] ${message}`),
|
|
1715
|
-
warn: (message) => console.warn(`[WARN] ${message}`)
|
|
1716
|
-
};
|
|
1717
|
-
|
|
1718
2203
|
// src/oss/src/memory/graph_memory.ts
|
|
1719
2204
|
var MemoryGraph = class {
|
|
1720
2205
|
constructor(config) {
|
|
@@ -2278,7 +2763,20 @@ var Memory = class _Memory {
|
|
|
2278
2763
|
this.config.llm.provider,
|
|
2279
2764
|
this.config.llm.config
|
|
2280
2765
|
);
|
|
2281
|
-
|
|
2766
|
+
if (this.config.disableHistory) {
|
|
2767
|
+
this.db = new DummyHistoryManager();
|
|
2768
|
+
} else {
|
|
2769
|
+
const defaultConfig = {
|
|
2770
|
+
provider: "sqlite",
|
|
2771
|
+
config: {
|
|
2772
|
+
historyDbPath: this.config.historyDbPath || ":memory:"
|
|
2773
|
+
}
|
|
2774
|
+
};
|
|
2775
|
+
this.db = this.config.historyStore && !this.config.disableHistory ? HistoryManagerFactory.create(
|
|
2776
|
+
this.config.historyStore.provider,
|
|
2777
|
+
this.config.historyStore
|
|
2778
|
+
) : HistoryManagerFactory.create("sqlite", defaultConfig);
|
|
2779
|
+
}
|
|
2282
2780
|
this.collectionName = this.config.vectorStore.config.collectionName;
|
|
2283
2781
|
this.apiVersion = this.config.version || "v1.0";
|
|
2284
2782
|
this.enableGraph = this.config.enableGraph || false;
|
|
@@ -2581,7 +3079,7 @@ ${parsedMessages}`] : getFactRetrievalMessages(parsedMessages);
|
|
|
2581
3079
|
return { results };
|
|
2582
3080
|
}
|
|
2583
3081
|
async createMemory(data, existingEmbeddings, metadata) {
|
|
2584
|
-
const memoryId = (0,
|
|
3082
|
+
const memoryId = (0, import_uuid3.v4)();
|
|
2585
3083
|
const embedding = existingEmbeddings[data] || await this.embedder.embed(data);
|
|
2586
3084
|
const memoryMetadata = {
|
|
2587
3085
|
...metadata,
|
|
@@ -2657,10 +3155,13 @@ ${parsedMessages}`] : getFactRetrievalMessages(parsedMessages);
|
|
|
2657
3155
|
AnthropicLLM,
|
|
2658
3156
|
EmbedderFactory,
|
|
2659
3157
|
GroqLLM,
|
|
3158
|
+
HistoryManagerFactory,
|
|
2660
3159
|
LLMFactory,
|
|
2661
3160
|
Memory,
|
|
2662
3161
|
MemoryConfigSchema,
|
|
2663
3162
|
MemoryVectorStore,
|
|
3163
|
+
OllamaEmbedder,
|
|
3164
|
+
OllamaLLM,
|
|
2664
3165
|
OpenAIEmbedder,
|
|
2665
3166
|
OpenAILLM,
|
|
2666
3167
|
OpenAIStructuredLLM,
|