@sentry/junior-memory 0.117.0 → 0.118.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
@@ -13,6 +13,8 @@ exported types, tools, and tests are authoritative.
13
13
  learning.
14
14
  - The `memory` CLI namespace provides explicit administrative search and
15
15
  inspection.
16
+ - The dashboard exposes a read-only **Memories** user page for personal
17
+ memories owned by actors linked to the signed-in user.
16
18
 
17
19
  ## Scope And Visibility
18
20
 
package/dist/index.js CHANGED
@@ -949,7 +949,7 @@ function mergeSearchCandidates(candidates, nowMs, currentChannelKey) {
949
949
  }).map((candidate) => candidate.memory);
950
950
  }
951
951
  function createMemoryStore(db, context, options = {}) {
952
- const runtimeContext = memoryRuntimeContextSchema.parse(context);
952
+ const runtimeContext2 = memoryRuntimeContextSchema.parse(context);
953
953
  const parsedOptions = memoryStoreOptionsSchema.parse({ now: options.now });
954
954
  const embedder = options.embedder;
955
955
  const maxVectorDistance = options.maxVectorDistance;
@@ -961,14 +961,14 @@ function createMemoryStore(db, context, options = {}) {
961
961
  db,
962
962
  limit: input.limit,
963
963
  nowMs,
964
- scopes: deriveVisibleMemoryScopes(runtimeContext)
964
+ scopes: deriveVisibleMemoryScopes(runtimeContext2)
965
965
  });
966
966
  }
967
967
  async function reuseDuplicateMemory(args) {
968
968
  await rememberDuplicateIdempotency({
969
969
  ...args,
970
970
  db,
971
- runtimeContext
971
+ runtimeContext: runtimeContext2
972
972
  });
973
973
  await storeEmbedding({
974
974
  content: args.duplicate.content,
@@ -983,8 +983,8 @@ function createMemoryStore(db, context, options = {}) {
983
983
  const input = createMemoryInputSchema.parse(rawInput);
984
984
  const nowMs = getNowMs();
985
985
  const content = normalizeContent(input.content);
986
- const scope = deriveMemoryScope(runtimeContext, scopeKind);
987
- const subject = deriveMemorySubject(runtimeContext, scope);
986
+ const scope = deriveMemoryScope(runtimeContext2, scopeKind);
987
+ const subject = deriveMemorySubject(runtimeContext2, scope);
988
988
  if (content.length > MAX_MEMORY_CONTENT_CHARS) {
989
989
  throw new Error("Memory content exceeds the maximum length.");
990
990
  }
@@ -1075,7 +1075,7 @@ function createMemoryStore(db, context, options = {}) {
1075
1075
  candidates: preferenceCandidates,
1076
1076
  content,
1077
1077
  decider: supersessionDecider,
1078
- runtimeContext
1078
+ runtimeContext: runtimeContext2
1079
1079
  });
1080
1080
  if (adjudication.decision === "duplicate") {
1081
1081
  return await reuseDuplicateMemory({
@@ -1102,8 +1102,8 @@ function createMemoryStore(db, context, options = {}) {
1102
1102
  observedAtMs: nowMs,
1103
1103
  scope: scope.scope,
1104
1104
  scopeKey: scope.scopeKey,
1105
- sourceKey: sourceKey(runtimeContext),
1106
- sourcePlatform: runtimeContext.source.platform,
1105
+ sourceKey: sourceKey(runtimeContext2),
1106
+ sourcePlatform: runtimeContext2.source.platform,
1107
1107
  subjectKey: subject.subjectKey,
1108
1108
  subjectType: subject.subjectType,
1109
1109
  kind: input.kind
@@ -1182,7 +1182,23 @@ function createMemoryStore(db, context, options = {}) {
1182
1182
  async listMemories(input) {
1183
1183
  input = listMemoriesInputSchema.parse(input);
1184
1184
  const nowMs = getNowMs();
1185
- const scopes = deriveVisibleMemoryScopes(runtimeContext);
1185
+ const scopes = deriveVisibleMemoryScopes(runtimeContext2);
1186
+ await archiveExpiredMemoryBatch({
1187
+ db,
1188
+ nowMs,
1189
+ scopes
1190
+ });
1191
+ return await listVisibleMemories({
1192
+ db,
1193
+ limit: input.limit,
1194
+ nowMs,
1195
+ scopes
1196
+ });
1197
+ },
1198
+ async listPersonalMemories(input) {
1199
+ input = listMemoriesInputSchema.parse(input);
1200
+ const nowMs = getNowMs();
1201
+ const scopes = [deriveMemoryScope(runtimeContext2, "personal")];
1186
1202
  await archiveExpiredMemoryBatch({
1187
1203
  db,
1188
1204
  nowMs,
@@ -1198,7 +1214,7 @@ function createMemoryStore(db, context, options = {}) {
1198
1214
  async searchMemories(input) {
1199
1215
  input = searchMemoriesInputSchema.parse(input);
1200
1216
  const nowMs = getNowMs();
1201
- const scopes = deriveVisibleMemoryScopes(runtimeContext);
1217
+ const scopes = deriveVisibleMemoryScopes(runtimeContext2);
1202
1218
  await archiveExpiredMemoryBatch({
1203
1219
  db,
1204
1220
  nowMs,
@@ -1228,13 +1244,13 @@ function createMemoryStore(db, context, options = {}) {
1228
1244
  return mergeSearchCandidates(
1229
1245
  [...vectorCandidates, ...lexicalCandidates],
1230
1246
  nowMs,
1231
- sourceChannelPrefix(runtimeContext)
1247
+ sourceChannelPrefix(runtimeContext2)
1232
1248
  ).slice(0, limit);
1233
1249
  },
1234
1250
  async archiveMemory(input) {
1235
1251
  input = archiveMemoryInputSchema.parse(input);
1236
1252
  const nowMs = getNowMs();
1237
- const scopes = deriveVisibleMemoryScopes(runtimeContext);
1253
+ const scopes = deriveVisibleMemoryScopes(runtimeContext2);
1238
1254
  const predicate = activeVisiblePredicate({ nowMs, scopes });
1239
1255
  const idPrefix = input.id.trim();
1240
1256
  if (!idPrefix) {
@@ -2072,7 +2088,7 @@ function createMemoryCreateTool(context) {
2072
2088
  const parsedInput = parseMemoryToolInput(createMemoryInputSchema2, input);
2073
2089
  const toolCallId = requireToolCallId(options.toolCallId);
2074
2090
  const requestedExpiresAtMs = parseExpiresAt(parsedInput.expires_at);
2075
- const runtimeContext = memoryRuntimeContext(context);
2091
+ const runtimeContext2 = memoryRuntimeContext(context);
2076
2092
  const store = memoryStore(context, {
2077
2093
  supersessionDecider: context.supersessionDecider
2078
2094
  });
@@ -2083,7 +2099,7 @@ function createMemoryCreateTool(context) {
2083
2099
  parseCreateMemoryRequest({
2084
2100
  content: requireMemoryContent(parsedInput.content),
2085
2101
  ...requestedExpiresAtMs !== void 0 ? { expiresAtMs: requestedExpiresAtMs } : {},
2086
- runtimeContext,
2102
+ runtimeContext: runtimeContext2,
2087
2103
  ...context.userText?.trim() ? {
2088
2104
  sourceContext: {
2089
2105
  currentUserText: context.userText.trim()
@@ -2309,13 +2325,13 @@ async function processMemorySession(context) {
2309
2325
  if (!evidenceText) {
2310
2326
  return;
2311
2327
  }
2312
- const runtimeContext = memoryRuntimeContextSchema.parse({
2328
+ const runtimeContext2 = memoryRuntimeContextSchema.parse({
2313
2329
  conversationId: run.conversationId,
2314
2330
  ...run.actor ? { actor: run.actor } : {},
2315
2331
  source: run.source
2316
2332
  });
2317
2333
  const agent = createMemoryAgent(context.model);
2318
- const store = createMemoryStore(context.db, runtimeContext, {
2334
+ const store = createMemoryStore(context.db, runtimeContext2, {
2319
2335
  embedder: context.embedder,
2320
2336
  supersessionDecider: agent
2321
2337
  });
@@ -2331,7 +2347,7 @@ async function processMemorySession(context) {
2331
2347
  })),
2332
2348
  actors: run.actors,
2333
2349
  transcript,
2334
- runtimeContext
2350
+ runtimeContext: runtimeContext2
2335
2351
  });
2336
2352
  });
2337
2353
  if (memories.length === 0) {
@@ -2421,12 +2437,12 @@ async function createMemoryPromptContributions(context) {
2421
2437
  if (!context.text.trim()) {
2422
2438
  return void 0;
2423
2439
  }
2424
- const runtimeContext = memoryRuntimeContextSchema.parse({
2440
+ const runtimeContext2 = memoryRuntimeContextSchema.parse({
2425
2441
  ...context.conversationId ? { conversationId: context.conversationId } : {},
2426
2442
  ...context.actor ? { actor: context.actor } : {},
2427
2443
  source: context.source
2428
2444
  });
2429
- const memories = await createMemoryStore(context.db, runtimeContext, {
2445
+ const memories = await createMemoryStore(context.db, runtimeContext2, {
2430
2446
  ...context.embedder ? { embedder: context.embedder } : {},
2431
2447
  ...context.maxVectorDistance !== void 0 ? { maxVectorDistance: context.maxVectorDistance } : {}
2432
2448
  }).searchMemories({
@@ -2443,6 +2459,79 @@ async function createMemoryPromptContributions(context) {
2443
2459
  return [memoryRecallContext({ memories: selected })];
2444
2460
  }
2445
2461
 
2462
+ // src/user-pages.ts
2463
+ var MEMORY_PAGE_LIMIT = 100;
2464
+ function runtimeContext(actor) {
2465
+ if (actor.platform === "slack") {
2466
+ return {
2467
+ actor,
2468
+ source: {
2469
+ platform: "slack",
2470
+ type: "priv",
2471
+ teamId: actor.teamId,
2472
+ channelId: "DDASHBOARD"
2473
+ }
2474
+ };
2475
+ }
2476
+ return {
2477
+ actor,
2478
+ source: {
2479
+ platform: "local",
2480
+ type: "priv",
2481
+ conversationId: "local:dashboard:memories"
2482
+ }
2483
+ };
2484
+ }
2485
+ function memoryKindLabel(kind) {
2486
+ return kind.charAt(0).toUpperCase() + kind.slice(1);
2487
+ }
2488
+ function rememberedDate(createdAtMs) {
2489
+ return new Intl.DateTimeFormat("en-US", {
2490
+ dateStyle: "medium",
2491
+ timeZone: "UTC"
2492
+ }).format(new Date(createdAtMs));
2493
+ }
2494
+ async function readPersonalMemories(db, actors) {
2495
+ const memories = await Promise.all(
2496
+ actors.flatMap((actor) => {
2497
+ const context = runtimeContext(actor);
2498
+ return context ? [
2499
+ createMemoryStore(db, context).listPersonalMemories({
2500
+ limit: MEMORY_PAGE_LIMIT
2501
+ })
2502
+ ] : [];
2503
+ })
2504
+ );
2505
+ return [
2506
+ ...new Map(memories.flat().map((memory) => [memory.id, memory])).values()
2507
+ ].sort((left, right) => right.createdAtMs - left.createdAtMs).slice(0, MEMORY_PAGE_LIMIT);
2508
+ }
2509
+ function createMemoryUserPage() {
2510
+ return {
2511
+ id: "memories",
2512
+ label: "Memories",
2513
+ description: "Personal facts and preferences Junior remembers about you.",
2514
+ async read(ctx) {
2515
+ const memories = await readPersonalMemories(
2516
+ ctx.db,
2517
+ ctx.viewer.actors
2518
+ );
2519
+ return {
2520
+ type: "list",
2521
+ emptyText: "No personal memories yet.",
2522
+ records: memories.map((memory) => ({
2523
+ id: memory.id,
2524
+ title: memory.content,
2525
+ metadata: [
2526
+ { label: "Type", value: memoryKindLabel(memory.kind) },
2527
+ { label: "Remembered", value: rememberedDate(memory.createdAtMs) }
2528
+ ]
2529
+ }))
2530
+ };
2531
+ }
2532
+ };
2533
+ }
2534
+
2446
2535
  // src/plugin.ts
2447
2536
  var MEMORY_MODEL_ENV = "AI_MEMORY_MODEL";
2448
2537
  var MEMORY_RECALL_MAX_VECTOR_DISTANCE_ENV = "MEMORY_RECALL_MAX_VECTOR_DISTANCE";
@@ -2505,6 +2594,7 @@ function createMemoryPlugin(options = {}) {
2505
2594
  }
2506
2595
  }
2507
2596
  },
2597
+ userPages: [createMemoryUserPage()],
2508
2598
  hooks: {
2509
2599
  tools(ctx) {
2510
2600
  const agent = createMemoryAgent(ctx.model);