@sentry/junior-memory 0.180.0 → 0.181.1

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.
@@ -0,0 +1,415 @@
1
+ {
2
+ "id": "3094a78d-54ba-42dc-926d-7563a6a651bd",
3
+ "prevId": "bf82349c-95b3-4edf-b8a0-2bc597b7c8b4",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.junior_memory_embeddings": {
8
+ "name": "junior_memory_embeddings",
9
+ "schema": "",
10
+ "columns": {
11
+ "memory_id": {
12
+ "name": "memory_id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "provider": {
18
+ "name": "provider",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true
22
+ },
23
+ "model": {
24
+ "name": "model",
25
+ "type": "text",
26
+ "primaryKey": false,
27
+ "notNull": true
28
+ },
29
+ "dimensions": {
30
+ "name": "dimensions",
31
+ "type": "integer",
32
+ "primaryKey": false,
33
+ "notNull": true
34
+ },
35
+ "metric": {
36
+ "name": "metric",
37
+ "type": "text",
38
+ "primaryKey": false,
39
+ "notNull": true
40
+ },
41
+ "content_hash": {
42
+ "name": "content_hash",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": true
46
+ },
47
+ "embedding": {
48
+ "name": "embedding",
49
+ "type": "vector(1536)",
50
+ "primaryKey": false,
51
+ "notNull": true
52
+ },
53
+ "created_at_ms": {
54
+ "name": "created_at_ms",
55
+ "type": "bigint",
56
+ "primaryKey": false,
57
+ "notNull": true
58
+ }
59
+ },
60
+ "indexes": {
61
+ "junior_memory_embeddings_model_idx": {
62
+ "name": "junior_memory_embeddings_model_idx",
63
+ "columns": [
64
+ {
65
+ "expression": "provider",
66
+ "isExpression": false,
67
+ "asc": true,
68
+ "nulls": "last"
69
+ },
70
+ {
71
+ "expression": "model",
72
+ "isExpression": false,
73
+ "asc": true,
74
+ "nulls": "last"
75
+ },
76
+ {
77
+ "expression": "dimensions",
78
+ "isExpression": false,
79
+ "asc": true,
80
+ "nulls": "last"
81
+ },
82
+ {
83
+ "expression": "metric",
84
+ "isExpression": false,
85
+ "asc": true,
86
+ "nulls": "last"
87
+ }
88
+ ],
89
+ "isUnique": false,
90
+ "concurrently": false,
91
+ "method": "btree",
92
+ "with": {}
93
+ },
94
+ "junior_memory_embeddings_embedding_hnsw_idx": {
95
+ "name": "junior_memory_embeddings_embedding_hnsw_idx",
96
+ "columns": [
97
+ {
98
+ "expression": "embedding",
99
+ "isExpression": false,
100
+ "asc": true,
101
+ "nulls": "last",
102
+ "opclass": "vector_cosine_ops"
103
+ }
104
+ ],
105
+ "isUnique": false,
106
+ "concurrently": false,
107
+ "method": "hnsw",
108
+ "with": {
109
+ "m": 16,
110
+ "ef_construction": 64
111
+ }
112
+ }
113
+ },
114
+ "foreignKeys": {
115
+ "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": {
116
+ "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk",
117
+ "tableFrom": "junior_memory_embeddings",
118
+ "tableTo": "junior_memory_memories",
119
+ "columnsFrom": [
120
+ "memory_id"
121
+ ],
122
+ "columnsTo": [
123
+ "id"
124
+ ],
125
+ "onDelete": "cascade",
126
+ "onUpdate": "no action"
127
+ }
128
+ },
129
+ "compositePrimaryKeys": {},
130
+ "uniqueConstraints": {},
131
+ "policies": {},
132
+ "checkConstraints": {
133
+ "junior_memory_embeddings_metric_check": {
134
+ "name": "junior_memory_embeddings_metric_check",
135
+ "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')"
136
+ },
137
+ "junior_memory_embeddings_dimensions_check": {
138
+ "name": "junior_memory_embeddings_dimensions_check",
139
+ "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536"
140
+ }
141
+ },
142
+ "isRLSEnabled": false
143
+ },
144
+ "public.junior_memory_memories": {
145
+ "name": "junior_memory_memories",
146
+ "schema": "",
147
+ "columns": {
148
+ "id": {
149
+ "name": "id",
150
+ "type": "text",
151
+ "primaryKey": true,
152
+ "notNull": true
153
+ },
154
+ "scope": {
155
+ "name": "scope",
156
+ "type": "text",
157
+ "primaryKey": false,
158
+ "notNull": true
159
+ },
160
+ "scope_key": {
161
+ "name": "scope_key",
162
+ "type": "text",
163
+ "primaryKey": false,
164
+ "notNull": true
165
+ },
166
+ "type": {
167
+ "name": "type",
168
+ "type": "text",
169
+ "primaryKey": false,
170
+ "notNull": true
171
+ },
172
+ "subject_type": {
173
+ "name": "subject_type",
174
+ "type": "text",
175
+ "primaryKey": false,
176
+ "notNull": true
177
+ },
178
+ "subject_key": {
179
+ "name": "subject_key",
180
+ "type": "text",
181
+ "primaryKey": false,
182
+ "notNull": false
183
+ },
184
+ "content": {
185
+ "name": "content",
186
+ "type": "text",
187
+ "primaryKey": false,
188
+ "notNull": true
189
+ },
190
+ "search_vector": {
191
+ "name": "search_vector",
192
+ "type": "tsvector",
193
+ "primaryKey": false,
194
+ "notNull": false,
195
+ "generated": {
196
+ "as": "to_tsvector('english', \"content\")",
197
+ "type": "stored"
198
+ }
199
+ },
200
+ "source_platform": {
201
+ "name": "source_platform",
202
+ "type": "text",
203
+ "primaryKey": false,
204
+ "notNull": true
205
+ },
206
+ "source_key": {
207
+ "name": "source_key",
208
+ "type": "text",
209
+ "primaryKey": false,
210
+ "notNull": true
211
+ },
212
+ "location_id": {
213
+ "name": "location_id",
214
+ "type": "text",
215
+ "primaryKey": false,
216
+ "notNull": false
217
+ },
218
+ "idempotency_key": {
219
+ "name": "idempotency_key",
220
+ "type": "text",
221
+ "primaryKey": false,
222
+ "notNull": false
223
+ },
224
+ "observed_at_ms": {
225
+ "name": "observed_at_ms",
226
+ "type": "bigint",
227
+ "primaryKey": false,
228
+ "notNull": true
229
+ },
230
+ "created_at_ms": {
231
+ "name": "created_at_ms",
232
+ "type": "bigint",
233
+ "primaryKey": false,
234
+ "notNull": true
235
+ },
236
+ "expires_at_ms": {
237
+ "name": "expires_at_ms",
238
+ "type": "bigint",
239
+ "primaryKey": false,
240
+ "notNull": false
241
+ },
242
+ "superseded_at_ms": {
243
+ "name": "superseded_at_ms",
244
+ "type": "bigint",
245
+ "primaryKey": false,
246
+ "notNull": false
247
+ },
248
+ "superseded_by_id": {
249
+ "name": "superseded_by_id",
250
+ "type": "text",
251
+ "primaryKey": false,
252
+ "notNull": false
253
+ },
254
+ "archived_at_ms": {
255
+ "name": "archived_at_ms",
256
+ "type": "bigint",
257
+ "primaryKey": false,
258
+ "notNull": false
259
+ },
260
+ "archive_reason": {
261
+ "name": "archive_reason",
262
+ "type": "text",
263
+ "primaryKey": false,
264
+ "notNull": false
265
+ }
266
+ },
267
+ "indexes": {
268
+ "junior_memory_memories_visible_idx": {
269
+ "name": "junior_memory_memories_visible_idx",
270
+ "columns": [
271
+ {
272
+ "expression": "scope",
273
+ "isExpression": false,
274
+ "asc": true,
275
+ "nulls": "last"
276
+ },
277
+ {
278
+ "expression": "scope_key",
279
+ "isExpression": false,
280
+ "asc": true,
281
+ "nulls": "last"
282
+ },
283
+ {
284
+ "expression": "created_at_ms",
285
+ "isExpression": false,
286
+ "asc": false,
287
+ "nulls": "last"
288
+ },
289
+ {
290
+ "expression": "id",
291
+ "isExpression": false,
292
+ "asc": true,
293
+ "nulls": "last"
294
+ }
295
+ ],
296
+ "isUnique": false,
297
+ "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL",
298
+ "concurrently": false,
299
+ "method": "btree",
300
+ "with": {}
301
+ },
302
+ "junior_memory_memories_expiration_idx": {
303
+ "name": "junior_memory_memories_expiration_idx",
304
+ "columns": [
305
+ {
306
+ "expression": "expires_at_ms",
307
+ "isExpression": false,
308
+ "asc": true,
309
+ "nulls": "last"
310
+ }
311
+ ],
312
+ "isUnique": false,
313
+ "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL",
314
+ "concurrently": false,
315
+ "method": "btree",
316
+ "with": {}
317
+ },
318
+ "junior_memory_memories_search_idx": {
319
+ "name": "junior_memory_memories_search_idx",
320
+ "columns": [
321
+ {
322
+ "expression": "scope",
323
+ "isExpression": false,
324
+ "asc": true,
325
+ "nulls": "last"
326
+ },
327
+ {
328
+ "expression": "scope_key",
329
+ "isExpression": false,
330
+ "asc": true,
331
+ "nulls": "last"
332
+ },
333
+ {
334
+ "expression": "search_vector",
335
+ "isExpression": false,
336
+ "asc": true,
337
+ "nulls": "last"
338
+ }
339
+ ],
340
+ "isUnique": false,
341
+ "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL",
342
+ "concurrently": false,
343
+ "method": "gin",
344
+ "with": {}
345
+ },
346
+ "junior_memory_memories_idempotency_idx": {
347
+ "name": "junior_memory_memories_idempotency_idx",
348
+ "columns": [
349
+ {
350
+ "expression": "scope",
351
+ "isExpression": false,
352
+ "asc": true,
353
+ "nulls": "last"
354
+ },
355
+ {
356
+ "expression": "scope_key",
357
+ "isExpression": false,
358
+ "asc": true,
359
+ "nulls": "last"
360
+ },
361
+ {
362
+ "expression": "idempotency_key",
363
+ "isExpression": false,
364
+ "asc": true,
365
+ "nulls": "last"
366
+ }
367
+ ],
368
+ "isUnique": true,
369
+ "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL",
370
+ "concurrently": false,
371
+ "method": "btree",
372
+ "with": {}
373
+ }
374
+ },
375
+ "foreignKeys": {},
376
+ "compositePrimaryKeys": {},
377
+ "uniqueConstraints": {},
378
+ "policies": {},
379
+ "checkConstraints": {
380
+ "junior_memory_memories_scope_check": {
381
+ "name": "junior_memory_memories_scope_check",
382
+ "value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')"
383
+ },
384
+ "junior_memory_memories_kind_check": {
385
+ "name": "junior_memory_memories_kind_check",
386
+ "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )"
387
+ },
388
+ "junior_memory_memories_subject_type_check": {
389
+ "name": "junior_memory_memories_subject_type_check",
390
+ "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')"
391
+ },
392
+ "junior_memory_memories_subject_key_check": {
393
+ "name": "junior_memory_memories_subject_key_check",
394
+ "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)"
395
+ },
396
+ "junior_memory_memories_source_platform_check": {
397
+ "name": "junior_memory_memories_source_platform_check",
398
+ "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')"
399
+ }
400
+ },
401
+ "isRLSEnabled": false
402
+ }
403
+ },
404
+ "enums": {},
405
+ "schemas": {},
406
+ "sequences": {},
407
+ "roles": {},
408
+ "policies": {},
409
+ "views": {},
410
+ "_meta": {
411
+ "columns": {},
412
+ "schemas": {},
413
+ "tables": {}
414
+ }
415
+ }
@@ -64,6 +64,20 @@
64
64
  "when": 1786345372977,
65
65
  "tag": "0008_web_memory_source_platform",
66
66
  "breakpoints": true
67
+ },
68
+ {
69
+ "idx": 9,
70
+ "version": "7",
71
+ "when": 1787417688130,
72
+ "tag": "0009_faithful_whizzer",
73
+ "breakpoints": true
74
+ },
75
+ {
76
+ "idx": 10,
77
+ "version": "7",
78
+ "when": 1787458882949,
79
+ "tag": "0010_memories_captured_scope_labels",
80
+ "breakpoints": true
67
81
  }
68
82
  ]
69
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-memory",
3
- "version": "0.180.0",
3
+ "version": "0.181.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,7 +27,7 @@
27
27
  "commander": "^14.0.3",
28
28
  "drizzle-orm": "^0.45.2",
29
29
  "zod": "^4.4.3",
30
- "@sentry/junior-plugin-api": "0.180.0"
30
+ "@sentry/junior-plugin-api": "0.181.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@oxlint/plugins": "1.79.0",
package/src/agent.ts CHANGED
@@ -187,7 +187,7 @@ const extractMemoriesResponseSchema = z
187
187
  .array(extractedMemorySchema)
188
188
  .max(5)
189
189
  .describe(
190
- "Accepted public/shareable durable memories from the completed run. Return one object per distinct source assertion and classify it with kind.",
190
+ "Accepted durable memories from the completed run. Return one object per distinct source assertion and classify it with kind.",
191
191
  ),
192
192
  })
193
193
  .strict();
@@ -235,7 +235,7 @@ export interface MemoryAgent {
235
235
  const MEMORY_REVIEW_SYSTEM = [
236
236
  "You are Junior's memory review agent.",
237
237
  "Review one memory candidate and return one structured review decision.",
238
- "Store only public/shareable, self-contained facts that are useful beyond this turn.",
238
+ "Store only self-contained facts that are useful beyond this turn and safe for the current Source.",
239
239
  "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.",
240
240
  "Use the runtime context only for authority and scope; do not accept model-provided actor ids, scope ids, aliases, or arbitrary subjects.",
241
241
  ].join("\n");
@@ -244,7 +244,7 @@ const MEMORY_EXTRACTION_SYSTEM = [
244
244
  "Use the completed run transcript as source evidence, including user-authored messages and tool results.",
245
245
  "Assistant text is context for interpreting the run, not independent evidence for new facts.",
246
246
  "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.",
247
- "If no public, durable, self-contained memory remains after rewriting, return an empty memories array.",
247
+ "If no durable, self-contained memory remains after rewriting, return an empty memories array.",
248
248
  ].join("\n");
249
249
  const MEMORY_RECALL_SYSTEM = [
250
250
  "You are Junior's memory recall relevance agent.",
@@ -277,9 +277,7 @@ function escapeXml(value: string): string {
277
277
  .replaceAll(">", ">");
278
278
  }
279
279
 
280
- function actorLabel(
281
- actor: z.output<typeof actorSchema> | undefined,
282
- ): string {
280
+ function actorLabel(actor: z.output<typeof actorSchema> | undefined): string {
283
281
  if (!actor) {
284
282
  return "none";
285
283
  }
@@ -351,7 +349,7 @@ function existingMemoriesContext(request: ExtractSessionRequest): string {
351
349
 
352
350
  /**
353
351
  * Passive extraction offers personal preferences only on single-actor runs.
354
- * Multi-actor runs restrict extraction to conversation-scoped kinds.
352
+ * Multi-actor runs restrict extraction to conversation-subject kinds.
355
353
  */
356
354
  function allowedExtractionKinds(actorCount: number): Set<MemoryKind> {
357
355
  return actorCount === 1
@@ -388,7 +386,7 @@ function reviewPrompt(request: CreateMemoryRequest): string {
388
386
  "</candidate>",
389
387
  "",
390
388
  "<rules>",
391
- "- Return store only when the candidate is public/shareable, durable, and self-contained.",
389
+ "- Return store only when the candidate is durable, self-contained, and safe for the current Source.",
392
390
  "- First classify the memory kind: preference, procedure, or knowledge.",
393
391
  "- Use kind=preference only for first-person facts authored by the current actor about their own preference, opinion, habit, identity, or workflow.",
394
392
  "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current actor.",
package/src/api.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Authenticated REST resources for viewer-visible memories.
2
+ * Authenticated REST access to memory.
3
3
  *
4
- * HTTP identity is one verified user whose linked identities authorize
5
- * personal and public workspace scopes.
4
+ * The signed-in User can read public memory and private memory that they own.
6
5
  */
7
6
  import { z } from "zod";
8
7
  import {
@@ -13,11 +12,15 @@ import {
13
12
  } from "@sentry/junior-plugin-api";
14
13
  import type { MemoryDb } from "./store";
15
14
  import {
16
- createViewerMemories,
15
+ archiveMemory,
16
+ getMemory,
17
+ getMemoryStats,
18
+ getMemoryTimeline,
17
19
  InvalidMemoryCursorError,
18
- PersonalMemoryNotFoundError,
19
- type PersonalMemoryRecord,
20
- } from "./personal";
20
+ listMemories,
21
+ MemoryNotFoundError,
22
+ type MemoryView,
23
+ } from "./viewer";
21
24
  import { MEMORY_SOURCE_PLATFORMS } from "./types";
22
25
 
23
26
  export const memoryApiSchema = z
@@ -109,9 +112,7 @@ function json(body: unknown, status = 200): Response {
109
112
  });
110
113
  }
111
114
 
112
- function apiMemory(
113
- memory: PersonalMemoryRecord,
114
- ): z.output<typeof memoryApiSchema> {
115
+ function apiMemory(memory: MemoryView): z.output<typeof memoryApiSchema> {
115
116
  return {
116
117
  content: memory.content,
117
118
  createdAt: new Date(memory.createdAtMs).toISOString(),
@@ -135,7 +136,7 @@ function viewerEmail(context: unknown): string | undefined {
135
136
  return parsed.data.auth.user.email?.trim().toLowerCase() || undefined;
136
137
  }
137
138
 
138
- /** Create the authenticated viewer-memory REST app. */
139
+ /** Create the authenticated memory REST app. */
139
140
  export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
140
141
  return {
141
142
  async fetch(request, context) {
@@ -156,15 +157,15 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
156
157
  return json({ error: "Method not allowed." }, 405);
157
158
  }
158
159
 
159
- const user = await options.users.resolve(email);
160
- if (!user) return json({ error: "Authentication required." }, 401);
160
+ const viewer = await options.users.resolve(email);
161
+ if (!viewer) return json({ error: "Authentication required." }, 401);
162
+ const userId = viewer.id;
161
163
 
162
- const memories = createViewerMemories(options.db, user);
163
164
  try {
164
165
  if (isDashboard && isRead) {
165
166
  const [stats, days, extractionDays, recallDays] = await Promise.all([
166
- memories.stats(),
167
- memories.timeline({ days: 90 }),
167
+ getMemoryStats(options.db, userId),
168
+ getMemoryTimeline(options.db, userId, 90),
168
169
  options.eventStats.costsByDay({
169
170
  days: 90,
170
171
  eventName: "memories_captured",
@@ -174,12 +175,16 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
174
175
  eventName: "memories_recalled",
175
176
  }),
176
177
  ]);
178
+ const { private: personal, ...dashboardStats } = stats;
177
179
  const body = memoryDashboardResponseSchema.parse({
178
- days,
180
+ days: days.map(({ private: personal, ...day }) => ({
181
+ ...day,
182
+ personal,
183
+ })),
179
184
  extractionDays,
180
185
  generatedAt: new Date().toISOString(),
181
186
  recallDays,
182
- stats,
187
+ stats: { ...dashboardStats, personal },
183
188
  });
184
189
  return request.method === "HEAD"
185
190
  ? new Response(null, {
@@ -195,7 +200,7 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
195
200
  limit: url.searchParams.get("limit") ?? undefined,
196
201
  q: url.searchParams.get("q") ?? undefined,
197
202
  });
198
- const page = await memories.list({
203
+ const page = await listMemories(options.db, userId, {
199
204
  cursor: query.cursor,
200
205
  limit: query.limit,
201
206
  ...(query.q ? { query: query.q } : undefined),
@@ -213,19 +218,23 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
213
218
  }
214
219
 
215
220
  if (memoryPath && isRead) {
216
- const memory = memoryApiSchema.parse(
217
- apiMemory(await memories.get(decodeURIComponent(memoryPath[1]!))),
221
+ const memory = await getMemory(
222
+ options.db,
223
+ userId,
224
+ decodeURIComponent(memoryPath[1]!),
218
225
  );
226
+ const body = memoryApiSchema.parse(apiMemory(memory));
219
227
  return request.method === "HEAD"
220
228
  ? new Response(null, {
221
229
  headers: { "cache-control": "no-store" },
222
230
  status: 200,
223
231
  })
224
- : json(memory);
232
+ : json(body);
225
233
  }
226
234
 
227
235
  if (memoryPath && request.method === "DELETE") {
228
- await memories.archive(decodeURIComponent(memoryPath[1]!));
236
+ const id = decodeURIComponent(memoryPath[1]!);
237
+ await archiveMemory(options.db, userId, id);
229
238
  return new Response(null, {
230
239
  headers: { "cache-control": "no-store" },
231
240
  status: 204,
@@ -238,7 +247,7 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
238
247
  ) {
239
248
  return json({ error: "Invalid memory request." }, 400);
240
249
  }
241
- if (error instanceof PersonalMemoryNotFoundError) {
250
+ if (error instanceof MemoryNotFoundError) {
242
251
  return json({ error: error.message }, 404);
243
252
  }
244
253
  throw error;
package/src/db/schema.ts CHANGED
@@ -48,6 +48,8 @@ export const juniorMemoryMemories = pgTable(
48
48
  enum: MEMORY_SOURCE_PLATFORMS,
49
49
  }).notNull(),
50
50
  sourceKey: text("source_key").notNull(),
51
+ /** Location where Junior learned the memory, when known. */
52
+ locationId: text("location_id"),
51
53
  idempotencyKey: text("idempotency_key"),
52
54
  observedAtMs: bigint("observed_at_ms", { mode: "number" }).notNull(),
53
55
  createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
@@ -80,7 +82,7 @@ export const juniorMemoryMemories = pgTable(
80
82
  ),
81
83
  check(
82
84
  "junior_memory_memories_scope_check",
83
- sql`${table.scope} IN ('personal', 'conversation')`,
85
+ sql`${table.scope} IN ('private', 'public')`,
84
86
  ),
85
87
  check(
86
88
  "junior_memory_memories_kind_check",