@sentry/junior-memory 0.123.0 → 0.124.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.
- package/dist/api.d.ts +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +240 -23
- package/dist/index.js.map +1 -1
- package/dist/personal-store.d.ts +40 -2
- package/dist/personal.d.ts +9 -1
- package/package.json +2 -2
- package/src/api.ts +54 -1
- package/src/index.ts +2 -0
- package/src/personal-store.ts +203 -5
- package/src/personal.ts +41 -10
- package/src/user-pages.ts +46 -9
package/dist/api.d.ts
CHANGED
|
@@ -34,7 +34,27 @@ export declare const memoryListResponseSchema: z.ZodObject<{
|
|
|
34
34
|
}, z.core.$strict>>;
|
|
35
35
|
nextCursor: z.ZodOptional<z.ZodString>;
|
|
36
36
|
}, z.core.$strict>;
|
|
37
|
+
export declare const memoryDashboardResponseSchema: z.ZodObject<{
|
|
38
|
+
days: z.ZodArray<z.ZodObject<{
|
|
39
|
+
date: z.ZodISODate;
|
|
40
|
+
knowledge: z.ZodNumber;
|
|
41
|
+
preference: z.ZodNumber;
|
|
42
|
+
procedure: z.ZodNumber;
|
|
43
|
+
}, z.core.$strict>>;
|
|
44
|
+
generatedAt: z.ZodISODateTime;
|
|
45
|
+
stats: z.ZodObject<{
|
|
46
|
+
active: z.ZodNumber;
|
|
47
|
+
automatic: z.ZodNumber;
|
|
48
|
+
createdThirtyDays: z.ZodNumber;
|
|
49
|
+
embedded: z.ZodNumber;
|
|
50
|
+
explicit: z.ZodNumber;
|
|
51
|
+
knowledge: z.ZodNumber;
|
|
52
|
+
preference: z.ZodNumber;
|
|
53
|
+
procedure: z.ZodNumber;
|
|
54
|
+
}, z.core.$strict>;
|
|
55
|
+
}, z.core.$strict>;
|
|
37
56
|
export type MemoryApi = z.output<typeof memoryApiSchema>;
|
|
57
|
+
export type MemoryDashboardResponse = z.output<typeof memoryDashboardResponseSchema>;
|
|
38
58
|
export type MemoryListResponse = z.output<typeof memoryListResponseSchema>;
|
|
39
59
|
interface MemoryApiOptions {
|
|
40
60
|
actors(email: string): Promise<PluginUserPageActor[]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { memoryPlugin } from "./plugin";
|
|
2
|
-
export { memoryApiSchema, memoryListResponseSchema, type MemoryApi, type MemoryListResponse, } from "./api";
|
|
2
|
+
export { memoryApiSchema, memoryDashboardResponseSchema, memoryListResponseSchema, type MemoryApi, type MemoryDashboardResponse, type MemoryListResponse, } from "./api";
|
|
3
3
|
export type { MemoryPluginOptions } from "./plugin";
|
|
4
4
|
export { createMemoryStore } from "./store";
|
|
5
5
|
export type { ArchiveMemoryInput, CreateMemoryInput, CreateMemoryResult, ListMemoriesInput, MemoryDb, MemoryEmbeddingProvider, MemoryRecord, MemoryStore, MemoryStoreOptions, SearchMemoriesInput, } from "./store";
|
package/dist/index.js
CHANGED
|
@@ -1762,7 +1762,7 @@ import {
|
|
|
1762
1762
|
import { z as z5 } from "zod";
|
|
1763
1763
|
|
|
1764
1764
|
// src/personal-store.ts
|
|
1765
|
-
import { and as and2, asc as asc2, desc as desc2, eq as eq2, gt as gt2, ilike, lt, or as or2, sql as sql3 } from "drizzle-orm";
|
|
1765
|
+
import { and as and2, asc as asc2, desc as desc2, eq as eq2, gt as gt2, ilike, like as like2, lt, or as or2, sql as sql3 } from "drizzle-orm";
|
|
1766
1766
|
import { z as z4 } from "zod";
|
|
1767
1767
|
var nonEmptyStringSchema3 = z4.string().min(1);
|
|
1768
1768
|
var personalMemoryCursorSchema = z4.object({
|
|
@@ -1771,9 +1771,15 @@ var personalMemoryCursorSchema = z4.object({
|
|
|
1771
1771
|
}).strict();
|
|
1772
1772
|
var personalMemoryPageInputSchema = z4.object({
|
|
1773
1773
|
cursor: personalMemoryCursorSchema.optional(),
|
|
1774
|
+
kind: z4.enum(MEMORY_KINDS).optional(),
|
|
1774
1775
|
limit: z4.number().int().min(1).max(50),
|
|
1776
|
+
origin: z4.enum(["automatic", "explicit"]).optional(),
|
|
1775
1777
|
query: z4.string().max(200).optional()
|
|
1776
1778
|
}).strict();
|
|
1779
|
+
var personalMemoryTimelineInputSchema = z4.object({
|
|
1780
|
+
days: z4.number().int().min(1).max(365)
|
|
1781
|
+
}).strict();
|
|
1782
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
1777
1783
|
var PersonalMemoryNotFoundError = class extends Error {
|
|
1778
1784
|
constructor() {
|
|
1779
1785
|
super("Memory was not found for the authenticated viewer.");
|
|
@@ -1790,6 +1796,20 @@ function personalScopes(runtimeContexts) {
|
|
|
1790
1796
|
).values()
|
|
1791
1797
|
];
|
|
1792
1798
|
}
|
|
1799
|
+
function personalScopePredicate(scopes) {
|
|
1800
|
+
if (scopes.length === 0) return void 0;
|
|
1801
|
+
return or2(
|
|
1802
|
+
...scopes.map(
|
|
1803
|
+
(scope) => and2(
|
|
1804
|
+
eq2(juniorMemoryMemories.scope, scope.scope),
|
|
1805
|
+
eq2(juniorMemoryMemories.scopeKey, scope.scopeKey)
|
|
1806
|
+
)
|
|
1807
|
+
)
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
function utcDate(ms) {
|
|
1811
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
1812
|
+
}
|
|
1793
1813
|
function searchTerms(query) {
|
|
1794
1814
|
return [
|
|
1795
1815
|
...new Set(
|
|
@@ -1797,6 +1817,18 @@ function searchTerms(query) {
|
|
|
1797
1817
|
)
|
|
1798
1818
|
];
|
|
1799
1819
|
}
|
|
1820
|
+
function memoryOrigin(idempotencyKey) {
|
|
1821
|
+
if (idempotencyKey?.startsWith("session:")) return "automatic";
|
|
1822
|
+
if (idempotencyKey?.startsWith("tool:")) return "explicit";
|
|
1823
|
+
return "other";
|
|
1824
|
+
}
|
|
1825
|
+
function personalMemoryRecord(row) {
|
|
1826
|
+
return {
|
|
1827
|
+
...parseMemoryRow(row),
|
|
1828
|
+
origin: memoryOrigin(row.idempotencyKey),
|
|
1829
|
+
sourcePlatform: row.sourcePlatform
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1800
1832
|
function createPersonalMemoryCollection(db, runtimeContexts, options = {}) {
|
|
1801
1833
|
const scopes = personalScopes(runtimeContexts);
|
|
1802
1834
|
const getNowMs = () => options.now?.() ?? Date.now();
|
|
@@ -1852,12 +1884,14 @@ function createPersonalMemoryCollection(db, runtimeContexts, options = {}) {
|
|
|
1852
1884
|
(term) => ilike(juniorMemoryMemories.content, `%${term}%`)
|
|
1853
1885
|
)
|
|
1854
1886
|
);
|
|
1855
|
-
const
|
|
1887
|
+
const kind = input.kind ? eq2(juniorMemoryMemories.kind, input.kind) : void 0;
|
|
1888
|
+
const origin = input.origin === "automatic" ? like2(juniorMemoryMemories.idempotencyKey, "session:%") : input.origin === "explicit" ? like2(juniorMemoryMemories.idempotencyKey, "tool:%") : void 0;
|
|
1889
|
+
const rows = await db.select().from(juniorMemoryMemories).where(and2(active, cursor, search, kind, origin)).orderBy(
|
|
1856
1890
|
desc2(juniorMemoryMemories.createdAtMs),
|
|
1857
1891
|
asc2(juniorMemoryMemories.id)
|
|
1858
1892
|
).limit(input.limit + 1);
|
|
1859
1893
|
const hasNextPage = rows.length > input.limit;
|
|
1860
|
-
const memories = rows.slice(0, input.limit).map(
|
|
1894
|
+
const memories = rows.slice(0, input.limit).map(personalMemoryRecord);
|
|
1861
1895
|
const last = memories.at(-1);
|
|
1862
1896
|
return {
|
|
1863
1897
|
memories,
|
|
@@ -1868,6 +1902,103 @@ function createPersonalMemoryCollection(db, runtimeContexts, options = {}) {
|
|
|
1868
1902
|
}
|
|
1869
1903
|
} : {}
|
|
1870
1904
|
};
|
|
1905
|
+
},
|
|
1906
|
+
async stats() {
|
|
1907
|
+
const nowMs = getNowMs();
|
|
1908
|
+
await archiveExpiredMemoryBatch({ db, nowMs, scopes });
|
|
1909
|
+
const active = activeVisiblePredicate({ nowMs, scopes });
|
|
1910
|
+
if (!active) {
|
|
1911
|
+
return {
|
|
1912
|
+
active: 0,
|
|
1913
|
+
automatic: 0,
|
|
1914
|
+
createdThirtyDays: 0,
|
|
1915
|
+
embedded: 0,
|
|
1916
|
+
explicit: 0,
|
|
1917
|
+
knowledge: 0,
|
|
1918
|
+
preference: 0,
|
|
1919
|
+
procedure: 0
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
const [counts] = await db.select({
|
|
1923
|
+
active: sql3`count(*)`.mapWith(Number),
|
|
1924
|
+
automatic: sql3`count(*) filter (where ${juniorMemoryMemories.idempotencyKey} like 'session:%')`.mapWith(
|
|
1925
|
+
Number
|
|
1926
|
+
),
|
|
1927
|
+
createdThirtyDays: sql3`count(*) filter (where ${juniorMemoryMemories.createdAtMs} >= ${nowMs - 30 * 24 * 60 * 60 * 1e3})`.mapWith(
|
|
1928
|
+
Number
|
|
1929
|
+
),
|
|
1930
|
+
embedded: sql3`count(${juniorMemoryEmbeddings.memoryId})`.mapWith(
|
|
1931
|
+
Number
|
|
1932
|
+
),
|
|
1933
|
+
explicit: sql3`count(*) filter (where ${juniorMemoryMemories.idempotencyKey} like 'tool:%')`.mapWith(
|
|
1934
|
+
Number
|
|
1935
|
+
),
|
|
1936
|
+
knowledge: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'knowledge')`.mapWith(
|
|
1937
|
+
Number
|
|
1938
|
+
),
|
|
1939
|
+
preference: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'preference')`.mapWith(
|
|
1940
|
+
Number
|
|
1941
|
+
),
|
|
1942
|
+
procedure: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'procedure')`.mapWith(
|
|
1943
|
+
Number
|
|
1944
|
+
)
|
|
1945
|
+
}).from(juniorMemoryMemories).leftJoin(
|
|
1946
|
+
juniorMemoryEmbeddings,
|
|
1947
|
+
eq2(juniorMemoryEmbeddings.memoryId, juniorMemoryMemories.id)
|
|
1948
|
+
).where(active);
|
|
1949
|
+
return {
|
|
1950
|
+
active: counts?.active ?? 0,
|
|
1951
|
+
automatic: counts?.automatic ?? 0,
|
|
1952
|
+
createdThirtyDays: counts?.createdThirtyDays ?? 0,
|
|
1953
|
+
embedded: counts?.embedded ?? 0,
|
|
1954
|
+
explicit: counts?.explicit ?? 0,
|
|
1955
|
+
knowledge: counts?.knowledge ?? 0,
|
|
1956
|
+
preference: counts?.preference ?? 0,
|
|
1957
|
+
procedure: counts?.procedure ?? 0
|
|
1958
|
+
};
|
|
1959
|
+
},
|
|
1960
|
+
async timeline(input) {
|
|
1961
|
+
input = personalMemoryTimelineInputSchema.parse(input);
|
|
1962
|
+
const todayMs = Date.parse(`${utcDate(getNowMs())}T00:00:00.000Z`);
|
|
1963
|
+
const startMs = todayMs - (input.days - 1) * DAY_MS;
|
|
1964
|
+
const ownership = personalScopePredicate(scopes);
|
|
1965
|
+
if (!ownership) {
|
|
1966
|
+
return Array.from({ length: input.days }, (_, index2) => ({
|
|
1967
|
+
date: utcDate(startMs + index2 * DAY_MS),
|
|
1968
|
+
knowledge: 0,
|
|
1969
|
+
preference: 0,
|
|
1970
|
+
procedure: 0
|
|
1971
|
+
}));
|
|
1972
|
+
}
|
|
1973
|
+
const rows = await db.select({
|
|
1974
|
+
date: sql3`to_char(to_timestamp(${juniorMemoryMemories.createdAtMs} / 1000.0) AT TIME ZONE 'UTC', 'YYYY-MM-DD')`.as(
|
|
1975
|
+
"date"
|
|
1976
|
+
),
|
|
1977
|
+
knowledge: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'knowledge')`.mapWith(
|
|
1978
|
+
Number
|
|
1979
|
+
),
|
|
1980
|
+
preference: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'preference')`.mapWith(
|
|
1981
|
+
Number
|
|
1982
|
+
),
|
|
1983
|
+
procedure: sql3`count(*) filter (where ${juniorMemoryMemories.kind} = 'procedure')`.mapWith(
|
|
1984
|
+
Number
|
|
1985
|
+
)
|
|
1986
|
+
}).from(juniorMemoryMemories).where(
|
|
1987
|
+
and2(ownership, gt2(juniorMemoryMemories.createdAtMs, startMs - 1))
|
|
1988
|
+
).groupBy(
|
|
1989
|
+
sql3`to_char(to_timestamp(${juniorMemoryMemories.createdAtMs} / 1000.0) AT TIME ZONE 'UTC', 'YYYY-MM-DD')`
|
|
1990
|
+
);
|
|
1991
|
+
const byDate = new Map(rows.map((row) => [row.date, row]));
|
|
1992
|
+
return Array.from({ length: input.days }, (_, index2) => {
|
|
1993
|
+
const date = utcDate(startMs + index2 * DAY_MS);
|
|
1994
|
+
const row = byDate.get(date);
|
|
1995
|
+
return {
|
|
1996
|
+
date,
|
|
1997
|
+
knowledge: row?.knowledge ?? 0,
|
|
1998
|
+
preference: row?.preference ?? 0,
|
|
1999
|
+
procedure: row?.procedure ?? 0
|
|
2000
|
+
};
|
|
2001
|
+
});
|
|
1871
2002
|
}
|
|
1872
2003
|
};
|
|
1873
2004
|
}
|
|
@@ -1876,6 +2007,8 @@ function createPersonalMemoryCollection(db, runtimeContexts, options = {}) {
|
|
|
1876
2007
|
var cursorSchema = z5.object({
|
|
1877
2008
|
createdAtMs: z5.number().finite(),
|
|
1878
2009
|
id: z5.string().min(1),
|
|
2010
|
+
kind: z5.enum(["preference", "procedure", "knowledge"]).optional(),
|
|
2011
|
+
origin: z5.enum(["automatic", "explicit"]).optional(),
|
|
1879
2012
|
query: z5.string().max(200).optional(),
|
|
1880
2013
|
version: z5.literal(1)
|
|
1881
2014
|
}).strict();
|
|
@@ -1906,13 +2039,13 @@ function runtimeContext(actor) {
|
|
|
1906
2039
|
}
|
|
1907
2040
|
};
|
|
1908
2041
|
}
|
|
1909
|
-
function decodeCursor(value,
|
|
2042
|
+
function decodeCursor(value, input) {
|
|
1910
2043
|
if (!value) return void 0;
|
|
1911
2044
|
try {
|
|
1912
2045
|
const parsed = cursorSchema.parse(
|
|
1913
2046
|
JSON.parse(Buffer.from(value, "base64url").toString("utf8"))
|
|
1914
2047
|
);
|
|
1915
|
-
if (parsed.query !== query) {
|
|
2048
|
+
if (parsed.query !== input.query || parsed.kind !== input.kind || parsed.origin !== input.origin) {
|
|
1916
2049
|
throw new InvalidMemoryCursorError();
|
|
1917
2050
|
}
|
|
1918
2051
|
return { createdAtMs: parsed.createdAtMs, id: parsed.id };
|
|
@@ -1920,9 +2053,15 @@ function decodeCursor(value, query) {
|
|
|
1920
2053
|
throw new InvalidMemoryCursorError();
|
|
1921
2054
|
}
|
|
1922
2055
|
}
|
|
1923
|
-
function encodeCursor(cursor,
|
|
2056
|
+
function encodeCursor(cursor, input) {
|
|
1924
2057
|
return Buffer.from(
|
|
1925
|
-
JSON.stringify({
|
|
2058
|
+
JSON.stringify({
|
|
2059
|
+
...cursor,
|
|
2060
|
+
...input.query ? { query: input.query } : {},
|
|
2061
|
+
...input.kind ? { kind: input.kind } : {},
|
|
2062
|
+
...input.origin ? { origin: input.origin } : {},
|
|
2063
|
+
version: 1
|
|
2064
|
+
}),
|
|
1926
2065
|
"utf8"
|
|
1927
2066
|
).toString("base64url");
|
|
1928
2067
|
}
|
|
@@ -1940,15 +2079,26 @@ function createViewerMemories(db, actors) {
|
|
|
1940
2079
|
},
|
|
1941
2080
|
async list(input) {
|
|
1942
2081
|
const query = input.query?.trim() || void 0;
|
|
1943
|
-
const
|
|
1944
|
-
|
|
1945
|
-
|
|
2082
|
+
const filters = {
|
|
2083
|
+
...input.kind ? { kind: input.kind } : {},
|
|
2084
|
+
...input.origin ? { origin: input.origin } : {},
|
|
1946
2085
|
...query ? { query } : {}
|
|
2086
|
+
};
|
|
2087
|
+
const page = await collection.list({
|
|
2088
|
+
cursor: decodeCursor(input.cursor, filters),
|
|
2089
|
+
...filters,
|
|
2090
|
+
limit: input.limit
|
|
1947
2091
|
});
|
|
1948
2092
|
return {
|
|
1949
2093
|
memories: page.memories,
|
|
1950
|
-
...page.nextCursor ? { nextCursor: encodeCursor(page.nextCursor,
|
|
2094
|
+
...page.nextCursor ? { nextCursor: encodeCursor(page.nextCursor, filters) } : {}
|
|
1951
2095
|
};
|
|
2096
|
+
},
|
|
2097
|
+
async stats() {
|
|
2098
|
+
return await collection.stats();
|
|
2099
|
+
},
|
|
2100
|
+
async timeline(input) {
|
|
2101
|
+
return await collection.timeline(input);
|
|
1952
2102
|
}
|
|
1953
2103
|
};
|
|
1954
2104
|
}
|
|
@@ -1966,6 +2116,26 @@ var memoryListResponseSchema = z6.object({
|
|
|
1966
2116
|
memories: z6.array(memoryApiSchema),
|
|
1967
2117
|
nextCursor: z6.string().min(1).optional()
|
|
1968
2118
|
}).strict();
|
|
2119
|
+
var memoryDashboardDaySchema = z6.object({
|
|
2120
|
+
date: z6.iso.date(),
|
|
2121
|
+
knowledge: z6.number().int().min(0),
|
|
2122
|
+
preference: z6.number().int().min(0),
|
|
2123
|
+
procedure: z6.number().int().min(0)
|
|
2124
|
+
}).strict();
|
|
2125
|
+
var memoryDashboardResponseSchema = z6.object({
|
|
2126
|
+
days: z6.array(memoryDashboardDaySchema).length(90),
|
|
2127
|
+
generatedAt: z6.iso.datetime(),
|
|
2128
|
+
stats: z6.object({
|
|
2129
|
+
active: z6.number().int().min(0),
|
|
2130
|
+
automatic: z6.number().int().min(0),
|
|
2131
|
+
createdThirtyDays: z6.number().int().min(0),
|
|
2132
|
+
embedded: z6.number().int().min(0),
|
|
2133
|
+
explicit: z6.number().int().min(0),
|
|
2134
|
+
knowledge: z6.number().int().min(0),
|
|
2135
|
+
preference: z6.number().int().min(0),
|
|
2136
|
+
procedure: z6.number().int().min(0)
|
|
2137
|
+
}).strict()
|
|
2138
|
+
}).strict();
|
|
1969
2139
|
var memoryListQuerySchema = z6.object({
|
|
1970
2140
|
cursor: z6.string().min(1).max(1e3).optional(),
|
|
1971
2141
|
limit: z6.coerce.number().int().min(1).max(50).default(25),
|
|
@@ -2004,12 +2174,28 @@ function createMemoryApi(options) {
|
|
|
2004
2174
|
const url = new URL(request.url);
|
|
2005
2175
|
const memoryPath = /^\/memories\/([^/]+)$/.exec(url.pathname);
|
|
2006
2176
|
const isCollection = url.pathname === "/memories";
|
|
2007
|
-
|
|
2177
|
+
const isDashboard = url.pathname === "/dashboard";
|
|
2178
|
+
if (!isCollection && !isDashboard && !memoryPath) {
|
|
2008
2179
|
return json({ error: "Not found." }, 404);
|
|
2009
2180
|
}
|
|
2010
2181
|
const actors = await options.actors(email);
|
|
2011
2182
|
const memories = createViewerMemories(options.db, actors);
|
|
2012
2183
|
try {
|
|
2184
|
+
if (isDashboard && (request.method === "GET" || request.method === "HEAD")) {
|
|
2185
|
+
const [stats, days] = await Promise.all([
|
|
2186
|
+
memories.stats(),
|
|
2187
|
+
memories.timeline({ days: 90 })
|
|
2188
|
+
]);
|
|
2189
|
+
const body = memoryDashboardResponseSchema.parse({
|
|
2190
|
+
days,
|
|
2191
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2192
|
+
stats
|
|
2193
|
+
});
|
|
2194
|
+
return request.method === "HEAD" ? new Response(null, {
|
|
2195
|
+
headers: { "cache-control": "no-store" },
|
|
2196
|
+
status: 200
|
|
2197
|
+
}) : json(body);
|
|
2198
|
+
}
|
|
2013
2199
|
if (isCollection && (request.method === "GET" || request.method === "HEAD")) {
|
|
2014
2200
|
const query = memoryListQuerySchema.parse({
|
|
2015
2201
|
cursor: url.searchParams.get("cursor") ?? void 0,
|
|
@@ -2925,7 +3111,7 @@ async function createMemoryPromptContributions(context) {
|
|
|
2925
3111
|
// src/operational-report.ts
|
|
2926
3112
|
import { and as and4, eq as eq5, gt as gt4, isNull as isNull3, or as or4, sql as sql4 } from "drizzle-orm";
|
|
2927
3113
|
import { z as z11 } from "zod";
|
|
2928
|
-
var
|
|
3114
|
+
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
2929
3115
|
var WINDOWS = [7, 30, 90];
|
|
2930
3116
|
var memoryDaySchema = z11.object({
|
|
2931
3117
|
conversation: z11.number().int().nonnegative(),
|
|
@@ -2945,8 +3131,8 @@ function startOfUtcDay(value) {
|
|
|
2945
3131
|
}
|
|
2946
3132
|
async function aggregateMemoryDays(args) {
|
|
2947
3133
|
const end = startOfUtcDay(args.nowMs);
|
|
2948
|
-
const start = startOfUtcDay(args.nowMs - (WINDOWS.at(-1) - 1) *
|
|
2949
|
-
const endExclusiveMs = end.getTime() +
|
|
3134
|
+
const start = startOfUtcDay(args.nowMs - (WINDOWS.at(-1) - 1) * DAY_MS2);
|
|
3135
|
+
const endExclusiveMs = end.getTime() + DAY_MS2;
|
|
2950
3136
|
const table = juniorMemoryMemories;
|
|
2951
3137
|
const result = await args.db.execute(sql4`
|
|
2952
3138
|
WITH days AS (
|
|
@@ -3010,7 +3196,7 @@ async function buildMemoryOperationalReport(args) {
|
|
|
3010
3196
|
conversation: sql4`count(*) filter (where ${active} and ${juniorMemoryMemories.scope} = 'conversation')`.mapWith(
|
|
3011
3197
|
Number
|
|
3012
3198
|
),
|
|
3013
|
-
createdThirtyDays: sql4`count(*) filter (where ${juniorMemoryMemories.createdAtMs} >= ${args.nowMs - 30 *
|
|
3199
|
+
createdThirtyDays: sql4`count(*) filter (where ${juniorMemoryMemories.createdAtMs} >= ${args.nowMs - 30 * DAY_MS2})`.mapWith(
|
|
3014
3200
|
Number
|
|
3015
3201
|
),
|
|
3016
3202
|
embedded: sql4`count(${juniorMemoryEmbeddings.memoryId}) filter (where ${active})`.mapWith(
|
|
@@ -3080,32 +3266,54 @@ async function buildMemoryOperationalReport(args) {
|
|
|
3080
3266
|
}
|
|
3081
3267
|
|
|
3082
3268
|
// src/user-pages.ts
|
|
3083
|
-
function
|
|
3084
|
-
return
|
|
3269
|
+
function titleCase(value) {
|
|
3270
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
3085
3271
|
}
|
|
3086
3272
|
function rememberedDate(createdAtMs) {
|
|
3087
3273
|
return new Intl.DateTimeFormat("en-US", {
|
|
3088
3274
|
dateStyle: "medium",
|
|
3275
|
+
timeStyle: "short",
|
|
3089
3276
|
timeZone: "UTC"
|
|
3090
3277
|
}).format(new Date(createdAtMs));
|
|
3091
3278
|
}
|
|
3279
|
+
function originLabel(origin) {
|
|
3280
|
+
if (origin === "automatic") return "Automatic";
|
|
3281
|
+
if (origin === "explicit") return "Explicit";
|
|
3282
|
+
return "Other";
|
|
3283
|
+
}
|
|
3284
|
+
function pageFilter(filter) {
|
|
3285
|
+
if (filter === "preferences") return { kind: "preference" };
|
|
3286
|
+
if (filter === "automatic") return { origin: "automatic" };
|
|
3287
|
+
if (filter === "explicit") return { origin: "explicit" };
|
|
3288
|
+
return {};
|
|
3289
|
+
}
|
|
3290
|
+
function pageEmptyText(input) {
|
|
3291
|
+
if (input.query) return "No memories matched your search.";
|
|
3292
|
+
if (input.filter === "preferences") return "No preferences yet.";
|
|
3293
|
+
if (input.filter === "automatic") return "No learned memories yet.";
|
|
3294
|
+
if (input.filter === "explicit") return "No saved memories yet.";
|
|
3295
|
+
return "No personal memories yet.";
|
|
3296
|
+
}
|
|
3092
3297
|
function createMemoryUserPage() {
|
|
3093
3298
|
return {
|
|
3094
3299
|
id: "memories",
|
|
3095
3300
|
label: "Memories",
|
|
3301
|
+
navigation: "primary",
|
|
3096
3302
|
description: "Personal facts and preferences Junior remembers about you.",
|
|
3097
3303
|
async read(ctx, input) {
|
|
3098
|
-
const
|
|
3304
|
+
const memories = createViewerMemories(
|
|
3099
3305
|
ctx.db,
|
|
3100
3306
|
ctx.viewer.actors
|
|
3101
|
-
)
|
|
3307
|
+
);
|
|
3308
|
+
const page = await memories.list({
|
|
3102
3309
|
cursor: input.cursor,
|
|
3310
|
+
...pageFilter(input.filter),
|
|
3103
3311
|
limit: input.limit,
|
|
3104
3312
|
...input.query ? { query: input.query } : {}
|
|
3105
3313
|
});
|
|
3106
3314
|
return {
|
|
3107
3315
|
type: "list",
|
|
3108
|
-
emptyText: input
|
|
3316
|
+
emptyText: pageEmptyText(input),
|
|
3109
3317
|
...page.nextCursor ? { nextCursor: page.nextCursor } : {},
|
|
3110
3318
|
searchPlaceholder: "Search memories",
|
|
3111
3319
|
records: page.memories.map((memory) => ({
|
|
@@ -3121,8 +3329,16 @@ function createMemoryUserPage() {
|
|
|
3121
3329
|
id: memory.id,
|
|
3122
3330
|
title: memory.content,
|
|
3123
3331
|
metadata: [
|
|
3124
|
-
{ label: "Type", value:
|
|
3125
|
-
{ label: "
|
|
3332
|
+
{ label: "Type", value: titleCase(memory.kind) },
|
|
3333
|
+
{ label: "Learned", value: originLabel(memory.origin) },
|
|
3334
|
+
{ label: "Source", value: titleCase(memory.sourcePlatform) },
|
|
3335
|
+
{ label: "Visibility", value: "Only you" },
|
|
3336
|
+
{ label: "Remembered", value: rememberedDate(memory.createdAtMs) },
|
|
3337
|
+
{ label: "Observed", value: rememberedDate(memory.observedAtMs) },
|
|
3338
|
+
{
|
|
3339
|
+
label: "Expires",
|
|
3340
|
+
value: memory.expiresAtMs ? rememberedDate(memory.expiresAtMs) : "Never"
|
|
3341
|
+
}
|
|
3126
3342
|
]
|
|
3127
3343
|
}))
|
|
3128
3344
|
};
|
|
@@ -3250,6 +3466,7 @@ export {
|
|
|
3250
3466
|
MEMORY_KINDS,
|
|
3251
3467
|
createMemoryStore,
|
|
3252
3468
|
memoryApiSchema,
|
|
3469
|
+
memoryDashboardResponseSchema,
|
|
3253
3470
|
memoryListResponseSchema,
|
|
3254
3471
|
memoryPlugin
|
|
3255
3472
|
};
|