@sentry/junior-memory 0.134.0 → 0.136.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/README.md CHANGED
@@ -71,6 +71,10 @@ exported types, tools, and tests are authoritative.
71
71
  and slightly prefers lexical ranks so exact tokens survive soft semantic
72
72
  neighbors. Vector recall also applies the cosine distance cutoff in SQL, and
73
73
  embeddings use an HNSW cosine index (`vector_cosine_ops`).
74
+ - Automatic recall also runs personal-scope-only vector and lexical probes so
75
+ older actor preferences are not buried when newer workspace conversation
76
+ memories fill the shared lexical recency window with common tokens. On RRF
77
+ score ties, personal-scope matches rank ahead of conversation matches.
74
78
  - Automatic recall retrieves a bounded candidate window, then uses the
75
79
  memory-owned relevance model to admit at most five directly useful memories.
76
80
  An empty result contributes no filler prompt text.
package/dist/api.d.ts CHANGED
@@ -18,6 +18,15 @@ export declare const memoryApiSchema: z.ZodObject<{
18
18
  knowledge: "knowledge";
19
19
  }>;
20
20
  observedAt: z.ZodISODateTime;
21
+ origin: z.ZodEnum<{
22
+ automatic: "automatic";
23
+ explicit: "explicit";
24
+ other: "other";
25
+ }>;
26
+ sourcePlatform: z.ZodEnum<{
27
+ slack: "slack";
28
+ local: "local";
29
+ }>;
21
30
  visibility: z.ZodEnum<{
22
31
  public: "public";
23
32
  private: "private";
@@ -35,6 +44,15 @@ export declare const memoryListResponseSchema: z.ZodObject<{
35
44
  knowledge: "knowledge";
36
45
  }>;
37
46
  observedAt: z.ZodISODateTime;
47
+ origin: z.ZodEnum<{
48
+ automatic: "automatic";
49
+ explicit: "explicit";
50
+ other: "other";
51
+ }>;
52
+ sourcePlatform: z.ZodEnum<{
53
+ slack: "slack";
54
+ local: "local";
55
+ }>;
38
56
  visibility: z.ZodEnum<{
39
57
  public: "public";
40
58
  private: "private";
package/dist/index.js CHANGED
@@ -224,8 +224,8 @@ function rankMemoryMatches(matches, options) {
224
224
  }
225
225
  byId.set(match.memory.id, {
226
226
  ...existing,
227
- ...match.lexical ? { lexical: match.lexical } : {},
228
- ...match.vector ? { vector: match.vector } : {}
227
+ ...!existing.lexical && match.lexical ? { lexical: match.lexical } : {},
228
+ ...!existing.vector && match.vector ? { vector: match.vector } : {}
229
229
  });
230
230
  }
231
231
  return [...byId.values()].sort((left, right) => {
@@ -233,6 +233,10 @@ function rankMemoryMatches(matches, options) {
233
233
  if (scoreDelta !== 0) {
234
234
  return scoreDelta;
235
235
  }
236
+ const personalDelta = Number(right.memory.scope === "personal") - Number(left.memory.scope === "personal");
237
+ if (personalDelta !== 0) {
238
+ return personalDelta;
239
+ }
236
240
  const channelDelta = Number(currentChannel(right, options.channelPrefix)) - Number(currentChannel(left, options.channelPrefix));
237
241
  if (channelDelta !== 0) {
238
242
  return channelDelta;
@@ -981,23 +985,11 @@ async function searchVisibleLexicalMemories(args) {
981
985
  }));
982
986
  }
983
987
  async function searchVisibleVectorMemories(args) {
984
- if (!args.embedder) {
985
- return [];
986
- }
987
988
  const predicate = activeVisiblePredicate(args);
988
989
  if (!predicate) {
989
990
  return [];
990
991
  }
991
- const query = normalizeRetrievalQuery(args.query);
992
- if (!query) {
993
- return [];
994
- }
995
- let embedding;
996
- try {
997
- embedding = await embedOne(args.embedder, query);
998
- } catch {
999
- return [];
1000
- }
992
+ const embedding = args.embedding;
1001
993
  const distance = cosineDistance(
1002
994
  juniorMemoryEmbeddings.embedding,
1003
995
  embedding.vector
@@ -1259,26 +1251,52 @@ function createMemoryStore(db, context, options = {}) {
1259
1251
  const limit = boundedLimit(input.limit, DEFAULT_SEARCH_LIMIT);
1260
1252
  const overfetch = vectorMaxDistance === void 0 ? SEARCH_RETRIEVAL_OVERFETCH : RECALL_RETRIEVAL_OVERFETCH;
1261
1253
  const candidateLimit = retrievalLegLimit(limit, overfetch);
1262
- const [vectorMatches, lexicalMatches] = await Promise.all([
1263
- searchVisibleVectorMemories({
1254
+ const personalScopes = scopes.filter((scope) => scope.scope === "personal");
1255
+ const probePersonal = vectorMaxDistance !== void 0 && personalScopes.length > 0;
1256
+ const query = normalizeRetrievalQuery(input.query);
1257
+ let queryEmbedding;
1258
+ if (embedder && query) {
1259
+ try {
1260
+ queryEmbedding = await embedOne(embedder, query);
1261
+ } catch {
1262
+ queryEmbedding = void 0;
1263
+ }
1264
+ }
1265
+ const emptyMatches = Promise.resolve([]);
1266
+ const lexicalArgs = {
1267
+ db,
1268
+ limit: candidateLimit,
1269
+ nowMs,
1270
+ query: input.query
1271
+ };
1272
+ const matches = await Promise.all([
1273
+ queryEmbedding ? searchVisibleVectorMemories({
1264
1274
  db,
1265
- embedder,
1275
+ embedding: queryEmbedding,
1266
1276
  limit: candidateLimit,
1267
1277
  ...vectorMaxDistance !== void 0 ? { maxDistance: vectorMaxDistance } : {},
1268
1278
  nowMs,
1269
- query: input.query,
1270
1279
  scopes
1271
- }),
1280
+ }) : emptyMatches,
1272
1281
  searchVisibleLexicalMemories({
1282
+ ...lexicalArgs,
1283
+ scopes
1284
+ }),
1285
+ queryEmbedding && probePersonal ? searchVisibleVectorMemories({
1273
1286
  db,
1287
+ embedding: queryEmbedding,
1274
1288
  limit: candidateLimit,
1289
+ maxDistance: vectorMaxDistance,
1275
1290
  nowMs,
1276
- query: input.query,
1277
- scopes
1278
- })
1291
+ scopes: personalScopes
1292
+ }) : emptyMatches,
1293
+ probePersonal ? searchVisibleLexicalMemories({
1294
+ ...lexicalArgs,
1295
+ scopes: personalScopes
1296
+ }) : emptyMatches
1279
1297
  ]);
1280
1298
  const channelPrefix = sourceChannelPrefix(runtimeContext);
1281
- return rankMemoryMatches([...vectorMatches, ...lexicalMatches], {
1299
+ return rankMemoryMatches(matches.flat(), {
1282
1300
  nowMs,
1283
1301
  // Slight lexical preference protects exact ids/names/timezones on ties.
1284
1302
  ...vectorMaxDistance === void 0 ? {} : { lexicalWeight: 1, vectorWeight: 0.85 },
@@ -2195,6 +2213,8 @@ var memoryApiSchema = z6.object({
2195
2213
  id: z6.string().min(1),
2196
2214
  kind: z6.enum(["preference", "procedure", "knowledge"]),
2197
2215
  observedAt: z6.iso.datetime(),
2216
+ origin: z6.enum(["automatic", "explicit", "other"]),
2217
+ sourcePlatform: z6.enum(["local", "slack"]),
2198
2218
  visibility: z6.enum(["private", "public"])
2199
2219
  }).strict();
2200
2220
  var memoryListResponseSchema = z6.object({
@@ -2248,6 +2268,8 @@ function apiMemory(memory) {
2248
2268
  id: memory.id,
2249
2269
  kind: memory.kind,
2250
2270
  observedAt: new Date(memory.observedAtMs).toISOString(),
2271
+ origin: memory.origin,
2272
+ sourcePlatform: memory.sourcePlatform,
2251
2273
  visibility: memory.visibility
2252
2274
  };
2253
2275
  }