linksee-memory 0.17.0 → 0.17.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.
@@ -27,7 +27,7 @@ export const PROMPTS = [
27
27
  },
28
28
  {
29
29
  name: 'weekly-consolidation',
30
- description: 'Sleep-mode summary of the past week\'s memories for an entity. Produces a single learning-layer entry that captures the trajectory. Use as input to the consolidate tool, or to write a Friday digest.',
30
+ description: 'Sleep-mode summary of the past week\'s memories for an entity. Produces a single learning-layer entry that captures the trajectory. Use as input when distilling learnings, or to write a Friday digest.',
31
31
  arguments: [
32
32
  { name: 'entity_name', description: 'The entity to consolidate.', required: true },
33
33
  { name: 'week_offset', description: 'Weeks-ago offset (0 = this week, 1 = last week). Default 0.', required: false },
@@ -63,23 +63,23 @@ export function getPrompt(name, args) {
63
63
  role: 'user',
64
64
  content: {
65
65
  type: 'text',
66
- text: `You are an agent-memory writer. Read the session transcript below and propose memories to save. Output a JSON array; each item has {entity_name, entity_kind, layer, content, importance}.
67
-
68
- Layers (use exactly one per memory):
69
- - goal: WHY this work exists, target outcome
70
- - context: WHY THIS NOW, situation, timing
71
- - emotion: USER tone, feelings expressed
72
- - implementation: HOW it was done, what worked, what failed
73
- - caveat: PAIN lesson, "never X" / "always Y" — these are protected from forgetting
74
- - learning: GROWTH, decisions made, insights
75
-
76
- Rules:
77
- - Max 6 entries (one per layer). Skip layers with nothing worth saving.
78
- - Importance 0-1. Set 0.9+ to pin (use sparingly).
79
- - Caveats must be 1 sentence and start with a verb.
80
- - Quote nothing verbatim; summarize.
81
-
82
- Transcript:
66
+ text: `You are an agent-memory writer. Read the session transcript below and propose memories to save. Output a JSON array; each item has {entity_name, entity_kind, layer, content, importance}.
67
+
68
+ Layers (use exactly one per memory):
69
+ - goal: WHY this work exists, target outcome
70
+ - context: WHY THIS NOW, situation, timing
71
+ - emotion: USER tone, feelings expressed
72
+ - implementation: HOW it was done, what worked, what failed
73
+ - caveat: PAIN lesson, "never X" / "always Y" — these are protected from forgetting
74
+ - learning: GROWTH, decisions made, insights
75
+
76
+ Rules:
77
+ - Max 6 entries (one per layer). Skip layers with nothing worth saving.
78
+ - Importance 0-1. Set 0.9+ to pin (use sparingly).
79
+ - Caveats must be 1 sentence and start with a verb.
80
+ - Quote nothing verbatim; summarize.
81
+
82
+ Transcript:
83
83
  ${transcript}${entityHint}`,
84
84
  },
85
85
  },
@@ -96,15 +96,15 @@ ${transcript}${entityHint}`,
96
96
  role: 'user',
97
97
  content: {
98
98
  type: 'text',
99
- text: `You are a caveat extractor. Read the source text below and output a JSON list of caveats. Each caveat:
100
- - Starts with a verb ("Never", "Always", "Watch out", "Reject", "Confirm")
101
- - Is one sentence
102
- - Is concrete (a specific failure mode, not abstract advice)
103
- - Captures something the reader does NOT want to relearn the hard way
104
-
105
- Output format: [{"content": "Never X when Y, because Z", "importance": 0.7-1.0}]
106
-
107
- Source text:
99
+ text: `You are a caveat extractor. Read the source text below and output a JSON list of caveats. Each caveat:
100
+ - Starts with a verb ("Never", "Always", "Watch out", "Reject", "Confirm")
101
+ - Is one sentence
102
+ - Is concrete (a specific failure mode, not abstract advice)
103
+ - Captures something the reader does NOT want to relearn the hard way
104
+
105
+ Output format: [{"content": "Never X when Y, because Z", "importance": 0.7-1.0}]
106
+
107
+ Source text:
108
108
  ${text}${entityHint}`,
109
109
  },
110
110
  },
@@ -121,17 +121,17 @@ ${text}${entityHint}`,
121
121
  role: 'user',
122
122
  content: {
123
123
  type: 'text',
124
- text: `Consolidate the past week's memories for entity "${entityName}" (week_offset=${weekOffset}).
125
-
126
- Step 1: Call recall(query="${entityName}", entity_name="${entityName}", max_tokens=4000) to retrieve recent memories.
127
- Step 2: Read the returned memories and produce ONE learning-layer summary that captures:
128
- - What we set out to do (goal trajectory)
129
- - What actually happened (implementation summary)
130
- - What we learned (1-3 insights)
131
- - Any caveats we should never forget (preserve these — do NOT consolidate them away)
132
-
133
- Step 3: Output a JSON object {entity_name, layer:"learning", content, importance:0.7}.
134
-
124
+ text: `Consolidate the past week's memories for entity "${entityName}" (week_offset=${weekOffset}).
125
+
126
+ Step 1: Call recall(query="${entityName}", entity_name="${entityName}", max_tokens=4000) to retrieve recent memories.
127
+ Step 2: Read the returned memories and produce ONE learning-layer summary that captures:
128
+ - What we set out to do (goal trajectory)
129
+ - What actually happened (implementation summary)
130
+ - What we learned (1-3 insights)
131
+ - Any caveats we should never forget (preserve these — do NOT consolidate them away)
132
+
133
+ Step 3: Output a JSON object {entity_name, layer:"learning", content, importance:0.7}.
134
+
135
135
  Do not write to memory directly — just return the JSON. The user will choose whether to save.`,
136
136
  },
137
137
  },
@@ -151,15 +151,15 @@ Do not write to memory directly — just return the JSON. The user will choose w
151
151
  role: 'user',
152
152
  content: {
153
153
  type: 'text',
154
- text: `Before doing this task, recall first.
155
-
156
- Task: ${task}
157
-
158
- Step 1: Call ${recallCmd}.
159
- Step 2: Skim the returned memories. Identify any caveats that apply.
160
- Step 3: Produce your output with INLINE citations to relevant memory_ids: e.g. "Use better-sqlite3 v12+ [memory:1234] because v11 breaks on Node 24 [memory:5678]."
161
- Step 4: If you found NO relevant memories, say so explicitly: "No prior memories on this — proceeding from first principles."
162
-
154
+ text: `Before doing this task, recall first.
155
+
156
+ Task: ${task}
157
+
158
+ Step 1: Call ${recallCmd}.
159
+ Step 2: Skim the returned memories. Identify any caveats that apply.
160
+ Step 3: Produce your output with INLINE citations to relevant memory_ids: e.g. "Use better-sqlite3 v12+ [memory:1234] because v11 breaks on Node 24 [memory:5678]."
161
+ Step 4: If you found NO relevant memories, say so explicitly: "No prior memories on this — proceeding from first principles."
162
+
163
163
  Goal: never solve a problem twice without checking.`,
164
164
  },
165
165
  },
@@ -176,18 +176,18 @@ Goal: never solve a problem twice without checking.`,
176
176
  role: 'user',
177
177
  content: {
178
178
  type: 'text',
179
- text: `Produce a handoff document for entity "${entityName}", aimed at: ${audience}.
180
-
181
- Step 1: Call recall(query="${entityName}", entity_name="${entityName}", max_tokens=6000).
182
- Step 2: Skim memories grouped by layer.
183
- Step 3: Output a markdown doc with these sections:
184
- - **Identity**: name, kind, canonical key (if any)
185
- - **Goal** (from goal-layer memories): what this entity is for
186
- - **State** (from latest implementation memories): where things stand right now
187
- - **Caveats** (from caveat-layer memories): what NEVER to do, with memory_id citations
188
- - **Open questions**: things the prior session left unresolved
189
- - **Suggested next steps**: 3 concrete actions for the audience
190
-
179
+ text: `Produce a handoff document for entity "${entityName}", aimed at: ${audience}.
180
+
181
+ Step 1: Call recall(query="${entityName}", entity_name="${entityName}", max_tokens=6000).
182
+ Step 2: Skim memories grouped by layer.
183
+ Step 3: Output a markdown doc with these sections:
184
+ - **Identity**: name, kind, canonical key (if any)
185
+ - **Goal** (from goal-layer memories): what this entity is for
186
+ - **State** (from latest implementation memories): where things stand right now
187
+ - **Caveats** (from caveat-layer memories): what NEVER to do, with memory_id citations
188
+ - **Open questions**: things the prior session left unresolved
189
+ - **Suggested next steps**: 3 concrete actions for the audience
190
+
191
191
  Keep it under 1 page. Cite memory_ids inline like [memory:1234].`,
192
192
  },
193
193
  },
@@ -71,10 +71,10 @@ function fmtMemory(row) {
71
71
  access_count: row.access_count,
72
72
  };
73
73
  }
74
- const SELECT_MEMORY_BASE = `
75
- SELECT m.id, m.layer, m.content, m.importance, m.protected, m.created_at, m.last_accessed_at, m.access_count,
76
- e.name as entity_name, e.kind as entity_kind
77
- FROM memories m JOIN entities e ON e.id = m.entity_id
74
+ const SELECT_MEMORY_BASE = `
75
+ SELECT m.id, m.layer, m.content, m.importance, m.protected, m.created_at, m.last_accessed_at, m.access_count,
76
+ e.name as entity_name, e.kind as entity_kind
77
+ FROM memories m JOIN entities e ON e.id = m.entity_id
78
78
  `;
79
79
  export function readResource(db, uri) {
80
80
  // Static endpoints
@@ -101,9 +101,9 @@ export function readResource(db, uri) {
101
101
  // heat_band is dynamic; approximate "hot" via access_count + recent access desc.
102
102
  // For exact heat scoring, use the recall tool with band='hot'.
103
103
  const rows = db
104
- .prepare(`${SELECT_MEMORY_BASE}
105
- WHERE m.last_accessed_at IS NOT NULL
106
- ORDER BY m.access_count DESC, m.last_accessed_at DESC
104
+ .prepare(`${SELECT_MEMORY_BASE}
105
+ WHERE m.last_accessed_at IS NOT NULL
106
+ ORDER BY m.access_count DESC, m.last_accessed_at DESC
107
107
  LIMIT 50`)
108
108
  .all();
109
109
  return {
@@ -38,15 +38,15 @@ export async function sampleConsolidation(server, memoryTexts, entityName) {
38
38
  if (memoryTexts.length === 0)
39
39
  return { ok: false, reason: 'no input memories' };
40
40
  const numbered = memoryTexts.map((t, i) => `[${i + 1}] ${t}`).join('\n\n');
41
- const userPrompt = `Consolidate these ${memoryTexts.length} memories about "${entityName}" into a single learning-layer summary. The summary must:
42
- - Preserve the trajectory (what was attempted, what worked, what changed)
43
- - Be 2-4 sentences max
44
- - Not invent facts not in the originals
45
- - Not include verbatim quotes
46
-
47
- Memories:
48
- ${numbered}
49
-
41
+ const userPrompt = `Consolidate these ${memoryTexts.length} memories about "${entityName}" into a single learning-layer summary. The summary must:
42
+ - Preserve the trajectory (what was attempted, what worked, what changed)
43
+ - Be 2-4 sentences max
44
+ - Not invent facts not in the originals
45
+ - Not include verbatim quotes
46
+
47
+ Memories:
48
+ ${numbered}
49
+
50
50
  Output the summary text only — no preamble, no JSON wrapper.`;
51
51
  return sample(server, {
52
52
  systemPrompt: 'You are a memory consolidator. Compress without distorting.',
@@ -56,17 +56,17 @@ Output the summary text only — no preamble, no JSON wrapper.`;
56
56
  });
57
57
  }
58
58
  export async function sampleLayerClassification(server, content) {
59
- const userPrompt = `Classify this memory content into exactly one layer:
60
- - goal: WHY this work exists, target outcome
61
- - context: WHY THIS NOW, situation, timing
62
- - emotion: USER tone, feelings expressed
63
- - implementation: HOW it was done, what worked, what failed
64
- - caveat: PAIN lesson, "never X" / "always Y"
65
- - learning: GROWTH, decisions made, insights
66
-
67
- Content:
68
- ${content}
69
-
59
+ const userPrompt = `Classify this memory content into exactly one layer:
60
+ - goal: WHY this work exists, target outcome
61
+ - context: WHY THIS NOW, situation, timing
62
+ - emotion: USER tone, feelings expressed
63
+ - implementation: HOW it was done, what worked, what failed
64
+ - caveat: PAIN lesson, "never X" / "always Y"
65
+ - learning: GROWTH, decisions made, insights
66
+
67
+ Content:
68
+ ${content}
69
+
70
70
  Output just the layer name — no explanation, no JSON.`;
71
71
  return sample(server, {
72
72
  systemPrompt: 'You are a layer classifier. Output one word.',