@sentry/junior-memory 0.81.0 → 0.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +60 -9
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +2 -0
- package/dist/recall.d.ts +2 -0
- package/dist/store.d.ts +2 -0
- package/package.json +2 -2
- package/src/plugin.ts +19 -0
- package/src/recall.ts +10 -3
- package/src/store.ts +53 -3
package/dist/index.js
CHANGED
|
@@ -770,6 +770,7 @@ var MAX_MEMORY_CONTENT_CHARS = 4e3;
|
|
|
770
770
|
var EMBEDDING_METRIC = "cosine";
|
|
771
771
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
772
772
|
var RELEVANCE_NEAR_TIE_DELTA = 0.01;
|
|
773
|
+
var SOURCE_CHANNEL_BOOST = 0.05;
|
|
773
774
|
var SUPERSESSION_STOP_TERMS = /* @__PURE__ */ new Set([
|
|
774
775
|
"and",
|
|
775
776
|
"for",
|
|
@@ -907,6 +908,12 @@ function sourceKey(ctx) {
|
|
|
907
908
|
}
|
|
908
909
|
return `slack:${ctx.source.teamId}:${ctx.source.channelId}:${threadKey}`;
|
|
909
910
|
}
|
|
911
|
+
function sourceChannelPrefix(ctx) {
|
|
912
|
+
if (ctx.source.platform !== "slack") {
|
|
913
|
+
return void 0;
|
|
914
|
+
}
|
|
915
|
+
return `slack:${ctx.source.teamId}:${ctx.source.channelId}:`;
|
|
916
|
+
}
|
|
910
917
|
function parseMemoryRow(row) {
|
|
911
918
|
const parsed = memoryRowSchema.parse(row);
|
|
912
919
|
return memoryRecordSchema.parse({
|
|
@@ -1339,7 +1346,11 @@ async function searchVisibleMemories(args) {
|
|
|
1339
1346
|
)
|
|
1340
1347
|
)
|
|
1341
1348
|
);
|
|
1342
|
-
return rows.map(
|
|
1349
|
+
return rows.map((row) => ({
|
|
1350
|
+
memory: parseMemoryRow(row),
|
|
1351
|
+
score: 0,
|
|
1352
|
+
sourceKey: row.sourceKey
|
|
1353
|
+
}));
|
|
1343
1354
|
}
|
|
1344
1355
|
async function searchVisibleVectorMemories(args) {
|
|
1345
1356
|
if (!args.embedder) {
|
|
@@ -1384,14 +1395,24 @@ async function searchVisibleVectorMemories(args) {
|
|
|
1384
1395
|
if (row.distance === null || !Number.isFinite(distanceValue) || hashEmbeddedContent(row.memory.content) !== row.contentHash) {
|
|
1385
1396
|
return [];
|
|
1386
1397
|
}
|
|
1398
|
+
if (args.maxDistance !== void 0 && distanceValue > args.maxDistance) {
|
|
1399
|
+
return [];
|
|
1400
|
+
}
|
|
1387
1401
|
return [
|
|
1388
1402
|
{
|
|
1389
1403
|
memory: parseMemoryRow(row.memory),
|
|
1390
|
-
score: 1 / (1 + Math.max(0, distanceValue))
|
|
1404
|
+
score: 1 / (1 + Math.max(0, distanceValue)),
|
|
1405
|
+
sourceKey: row.memory.sourceKey
|
|
1391
1406
|
}
|
|
1392
1407
|
];
|
|
1393
1408
|
});
|
|
1394
1409
|
}
|
|
1410
|
+
function sourceBoost(candidate, currentChannelPrefix) {
|
|
1411
|
+
if (!currentChannelPrefix) {
|
|
1412
|
+
return 0;
|
|
1413
|
+
}
|
|
1414
|
+
return candidate.sourceKey.startsWith(currentChannelPrefix) ? SOURCE_CHANNEL_BOOST : 0;
|
|
1415
|
+
}
|
|
1395
1416
|
function observedAgeBoost(memory, nowMs) {
|
|
1396
1417
|
const ageMs = Math.max(0, nowMs - memory.observedAtMs);
|
|
1397
1418
|
if (ageMs <= 7 * ONE_DAY_MS) {
|
|
@@ -1405,7 +1426,7 @@ function observedAgeBoost(memory, nowMs) {
|
|
|
1405
1426
|
}
|
|
1406
1427
|
return 0;
|
|
1407
1428
|
}
|
|
1408
|
-
function mergeSearchCandidates(candidates, nowMs) {
|
|
1429
|
+
function mergeSearchCandidates(candidates, nowMs, currentChannelKey) {
|
|
1409
1430
|
const byId = /* @__PURE__ */ new Map();
|
|
1410
1431
|
for (const candidate of candidates) {
|
|
1411
1432
|
const existing = byId.get(candidate.memory.id);
|
|
@@ -1415,7 +1436,8 @@ function mergeSearchCandidates(candidates, nowMs) {
|
|
|
1415
1436
|
}
|
|
1416
1437
|
byId.set(candidate.memory.id, {
|
|
1417
1438
|
memory: candidate.memory,
|
|
1418
|
-
score: candidate.score
|
|
1439
|
+
score: candidate.score,
|
|
1440
|
+
sourceKey: candidate.sourceKey
|
|
1419
1441
|
});
|
|
1420
1442
|
}
|
|
1421
1443
|
return [...byId.values()].sort((left, right) => {
|
|
@@ -1423,6 +1445,10 @@ function mergeSearchCandidates(candidates, nowMs) {
|
|
|
1423
1445
|
if (Math.abs(scoreDelta) > RELEVANCE_NEAR_TIE_DELTA) {
|
|
1424
1446
|
return scoreDelta;
|
|
1425
1447
|
}
|
|
1448
|
+
const sourceDelta = sourceBoost(right, currentChannelKey) - sourceBoost(left, currentChannelKey);
|
|
1449
|
+
if (sourceDelta !== 0) {
|
|
1450
|
+
return sourceDelta;
|
|
1451
|
+
}
|
|
1426
1452
|
return observedAgeBoost(right.memory, nowMs) - observedAgeBoost(left.memory, nowMs) || right.memory.observedAtMs - left.memory.observedAtMs || left.memory.id.localeCompare(right.memory.id);
|
|
1427
1453
|
}).map((candidate) => candidate.memory);
|
|
1428
1454
|
}
|
|
@@ -1430,6 +1456,7 @@ function createMemoryStore(db, context, options = {}) {
|
|
|
1430
1456
|
const runtimeContext = memoryRuntimeContextSchema.parse(context);
|
|
1431
1457
|
const parsedOptions = memoryStoreOptionsSchema.parse({ now: options.now });
|
|
1432
1458
|
const embedder = options.embedder;
|
|
1459
|
+
const maxVectorDistance = options.maxVectorDistance;
|
|
1433
1460
|
const supersessionDecider = options.supersessionDecider;
|
|
1434
1461
|
const getNowMs = parsedOptions.now ?? Date.now;
|
|
1435
1462
|
async function archiveExpiredVisibleMemories(input, nowMs) {
|
|
@@ -1681,6 +1708,7 @@ function createMemoryStore(db, context, options = {}) {
|
|
|
1681
1708
|
db,
|
|
1682
1709
|
embedder,
|
|
1683
1710
|
limit: limit * VECTOR_SEARCH_OVERFETCH,
|
|
1711
|
+
...maxVectorDistance !== void 0 ? { maxDistance: maxVectorDistance } : {},
|
|
1684
1712
|
nowMs,
|
|
1685
1713
|
query: input.query,
|
|
1686
1714
|
scopes
|
|
@@ -1692,10 +1720,14 @@ function createMemoryStore(db, context, options = {}) {
|
|
|
1692
1720
|
scopes
|
|
1693
1721
|
});
|
|
1694
1722
|
const terms = searchTerms(input.query);
|
|
1695
|
-
const lexicalCandidates = candidates.map((
|
|
1723
|
+
const lexicalCandidates = candidates.map((candidate) => ({
|
|
1724
|
+
...candidate,
|
|
1725
|
+
score: searchScore(candidate.memory, terms)
|
|
1726
|
+
})).filter((item) => item.score > 0);
|
|
1696
1727
|
return mergeSearchCandidates(
|
|
1697
1728
|
[...vectorCandidates, ...lexicalCandidates],
|
|
1698
|
-
nowMs
|
|
1729
|
+
nowMs,
|
|
1730
|
+
sourceChannelPrefix(runtimeContext)
|
|
1699
1731
|
).slice(0, limit);
|
|
1700
1732
|
},
|
|
1701
1733
|
async archiveMemory(input) {
|
|
@@ -2220,8 +2252,8 @@ async function processMemorySession(context) {
|
|
|
2220
2252
|
|
|
2221
2253
|
// src/recall.ts
|
|
2222
2254
|
var DEFAULT_RECALL_LIMIT = 5;
|
|
2223
|
-
var MAX_PROMPT_CHARS =
|
|
2224
|
-
var MAX_MEMORY_LINE_CHARS =
|
|
2255
|
+
var MAX_PROMPT_CHARS = 4e3;
|
|
2256
|
+
var MAX_MEMORY_LINE_CHARS = 600;
|
|
2225
2257
|
function trimContent(content, maxLength) {
|
|
2226
2258
|
const trimmed = content.trim();
|
|
2227
2259
|
if (trimmed.length <= maxLength) {
|
|
@@ -2268,7 +2300,10 @@ async function createMemoryPromptMessages(context) {
|
|
|
2268
2300
|
const memories = await createMemoryStore(
|
|
2269
2301
|
context.db,
|
|
2270
2302
|
runtimeContext,
|
|
2271
|
-
|
|
2303
|
+
{
|
|
2304
|
+
...context.embedder ? { embedder: context.embedder } : {},
|
|
2305
|
+
...context.maxVectorDistance !== void 0 ? { maxVectorDistance: context.maxVectorDistance } : {}
|
|
2306
|
+
}
|
|
2272
2307
|
).searchMemories({
|
|
2273
2308
|
query: context.text,
|
|
2274
2309
|
limit: DEFAULT_RECALL_LIMIT
|
|
@@ -2279,6 +2314,8 @@ async function createMemoryPromptMessages(context) {
|
|
|
2279
2314
|
|
|
2280
2315
|
// src/plugin.ts
|
|
2281
2316
|
var MEMORY_MODEL_ENV = "AI_MEMORY_MODEL";
|
|
2317
|
+
var MEMORY_RECALL_MAX_VECTOR_DISTANCE_ENV = "MEMORY_RECALL_MAX_VECTOR_DISTANCE";
|
|
2318
|
+
var DEFAULT_RECALL_MAX_VECTOR_DISTANCE = 0.45;
|
|
2282
2319
|
function memoryModelId(options) {
|
|
2283
2320
|
const explicitModelId = options.modelId?.trim();
|
|
2284
2321
|
if (explicitModelId) {
|
|
@@ -2287,6 +2324,19 @@ function memoryModelId(options) {
|
|
|
2287
2324
|
const envModelId = process.env[MEMORY_MODEL_ENV]?.trim();
|
|
2288
2325
|
return envModelId || void 0;
|
|
2289
2326
|
}
|
|
2327
|
+
function recallMaxVectorDistance(options) {
|
|
2328
|
+
if (options.recallMaxVectorDistance !== void 0) {
|
|
2329
|
+
return options.recallMaxVectorDistance;
|
|
2330
|
+
}
|
|
2331
|
+
const raw = process.env[MEMORY_RECALL_MAX_VECTOR_DISTANCE_ENV]?.trim();
|
|
2332
|
+
if (raw) {
|
|
2333
|
+
const parsed = Number(raw);
|
|
2334
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
2335
|
+
return Math.min(parsed, 1);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
return DEFAULT_RECALL_MAX_VECTOR_DISTANCE;
|
|
2339
|
+
}
|
|
2290
2340
|
function memoryToolContext(ctx) {
|
|
2291
2341
|
return {
|
|
2292
2342
|
agent: ctx.agent,
|
|
@@ -2354,6 +2404,7 @@ function createMemoryPlugin(options = {}) {
|
|
|
2354
2404
|
...ctx.requester ? { requester: ctx.requester } : {},
|
|
2355
2405
|
db: ctx.db,
|
|
2356
2406
|
embedder: ctx.embedder,
|
|
2407
|
+
maxVectorDistance: recallMaxVectorDistance(options),
|
|
2357
2408
|
source: ctx.source,
|
|
2358
2409
|
text: ctx.text
|
|
2359
2410
|
});
|