@sentry/junior-memory 0.180.0 → 0.181.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 +25 -24
- package/dist/agent.d.ts +4 -0
- package/dist/api.d.ts +3 -4
- package/dist/db/schema.d.ts +19 -2
- package/dist/events.d.ts +3 -3
- package/dist/index.js +487 -666
- package/dist/index.js.map +1 -1
- package/dist/process-session.d.ts +3 -4
- package/dist/ranking.d.ts +0 -2
- package/dist/recall.d.ts +9 -2
- package/dist/scope.d.ts +11 -15
- package/dist/store.d.ts +6 -7
- package/dist/tools.d.ts +8 -1
- package/dist/types.d.ts +4 -2
- package/dist/user-pages.d.ts +1 -1
- package/dist/viewer.d.ts +85 -0
- package/migrations/0009_faithful_whizzer.sql +114 -0
- package/migrations/meta/0009_snapshot.json +411 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +2 -2
- package/src/agent.ts +6 -8
- package/src/api.ts +33 -24
- package/src/db/schema.ts +3 -1
- package/src/events.ts +30 -8
- package/src/operational-report.ts +20 -20
- package/src/plugin.ts +13 -1
- package/src/process-session.ts +21 -35
- package/src/ranking.ts +9 -26
- package/src/recall.ts +11 -1
- package/src/scope.ts +34 -135
- package/src/store.ts +34 -91
- package/src/tools.ts +30 -14
- package/src/types.ts +5 -2
- package/src/user-pages.ts +4 -6
- package/src/viewer.ts +393 -0
- package/dist/personal-store.d.ts +0 -92
- package/dist/personal.d.ts +0 -31
- package/src/personal-store.ts +0 -421
- package/src/personal.ts +0 -140
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "bf82349c-95b3-4edf-b8a0-2bc597b7c8b4",
|
|
3
|
+
"prevId": "030f5fc1-7062-4287-bd0b-14fcfd1c6a65",
|
|
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": ["memory_id"],
|
|
120
|
+
"columnsTo": ["id"],
|
|
121
|
+
"onDelete": "cascade",
|
|
122
|
+
"onUpdate": "no action"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"compositePrimaryKeys": {},
|
|
126
|
+
"uniqueConstraints": {},
|
|
127
|
+
"policies": {},
|
|
128
|
+
"checkConstraints": {
|
|
129
|
+
"junior_memory_embeddings_metric_check": {
|
|
130
|
+
"name": "junior_memory_embeddings_metric_check",
|
|
131
|
+
"value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')"
|
|
132
|
+
},
|
|
133
|
+
"junior_memory_embeddings_dimensions_check": {
|
|
134
|
+
"name": "junior_memory_embeddings_dimensions_check",
|
|
135
|
+
"value": "\"junior_memory_embeddings\".\"dimensions\" = 1536"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"isRLSEnabled": false
|
|
139
|
+
},
|
|
140
|
+
"public.junior_memory_memories": {
|
|
141
|
+
"name": "junior_memory_memories",
|
|
142
|
+
"schema": "",
|
|
143
|
+
"columns": {
|
|
144
|
+
"id": {
|
|
145
|
+
"name": "id",
|
|
146
|
+
"type": "text",
|
|
147
|
+
"primaryKey": true,
|
|
148
|
+
"notNull": true
|
|
149
|
+
},
|
|
150
|
+
"scope": {
|
|
151
|
+
"name": "scope",
|
|
152
|
+
"type": "text",
|
|
153
|
+
"primaryKey": false,
|
|
154
|
+
"notNull": true
|
|
155
|
+
},
|
|
156
|
+
"scope_key": {
|
|
157
|
+
"name": "scope_key",
|
|
158
|
+
"type": "text",
|
|
159
|
+
"primaryKey": false,
|
|
160
|
+
"notNull": true
|
|
161
|
+
},
|
|
162
|
+
"type": {
|
|
163
|
+
"name": "type",
|
|
164
|
+
"type": "text",
|
|
165
|
+
"primaryKey": false,
|
|
166
|
+
"notNull": true
|
|
167
|
+
},
|
|
168
|
+
"subject_type": {
|
|
169
|
+
"name": "subject_type",
|
|
170
|
+
"type": "text",
|
|
171
|
+
"primaryKey": false,
|
|
172
|
+
"notNull": true
|
|
173
|
+
},
|
|
174
|
+
"subject_key": {
|
|
175
|
+
"name": "subject_key",
|
|
176
|
+
"type": "text",
|
|
177
|
+
"primaryKey": false,
|
|
178
|
+
"notNull": false
|
|
179
|
+
},
|
|
180
|
+
"content": {
|
|
181
|
+
"name": "content",
|
|
182
|
+
"type": "text",
|
|
183
|
+
"primaryKey": false,
|
|
184
|
+
"notNull": true
|
|
185
|
+
},
|
|
186
|
+
"search_vector": {
|
|
187
|
+
"name": "search_vector",
|
|
188
|
+
"type": "tsvector",
|
|
189
|
+
"primaryKey": false,
|
|
190
|
+
"notNull": false,
|
|
191
|
+
"generated": {
|
|
192
|
+
"as": "to_tsvector('english', \"content\")",
|
|
193
|
+
"type": "stored"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"source_platform": {
|
|
197
|
+
"name": "source_platform",
|
|
198
|
+
"type": "text",
|
|
199
|
+
"primaryKey": false,
|
|
200
|
+
"notNull": true
|
|
201
|
+
},
|
|
202
|
+
"source_key": {
|
|
203
|
+
"name": "source_key",
|
|
204
|
+
"type": "text",
|
|
205
|
+
"primaryKey": false,
|
|
206
|
+
"notNull": true
|
|
207
|
+
},
|
|
208
|
+
"location_id": {
|
|
209
|
+
"name": "location_id",
|
|
210
|
+
"type": "text",
|
|
211
|
+
"primaryKey": false,
|
|
212
|
+
"notNull": false
|
|
213
|
+
},
|
|
214
|
+
"idempotency_key": {
|
|
215
|
+
"name": "idempotency_key",
|
|
216
|
+
"type": "text",
|
|
217
|
+
"primaryKey": false,
|
|
218
|
+
"notNull": false
|
|
219
|
+
},
|
|
220
|
+
"observed_at_ms": {
|
|
221
|
+
"name": "observed_at_ms",
|
|
222
|
+
"type": "bigint",
|
|
223
|
+
"primaryKey": false,
|
|
224
|
+
"notNull": true
|
|
225
|
+
},
|
|
226
|
+
"created_at_ms": {
|
|
227
|
+
"name": "created_at_ms",
|
|
228
|
+
"type": "bigint",
|
|
229
|
+
"primaryKey": false,
|
|
230
|
+
"notNull": true
|
|
231
|
+
},
|
|
232
|
+
"expires_at_ms": {
|
|
233
|
+
"name": "expires_at_ms",
|
|
234
|
+
"type": "bigint",
|
|
235
|
+
"primaryKey": false,
|
|
236
|
+
"notNull": false
|
|
237
|
+
},
|
|
238
|
+
"superseded_at_ms": {
|
|
239
|
+
"name": "superseded_at_ms",
|
|
240
|
+
"type": "bigint",
|
|
241
|
+
"primaryKey": false,
|
|
242
|
+
"notNull": false
|
|
243
|
+
},
|
|
244
|
+
"superseded_by_id": {
|
|
245
|
+
"name": "superseded_by_id",
|
|
246
|
+
"type": "text",
|
|
247
|
+
"primaryKey": false,
|
|
248
|
+
"notNull": false
|
|
249
|
+
},
|
|
250
|
+
"archived_at_ms": {
|
|
251
|
+
"name": "archived_at_ms",
|
|
252
|
+
"type": "bigint",
|
|
253
|
+
"primaryKey": false,
|
|
254
|
+
"notNull": false
|
|
255
|
+
},
|
|
256
|
+
"archive_reason": {
|
|
257
|
+
"name": "archive_reason",
|
|
258
|
+
"type": "text",
|
|
259
|
+
"primaryKey": false,
|
|
260
|
+
"notNull": false
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"indexes": {
|
|
264
|
+
"junior_memory_memories_visible_idx": {
|
|
265
|
+
"name": "junior_memory_memories_visible_idx",
|
|
266
|
+
"columns": [
|
|
267
|
+
{
|
|
268
|
+
"expression": "scope",
|
|
269
|
+
"isExpression": false,
|
|
270
|
+
"asc": true,
|
|
271
|
+
"nulls": "last"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"expression": "scope_key",
|
|
275
|
+
"isExpression": false,
|
|
276
|
+
"asc": true,
|
|
277
|
+
"nulls": "last"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"expression": "created_at_ms",
|
|
281
|
+
"isExpression": false,
|
|
282
|
+
"asc": false,
|
|
283
|
+
"nulls": "last"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"expression": "id",
|
|
287
|
+
"isExpression": false,
|
|
288
|
+
"asc": true,
|
|
289
|
+
"nulls": "last"
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
"isUnique": false,
|
|
293
|
+
"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",
|
|
294
|
+
"concurrently": false,
|
|
295
|
+
"method": "btree",
|
|
296
|
+
"with": {}
|
|
297
|
+
},
|
|
298
|
+
"junior_memory_memories_expiration_idx": {
|
|
299
|
+
"name": "junior_memory_memories_expiration_idx",
|
|
300
|
+
"columns": [
|
|
301
|
+
{
|
|
302
|
+
"expression": "expires_at_ms",
|
|
303
|
+
"isExpression": false,
|
|
304
|
+
"asc": true,
|
|
305
|
+
"nulls": "last"
|
|
306
|
+
}
|
|
307
|
+
],
|
|
308
|
+
"isUnique": false,
|
|
309
|
+
"where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL",
|
|
310
|
+
"concurrently": false,
|
|
311
|
+
"method": "btree",
|
|
312
|
+
"with": {}
|
|
313
|
+
},
|
|
314
|
+
"junior_memory_memories_search_idx": {
|
|
315
|
+
"name": "junior_memory_memories_search_idx",
|
|
316
|
+
"columns": [
|
|
317
|
+
{
|
|
318
|
+
"expression": "scope",
|
|
319
|
+
"isExpression": false,
|
|
320
|
+
"asc": true,
|
|
321
|
+
"nulls": "last"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"expression": "scope_key",
|
|
325
|
+
"isExpression": false,
|
|
326
|
+
"asc": true,
|
|
327
|
+
"nulls": "last"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"expression": "search_vector",
|
|
331
|
+
"isExpression": false,
|
|
332
|
+
"asc": true,
|
|
333
|
+
"nulls": "last"
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
"isUnique": false,
|
|
337
|
+
"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",
|
|
338
|
+
"concurrently": false,
|
|
339
|
+
"method": "gin",
|
|
340
|
+
"with": {}
|
|
341
|
+
},
|
|
342
|
+
"junior_memory_memories_idempotency_idx": {
|
|
343
|
+
"name": "junior_memory_memories_idempotency_idx",
|
|
344
|
+
"columns": [
|
|
345
|
+
{
|
|
346
|
+
"expression": "scope",
|
|
347
|
+
"isExpression": false,
|
|
348
|
+
"asc": true,
|
|
349
|
+
"nulls": "last"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"expression": "scope_key",
|
|
353
|
+
"isExpression": false,
|
|
354
|
+
"asc": true,
|
|
355
|
+
"nulls": "last"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"expression": "idempotency_key",
|
|
359
|
+
"isExpression": false,
|
|
360
|
+
"asc": true,
|
|
361
|
+
"nulls": "last"
|
|
362
|
+
}
|
|
363
|
+
],
|
|
364
|
+
"isUnique": true,
|
|
365
|
+
"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",
|
|
366
|
+
"concurrently": false,
|
|
367
|
+
"method": "btree",
|
|
368
|
+
"with": {}
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"foreignKeys": {},
|
|
372
|
+
"compositePrimaryKeys": {},
|
|
373
|
+
"uniqueConstraints": {},
|
|
374
|
+
"policies": {},
|
|
375
|
+
"checkConstraints": {
|
|
376
|
+
"junior_memory_memories_scope_check": {
|
|
377
|
+
"name": "junior_memory_memories_scope_check",
|
|
378
|
+
"value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')"
|
|
379
|
+
},
|
|
380
|
+
"junior_memory_memories_kind_check": {
|
|
381
|
+
"name": "junior_memory_memories_kind_check",
|
|
382
|
+
"value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )"
|
|
383
|
+
},
|
|
384
|
+
"junior_memory_memories_subject_type_check": {
|
|
385
|
+
"name": "junior_memory_memories_subject_type_check",
|
|
386
|
+
"value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')"
|
|
387
|
+
},
|
|
388
|
+
"junior_memory_memories_subject_key_check": {
|
|
389
|
+
"name": "junior_memory_memories_subject_key_check",
|
|
390
|
+
"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)"
|
|
391
|
+
},
|
|
392
|
+
"junior_memory_memories_source_platform_check": {
|
|
393
|
+
"name": "junior_memory_memories_source_platform_check",
|
|
394
|
+
"value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')"
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"isRLSEnabled": false
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
"enums": {},
|
|
401
|
+
"schemas": {},
|
|
402
|
+
"sequences": {},
|
|
403
|
+
"roles": {},
|
|
404
|
+
"policies": {},
|
|
405
|
+
"views": {},
|
|
406
|
+
"_meta": {
|
|
407
|
+
"columns": {},
|
|
408
|
+
"schemas": {},
|
|
409
|
+
"tables": {}
|
|
410
|
+
}
|
|
411
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.181.0",
|
|
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.
|
|
30
|
+
"@sentry/junior-plugin-api": "0.181.0"
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
2
|
+
* Authenticated REST access to memory.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
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
|
-
|
|
15
|
+
archiveMemory,
|
|
16
|
+
getMemory,
|
|
17
|
+
getMemoryStats,
|
|
18
|
+
getMemoryTimeline,
|
|
17
19
|
InvalidMemoryCursorError,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
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
|
|
160
|
-
if (!
|
|
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
|
-
|
|
167
|
-
|
|
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
|
|
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 =
|
|
217
|
-
|
|
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(
|
|
232
|
+
: json(body);
|
|
225
233
|
}
|
|
226
234
|
|
|
227
235
|
if (memoryPath && request.method === "DELETE") {
|
|
228
|
-
|
|
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
|
|
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 ('
|
|
85
|
+
sql`${table.scope} IN ('private', 'public')`,
|
|
84
86
|
),
|
|
85
87
|
check(
|
|
86
88
|
"junior_memory_memories_kind_check",
|