@sentry/junior-memory 0.81.0 → 0.82.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 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(parseMemoryRow);
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((memory) => ({ memory, score: searchScore(memory, terms) })).filter((item) => item.score > 0);
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 = 1600;
2224
- var MAX_MEMORY_LINE_CHARS = 320;
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
- context.embedder ? { embedder: context.embedder } : {}
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
  });