mem0ai 3.0.10 → 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 +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/dist/oss/index.d.mts +19 -5
- package/dist/oss/index.d.ts +19 -5
- package/dist/oss/index.js +353 -123
- package/dist/oss/index.js.map +1 -1
- package/dist/oss/index.mjs +348 -119
- package/dist/oss/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/oss/index.mjs
CHANGED
|
@@ -1836,13 +1836,15 @@ var RedisDB = class {
|
|
|
1836
1836
|
}
|
|
1837
1837
|
async insert(vectors, ids, payloads) {
|
|
1838
1838
|
const data = vectors.map((vector, idx) => {
|
|
1839
|
+
var _a2, _b2;
|
|
1839
1840
|
const payload = toSnakeCase(payloads[idx]);
|
|
1840
1841
|
const id = ids[idx];
|
|
1842
|
+
const createdAt = payload.created_at ? new Date(payload.created_at).getTime() : 0;
|
|
1841
1843
|
const entry = {
|
|
1842
1844
|
memory_id: id,
|
|
1843
|
-
hash: payload.hash,
|
|
1844
|
-
memory: payload.data,
|
|
1845
|
-
created_at:
|
|
1845
|
+
hash: (_a2 = payload.hash) != null ? _a2 : "",
|
|
1846
|
+
memory: (_b2 = payload.data) != null ? _b2 : "",
|
|
1847
|
+
created_at: createdAt,
|
|
1846
1848
|
embedding: new Float32Array(vector).buffer
|
|
1847
1849
|
};
|
|
1848
1850
|
["agent_id", "run_id", "user_id"].forEach((field) => {
|
|
@@ -2021,13 +2023,16 @@ var RedisDB = class {
|
|
|
2021
2023
|
}
|
|
2022
2024
|
}
|
|
2023
2025
|
async update(vectorId, vector, payload) {
|
|
2026
|
+
var _a2, _b2;
|
|
2024
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;
|
|
2025
2030
|
const entry = {
|
|
2026
2031
|
memory_id: vectorId,
|
|
2027
|
-
hash: snakePayload.hash,
|
|
2028
|
-
memory: snakePayload.data,
|
|
2029
|
-
created_at:
|
|
2030
|
-
updated_at:
|
|
2032
|
+
hash: (_a2 = snakePayload.hash) != null ? _a2 : "",
|
|
2033
|
+
memory: (_b2 = snakePayload.data) != null ? _b2 : "",
|
|
2034
|
+
created_at: createdAt,
|
|
2035
|
+
updated_at: updatedAt,
|
|
2031
2036
|
embedding: Buffer.from(new Float32Array(vector).buffer)
|
|
2032
2037
|
};
|
|
2033
2038
|
["agent_id", "run_id", "user_id"].forEach((field) => {
|
|
@@ -2273,6 +2278,66 @@ var DeepSeekLLM = class extends OpenAILLM {
|
|
|
2273
2278
|
}
|
|
2274
2279
|
};
|
|
2275
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
|
+
|
|
2276
2341
|
// src/oss/src/vector_stores/supabase.ts
|
|
2277
2342
|
import { createClient as createClient2 } from "@supabase/supabase-js";
|
|
2278
2343
|
var SupabaseDB = class {
|
|
@@ -4554,24 +4619,59 @@ function buildFilterConditions(filters, startIndex) {
|
|
|
4554
4619
|
}
|
|
4555
4620
|
return { conditions, values, paramIndex };
|
|
4556
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
|
+
}
|
|
4557
4657
|
var PGVector = class {
|
|
4558
4658
|
constructor(config) {
|
|
4659
|
+
validateConnectionConfig(config);
|
|
4559
4660
|
this.collectionName = validateIdentifier(
|
|
4560
4661
|
config.collectionName || "memories",
|
|
4561
4662
|
"collectionName"
|
|
4562
4663
|
);
|
|
4563
4664
|
this.useDiskann = config.diskann || false;
|
|
4564
4665
|
this.useHnsw = config.hnsw || false;
|
|
4565
|
-
this.
|
|
4666
|
+
this.useDirectConnection = !!getConnectionString(config);
|
|
4667
|
+
this.dbName = this.useDirectConnection ? "" : validateIdentifier(config.dbname || "vector_store", "dbname");
|
|
4566
4668
|
this.config = config;
|
|
4567
|
-
this.client = new Client(
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
port: config.port
|
|
4574
|
-
});
|
|
4669
|
+
this.client = new Client(
|
|
4670
|
+
buildClientConfig(
|
|
4671
|
+
config,
|
|
4672
|
+
this.useDirectConnection ? void 0 : "postgres"
|
|
4673
|
+
)
|
|
4674
|
+
);
|
|
4575
4675
|
this.initialize().catch(console.error);
|
|
4576
4676
|
}
|
|
4577
4677
|
col() {
|
|
@@ -4586,19 +4686,15 @@ var PGVector = class {
|
|
|
4586
4686
|
async _doInitialize() {
|
|
4587
4687
|
try {
|
|
4588
4688
|
await this.client.connect();
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
host: this.config.host,
|
|
4599
|
-
port: this.config.port
|
|
4600
|
-
});
|
|
4601
|
-
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
|
+
}
|
|
4602
4698
|
await this.client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
4603
4699
|
await this.client.query(`
|
|
4604
4700
|
CREATE TABLE IF NOT EXISTS memory_migrations (
|
|
@@ -4869,6 +4965,10 @@ var LLMFactory = class {
|
|
|
4869
4965
|
return new LangchainLLM(config);
|
|
4870
4966
|
case "deepseek":
|
|
4871
4967
|
return new DeepSeekLLM(config);
|
|
4968
|
+
case "litellm":
|
|
4969
|
+
return new LiteLLM(config);
|
|
4970
|
+
case "minimax":
|
|
4971
|
+
return new MiniMaxLLM(config);
|
|
4872
4972
|
default:
|
|
4873
4973
|
throw new Error(`Unsupported LLM provider: ${provider}`);
|
|
4874
4974
|
}
|
|
@@ -5121,7 +5221,7 @@ var parse_vision_messages = async (messages) => {
|
|
|
5121
5221
|
};
|
|
5122
5222
|
|
|
5123
5223
|
// src/oss/src/utils/telemetry.ts
|
|
5124
|
-
var version = true ? "3.0.
|
|
5224
|
+
var version = true ? "3.0.12" : "dev";
|
|
5125
5225
|
var MEM0_TELEMETRY = true;
|
|
5126
5226
|
var _a, _b;
|
|
5127
5227
|
try {
|
|
@@ -6654,7 +6754,24 @@ var NON_SPECIFIC_ADJ = /* @__PURE__ */ new Set([
|
|
|
6654
6754
|
"collaborative",
|
|
6655
6755
|
"final",
|
|
6656
6756
|
"initial",
|
|
6657
|
-
"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"
|
|
6658
6775
|
]);
|
|
6659
6776
|
var GENERIC_ENDINGS = /* @__PURE__ */ new Set([
|
|
6660
6777
|
"work",
|
|
@@ -6721,6 +6838,23 @@ var GENERIC_CAPS = /* @__PURE__ */ new Set([
|
|
|
6721
6838
|
"advantages",
|
|
6722
6839
|
"disadvantages"
|
|
6723
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
|
+
]);
|
|
6724
6858
|
var FORMATTING_MARKERS = /* @__PURE__ */ new Set([
|
|
6725
6859
|
"*",
|
|
6726
6860
|
"-",
|
|
@@ -6767,22 +6901,64 @@ function stripGenericEnding(words) {
|
|
|
6767
6901
|
}
|
|
6768
6902
|
return words;
|
|
6769
6903
|
}
|
|
6770
|
-
function
|
|
6771
|
-
|
|
6772
|
-
|
|
6904
|
+
function stripTopicPrefix(words) {
|
|
6905
|
+
let start = 0;
|
|
6906
|
+
while (start < words.length && TOPIC_PREFIX_WORDS.has(words[start].toLowerCase())) {
|
|
6907
|
+
start++;
|
|
6773
6908
|
}
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
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))
|
|
6783
6954
|
return true;
|
|
6784
|
-
|
|
6785
|
-
|
|
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);
|
|
6786
6962
|
}
|
|
6787
6963
|
function extractQuoted(text) {
|
|
6788
6964
|
const entities = [];
|
|
@@ -6803,62 +6979,57 @@ function extractQuoted(text) {
|
|
|
6803
6979
|
}
|
|
6804
6980
|
return entities;
|
|
6805
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
|
+
}
|
|
6806
6991
|
function extractProper(text) {
|
|
6807
6992
|
const entities = [];
|
|
6808
|
-
const tokens = text
|
|
6809
|
-
const
|
|
6810
|
-
"'s",
|
|
6811
|
-
"of",
|
|
6812
|
-
"the",
|
|
6813
|
-
"in",
|
|
6814
|
-
"and",
|
|
6815
|
-
"for",
|
|
6816
|
-
"at",
|
|
6817
|
-
"is"
|
|
6818
|
-
]);
|
|
6993
|
+
const tokens = tokenize(text);
|
|
6994
|
+
const innerConnectors = /* @__PURE__ */ new Set(["of", "the", "in", "for", "at"]);
|
|
6819
6995
|
let i = 0;
|
|
6820
6996
|
while (i < tokens.length) {
|
|
6821
|
-
const
|
|
6822
|
-
|
|
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)) {
|
|
6823
7009
|
i++;
|
|
6824
7010
|
continue;
|
|
6825
7011
|
}
|
|
6826
|
-
const
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
const
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
const t = tokens[j];
|
|
6835
|
-
const tIsCap = t.length > 0 && t.charAt(0) === t.charAt(0).toUpperCase() && /[A-Z]/.test(t.charAt(0));
|
|
6836
|
-
if (tIsCap || functionWords.has(t.toLowerCase())) {
|
|
6837
|
-
seq.push({ token: t, idx: j });
|
|
6838
|
-
j++;
|
|
6839
|
-
} else {
|
|
6840
|
-
break;
|
|
6841
|
-
}
|
|
6842
|
-
}
|
|
6843
|
-
while (seq.length > 0 && functionWords.has(seq[seq.length - 1].token.toLowerCase())) {
|
|
6844
|
-
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;
|
|
6845
7020
|
}
|
|
6846
|
-
if (
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
});
|
|
6851
|
-
if (hasMidCap) {
|
|
6852
|
-
const phrase = seq.map((s) => s.token).join(" ");
|
|
6853
|
-
if (phrase.length > 2) {
|
|
6854
|
-
entities.push({ type: "PROPER", text: phrase });
|
|
6855
|
-
}
|
|
6856
|
-
}
|
|
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;
|
|
6857
7025
|
}
|
|
6858
|
-
|
|
6859
|
-
}
|
|
6860
|
-
|
|
7026
|
+
break;
|
|
7027
|
+
}
|
|
7028
|
+
const phrase = cleanEntityText(span.join(" "));
|
|
7029
|
+
if (phrase.length > 2) {
|
|
7030
|
+
entities.push({ type: "PROPER", text: phrase });
|
|
6861
7031
|
}
|
|
7032
|
+
i = Math.max(j, i + 1);
|
|
6862
7033
|
}
|
|
6863
7034
|
return entities;
|
|
6864
7035
|
}
|
|
@@ -6890,11 +7061,11 @@ function extractCompoundsWithNlp(text) {
|
|
|
6890
7061
|
const filtered = words.filter(
|
|
6891
7062
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6892
7063
|
);
|
|
6893
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7064
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6894
7065
|
if (cleaned.length >= 2) {
|
|
6895
|
-
const phrase = cleaned.join(" ");
|
|
7066
|
+
const phrase = cleanEntityText(cleaned.join(" "));
|
|
6896
7067
|
if (phrase.length > 3) {
|
|
6897
|
-
entities.push({ type: "
|
|
7068
|
+
entities.push({ type: "TOPIC", text: phrase });
|
|
6898
7069
|
}
|
|
6899
7070
|
}
|
|
6900
7071
|
}
|
|
@@ -6902,7 +7073,7 @@ function extractCompoundsWithNlp(text) {
|
|
|
6902
7073
|
}
|
|
6903
7074
|
function extractCompoundsRegex(text) {
|
|
6904
7075
|
const entities = [];
|
|
6905
|
-
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;
|
|
6906
7077
|
let match;
|
|
6907
7078
|
while ((match = compoundRe.exec(text)) !== null) {
|
|
6908
7079
|
const phrase = match[1].trim();
|
|
@@ -6913,9 +7084,12 @@ function extractCompoundsRegex(text) {
|
|
|
6913
7084
|
const filtered = words.filter(
|
|
6914
7085
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6915
7086
|
);
|
|
6916
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7087
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6917
7088
|
if (cleaned.length >= 2) {
|
|
6918
|
-
entities.push({
|
|
7089
|
+
entities.push({
|
|
7090
|
+
type: "TOPIC",
|
|
7091
|
+
text: cleanEntityText(cleaned.join(" "))
|
|
7092
|
+
});
|
|
6919
7093
|
}
|
|
6920
7094
|
}
|
|
6921
7095
|
}
|
|
@@ -6937,9 +7111,12 @@ function extractCompoundsRegex(text) {
|
|
|
6937
7111
|
const filtered = words.filter(
|
|
6938
7112
|
(w) => !NON_SPECIFIC_ADJ.has(w.toLowerCase())
|
|
6939
7113
|
);
|
|
6940
|
-
const cleaned = stripGenericEnding(filtered);
|
|
7114
|
+
const cleaned = stripGenericEnding(stripTopicPrefix(filtered));
|
|
6941
7115
|
if (cleaned.length >= 2) {
|
|
6942
|
-
entities.push({
|
|
7116
|
+
entities.push({
|
|
7117
|
+
type: "TOPIC",
|
|
7118
|
+
text: cleanEntityText(cleaned.join(" "))
|
|
7119
|
+
});
|
|
6943
7120
|
}
|
|
6944
7121
|
}
|
|
6945
7122
|
}
|
|
@@ -6952,6 +7129,7 @@ function extractEntities(text) {
|
|
|
6952
7129
|
const raw = [];
|
|
6953
7130
|
raw.push(...extractQuoted(text));
|
|
6954
7131
|
raw.push(...extractProper(text));
|
|
7132
|
+
raw.push(...extractIdentifiers(text));
|
|
6955
7133
|
if (nlp) {
|
|
6956
7134
|
raw.push(...extractCompoundsWithNlp(text));
|
|
6957
7135
|
} else {
|
|
@@ -6969,13 +7147,13 @@ function extractEntities(text) {
|
|
|
6969
7147
|
const cleaned = [];
|
|
6970
7148
|
for (const entity of deduped) {
|
|
6971
7149
|
let txt = entity.text.trim();
|
|
6972
|
-
txt = txt
|
|
6973
|
-
txt = txt.replace(/\s*:+$/, "");
|
|
6974
|
-
txt = txt.replace(/^\d+\s*\.\s*/, "");
|
|
6975
|
-
txt = txt.replace(/[.,;!?]+$/, "").trim();
|
|
7150
|
+
txt = cleanEntityText(txt);
|
|
6976
7151
|
if (!txt || txt.length <= 2 || hasArtifacts(txt)) {
|
|
6977
7152
|
continue;
|
|
6978
7153
|
}
|
|
7154
|
+
if (entity.type === "TOPIC" && (/^\d/.test(txt) || isCoordinatedNameTopic(txt))) {
|
|
7155
|
+
continue;
|
|
7156
|
+
}
|
|
6979
7157
|
if (entity.type === "PROPER" && !txt.includes(" ") && GENERIC_CAPS.has(txt.toLowerCase())) {
|
|
6980
7158
|
continue;
|
|
6981
7159
|
}
|
|
@@ -6983,9 +7161,9 @@ function extractEntities(text) {
|
|
|
6983
7161
|
}
|
|
6984
7162
|
const typePriority = {
|
|
6985
7163
|
PROPER: 0,
|
|
6986
|
-
|
|
7164
|
+
IDENTIFIER: 1,
|
|
6987
7165
|
QUOTED: 2,
|
|
6988
|
-
|
|
7166
|
+
TOPIC: 3
|
|
6989
7167
|
};
|
|
6990
7168
|
const best = /* @__PURE__ */ new Map();
|
|
6991
7169
|
for (const entity of cleaned) {
|
|
@@ -6996,10 +7174,14 @@ function extractEntities(text) {
|
|
|
6996
7174
|
}
|
|
6997
7175
|
}
|
|
6998
7176
|
const bestEntities = Array.from(best.values());
|
|
6999
|
-
const allLower = bestEntities.map((e) => e.text.toLowerCase());
|
|
7000
7177
|
return bestEntities.filter(
|
|
7001
|
-
(entity) => !
|
|
7002
|
-
(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
|
+
}
|
|
7003
7185
|
)
|
|
7004
7186
|
);
|
|
7005
7187
|
}
|
|
@@ -7291,6 +7473,32 @@ var Memory = class _Memory {
|
|
|
7291
7473
|
if (payload.run_id) filters.run_id = payload.run_id;
|
|
7292
7474
|
return filters;
|
|
7293
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
|
+
}
|
|
7294
7502
|
/**
|
|
7295
7503
|
* Remove `memoryId` from every entity record scoped to `filters`.
|
|
7296
7504
|
* If an entity's `linkedMemoryIds` becomes empty after removal, the
|
|
@@ -7368,6 +7576,10 @@ var Memory = class _Memory {
|
|
|
7368
7576
|
const entities = extractEntities(text);
|
|
7369
7577
|
if (entities.length === 0) return;
|
|
7370
7578
|
const entityStore = await this.getEntityStore();
|
|
7579
|
+
const exactMatches = await this._existingEntitiesByText(
|
|
7580
|
+
entityStore,
|
|
7581
|
+
filters
|
|
7582
|
+
);
|
|
7371
7583
|
for (const entity of entities) {
|
|
7372
7584
|
try {
|
|
7373
7585
|
let entityVec;
|
|
@@ -7378,12 +7590,18 @@ var Memory = class _Memory {
|
|
|
7378
7590
|
continue;
|
|
7379
7591
|
}
|
|
7380
7592
|
let matches = [];
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
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
|
+
}
|
|
7384
7601
|
}
|
|
7385
|
-
|
|
7386
|
-
|
|
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) {
|
|
7387
7605
|
const payload = match.payload || {};
|
|
7388
7606
|
const linked = new Set(
|
|
7389
7607
|
Array.isArray(payload.linkedMemoryIds) ? payload.linkedMemoryIds : []
|
|
@@ -7900,6 +8118,10 @@ var Memory = class _Memory {
|
|
|
7900
8118
|
}
|
|
7901
8119
|
if (valid.length > 0) {
|
|
7902
8120
|
const entityStore = await this.getEntityStore();
|
|
8121
|
+
const exactMatches = await this._existingEntitiesByText(
|
|
8122
|
+
entityStore,
|
|
8123
|
+
filters
|
|
8124
|
+
);
|
|
7903
8125
|
const toInsertVectors = [];
|
|
7904
8126
|
const toInsertIds = [];
|
|
7905
8127
|
const toInsertPayloads = [];
|
|
@@ -7907,12 +8129,16 @@ var Memory = class _Memory {
|
|
|
7907
8129
|
const { entityType, entityText, memoryIds } = globalEntities[key];
|
|
7908
8130
|
const entityVec = entityEmbeddings[j];
|
|
7909
8131
|
let matches = [];
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
8132
|
+
const exactMatch = exactMatches.get(key);
|
|
8133
|
+
if (!exactMatch) {
|
|
8134
|
+
try {
|
|
8135
|
+
matches = await entityStore.search(entityVec, 1, filters);
|
|
8136
|
+
} catch (e) {
|
|
8137
|
+
}
|
|
7913
8138
|
}
|
|
7914
|
-
|
|
7915
|
-
|
|
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) {
|
|
7916
8142
|
const payload = match.payload || {};
|
|
7917
8143
|
const linked = new Set((_g = payload.linkedMemoryIds) != null ? _g : []);
|
|
7918
8144
|
for (const mid of memoryIds) linked.add(mid);
|
|
@@ -8284,7 +8510,9 @@ var Memory = class _Memory {
|
|
|
8284
8510
|
has_agent_id: !!config.agentId,
|
|
8285
8511
|
has_run_id: !!config.runId
|
|
8286
8512
|
});
|
|
8287
|
-
const
|
|
8513
|
+
const userId = validateAndTrimEntityId(config.userId, "userId");
|
|
8514
|
+
const agentId = validateAndTrimEntityId(config.agentId, "agentId");
|
|
8515
|
+
const runId = validateAndTrimEntityId(config.runId, "runId");
|
|
8288
8516
|
const filters = {};
|
|
8289
8517
|
if (userId) filters.user_id = userId;
|
|
8290
8518
|
if (agentId) filters.agent_id = agentId;
|
|
@@ -8641,6 +8869,7 @@ export {
|
|
|
8641
8869
|
LangchainEmbedder,
|
|
8642
8870
|
LangchainLLM,
|
|
8643
8871
|
LangchainVectorStore,
|
|
8872
|
+
LiteLLM,
|
|
8644
8873
|
Memory,
|
|
8645
8874
|
MemoryConfigSchema,
|
|
8646
8875
|
MemoryVectorStore,
|