@sentry/junior-memory 0.106.0 → 0.107.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/store.d.ts CHANGED
@@ -53,6 +53,69 @@ declare const memoryRecordSchema: z.ZodObject<{
53
53
  knowledge: "knowledge";
54
54
  }>;
55
55
  }, z.core.$strict>;
56
+ /** Validated preference comparison input supplied to a supersession decider. */
57
+ export declare const memorySupersessionInputSchema: z.ZodObject<{
58
+ candidate: z.ZodObject<{
59
+ content: z.ZodString;
60
+ kind: z.ZodLiteral<"preference">;
61
+ }, z.core.$strict>;
62
+ existingMemories: z.ZodArray<z.ZodObject<{
63
+ content: z.ZodString;
64
+ id: z.ZodString;
65
+ }, z.core.$strict>>;
66
+ runtimeContext: z.ZodUnion<readonly [z.ZodObject<{
67
+ conversationId: z.ZodOptional<z.ZodString>;
68
+ actor: z.ZodOptional<z.ZodObject<{
69
+ platform: z.ZodLiteral<"slack">;
70
+ teamId: z.ZodString;
71
+ email: z.ZodOptional<z.ZodString>;
72
+ fullName: z.ZodOptional<z.ZodString>;
73
+ userId: z.ZodString;
74
+ userName: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strict>>;
76
+ source: z.ZodObject<{
77
+ platform: z.ZodLiteral<"slack">;
78
+ teamId: z.ZodString;
79
+ channelId: z.ZodString;
80
+ type: z.ZodEnum<{
81
+ pub: "pub";
82
+ priv: "priv";
83
+ }>;
84
+ messageTs: z.ZodOptional<z.ZodString>;
85
+ threadTs: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strict>;
87
+ }, z.core.$strict>, z.ZodObject<{
88
+ conversationId: z.ZodOptional<z.ZodString>;
89
+ actor: z.ZodOptional<z.ZodObject<{
90
+ platform: z.ZodLiteral<"local">;
91
+ email: z.ZodOptional<z.ZodString>;
92
+ fullName: z.ZodOptional<z.ZodString>;
93
+ userId: z.ZodString;
94
+ userName: z.ZodOptional<z.ZodString>;
95
+ }, z.core.$strict>>;
96
+ source: z.ZodObject<{
97
+ platform: z.ZodLiteral<"local">;
98
+ type: z.ZodLiteral<"priv">;
99
+ conversationId: z.ZodString;
100
+ }, z.core.$strict>;
101
+ }, z.core.$strict>]>;
102
+ }, z.core.$strict>;
103
+ /**
104
+ * Validated preference decision whose referenced ids must come from the
105
+ * supplied existing memories.
106
+ */
107
+ export declare const memorySupersessionDecisionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
108
+ decision: z.ZodLiteral<"duplicate">;
109
+ duplicateId: z.ZodString;
110
+ }, z.core.$strict>, z.ZodObject<{
111
+ decision: z.ZodLiteral<"supersedes_old">;
112
+ supersededIds: z.ZodArray<z.ZodString>;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ decision: z.ZodEnum<{
115
+ distinct: "distinct";
116
+ uncertain: "uncertain";
117
+ }>;
118
+ }, z.core.$strict>], "decision">;
56
119
  export type MemoryRecord = z.output<typeof memoryRecordSchema>;
57
120
  export type CreateMemoryInput = z.output<typeof createMemoryInputSchema>;
58
121
  /** Result of a memory write after idempotency checks. */
@@ -78,31 +141,10 @@ export interface MemoryEmbeddingProvider {
78
141
  vectors: number[][];
79
142
  }>;
80
143
  }
81
- export interface MemorySupersessionInput {
82
- candidate: {
83
- content: string;
84
- kind: "preference";
85
- };
86
- existingMemories: [
87
- {
88
- content: string;
89
- id: string;
90
- },
91
- ...Array<{
92
- content: string;
93
- id: string;
94
- }>
95
- ];
96
- runtimeContext: MemoryRuntimeContext;
97
- }
98
- export type MemorySupersessionDecision = {
99
- decision: "supersedes_old";
100
- supersededIds: [string, ...string[]];
101
- } | {
102
- decision: "distinct" | "uncertain";
103
- };
144
+ export type MemorySupersessionInput = z.output<typeof memorySupersessionInputSchema>;
145
+ export type MemorySupersessionDecision = z.output<typeof memorySupersessionDecisionSchema>;
104
146
  export interface MemorySupersessionDecider {
105
- /** Decide whether a new preference clearly replaces active old preferences. */
147
+ /** Classify a new preference against related active preferences. */
106
148
  adjudicateSupersession(input: MemorySupersessionInput): Promise<MemorySupersessionDecision> | MemorySupersessionDecision;
107
149
  }
108
150
  export interface MemoryStoreOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-memory",
3
- "version": "0.106.0",
3
+ "version": "0.107.1",
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.106.0"
30
+ "@sentry/junior-plugin-api": "0.107.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^25.9.1",
package/src/agent.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { actorSchema, type PluginModel } from "@sentry/junior-plugin-api";
2
2
  import { z } from "zod";
3
- import type {
4
- MemorySupersessionDecision,
5
- MemorySupersessionInput,
3
+ import {
4
+ memorySupersessionDecisionSchema,
5
+ memorySupersessionInputSchema,
6
+ type MemorySupersessionDecision,
7
+ type MemorySupersessionInput,
6
8
  } from "./store";
7
9
  import {
8
10
  MEMORY_KINDS,
@@ -84,29 +86,6 @@ const extractSessionRequestSchema = z
84
86
  .min(1),
85
87
  })
86
88
  .strict();
87
- const supersessionRequestSchema = z
88
- .object({
89
- candidate: z
90
- .object({
91
- content: z.string().min(1),
92
- kind: z.literal("preference"),
93
- })
94
- .strict(),
95
- existingMemories: z
96
- .array(
97
- z
98
- .object({
99
- content: z.string().min(1),
100
- id: z.string().min(1),
101
- })
102
- .strict(),
103
- )
104
- .min(1)
105
- .max(10),
106
- runtimeContext: memoryRuntimeContextSchema,
107
- })
108
- .strict();
109
-
110
89
  const expiresAtMsSchema = z
111
90
  .number()
112
91
  .finite()
@@ -186,20 +165,6 @@ const extractMemoriesResponseSchema = z
186
165
  ),
187
166
  })
188
167
  .strict();
189
- const supersessionDecisionResponseSchema = z.discriminatedUnion("decision", [
190
- z
191
- .object({
192
- decision: z.literal("supersedes_old"),
193
- supersededIds: z.array(z.string().min(1)).min(1).max(10),
194
- })
195
- .strict(),
196
- z
197
- .object({
198
- decision: z.enum(["distinct", "uncertain"]),
199
- })
200
- .strict(),
201
- ]);
202
-
203
168
  type MemoryReviewResponse = z.output<typeof memoryReviewResponseSchema>;
204
169
  type ExtractMemoriesResponse = z.output<typeof extractMemoriesResponseSchema>;
205
170
 
@@ -212,7 +177,7 @@ export type ExtractSessionRequest = z.output<
212
177
  export type ExtractedMemory = z.output<typeof extractedMemoryResultSchema>;
213
178
 
214
179
  export interface MemoryAgent {
215
- /** Decide whether a new preference safely replaces active old preferences. */
180
+ /** Classify a new preference against related active preferences. */
216
181
  adjudicateSupersession(
217
182
  request: MemorySupersessionInput,
218
183
  ): Promise<MemorySupersessionDecision> | MemorySupersessionDecision;
@@ -238,11 +203,12 @@ const MEMORY_EXTRACTION_SYSTEM = [
238
203
  "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.",
239
204
  "If no public, durable, self-contained memory remains after rewriting, return an empty memories array.",
240
205
  ].join("\n");
241
- const MEMORY_SUPERSESSION_SYSTEM = [
242
- "You are Junior's memory supersession agent.",
243
- "Decide whether a new actor preference clearly replaces existing active actor preferences.",
244
- "Return supersedes_old only for obvious changed preferences about the same mutable slot.",
245
- "If the facts are additive, different topics, duplicate, broader/narrower without direct replacement, or uncertain, do not supersede.",
206
+ const MEMORY_PREFERENCE_ADJUDICATION_SYSTEM = [
207
+ "You are Junior's memory preference adjudication agent.",
208
+ "Classify how one new actor preference relates to existing active actor preferences.",
209
+ "Return duplicate when the same durable preference is merely phrased differently.",
210
+ "Return supersedes_old only for an obvious changed value in the same mutable preference slot.",
211
+ "Return distinct for additive preferences or different topics, and uncertain when the relationship is unclear.",
246
212
  ].join("\n");
247
213
  const CANONICAL_CONTENT_RULES = [
248
214
  "- Stored memory text must be a rewritten fact, not copied user wording or a sentence about who said it.",
@@ -478,10 +444,12 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string {
478
444
  ].join("\n");
479
445
  }
480
446
 
481
- function supersessionPrompt(request: MemorySupersessionInput): string {
447
+ function preferenceAdjudicationPrompt(
448
+ request: MemorySupersessionInput,
449
+ ): string {
482
450
  return [
483
- "<memory-supersession-input>",
484
- "Decide whether the candidate preference clearly replaces one or more existing active preferences.",
451
+ "<memory-preference-adjudication-input>",
452
+ "Classify the candidate preference against the related active preferences.",
485
453
  "",
486
454
  runtimeDescription({
487
455
  runtimeContext: request.runtimeContext,
@@ -496,14 +464,16 @@ function supersessionPrompt(request: MemorySupersessionInput): string {
496
464
  "</existing-memories>",
497
465
  "",
498
466
  "<rules>",
467
+ "- Return duplicate when the candidate and one existing memory express the same durable preference or value with different wording.",
499
468
  "- Return supersedes_old only when the candidate and old memory describe the same mutable preference slot and the candidate is the newer value.",
500
469
  "- Examples of same mutable slot: preferred programming language, preferred review style, preferred notification cadence, preferred tool for a task.",
501
- "- Do not supersede when the candidate is just more specific, an additional preference, a different task/context, or the same value phrased differently.",
470
+ "- Return distinct when the candidate is an additional preference or belongs to a different task or topic.",
471
+ "- Return uncertain when broader or narrower wording makes equivalence or replacement unclear.",
502
472
  "- Do not supersede memories from different topics even if they are both preferences.",
503
- "- Only return ids that appear in existing-memories.",
473
+ "- duplicateId and supersededIds may contain only ids from existing-memories.",
504
474
  "- If unsure, return uncertain.",
505
475
  "</rules>",
506
- "</memory-supersession-input>",
476
+ "</memory-preference-adjudication-input>",
507
477
  ].join("\n");
508
478
  }
509
479
 
@@ -511,18 +481,14 @@ function supersessionPrompt(request: MemorySupersessionInput): string {
511
481
  export function createMemoryAgent(model: PluginModel): MemoryAgent {
512
482
  return {
513
483
  async adjudicateSupersession(rawRequest) {
514
- const request = supersessionRequestSchema.parse(
515
- rawRequest,
516
- ) as MemorySupersessionInput;
484
+ const request = memorySupersessionInputSchema.parse(rawRequest);
517
485
  const result = await model.completeObject({
518
- schema: supersessionDecisionResponseSchema,
519
- system: MEMORY_SUPERSESSION_SYSTEM,
520
- prompt: supersessionPrompt(request),
486
+ schema: memorySupersessionDecisionSchema,
487
+ system: MEMORY_PREFERENCE_ADJUDICATION_SYSTEM,
488
+ prompt: preferenceAdjudicationPrompt(request),
521
489
  maxTokens: 400,
522
490
  });
523
- return supersessionDecisionResponseSchema.parse(
524
- result.object,
525
- ) as MemorySupersessionDecision;
491
+ return memorySupersessionDecisionSchema.parse(result.object);
526
492
  },
527
493
  async extractSessionMemories(rawRequest) {
528
494
  const request = extractSessionRequestSchema.parse(rawRequest);