@langgraph-js/memory
Version:
A memory management system based on PostgreSQL + pgvector for LangGraph workflows
146 lines (124 loc) • 4.7 kB
text/typescript
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
import { z } from 'zod';
export const UpdateMemorySchema = z.object({
memory: z.array(
z.object({
id: z.string(),
text: z.string(),
categories: z.array(z.string()),
event: z.enum(['ADD', 'UPDATE', 'DELETE']),
old_memory: z.string(),
}),
),
});
export function getUpdateMemoryMessages(
retrievedOldMemory: Array<{ id: string; text: string }>,
newRetrievedFacts: string[],
) {
return [
new SystemMessage(`You are a memory manager. Compare existing memories with new facts and determine changes needed.
# CORE OPERATIONS
1. **ADD**: New information not in existing memory
- Set id="" and old_memory=""
2. **UPDATE**: Existing information needs modification
- When new fact adds detail: "likes cricket" → "likes playing cricket with friends" = UPDATE
- When facts convey SAME meaning: "likes pizza" vs "loves pizza" = NO CHANGE (don't return anything)
- When preferences change: "prefers light theme" → "prefers dark theme" = UPDATE (preserve evolution)
- MUST use existing memory ID
3. **DELETE**: New fact directly contradicts existing memory
- "loves cheese pizza" + new fact "dislikes cheese pizza" = DELETE old memory AND ADD new fact
- MUST use existing memory ID for DELETE
- Return BOTH operations: one DELETE for old, one ADD for new
# PRIORITY RULES
- **AVOID DUPLICATES**: If new fact is essentially the same as existing memory (same meaning, just different wording), return EMPTY array
- **HANDLE CONFLICTS**: If new fact contradicts existing memory, DELETE old and ADD new
- User preferences (likes/dislikes/habits) are CRITICAL for user profiles
- Only return changed memories (ADD/UPDATE/DELETE)
- When similar info exists, keep the one with more detail
- Empty memory → ADD all new facts
# OUTPUT FORMAT
Return a JSON object with a single "memory" field containing an array of memory operations.
All operations require these fields:
- "text": The memory content
- "categories": 2-5 relevant tags (e.g., ["preferences", "food"])
- "event": "ADD" | "UPDATE" | "DELETE"
- "id": existing ID for UPDATE/DELETE, "" for ADD
- "old_memory": previous text for UPDATE/DELETE, "" for ADD
# EXAMPLES
**ADD Example:**
Old: [{"id":"0", "text":"User is a software engineer"}]
Facts: ["Name is John"]
Output:
{
"memory": [{
"text": "Name is John",
"categories": ["personal", "name"],
"event": "ADD",
"id": "",
"old_memory": ""
}]
}
**UPDATE Example:**
Old: [{"id":"0", "text":"Likes cheese pizza"}, {"id":"2", "text":"User likes to play cricket"}]
Facts: ["Loves chicken pizza", "Loves to play cricket with friends"]
Output:
{
"memory": [
{
"id": "0",
"text": "Loves cheese and chicken pizza",
"categories": ["food", "pizza", "preferences"],
"event": "UPDATE",
"old_memory": "Likes cheese pizza"
},
{
"id": "2",
"text": "Loves to play cricket with friends",
"categories": ["sports", "cricket", "social"],
"event": "UPDATE",
"old_memory": "User likes to play cricket"
}
]
}
**DELETE Example (with conflict):**
Old: [{"id":"1", "text":"Loves cheese pizza"}]
Facts: ["Dislikes cheese pizza"]
Output:
{
"memory": [
{
"id": "1",
"text": "Loves cheese pizza",
"categories": ["food", "pizza", "preferences"],
"event": "DELETE",
"old_memory": "Loves cheese pizza"
},
{
"id": "",
"text": "Dislikes cheese pizza",
"categories": ["food", "pizza", "preferences"],
"event": "ADD",
"old_memory": ""
}
]
}
**NO CHANGE Example (duplicate):**
Old: [{"id":"1", "text":"User likes pizza"}]
Facts: ["User loves pizza"]
Output:
{
"memory": []
}
# CRITICAL CONSTRAINTS
- Return ONLY valid JSON object with "memory" field (no markdown code blocks, no extra text)
- Use existing IDs for UPDATE/DELETE (never generate new ones)
- Do NOT return unchanged memories
- Return EMPTY array [] if new fact is essentially same as existing memory (avoid duplicates)
- For conflicts: return DELETE for old + ADD for new (two operations)
- Do NOT include examples above in output`),
new HumanMessage(`Below is the current content of my memory which I have collected till now. You have to update it in the following format only:
${JSON.stringify(retrievedOldMemory, null, 2)}
The new retrieved facts are mentioned below. You have to analyze the new retrieved facts and determine whether these facts should be added, updated, or deleted in the memory.
${JSON.stringify(newRetrievedFacts, null, 2)}`),
];
}