@sentry/junior-memory 0.120.0 → 0.122.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/index.js CHANGED
@@ -2829,12 +2829,166 @@ async function createMemoryPromptContributions(context) {
2829
2829
  if (selected.length === 0) {
2830
2830
  return void 0;
2831
2831
  }
2832
- if (selected.some((memory) => memory.scope === "personal")) {
2833
- return [{ text: renderMemoryPrompt(selected) }];
2834
- }
2835
2832
  return [memoryRecallContext({ memories: selected })];
2836
2833
  }
2837
2834
 
2835
+ // src/operational-report.ts
2836
+ import { and as and4, eq as eq5, gt as gt4, isNull as isNull3, or as or4, sql as sql4 } from "drizzle-orm";
2837
+ import { z as z10 } from "zod";
2838
+ var DAY_MS = 24 * 60 * 60 * 1e3;
2839
+ var WINDOWS = [7, 30, 90];
2840
+ var memoryDaySchema = z10.object({
2841
+ conversation: z10.number().int().nonnegative(),
2842
+ date: z10.string().date(),
2843
+ personal: z10.number().int().nonnegative()
2844
+ }).strict();
2845
+ function queryRows(result) {
2846
+ if (typeof result !== "object" || result === null || !("rows" in result) || !Array.isArray(result.rows)) {
2847
+ throw new TypeError("Memory activity query did not return rows");
2848
+ }
2849
+ return result.rows;
2850
+ }
2851
+ function startOfUtcDay(value) {
2852
+ const date = new Date(value);
2853
+ date.setUTCHours(0, 0, 0, 0);
2854
+ return date;
2855
+ }
2856
+ async function aggregateMemoryDays(args) {
2857
+ const end = startOfUtcDay(args.nowMs);
2858
+ const start = startOfUtcDay(args.nowMs - (WINDOWS.at(-1) - 1) * DAY_MS);
2859
+ const endExclusiveMs = end.getTime() + DAY_MS;
2860
+ const table = juniorMemoryMemories;
2861
+ const result = await args.db.execute(sql4`
2862
+ WITH days AS (
2863
+ SELECT generate_series(
2864
+ date_trunc('day', ${start}::timestamptz AT TIME ZONE 'UTC'),
2865
+ date_trunc('day', ${end}::timestamptz AT TIME ZONE 'UTC'),
2866
+ interval '1 day'
2867
+ ) AS day
2868
+ ), daily AS (
2869
+ SELECT
2870
+ date_trunc(
2871
+ 'day',
2872
+ to_timestamp(${table.createdAtMs} / 1000.0) AT TIME ZONE 'UTC'
2873
+ ) AS day,
2874
+ count(*) FILTER (
2875
+ WHERE ${table.scope} = 'personal'
2876
+ )::integer AS personal,
2877
+ count(*) FILTER (
2878
+ WHERE ${table.scope} = 'conversation'
2879
+ )::integer AS conversation
2880
+ FROM ${table}
2881
+ WHERE ${table.createdAtMs} >= ${start.getTime()}
2882
+ AND ${table.createdAtMs} < ${endExclusiveMs}
2883
+ GROUP BY date_trunc(
2884
+ 'day',
2885
+ to_timestamp(${table.createdAtMs} / 1000.0) AT TIME ZONE 'UTC'
2886
+ )
2887
+ )
2888
+ SELECT
2889
+ to_char(days.day, 'YYYY-MM-DD') AS date,
2890
+ coalesce(daily.personal, 0)::integer AS personal,
2891
+ coalesce(daily.conversation, 0)::integer AS conversation
2892
+ FROM days
2893
+ LEFT JOIN daily ON daily.day = days.day
2894
+ ORDER BY days.day
2895
+ `);
2896
+ return z10.array(memoryDaySchema).parse(queryRows(result));
2897
+ }
2898
+ function formatCount(value) {
2899
+ return new Intl.NumberFormat("en-US").format(value);
2900
+ }
2901
+ function formatPercent(value) {
2902
+ return new Intl.NumberFormat("en-US", {
2903
+ maximumFractionDigits: 0,
2904
+ style: "percent"
2905
+ }).format(value);
2906
+ }
2907
+ async function buildMemoryOperationalReport(args) {
2908
+ const active = and4(
2909
+ isNull3(juniorMemoryMemories.archivedAtMs),
2910
+ isNull3(juniorMemoryMemories.supersededAtMs),
2911
+ isNull3(juniorMemoryMemories.supersededById),
2912
+ or4(
2913
+ isNull3(juniorMemoryMemories.expiresAtMs),
2914
+ gt4(juniorMemoryMemories.expiresAtMs, args.nowMs)
2915
+ )
2916
+ );
2917
+ const [[counts], memoryDays] = await Promise.all([
2918
+ args.db.select({
2919
+ active: sql4`count(*) filter (where ${active})`.mapWith(Number),
2920
+ conversation: sql4`count(*) filter (where ${active} and ${juniorMemoryMemories.scope} = 'conversation')`.mapWith(
2921
+ Number
2922
+ ),
2923
+ createdThirtyDays: sql4`count(*) filter (where ${juniorMemoryMemories.createdAtMs} >= ${args.nowMs - 30 * DAY_MS})`.mapWith(
2924
+ Number
2925
+ ),
2926
+ embedded: sql4`count(${juniorMemoryEmbeddings.memoryId}) filter (where ${active})`.mapWith(
2927
+ Number
2928
+ ),
2929
+ personal: sql4`count(*) filter (where ${active} and ${juniorMemoryMemories.scope} = 'personal')`.mapWith(
2930
+ Number
2931
+ )
2932
+ }).from(juniorMemoryMemories).leftJoin(
2933
+ juniorMemoryEmbeddings,
2934
+ eq5(juniorMemoryEmbeddings.memoryId, juniorMemoryMemories.id)
2935
+ ),
2936
+ aggregateMemoryDays(args)
2937
+ ]);
2938
+ const activeCount = counts?.active ?? 0;
2939
+ const embeddedCount = counts?.embedded ?? 0;
2940
+ const embeddingCoverage = activeCount === 0 ? 0 : embeddedCount / activeCount;
2941
+ return {
2942
+ generatedAt: new Date(args.nowMs).toISOString(),
2943
+ title: "Memory",
2944
+ metrics: [
2945
+ {
2946
+ label: "active memories",
2947
+ tone: activeCount > 0 ? "good" : "neutral",
2948
+ value: formatCount(activeCount)
2949
+ },
2950
+ {
2951
+ label: "created \xB7 30d",
2952
+ value: formatCount(counts?.createdThirtyDays ?? 0)
2953
+ },
2954
+ {
2955
+ label: "personal",
2956
+ value: formatCount(counts?.personal ?? 0)
2957
+ },
2958
+ {
2959
+ label: "conversation",
2960
+ value: formatCount(counts?.conversation ?? 0)
2961
+ },
2962
+ {
2963
+ label: "embedding coverage",
2964
+ tone: activeCount === 0 ? "neutral" : embeddedCount === activeCount ? "good" : "warning",
2965
+ value: formatPercent(embeddingCoverage)
2966
+ }
2967
+ ],
2968
+ widgets: [
2969
+ {
2970
+ categories: memoryDays.map((day) => ({
2971
+ id: day.date,
2972
+ label: day.date,
2973
+ values: {
2974
+ conversation: day.conversation,
2975
+ personal: day.personal
2976
+ }
2977
+ })),
2978
+ description: "Memories stored per day by scope",
2979
+ id: "memories-created",
2980
+ series: [
2981
+ { key: "personal", label: "Personal" },
2982
+ { key: "conversation", label: "Conversation" }
2983
+ ],
2984
+ timeRangeDays: [...WINDOWS],
2985
+ title: "Memories created",
2986
+ type: "bar_chart"
2987
+ }
2988
+ ]
2989
+ };
2990
+ }
2991
+
2838
2992
  // src/user-pages.ts
2839
2993
  function memoryKindLabel(kind) {
2840
2994
  return kind.charAt(0).toUpperCase() + kind.slice(1);
@@ -2950,6 +3104,12 @@ function memoryPlugin(options = {}) {
2950
3104
  },
2951
3105
  userPages: [createMemoryUserPage()],
2952
3106
  hooks: {
3107
+ async operationalReport(ctx) {
3108
+ return await buildMemoryOperationalReport({
3109
+ db: ctx.db,
3110
+ nowMs: ctx.nowMs
3111
+ });
3112
+ },
2953
3113
  apiRoutes(ctx) {
2954
3114
  return createMemoryApi({
2955
3115
  actors: ctx.viewer.actors,