@sentry/junior-memory 0.117.0 → 0.118.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 +2 -0
- package/dist/index.js +109 -19
- package/dist/index.js.map +1 -1
- package/dist/store.d.ts +2 -0
- package/dist/user-pages.d.ts +4 -0
- package/package.json +2 -2
- package/src/plugin.ts +2 -0
- package/src/store.ts +19 -0
- package/src/user-pages.ts +94 -0
package/dist/store.d.ts
CHANGED
|
@@ -166,6 +166,8 @@ export interface MemoryStore {
|
|
|
166
166
|
createConversationMemory(input: CreateMemoryInput): Promise<CreateMemoryResult>;
|
|
167
167
|
/** List active memories visible in the current runtime context. */
|
|
168
168
|
listMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
|
|
169
|
+
/** List active personal memories owned by the current actor. */
|
|
170
|
+
listPersonalMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
|
|
169
171
|
/** Search active memories visible in the current runtime context. */
|
|
170
172
|
searchMemories(input: SearchMemoriesInput): Promise<MemoryRecord[]>;
|
|
171
173
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Project actor-owned memories into Junior's core-rendered user page. */
|
|
2
|
+
import type { PluginUserPageDefinition } from "@sentry/junior-plugin-api";
|
|
3
|
+
/** Create the read-only personal Memories dashboard page. */
|
|
4
|
+
export declare function createMemoryUserPage(): PluginUserPageDefinition;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.118.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.118.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^25.9.1",
|
package/src/plugin.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { processMemorySession } from "./process-session";
|
|
14
14
|
import { createMemoryPromptContributions } from "./recall";
|
|
15
15
|
import type { MemoryDb } from "./store";
|
|
16
|
+
import { createMemoryUserPage } from "./user-pages";
|
|
16
17
|
|
|
17
18
|
const MEMORY_MODEL_ENV = "AI_MEMORY_MODEL";
|
|
18
19
|
const MEMORY_RECALL_MAX_VECTOR_DISTANCE_ENV =
|
|
@@ -107,6 +108,7 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) {
|
|
|
107
108
|
},
|
|
108
109
|
},
|
|
109
110
|
},
|
|
111
|
+
userPages: [createMemoryUserPage()],
|
|
110
112
|
hooks: {
|
|
111
113
|
tools(ctx) {
|
|
112
114
|
const agent = createMemoryAgent(ctx.model);
|
package/src/store.ts
CHANGED
|
@@ -324,6 +324,8 @@ export interface MemoryStore {
|
|
|
324
324
|
): Promise<CreateMemoryResult>;
|
|
325
325
|
/** List active memories visible in the current runtime context. */
|
|
326
326
|
listMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
|
|
327
|
+
/** List active personal memories owned by the current actor. */
|
|
328
|
+
listPersonalMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
|
|
327
329
|
/** Search active memories visible in the current runtime context. */
|
|
328
330
|
searchMemories(input: SearchMemoriesInput): Promise<MemoryRecord[]>;
|
|
329
331
|
}
|
|
@@ -1468,6 +1470,23 @@ export function createMemoryStore(
|
|
|
1468
1470
|
});
|
|
1469
1471
|
},
|
|
1470
1472
|
|
|
1473
|
+
async listPersonalMemories(input) {
|
|
1474
|
+
input = listMemoriesInputSchema.parse(input);
|
|
1475
|
+
const nowMs = getNowMs();
|
|
1476
|
+
const scopes = [deriveMemoryScope(runtimeContext, "personal")];
|
|
1477
|
+
await archiveExpiredMemoryBatch({
|
|
1478
|
+
db,
|
|
1479
|
+
nowMs,
|
|
1480
|
+
scopes,
|
|
1481
|
+
});
|
|
1482
|
+
return await listVisibleMemories({
|
|
1483
|
+
db,
|
|
1484
|
+
limit: input.limit,
|
|
1485
|
+
nowMs,
|
|
1486
|
+
scopes,
|
|
1487
|
+
});
|
|
1488
|
+
},
|
|
1489
|
+
|
|
1471
1490
|
async searchMemories(input) {
|
|
1472
1491
|
input = searchMemoriesInputSchema.parse(input);
|
|
1473
1492
|
const nowMs = getNowMs();
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Project actor-owned memories into Junior's core-rendered user page. */
|
|
2
|
+
import type {
|
|
3
|
+
PluginUserPageActor,
|
|
4
|
+
PluginUserPageDefinition,
|
|
5
|
+
} from "@sentry/junior-plugin-api";
|
|
6
|
+
import { createMemoryStore, type MemoryDb, type MemoryRecord } from "./store";
|
|
7
|
+
import type { MemoryRuntimeContext } from "./types";
|
|
8
|
+
|
|
9
|
+
const MEMORY_PAGE_LIMIT = 100;
|
|
10
|
+
|
|
11
|
+
function runtimeContext(
|
|
12
|
+
actor: PluginUserPageActor,
|
|
13
|
+
): MemoryRuntimeContext | undefined {
|
|
14
|
+
if (actor.platform === "slack") {
|
|
15
|
+
return {
|
|
16
|
+
actor,
|
|
17
|
+
source: {
|
|
18
|
+
platform: "slack",
|
|
19
|
+
type: "priv",
|
|
20
|
+
teamId: actor.teamId,
|
|
21
|
+
channelId: "DDASHBOARD",
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
actor,
|
|
27
|
+
source: {
|
|
28
|
+
platform: "local",
|
|
29
|
+
type: "priv",
|
|
30
|
+
conversationId: "local:dashboard:memories",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function memoryKindLabel(kind: MemoryRecord["kind"]): string {
|
|
36
|
+
return kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function rememberedDate(createdAtMs: number): string {
|
|
40
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
41
|
+
dateStyle: "medium",
|
|
42
|
+
timeZone: "UTC",
|
|
43
|
+
}).format(new Date(createdAtMs));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function readPersonalMemories(
|
|
47
|
+
db: MemoryDb,
|
|
48
|
+
actors: PluginUserPageActor[],
|
|
49
|
+
): Promise<MemoryRecord[]> {
|
|
50
|
+
const memories = await Promise.all(
|
|
51
|
+
actors.flatMap((actor) => {
|
|
52
|
+
const context = runtimeContext(actor);
|
|
53
|
+
return context
|
|
54
|
+
? [
|
|
55
|
+
createMemoryStore(db, context).listPersonalMemories({
|
|
56
|
+
limit: MEMORY_PAGE_LIMIT,
|
|
57
|
+
}),
|
|
58
|
+
]
|
|
59
|
+
: [];
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
return [
|
|
63
|
+
...new Map(memories.flat().map((memory) => [memory.id, memory])).values(),
|
|
64
|
+
]
|
|
65
|
+
.sort((left, right) => right.createdAtMs - left.createdAtMs)
|
|
66
|
+
.slice(0, MEMORY_PAGE_LIMIT);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Create the read-only personal Memories dashboard page. */
|
|
70
|
+
export function createMemoryUserPage(): PluginUserPageDefinition {
|
|
71
|
+
return {
|
|
72
|
+
id: "memories",
|
|
73
|
+
label: "Memories",
|
|
74
|
+
description: "Personal facts and preferences Junior remembers about you.",
|
|
75
|
+
async read(ctx) {
|
|
76
|
+
const memories = await readPersonalMemories(
|
|
77
|
+
ctx.db as MemoryDb,
|
|
78
|
+
ctx.viewer.actors,
|
|
79
|
+
);
|
|
80
|
+
return {
|
|
81
|
+
type: "list",
|
|
82
|
+
emptyText: "No personal memories yet.",
|
|
83
|
+
records: memories.map((memory) => ({
|
|
84
|
+
id: memory.id,
|
|
85
|
+
title: memory.content,
|
|
86
|
+
metadata: [
|
|
87
|
+
{ label: "Type", value: memoryKindLabel(memory.kind) },
|
|
88
|
+
{ label: "Remembered", value: rememberedDate(memory.createdAtMs) },
|
|
89
|
+
],
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|