mem0ai 3.0.9 → 3.0.12
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/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +21 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -6
- package/dist/index.mjs.map +1 -1
- package/dist/oss/index.d.mts +20 -5
- package/dist/oss/index.d.ts +20 -5
- package/dist/oss/index.js +397 -131
- package/dist/oss/index.js.map +1 -1
- package/dist/oss/index.mjs +392 -127
- package/dist/oss/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/oss/index.mjs
CHANGED
|
@@ -339,7 +339,11 @@ var AnthropicLLM = class {
|
|
|
339
339
|
if (!apiKey) {
|
|
340
340
|
throw new Error("Anthropic API key is required");
|
|
341
341
|
}
|
|
342
|
-
|
|
342
|
+
const clientArgs = { apiKey };
|
|
343
|
+
if (config.baseURL) {
|
|
344
|
+
clientArgs.baseURL = config.baseURL;
|
|
345
|
+
}
|
|
346
|
+
this.client = new Anthropic(clientArgs);
|
|
343
347
|
this.model = config.model || "claude-sonnet-4-6";
|
|
344
348
|
this.maxTokens = (_a2 = config.maxTokens) != null ? _a2 : 2e3;
|
|
345
349
|
this.temperature = (_b2 = config.temperature) != null ? _b2 : 0.1;
|
|
@@ -1832,13 +1836,15 @@ var RedisDB = class {
|
|
|
1832
1836
|
}
|
|
1833
1837
|
async insert(vectors, ids, payloads) {
|
|
1834
1838
|
const data = vectors.map((vector, idx) => {
|
|
1839
|
+
var _a2, _b2;
|
|
1835
1840
|
const payload = toSnakeCase(payloads[idx]);
|
|
1836
1841
|
const id = ids[idx];
|
|
1842
|
+
const createdAt = payload.created_at ? new Date(payload.created_at).getTime() : 0;
|
|
1837
1843
|
const entry = {
|
|
1838
1844
|
memory_id: id,
|
|
1839
|
-
hash: payload.hash,
|
|
1840
|
-
memory: payload.data,
|
|
1841
|
-
created_at:
|
|
1845
|
+
hash: (_a2 = payload.hash) != null ? _a2 : "",
|
|
1846
|
+
memory: (_b2 = payload.data) != null ? _b2 : "",
|
|
1847
|
+
created_at: createdAt,
|
|
1842
1848
|
embedding: new Float32Array(vector).buffer
|
|
1843
1849
|
};
|
|
1844
1850
|
["agent_id", "run_id", "user_id"].forEach((field) => {
|
|
@@ -2017,13 +2023,16 @@ var RedisDB = class {
|
|
|
2017
2023
|
}
|
|
2018
2024
|
}
|
|
2019
2025
|
async update(vectorId, vector, payload) {
|
|
2026
|
+
var _a2, _b2;
|
|
2020
2027
|
const snakePayload = toSnakeCase(payload);
|
|
2028
|
+
const createdAt = snakePayload.created_at ? new Date(snakePayload.created_at).getTime() : 0;
|
|
2029
|
+
const updatedAt = snakePayload.updated_at ? new Date(snakePayload.updated_at).getTime() : 0;
|
|
2021
2030
|
const entry = {
|
|
2022
2031
|
memory_id: vectorId,
|
|
2023
|
-
hash: snakePayload.hash,
|
|
2024
|
-
memory: snakePayload.data,
|
|
2025
|
-
created_at:
|
|
2026
|
-
updated_at:
|
|
2032
|
+
hash: (_a2 = snakePayload.hash) != null ? _a2 : "",
|
|
2033
|
+
memory: (_b2 = snakePayload.data) != null ? _b2 : "",
|
|
2034
|
+
created_at: createdAt,
|
|
2035
|
+
updated_at: updatedAt,
|
|
2027
2036
|
embedding: Buffer.from(new Float32Array(vector).buffer)
|
|
2028
2037
|
};
|
|
2029
2038
|
["agent_id", "run_id", "user_id"].forEach((field) => {
|
|
@@ -2269,6 +2278,66 @@ var DeepSeekLLM = class extends OpenAILLM {
|
|
|
2269
2278
|
}
|
|
2270
2279
|
};
|
|
2271
2280
|
|
|
2281
|
+
// src/oss/src/llms/litellm.ts
|
|
2282
|
+
var LiteLLM = class extends OpenAILLM {
|
|
2283
|
+
constructor(config) {
|
|
2284
|
+
super({
|
|
2285
|
+
...config,
|
|
2286
|
+
apiKey: config.apiKey || process.env.LITELLM_API_KEY || "sk-anything",
|
|
2287
|
+
baseURL: config.baseURL || process.env.LITELLM_API_BASE || "http://localhost:4000",
|
|
2288
|
+
model: config.model || "gpt-5-mini"
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
async generateResponse(messages, responseFormat, tools) {
|
|
2292
|
+
try {
|
|
2293
|
+
return await super.generateResponse(messages, responseFormat, tools);
|
|
2294
|
+
} catch (err) {
|
|
2295
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2296
|
+
throw new Error(`LiteLLM failed: ${message}`);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
async generateChat(messages) {
|
|
2300
|
+
try {
|
|
2301
|
+
return await super.generateChat(messages);
|
|
2302
|
+
} catch (err) {
|
|
2303
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2304
|
+
throw new Error(`LiteLLM failed: ${message}`);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
|
|
2309
|
+
// src/oss/src/llms/minimax.ts
|
|
2310
|
+
var MiniMaxLLM = class extends OpenAILLM {
|
|
2311
|
+
constructor(config) {
|
|
2312
|
+
const apiKey = config.apiKey || process.env.MINIMAX_API_KEY;
|
|
2313
|
+
if (!apiKey) {
|
|
2314
|
+
throw new Error("MiniMax API key is required");
|
|
2315
|
+
}
|
|
2316
|
+
super({
|
|
2317
|
+
...config,
|
|
2318
|
+
apiKey,
|
|
2319
|
+
baseURL: config.baseURL || process.env.MINIMAX_API_BASE || "https://api.minimax.io/v1",
|
|
2320
|
+
model: config.model || "MiniMax-M2.7"
|
|
2321
|
+
});
|
|
2322
|
+
}
|
|
2323
|
+
async generateResponse(messages, responseFormat, tools) {
|
|
2324
|
+
try {
|
|
2325
|
+
return await super.generateResponse(messages, responseFormat, tools);
|
|
2326
|
+
} catch (err) {
|
|
2327
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2328
|
+
throw new Error(`MiniMax LLM failed: ${message}`);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
async generateChat(messages) {
|
|
2332
|
+
try {
|
|
2333
|
+
return await super.generateChat(messages);
|
|
2334
|
+
} catch (err) {
|
|
2335
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2336
|
+
throw new Error(`MiniMax LLM failed: ${message}`);
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
};
|
|
2340
|
+
|
|
2272
2341
|
// src/oss/src/vector_stores/supabase.ts
|
|
2273
2342
|
import { createClient as createClient2 } from "@supabase/supabase-js";
|
|
2274
2343
|
var SupabaseDB = class {
|
|
@@ -4550,24 +4619,59 @@ function buildFilterConditions(filters, startIndex) {
|
|
|
4550
4619
|
}
|
|
4551
4620
|
return { conditions, values, paramIndex };
|
|
4552
4621
|
}
|
|
4622
|
+
function getConnectionString(config) {
|
|
4623
|
+
var _a2;
|
|
4624
|
+
return ((_a2 = config.connectionString) == null ? void 0 : _a2.trim()) || void 0;
|
|
4625
|
+
}
|
|
4626
|
+
function validateConnectionConfig(config) {
|
|
4627
|
+
if (getConnectionString(config)) {
|
|
4628
|
+
return;
|
|
4629
|
+
}
|
|
4630
|
+
const missingFields = ["user", "password", "host", "port"].filter((field) => {
|
|
4631
|
+
const v = config[field];
|
|
4632
|
+
return v === void 0 || v === null || v === "";
|
|
4633
|
+
});
|
|
4634
|
+
if (missingFields.length > 0) {
|
|
4635
|
+
throw new Error(
|
|
4636
|
+
`PGVector requires either connectionString or ${missingFields.join(", ")}`
|
|
4637
|
+
);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
function buildClientConfig(config, database) {
|
|
4641
|
+
const connectionString = getConnectionString(config);
|
|
4642
|
+
if (connectionString) {
|
|
4643
|
+
return {
|
|
4644
|
+
connectionString,
|
|
4645
|
+
...config.ssl !== void 0 ? { ssl: config.ssl } : {}
|
|
4646
|
+
};
|
|
4647
|
+
}
|
|
4648
|
+
return {
|
|
4649
|
+
database,
|
|
4650
|
+
user: config.user,
|
|
4651
|
+
password: config.password,
|
|
4652
|
+
host: config.host,
|
|
4653
|
+
port: config.port,
|
|
4654
|
+
...config.ssl !== void 0 ? { ssl: config.ssl } : {}
|
|
4655
|
+
};
|
|
4656
|
+
}
|
|
4553
4657
|
var PGVector = class {
|
|
4554
4658
|
constructor(config) {
|
|
4659
|
+
validateConnectionConfig(config);
|
|
4555
4660
|
this.collectionName = validateIdentifier(
|
|
4556
4661
|
config.collectionName || "memories",
|
|
4557
4662
|
"collectionName"
|
|
4558
4663
|
);
|
|
4559
4664
|
this.useDiskann = config.diskann || false;
|
|
4560
4665
|
this.useHnsw = config.hnsw || false;
|
|
4561
|
-
this.
|
|
4666
|
+
this.useDirectConnection = !!getConnectionString(config);
|
|
4667
|
+
this.dbName = this.useDirectConnection ? "" : validateIdentifier(config.dbname || "vector_store", "dbname");
|
|
4562
4668
|
this.config = config;
|
|
4563
|
-
this.client = new Client(
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
port: config.port
|
|
4570
|
-
});
|
|
4669
|
+
this.client = new Client(
|
|
4670
|
+
buildClientConfig(
|
|
4671
|
+
config,
|
|
4672
|
+
this.useDirectConnection ? void 0 : "postgres"
|
|
4673
|
+
)
|
|
4674
|
+
);
|
|
4571
4675
|
this.initialize().catch(console.error);
|
|
4572
4676
|
}
|
|
4573
4677
|
col() {
|
|
@@ -4582,19 +4686,15 @@ var PGVector = class {
|
|
|
4582
4686
|
async _doInitialize() {
|
|
4583
4687
|
try {
|
|
4584
4688
|
await this.client.connect();
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
host: this.config.host,
|
|
4595
|
-
port: this.config.port
|
|
4596
|
-
});
|
|
4597
|
-
await this.client.connect();
|
|
4689
|
+
if (!this.useDirectConnection) {
|
|
4690
|
+
const dbExists = await this.checkDatabaseExists(this.dbName);
|
|
4691
|
+
if (!dbExists) {
|
|
4692
|
+
await this.createDatabase(this.dbName);
|
|
4693
|
+
}
|
|
4694
|
+
await this.client.end();
|
|
4695
|
+
this.client = new Client(buildClientConfig(this.config, this.dbName));
|
|
4696
|
+
await this.client.connect();
|
|
4697
|
+
}
|
|
4598
4698
|
await this.client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
4599
4699
|
await this.client.query(`
|
|
4600
4700
|
CREATE TABLE IF NOT EXISTS memory_migrations (
|
|
@@ -4865,6 +4965,10 @@ var LLMFactory = class {
|
|
|
4865
4965
|
return new LangchainLLM(config);
|
|
4866
4966
|
case "deepseek":
|
|
4867
4967
|
return new DeepSeekLLM(config);
|
|
4968
|
+
case "litellm":
|
|
4969
|
+
return new LiteLLM(config);
|
|
4970
|
+
case "minimax":
|
|
4971
|
+
return new MiniMaxLLM(config);
|
|
4868
4972
|
default:
|
|
4869
4973
|
throw new Error(`Unsupported LLM provider: ${provider}`);
|
|
4870
4974
|
}
|
|
@@ -5094,6 +5198,7 @@ var get_image_description = async (image_url) => {
|
|
|
5094
5198
|
return response;
|
|
5095
5199
|
};
|
|
5096
5200
|
var parse_vision_messages = async (messages) => {
|
|
5201
|
+
var _a2;
|
|
5097
5202
|
const parsed_messages = [];
|
|
5098
5203
|
for (const message of messages) {
|
|
5099
5204
|
let new_message = {
|
|
@@ -5102,9 +5207,11 @@ var parse_vision_messages = async (messages) => {
|
|
|
5102
5207
|
};
|
|
5103
5208
|
if (message.role !== "system") {
|
|
5104
5209
|
if (typeof message.content === "object" && message.content.type === "image_url") {
|
|
5105
|
-
const
|
|
5106
|
-
|
|
5107
|
-
|
|
5210
|
+
const imageUrl = (_a2 = message.content.image_url) == null ? void 0 : _a2.url;
|
|
5211
|
+
if (!imageUrl) {
|
|
5212
|
+
throw new Error("image_url content part is missing image_url.url");
|
|
5213
|
+
}
|
|
5214
|
+
const description = await get_image_description(imageUrl);
|
|
5108
5215
|
new_message.content = typeof description === "string" ? description : JSON.stringify(description);
|
|
5109
5216
|
parsed_messages.push(new_message);
|
|
5110
5217
|
} else parsed_messages.push(message);
|
|
@@ -5114,7 +5221,7 @@ var parse_vision_messages = async (messages) => {
|
|
|
5114
5221
|
};
|
|
5115
5222
|
|
|
5116
5223
|
// src/oss/src/utils/telemetry.ts
|
|
5117
|
-
var version = true ? "3.0.
|
|
5224
|
+
var version = true ? "3.0.12" : "dev";
|
|
5118
5225
|
var MEM0_TELEMETRY = true;
|
|
5119
5226
|
var _a, _b;
|
|
5120
5227
|
try {
|
|
@@ -6647,7 +6754,24 @@ var NON_SPECIFIC_ADJ = /* @__PURE__ */ new Set([
|
|
|
6647
6754
|
"collaborative",
|
|
6648
6755
|
"final",
|
|
6649
6756
|
"initial",
|
|
6650
|
-
"side"
|
|
6757
|
+
"side",
|
|
6758
|
+
"top"
|
|
6759
|
+
]);
|
|
6760
|
+
var TOPIC_PREFIX_WORDS = /* @__PURE__ */ new Set([
|
|
6761
|
+
"a",
|
|
6762
|
+
"an",
|
|
6763
|
+
"the",
|
|
6764
|
+
"my",
|
|
6765
|
+
"your",
|
|
6766
|
+
"our",
|
|
6767
|
+
"their",
|
|
6768
|
+
"his",
|
|
6769
|
+
"her",
|
|
6770
|
+
"its",
|
|
6771
|
+
"this",
|
|
6772
|
+
"that",
|
|
6773
|
+
"these",
|
|
6774
|
+
"those"
|
|
6651
6775
|
]);
|
|
6652
6776
|
var GENERIC_ENDINGS = /* @__PURE__ */ new Set([
|
|
6653
6777
|
"work",
|
|
@@ -6714,6 +6838,23 @@ var GENERIC_CAPS = /* @__PURE__ */ new Set([
|
|
|
6714
6838
|
"advantages",
|
|
6715
6839
|
"disadvantages"
|
|
6716
6840
|
]);
|
|
6841
|
+
var GENERIC_SINGLE_ENTITY_TERMS = /* @__PURE__ */ new Set([
|
|
6842
|
+
"user",
|
|
6843
|
+
"assistant",
|
|
6844
|
+
"agent",
|
|
6845
|
+
"customer",
|
|
6846
|
+
"client",
|
|
6847
|
+
"person",
|
|
6848
|
+
"people",
|
|
6849
|
+
"human",
|
|
6850
|
+
"memory",
|
|
6851
|
+
"message",
|
|
6852
|
+
"conversation",
|
|
6853
|
+
"chat",
|
|
6854
|
+
"session",
|
|
6855
|
+
"system",
|
|
6856
|
+
"top"
|
|
6857
|
+
]);
|
|
6717
6858
|
var FORMATTING_MARKERS = /* @__PURE__ */ new Set([
|
|
6718
6859
|
"*",
|
|
6719
6860
|
"-",
|
|
@@ -6760,22 +6901,64 @@ function stripGenericEnding(words) {
|
|
|
6760
6901
|
}
|
|
6761
6902
|
return words;
|
|
6762
6903
|
}
|
|
6763
|
-
function
|
|
6764
|
-
|
|
6765
|
-
|
|
6904
|
+
function stripTopicPrefix(words) {
|
|
6905
|
+
let start = 0;
|
|
6906
|
+
while (start < words.length && TOPIC_PREFIX_WORDS.has(words[start].toLowerCase())) {
|
|
6907
|
+
start++;
|
|
6766
6908
|
}
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6909
|
+
return words.slice(start);
|
|
6910
|
+
}
|
|
6911
|
+
function cleanToken(token) {
|
|
6912
|
+
return token.replace(/^[^\w.]+|[^\w.]+$/g, "");
|
|
6913
|
+
}
|
|
6914
|
+
function tokenize(text) {
|
|
6915
|
+
var _a2;
|
|
6916
|
+
return (_a2 = text.match(
|
|
6917
|
+
/[A-Za-z_][\w-]*(?:\.[A-Za-z_][\w-]*)*|\d[\d,]*(?:\.\d+)?|[,:;.!?&]/g
|
|
6918
|
+
)) != null ? _a2 : [];
|
|
6919
|
+
}
|
|
6920
|
+
function isCapitalized(token) {
|
|
6921
|
+
return /^[A-Z]/.test(token) && /[A-Za-z]/.test(token);
|
|
6922
|
+
}
|
|
6923
|
+
function hasInternalCapOrDigit(token) {
|
|
6924
|
+
return /\d/.test(token) || /[A-Z]/.test(token.slice(1)) || /^[A-Z]{2,}$/.test(token);
|
|
6925
|
+
}
|
|
6926
|
+
function isBadSingleNameToken(token) {
|
|
6927
|
+
const lower = token.toLowerCase();
|
|
6928
|
+
return GENERIC_SINGLE_ENTITY_TERMS.has(lower) || GENERIC_CAPS.has(lower);
|
|
6929
|
+
}
|
|
6930
|
+
function looksLikeMetricCount(token) {
|
|
6931
|
+
return /^\d[\d,]*(?:\.\d+)?$/.test(token);
|
|
6932
|
+
}
|
|
6933
|
+
function isMetricListContext(tokens, idx) {
|
|
6934
|
+
const prev = idx > 0 ? tokens[idx - 1] : "";
|
|
6935
|
+
const next = idx + 1 < tokens.length ? tokens[idx + 1] : "";
|
|
6936
|
+
return [":", ",", ";"].includes(prev) || [",", ";"].includes(next);
|
|
6937
|
+
}
|
|
6938
|
+
function isSentenceStart(tokens, idx) {
|
|
6939
|
+
if (idx === 0) return true;
|
|
6940
|
+
return [".", "!", "?", ":"].includes(tokens[idx - 1]) || FORMATTING_MARKERS.has(tokens[idx - 1]);
|
|
6941
|
+
}
|
|
6942
|
+
function isListItemNameToken(tokens, idx) {
|
|
6943
|
+
const token = cleanToken(tokens[idx]);
|
|
6944
|
+
if (!isCapitalized(token) || isBadSingleNameToken(token)) return false;
|
|
6945
|
+
const next = idx + 1 < tokens.length ? cleanToken(tokens[idx + 1]) : "";
|
|
6946
|
+
if (!looksLikeMetricCount(next)) return false;
|
|
6947
|
+
return isMetricListContext(tokens, idx) || isMetricListContext(tokens, idx + 1);
|
|
6948
|
+
}
|
|
6949
|
+
function isNameToken(tokens, idx) {
|
|
6950
|
+
const token = cleanToken(tokens[idx]);
|
|
6951
|
+
if (!token || !isCapitalized(token) || isBadSingleNameToken(token))
|
|
6952
|
+
return false;
|
|
6953
|
+
if (hasInternalCapOrDigit(token) || isListItemNameToken(tokens, idx))
|
|
6776
6954
|
return true;
|
|
6777
|
-
|
|
6778
|
-
|
|
6955
|
+
return !isSentenceStart(tokens, idx);
|
|
6956
|
+
}
|
|
6957
|
+
function cleanEntityText(text) {
|
|
6958
|
+
return text.replace(/^\*+\s*|\s*\*+$/g, "").replace(/\s*:+$/g, "").replace(/^\d+\s*\.\s*/, "").replace(/\s+\d[\d,]*(?:\.\d+)?$/g, "").replace(/[.,;!?]+$/, "").trim().replace(/\s+/g, " ");
|
|
6959
|
+
}
|
|
6960
|
+
function isCoordinatedNameTopic(text) {
|
|
6961
|
+
return /\b[A-Z][\w-]+\s+and\s+[A-Z][\w-]+\b/.test(text);
|
|
6779
6962
|
}
|
|
6780
6963
|
function extractQuoted(text) {
|
|
6781
6964
|
const entities = [];
|
|
@@ -6796,62 +6979,57 @@ function extractQuoted(text) {
|
|
|
6796
6979
|
}
|
|
6797
6980
|
return entities;
|
|
6798
6981
|
}
|
|
6982
|
+
function extractIdentifiers(text) {
|
|
6983
|
+
const entities = [];
|
|
6984
|
+
const identifierRe = /\b[A-Za-z_][\w-]*(?:\.[A-Za-z_][\w-]*)+\b/g;
|
|
6985
|
+
let match;
|
|
6986
|
+
while ((match = identifierRe.exec(text)) !== null) {
|
|
6987
|
+
entities.push({ type: "IDENTIFIER", text: match[0] });
|
|
6988
|
+
}
|
|
6989
|
+
return entities;
|
|
6990
|
+
}
|
|
6799
6991
|
function extractProper(text) {
|
|
6800
6992
|
const entities = [];
|
|
6801
|
-
const tokens = text
|
|
6802
|
-
const
|
|
6803
|
-
"'s",
|
|
6804
|
-
"of",
|
|
6805
|
-
"the",
|
|
6806
|
-
"in",
|
|
6807
|
-
"and",
|
|
6808
|
-
"for",
|
|
6809
|
-
"at",
|
|
6810
|
-
"is"
|
|
6811
|
-
]);
|
|
6993
|
+
const tokens = tokenize(text);
|
|
6994
|
+
const innerConnectors = /* @__PURE__ */ new Set(["of", "the", "in", "for", "at"]);
|
|
6812
6995
|
let i = 0;
|
|
6813
6996
|
while (i < tokens.length) {
|
|
6814
|
-
const
|
|
6815
|
-
|
|
6997
|
+
const token = cleanToken(tokens[i]);
|
|
6998
|
+
const next = i + 1 < tokens.length ? tokens[i + 1] : "";
|
|
6999
|
+
const afterNext = i + 2 < tokens.length ? cleanToken(tokens[i + 2]) : "";
|
|
7000
|
+
if (token && next === "&" && afterNext && isCapitalized(token) && isCapitalized(afterNext) && !isBadSingleNameToken(token) && !isBadSingleNameToken(afterNext)) {
|
|
7001
|
+
entities.push({
|
|
7002
|
+
type: "PROPER",
|
|
7003
|
+
text: cleanEntityText(`${token} & ${afterNext}`)
|
|
7004
|
+
});
|
|
7005
|
+
i += 3;
|
|
7006
|
+
continue;
|
|
7007
|
+
}
|
|
7008
|
+
if (!isNameToken(tokens, i)) {
|
|
6816
7009
|
i++;
|
|
6817
7010
|
continue;
|
|
6818
7011
|
}
|
|
6819
|
-
const
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
const
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
const t = tokens[j];
|
|
6828
|
-
const tIsCap = t.length > 0 && t.charAt(0) === t.charAt(0).toUpperCase() && /[A-Z]/.test(t.charAt(0));
|
|
6829
|
-
if (tIsCap || functionWords.has(t.toLowerCase())) {
|
|
6830
|
-
seq.push({ token: t, idx: j });
|
|
6831
|
-
j++;
|
|
6832
|
-
} else {
|
|
6833
|
-
break;
|
|
6834
|
-
}
|
|
6835
|
-
}
|
|
6836
|
-
while (seq.length > 0 && functionWords.has(seq[seq.length - 1].token.toLowerCase())) {
|
|
6837
|
-
seq.pop();
|
|
7012
|
+
const span = [cleanToken(tokens[i])];
|
|
7013
|
+
let j = i + 1;
|
|
7014
|
+
while (j < tokens.length) {
|
|
7015
|
+
const current = cleanToken(tokens[j]);
|
|
7016
|
+
if (isNameToken(tokens, j)) {
|
|
7017
|
+
span.push(current);
|
|
7018
|
+
j++;
|
|
7019
|
+
continue;
|
|
6838
7020
|
}
|
|
6839
|
-
if (
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
});
|
|
6844
|
-
if (hasMidCap) {
|
|
6845
|
-
const phrase = seq.map((s) => s.token).join(" ");
|
|
6846
|
-
if (phrase.length > 2) {
|
|
6847
|
-
entities.push({ type: "PROPER", text: phrase });
|
|
6848
|
-
}
|
|
6849
|
-
}
|
|
7021
|
+
if (innerConnectors.has(current.toLowerCase()) && j + 1 < tokens.length && isNameToken(tokens, j + 1)) {
|
|
7022
|
+
span.push(current, cleanToken(tokens[j + 1]));
|
|
7023
|
+
j += 2;
|
|
7024
|
+
continue;
|
|
6850
7025
|
}
|
|
6851
|
-
|
|
6852
|
-
} else {
|
|
6853
|
-
i++;
|
|
7026
|
+
break;
|
|
6854
7027
|
}
|
|
7028
|
+
const phrase = cleanEntityText(span.join(" "));
|
|
7029
|
+
if (phrase.length > 2) {
|
|
7030
|
+
entities.push({ type: "PROPER", text: phrase });
|
|
7031
|
+
}
|
|
7032
|
+
i = Math.max(j, i + 1);
|
|
6855
7033
|
}
|
|
6856
7034
|
return entities;
|
|
6857
7035
|
}
|
|
@@ -6883,11 +7061,11 @@ function extractCompoundsWithNlp(text) {
|
|
|
6883
7061
|
const filtered = words.filter(
|
|
6884
7062
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6885
7063
|
);
|
|
6886
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7064
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6887
7065
|
if (cleaned.length >= 2) {
|
|
6888
|
-
const phrase = cleaned.join(" ");
|
|
7066
|
+
const phrase = cleanEntityText(cleaned.join(" "));
|
|
6889
7067
|
if (phrase.length > 3) {
|
|
6890
|
-
entities.push({ type: "
|
|
7068
|
+
entities.push({ type: "TOPIC", text: phrase });
|
|
6891
7069
|
}
|
|
6892
7070
|
}
|
|
6893
7071
|
}
|
|
@@ -6895,7 +7073,7 @@ function extractCompoundsWithNlp(text) {
|
|
|
6895
7073
|
}
|
|
6896
7074
|
function extractCompoundsRegex(text) {
|
|
6897
7075
|
const entities = [];
|
|
6898
|
-
const compoundRe = /\b([A-Z][a-z]+(?:\s+(?:of|
|
|
7076
|
+
const compoundRe = /\b([A-Z][a-z]+(?:\s+(?:of|the|for|in)\s+)?[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b/g;
|
|
6899
7077
|
let match;
|
|
6900
7078
|
while ((match = compoundRe.exec(text)) !== null) {
|
|
6901
7079
|
const phrase = match[1].trim();
|
|
@@ -6906,9 +7084,12 @@ function extractCompoundsRegex(text) {
|
|
|
6906
7084
|
const filtered = words.filter(
|
|
6907
7085
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6908
7086
|
);
|
|
6909
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7087
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6910
7088
|
if (cleaned.length >= 2) {
|
|
6911
|
-
entities.push({
|
|
7089
|
+
entities.push({
|
|
7090
|
+
type: "TOPIC",
|
|
7091
|
+
text: cleanEntityText(cleaned.join(" "))
|
|
7092
|
+
});
|
|
6912
7093
|
}
|
|
6913
7094
|
}
|
|
6914
7095
|
}
|
|
@@ -6930,9 +7111,12 @@ function extractCompoundsRegex(text) {
|
|
|
6930
7111
|
const filtered = words.filter(
|
|
6931
7112
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6932
7113
|
);
|
|
6933
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7114
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6934
7115
|
if (cleaned.length >= 2) {
|
|
6935
|
-
entities.push({
|
|
7116
|
+
entities.push({
|
|
7117
|
+
type: "TOPIC",
|
|
7118
|
+
text: cleanEntityText(cleaned.join(" "))
|
|
7119
|
+
});
|
|
6936
7120
|
}
|
|
6937
7121
|
}
|
|
6938
7122
|
}
|
|
@@ -6945,6 +7129,7 @@ function extractEntities(text) {
|
|
|
6945
7129
|
const raw = [];
|
|
6946
7130
|
raw.push(...extractQuoted(text));
|
|
6947
7131
|
raw.push(...extractProper(text));
|
|
7132
|
+
raw.push(...extractIdentifiers(text));
|
|
6948
7133
|
if (nlp) {
|
|
6949
7134
|
raw.push(...extractCompoundsWithNlp(text));
|
|
6950
7135
|
} else {
|
|
@@ -6962,13 +7147,13 @@ function extractEntities(text) {
|
|
|
6962
7147
|
const cleaned = [];
|
|
6963
7148
|
for (const entity of deduped) {
|
|
6964
7149
|
let txt = entity.text.trim();
|
|
6965
|
-
txt = txt
|
|
6966
|
-
txt = txt.replace(/\s*:+$/, "");
|
|
6967
|
-
txt = txt.replace(/^\d+\s*\.\s*/, "");
|
|
6968
|
-
txt = txt.replace(/[.,;!?]+$/, "").trim();
|
|
7150
|
+
txt = cleanEntityText(txt);
|
|
6969
7151
|
if (!txt || txt.length <= 2 || hasArtifacts(txt)) {
|
|
6970
7152
|
continue;
|
|
6971
7153
|
}
|
|
7154
|
+
if (entity.type === "TOPIC" && (/^\d/.test(txt) || isCoordinatedNameTopic(txt))) {
|
|
7155
|
+
continue;
|
|
7156
|
+
}
|
|
6972
7157
|
if (entity.type === "PROPER" && !txt.includes(" ") && GENERIC_CAPS.has(txt.toLowerCase())) {
|
|
6973
7158
|
continue;
|
|
6974
7159
|
}
|
|
@@ -6976,9 +7161,9 @@ function extractEntities(text) {
|
|
|
6976
7161
|
}
|
|
6977
7162
|
const typePriority = {
|
|
6978
7163
|
PROPER: 0,
|
|
6979
|
-
|
|
7164
|
+
IDENTIFIER: 1,
|
|
6980
7165
|
QUOTED: 2,
|
|
6981
|
-
|
|
7166
|
+
TOPIC: 3
|
|
6982
7167
|
};
|
|
6983
7168
|
const best = /* @__PURE__ */ new Map();
|
|
6984
7169
|
for (const entity of cleaned) {
|
|
@@ -6989,10 +7174,14 @@ function extractEntities(text) {
|
|
|
6989
7174
|
}
|
|
6990
7175
|
}
|
|
6991
7176
|
const bestEntities = Array.from(best.values());
|
|
6992
|
-
const allLower = bestEntities.map((e) => e.text.toLowerCase());
|
|
6993
7177
|
return bestEntities.filter(
|
|
6994
|
-
(entity) => !
|
|
6995
|
-
(other) =>
|
|
7178
|
+
(entity) => !bestEntities.some(
|
|
7179
|
+
(other) => {
|
|
7180
|
+
var _a3, _b3;
|
|
7181
|
+
return entity.text.toLowerCase() !== other.text.toLowerCase() && ((_a3 = typePriority[entity.type]) != null ? _a3 : 99) >= ((_b3 = typePriority[other.type]) != null ? _b3 : 99) && new RegExp(
|
|
7182
|
+
`(^|\\s)${entity.text.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(\\s|$)`
|
|
7183
|
+
).test(other.text.toLowerCase());
|
|
7184
|
+
}
|
|
6996
7185
|
)
|
|
6997
7186
|
);
|
|
6998
7187
|
}
|
|
@@ -7284,6 +7473,32 @@ var Memory = class _Memory {
|
|
|
7284
7473
|
if (payload.run_id) filters.run_id = payload.run_id;
|
|
7285
7474
|
return filters;
|
|
7286
7475
|
}
|
|
7476
|
+
_normalizeEntityText(value) {
|
|
7477
|
+
return value.trim().toLowerCase().replace(/\s+/g, " ");
|
|
7478
|
+
}
|
|
7479
|
+
async _existingEntitiesByText(entityStore, filters) {
|
|
7480
|
+
var _a2;
|
|
7481
|
+
const rowsByText = /* @__PURE__ */ new Map();
|
|
7482
|
+
let rows = [];
|
|
7483
|
+
try {
|
|
7484
|
+
const listed = await entityStore.list(filters, 1e4);
|
|
7485
|
+
rows = Array.isArray(listed) && Array.isArray(listed[0]) ? listed[0] : listed;
|
|
7486
|
+
} catch (e) {
|
|
7487
|
+
console.debug(
|
|
7488
|
+
`Exact entity lookup failed, falling back to semantic dedup: ${e}`
|
|
7489
|
+
);
|
|
7490
|
+
return rowsByText;
|
|
7491
|
+
}
|
|
7492
|
+
for (const row of rows) {
|
|
7493
|
+
const text = (_a2 = row.payload) == null ? void 0 : _a2.data;
|
|
7494
|
+
if (typeof text !== "string") continue;
|
|
7495
|
+
const key = this._normalizeEntityText(text);
|
|
7496
|
+
if (key && !rowsByText.has(key)) {
|
|
7497
|
+
rowsByText.set(key, row);
|
|
7498
|
+
}
|
|
7499
|
+
}
|
|
7500
|
+
return rowsByText;
|
|
7501
|
+
}
|
|
7287
7502
|
/**
|
|
7288
7503
|
* Remove `memoryId` from every entity record scoped to `filters`.
|
|
7289
7504
|
* If an entity's `linkedMemoryIds` becomes empty after removal, the
|
|
@@ -7361,6 +7576,10 @@ var Memory = class _Memory {
|
|
|
7361
7576
|
const entities = extractEntities(text);
|
|
7362
7577
|
if (entities.length === 0) return;
|
|
7363
7578
|
const entityStore = await this.getEntityStore();
|
|
7579
|
+
const exactMatches = await this._existingEntitiesByText(
|
|
7580
|
+
entityStore,
|
|
7581
|
+
filters
|
|
7582
|
+
);
|
|
7364
7583
|
for (const entity of entities) {
|
|
7365
7584
|
try {
|
|
7366
7585
|
let entityVec;
|
|
@@ -7371,12 +7590,18 @@ var Memory = class _Memory {
|
|
|
7371
7590
|
continue;
|
|
7372
7591
|
}
|
|
7373
7592
|
let matches = [];
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7593
|
+
const exactMatch = exactMatches.get(
|
|
7594
|
+
this._normalizeEntityText(entity.text)
|
|
7595
|
+
);
|
|
7596
|
+
if (!exactMatch) {
|
|
7597
|
+
try {
|
|
7598
|
+
matches = await entityStore.search(entityVec, 1, filters);
|
|
7599
|
+
} catch (e) {
|
|
7600
|
+
}
|
|
7377
7601
|
}
|
|
7378
|
-
|
|
7379
|
-
|
|
7602
|
+
const semanticMatch = matches.length > 0 && ((_a2 = matches[0].score) != null ? _a2 : 0) >= 0.95 ? matches[0] : void 0;
|
|
7603
|
+
const match = exactMatch != null ? exactMatch : semanticMatch;
|
|
7604
|
+
if (match) {
|
|
7380
7605
|
const payload = match.payload || {};
|
|
7381
7606
|
const linked = new Set(
|
|
7382
7607
|
Array.isArray(payload.linkedMemoryIds) ? payload.linkedMemoryIds : []
|
|
@@ -7538,6 +7763,25 @@ var Memory = class _Memory {
|
|
|
7538
7763
|
"messages is required and cannot be undefined or null. Provide a string or array of messages."
|
|
7539
7764
|
);
|
|
7540
7765
|
}
|
|
7766
|
+
if (Array.isArray(messages)) {
|
|
7767
|
+
if (messages.length === 0) {
|
|
7768
|
+
throw new Error(
|
|
7769
|
+
"messages array cannot be empty. Provide at least one message with non-empty content."
|
|
7770
|
+
);
|
|
7771
|
+
}
|
|
7772
|
+
const allBlank = messages.every(
|
|
7773
|
+
(m) => typeof m.content === "string" && m.content.trim() === ""
|
|
7774
|
+
);
|
|
7775
|
+
if (allBlank) {
|
|
7776
|
+
throw new Error(
|
|
7777
|
+
"messages array cannot contain only blank content. Provide at least one message with non-empty content."
|
|
7778
|
+
);
|
|
7779
|
+
}
|
|
7780
|
+
} else if (messages.trim() === "") {
|
|
7781
|
+
throw new Error(
|
|
7782
|
+
"messages string cannot be empty. Provide non-empty content."
|
|
7783
|
+
);
|
|
7784
|
+
}
|
|
7541
7785
|
const temporalUsageNotice = detectTemporalUsageFromMetadata(
|
|
7542
7786
|
config == null ? void 0 : config.metadata
|
|
7543
7787
|
);
|
|
@@ -7597,7 +7841,7 @@ var Memory = class _Memory {
|
|
|
7597
7841
|
if (!infer) {
|
|
7598
7842
|
const returnedMemories = [];
|
|
7599
7843
|
for (const message of messages) {
|
|
7600
|
-
if (message.
|
|
7844
|
+
if (message.role === "system") {
|
|
7601
7845
|
continue;
|
|
7602
7846
|
}
|
|
7603
7847
|
const memoryId = await this.createMemory(
|
|
@@ -7621,7 +7865,7 @@ var Memory = class _Memory {
|
|
|
7621
7865
|
} catch (e) {
|
|
7622
7866
|
}
|
|
7623
7867
|
}
|
|
7624
|
-
const parsedMessages = messages.map((m) => m.content).join("\n");
|
|
7868
|
+
const parsedMessages = messages.map((m) => `${m.role}: ${m.content}`).join("\n");
|
|
7625
7869
|
const queryEmbedding = await this.embedder.embed(parsedMessages);
|
|
7626
7870
|
const existingResults = await this.vectorStore.search(
|
|
7627
7871
|
queryEmbedding,
|
|
@@ -7874,6 +8118,10 @@ var Memory = class _Memory {
|
|
|
7874
8118
|
}
|
|
7875
8119
|
if (valid.length > 0) {
|
|
7876
8120
|
const entityStore = await this.getEntityStore();
|
|
8121
|
+
const exactMatches = await this._existingEntitiesByText(
|
|
8122
|
+
entityStore,
|
|
8123
|
+
filters
|
|
8124
|
+
);
|
|
7877
8125
|
const toInsertVectors = [];
|
|
7878
8126
|
const toInsertIds = [];
|
|
7879
8127
|
const toInsertPayloads = [];
|
|
@@ -7881,12 +8129,16 @@ var Memory = class _Memory {
|
|
|
7881
8129
|
const { entityType, entityText, memoryIds } = globalEntities[key];
|
|
7882
8130
|
const entityVec = entityEmbeddings[j];
|
|
7883
8131
|
let matches = [];
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
8132
|
+
const exactMatch = exactMatches.get(key);
|
|
8133
|
+
if (!exactMatch) {
|
|
8134
|
+
try {
|
|
8135
|
+
matches = await entityStore.search(entityVec, 1, filters);
|
|
8136
|
+
} catch (e) {
|
|
8137
|
+
}
|
|
7887
8138
|
}
|
|
7888
|
-
|
|
7889
|
-
|
|
8139
|
+
const semanticMatch = matches.length > 0 && ((_f = matches[0].score) != null ? _f : 0) >= 0.95 ? matches[0] : void 0;
|
|
8140
|
+
const match = exactMatch != null ? exactMatch : semanticMatch;
|
|
8141
|
+
if (match) {
|
|
7890
8142
|
const payload = match.payload || {};
|
|
7891
8143
|
const linked = new Set((_g = payload.linkedMemoryIds) != null ? _g : []);
|
|
7892
8144
|
for (const mid of memoryIds) linked.add(mid);
|
|
@@ -7980,7 +8232,13 @@ var Memory = class _Memory {
|
|
|
7980
8232
|
memoryItem.metadata[key] = value;
|
|
7981
8233
|
}
|
|
7982
8234
|
}
|
|
7983
|
-
const result = {
|
|
8235
|
+
const result = {
|
|
8236
|
+
...memoryItem,
|
|
8237
|
+
...filters,
|
|
8238
|
+
...memory.payload.attributedTo && {
|
|
8239
|
+
attributedTo: memory.payload.attributedTo
|
|
8240
|
+
}
|
|
8241
|
+
};
|
|
7984
8242
|
await this._displayFirstRunNotice("get");
|
|
7985
8243
|
return result;
|
|
7986
8244
|
}
|
|
@@ -8178,6 +8436,7 @@ var Memory = class _Memory {
|
|
|
8178
8436
|
...payload.user_id && { user_id: payload.user_id },
|
|
8179
8437
|
...payload.agent_id && { agent_id: payload.agent_id },
|
|
8180
8438
|
...payload.run_id && { run_id: payload.run_id },
|
|
8439
|
+
...payload.attributedTo && { attributedTo: payload.attributedTo },
|
|
8181
8440
|
...scored.scoreDetails && { score_details: scored.scoreDetails }
|
|
8182
8441
|
};
|
|
8183
8442
|
});
|
|
@@ -8251,7 +8510,9 @@ var Memory = class _Memory {
|
|
|
8251
8510
|
has_agent_id: !!config.agentId,
|
|
8252
8511
|
has_run_id: !!config.runId
|
|
8253
8512
|
});
|
|
8254
|
-
const
|
|
8513
|
+
const userId = validateAndTrimEntityId(config.userId, "userId");
|
|
8514
|
+
const agentId = validateAndTrimEntityId(config.agentId, "agentId");
|
|
8515
|
+
const runId = validateAndTrimEntityId(config.runId, "runId");
|
|
8255
8516
|
const filters = {};
|
|
8256
8517
|
if (userId) filters.user_id = userId;
|
|
8257
8518
|
if (agentId) filters.agent_id = agentId;
|
|
@@ -8371,7 +8632,10 @@ var Memory = class _Memory {
|
|
|
8371
8632
|
metadata: Object.entries(mem.payload).filter(([key]) => !excludedKeys.has(key)).reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
|
|
8372
8633
|
...mem.payload.user_id && { user_id: mem.payload.user_id },
|
|
8373
8634
|
...mem.payload.agent_id && { agent_id: mem.payload.agent_id },
|
|
8374
|
-
...mem.payload.run_id && { run_id: mem.payload.run_id }
|
|
8635
|
+
...mem.payload.run_id && { run_id: mem.payload.run_id },
|
|
8636
|
+
...mem.payload.attributedTo && {
|
|
8637
|
+
attributedTo: mem.payload.attributedTo
|
|
8638
|
+
}
|
|
8375
8639
|
}));
|
|
8376
8640
|
const result = { results };
|
|
8377
8641
|
const scaleThresholdNotice = detectScaleThresholdFromTopK(topK);
|
|
@@ -8605,6 +8869,7 @@ export {
|
|
|
8605
8869
|
LangchainEmbedder,
|
|
8606
8870
|
LangchainLLM,
|
|
8607
8871
|
LangchainVectorStore,
|
|
8872
|
+
LiteLLM,
|
|
8608
8873
|
Memory,
|
|
8609
8874
|
MemoryConfigSchema,
|
|
8610
8875
|
MemoryVectorStore,
|