@sentry/junior-memory 0.191.0 → 0.193.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/store.d.ts CHANGED
@@ -118,6 +118,14 @@ export declare const memorySupersessionInputSchema: z.ZodObject<{
118
118
  eventType: z.ZodString;
119
119
  identifier: z.ZodString;
120
120
  namespace: z.ZodString;
121
+ }, z.core.$strict>, z.ZodObject<{
122
+ kind: z.ZodLiteral<"scheduled_task">;
123
+ }, z.core.$strict>, z.ZodObject<{
124
+ kind: z.ZodLiteral<"event_task">;
125
+ }, z.core.$strict>, z.ZodObject<{
126
+ kind: z.ZodLiteral<"plugin_dispatch">;
127
+ }, z.core.$strict>, z.ZodObject<{
128
+ kind: z.ZodLiteral<"agent_invocation">;
121
129
  }, z.core.$strict>], "kind">, unknown>;
122
130
  userId: z.ZodOptional<z.ZodString>;
123
131
  }, z.core.$strict>;
package/dist/types.d.ts CHANGED
@@ -64,6 +64,14 @@ export declare const memoryRuntimeContextSchema: z.ZodObject<{
64
64
  eventType: z.ZodString;
65
65
  identifier: z.ZodString;
66
66
  namespace: z.ZodString;
67
+ }, z.core.$strict>, z.ZodObject<{
68
+ kind: z.ZodLiteral<"scheduled_task">;
69
+ }, z.core.$strict>, z.ZodObject<{
70
+ kind: z.ZodLiteral<"event_task">;
71
+ }, z.core.$strict>, z.ZodObject<{
72
+ kind: z.ZodLiteral<"plugin_dispatch">;
73
+ }, z.core.$strict>, z.ZodObject<{
74
+ kind: z.ZodLiteral<"agent_invocation">;
67
75
  }, z.core.$strict>], "kind">, unknown>;
68
76
  userId: z.ZodOptional<z.ZodString>;
69
77
  }, z.core.$strict>;
package/dist/viewer.d.ts CHANGED
@@ -82,4 +82,10 @@ export declare function getMemoryTimeline(db: MemoryDb, userId: string, days: nu
82
82
  private: number;
83
83
  public: number;
84
84
  }[]>;
85
+ /** Read hourly memory creation totals visible to the authenticated User in UTC. */
86
+ export declare function getMemoryTimelineHours(db: MemoryDb, userId: string, hours?: number): Promise<{
87
+ date: string;
88
+ private: number;
89
+ public: number;
90
+ }[]>;
85
91
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-memory",
3
- "version": "0.191.0",
3
+ "version": "0.193.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.5.4",
30
- "@sentry/junior-plugin-api": "0.191.0"
30
+ "@sentry/junior-plugin-api": "0.193.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@oxlint/plugins": "1.79.0",
package/src/agent.ts CHANGED
@@ -302,6 +302,11 @@ function sourceLabel(source: z.output<typeof sourceSchema>): string {
302
302
  return `${source.kind}:${source.conversationId}`;
303
303
  case "resource_event":
304
304
  return `resource-event:${source.namespace}:${source.eventKey}`;
305
+ case "scheduled_task":
306
+ case "event_task":
307
+ case "plugin_dispatch":
308
+ case "agent_invocation":
309
+ return source.kind;
305
310
  }
306
311
  }
307
312
 
package/src/api.ts CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  getMemory,
17
17
  getMemoryStats,
18
18
  getMemoryTimeline,
19
+ getMemoryTimelineHours,
19
20
  InvalidMemoryCursorError,
20
21
  listMemories,
21
22
  MemoryNotFoundError,
@@ -44,9 +45,11 @@ export const memoryListResponseSchema = z
44
45
  })
45
46
  .strict();
46
47
 
48
+ const memoryBucketSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/);
49
+
47
50
  const memoryDashboardDaySchema = z
48
51
  .object({
49
- date: z.iso.date(),
52
+ date: memoryBucketSchema,
50
53
  personal: z.number().int().min(0),
51
54
  public: z.number().int().min(0),
52
55
  })
@@ -55,7 +58,7 @@ const memoryDashboardDaySchema = z
55
58
  const memoryCostDaySchema = z
56
59
  .object({
57
60
  costUsd: z.number().finite().nonnegative(),
58
- date: z.iso.date(),
61
+ date: memoryBucketSchema,
59
62
  events: z.number().int().min(0),
60
63
  })
61
64
  .strict();
@@ -64,8 +67,11 @@ export const memoryDashboardResponseSchema = z
64
67
  .object({
65
68
  days: z.array(memoryDashboardDaySchema).length(90),
66
69
  extractionDays: z.array(memoryCostDaySchema).length(90),
70
+ extractionHours: z.array(memoryCostDaySchema).length(24).optional(),
67
71
  generatedAt: z.iso.datetime(),
72
+ hours: z.array(memoryDashboardDaySchema).length(24).optional(),
68
73
  recallDays: z.array(memoryCostDaySchema).length(90),
74
+ recallHours: z.array(memoryCostDaySchema).length(24).optional(),
69
75
  stats: z
70
76
  .object({
71
77
  active: z.number().int().min(0),
@@ -163,17 +169,32 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
163
169
 
164
170
  try {
165
171
  if (isDashboard && isRead) {
166
- const [stats, days, extractionDays, recallDays] = await Promise.all([
172
+ const [
173
+ stats,
174
+ days,
175
+ hours,
176
+ extractionDays,
177
+ extractionHours,
178
+ recallDays,
179
+ recallHours,
180
+ ] = await Promise.all([
167
181
  getMemoryStats(options.db, userId),
168
182
  getMemoryTimeline(options.db, userId, 90),
183
+ getMemoryTimelineHours(options.db, userId, 24),
169
184
  options.eventStats.costsByDay({
170
185
  days: 90,
171
186
  eventName: "memories_captured",
172
187
  }),
188
+ options.eventStats.costsByHour({
189
+ eventName: "memories_captured",
190
+ }),
173
191
  options.eventStats.costsByDay({
174
192
  days: 90,
175
193
  eventName: "memories_recalled",
176
194
  }),
195
+ options.eventStats.costsByHour({
196
+ eventName: "memories_recalled",
197
+ }),
177
198
  ]);
178
199
  const { private: personal, ...dashboardStats } = stats;
179
200
  const body = memoryDashboardResponseSchema.parse({
@@ -182,8 +203,14 @@ export function createMemoryApi(options: MemoryApiOptions): PluginRouteApp {
182
203
  personal,
183
204
  })),
184
205
  extractionDays,
206
+ extractionHours,
185
207
  generatedAt: new Date().toISOString(),
208
+ hours: hours.map(({ private: personal, ...day }) => ({
209
+ ...day,
210
+ personal,
211
+ })),
186
212
  recallDays,
213
+ recallHours,
187
214
  stats: { ...dashboardStats, personal },
188
215
  });
189
216
  return request.method === "HEAD"
@@ -8,6 +8,7 @@ import { juniorMemoryEmbeddings, juniorMemoryMemories } from "./db/schema";
8
8
  import type { MemoryDb } from "./store";
9
9
 
10
10
  const DAY_MS = 24 * 60 * 60 * 1_000;
11
+ // TODO: add hour categories + `1` when these system widgets can plot 24h hourly.
11
12
  const WINDOWS = [7, 30, 90] as const;
12
13
 
13
14
  const memoryDaySchema = z
@@ -212,7 +213,7 @@ export async function buildMemoryOperationalReport(args: {
212
213
  public: day.public,
213
214
  },
214
215
  })),
215
- description: "Memories stored per day by scope",
216
+ description: "Memories stored by scope",
216
217
  id: "memories-created",
217
218
  series: [
218
219
  { key: "private", label: "Private" },
@@ -223,7 +223,9 @@ export async function processMemorySession(
223
223
  context: PluginTaskContext,
224
224
  ): Promise<void> {
225
225
  const run = await context.run.load();
226
- if (run.source.kind === "local" || run.source.kind === "resource_event") {
226
+ // TODO(dcramer): Replace this hardcoded Source check when a plugin Run can
227
+ // state whether passive memory extraction should run.
228
+ if (run.source.kind !== "slack" && run.source.kind !== "web") {
227
229
  return;
228
230
  }
229
231
  // Memory tool turns already own memory management or recall; do not reinterpret
package/src/store.ts CHANGED
@@ -187,10 +187,18 @@ const memoryRowSchema = z
187
187
  function storedMemorySource(
188
188
  source: MemoryRuntimeContext["source"],
189
189
  ): MemorySourcePlatform {
190
- if (source.kind === "resource_event") {
191
- throw new Error("Resource event Source cannot own a Memory.");
190
+ switch (source.kind) {
191
+ case "slack":
192
+ case "local":
193
+ case "web":
194
+ return source.kind;
195
+ case "resource_event":
196
+ case "scheduled_task":
197
+ case "event_task":
198
+ case "plugin_dispatch":
199
+ case "agent_invocation":
200
+ throw new Error(`${source.kind} Source cannot own a Memory.`);
192
201
  }
193
- return source.kind;
194
202
  }
195
203
 
196
204
  const memoryRecordSchema = z
package/src/viewer.ts CHANGED
@@ -391,3 +391,51 @@ export async function getMemoryTimeline(
391
391
  };
392
392
  });
393
393
  }
394
+
395
+ /** Read hourly memory creation totals visible to the authenticated User in UTC. */
396
+ export async function getMemoryTimelineHours(
397
+ db: MemoryDb,
398
+ userId: string,
399
+ hours = 24,
400
+ ) {
401
+ const end = new Date();
402
+ end.setUTCMinutes(0, 0, 0);
403
+ const startMs = end.getTime() - (hours - 1) * 60 * 60 * 1_000;
404
+ const rows = await db
405
+ .select({
406
+ date: sql<string>`to_char(to_timestamp(${juniorMemoryMemories.createdAtMs} / 1000.0) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24')`.as(
407
+ "date",
408
+ ),
409
+ private:
410
+ sql<number>`count(*) filter (where ${juniorMemoryMemories.scope} = 'private')`.mapWith(
411
+ Number,
412
+ ),
413
+ public:
414
+ sql<number>`count(*) filter (where ${juniorMemoryMemories.scope} = 'public')`.mapWith(
415
+ Number,
416
+ ),
417
+ })
418
+ .from(juniorMemoryMemories)
419
+ .where(
420
+ and(
421
+ visibleScopePredicate(userId),
422
+ gt(juniorMemoryMemories.createdAtMs, startMs - 1),
423
+ ),
424
+ )
425
+ .groupBy(
426
+ sql`to_char(to_timestamp(${juniorMemoryMemories.createdAtMs} / 1000.0) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24')`,
427
+ );
428
+ const byHour = new Map(rows.map((row) => [row.date, row]));
429
+ return Array.from({ length: hours }, (_, index) => {
430
+ const date = new Date(startMs + index * 60 * 60 * 1_000)
431
+ .toISOString()
432
+ .slice(0, 13);
433
+ const row = byHour.get(date);
434
+ return {
435
+ date,
436
+ private: row?.private ?? 0,
437
+ public: row?.public ?? 0,
438
+ };
439
+ });
440
+ }
441
+