@voidwire/llm-summarize 3.9.3 → 3.10.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.
Files changed (2) hide show
  1. package/index.ts +53 -90
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -25,16 +25,19 @@ export interface Extraction {
25
25
 
26
26
  export interface SessionInsights {
27
27
  summary: string;
28
- // Quick mode extraction fields
29
- should_search?: boolean;
28
+ // Optional fields populated by custom prompts (e.g., Lore injection)
30
29
  extractions?: Extraction[];
31
- // Insights mode fields
30
+ keywords?: string[];
31
+ // Insights mode fields (delta extraction)
32
32
  current_focus?: string;
33
33
  next_steps?: string[];
34
34
  decisions?: string[];
35
+ corrections?: string[];
36
+ validated?: string[];
37
+ problems_solved?: string[];
38
+ // Legacy fields — kept for backward compatibility with existing session JSONL data
35
39
  patterns_used?: string[];
36
40
  preferences_expressed?: string[];
37
- problems_solved?: string[];
38
41
  }
39
42
 
40
43
  export interface SummarizeResult {
@@ -69,71 +72,13 @@ export type SummarizeMode = "quick" | "insights";
69
72
 
70
73
  /**
71
74
  * Build quick mode prompt with optional user name
72
- * Now includes context extraction for knowledge retrieval
73
75
  */
74
76
  function buildQuickPrompt(userName?: string): string {
75
- const name = userName || "User";
76
-
77
- return `You are a context classifier for knowledge retrieval. Analyze conversation context to determine what prior knowledge would be valuable.
78
-
79
- Input format:
80
- Project: <project name>
81
- Previous Assistant: <last assistant message>
82
- User Prompt: <current user message>
83
-
84
- Produce JSON with:
85
- 1. summary: Brief description (1-2 sentences) of what the user is doing/asking. Start with "${name}". Include 2-3 key searchable terms from the prompt (names, tools, concepts) naturally in the sentence.
86
- 2. should_search: Whether to search the knowledge base
87
- 3. extractions: Terms worth searching for
88
-
89
- should_search = true when:
90
- - References past work, decisions, discussions
91
- - Mentions project, tool, or person by name
92
- - Asks "what was...", "how did we...", "remember when..."
93
- - Technical domain benefits from prior learnings
94
-
95
- should_search = false when:
96
- - Greetings, acknowledgments ("ready", "thanks", "ok")
97
- - Simple commands ("run tests", "commit this")
98
- - Continuation signals ("yes", "do it", "go ahead")
99
-
100
- Extraction types:
101
- - project: Named codebase, repo, system (sable, lore, momentum)
102
- - topic: Domain, concept, technical area (hooks, authentication, Tier 2)
103
- - tool: Library, CLI, framework (llm-summarize, SQLite, Bun)
104
- - person: Named individual
105
-
106
- Confidence:
107
- - high: Explicitly stated
108
- - medium: Strongly implied
109
-
110
- Skip generic words. Only extract terms that yield useful knowledge results.
111
-
112
- <example>
113
- Project: sable
114
- Previous Assistant: I'll update the UserPromptSubmit hook to call llm-summarize.
115
- User Prompt: What does Lore return for project queries?
116
-
117
- {"summary": "${name} is asking about Lore's return format for project queries", "should_search": true, "extractions": [{"term": "Lore", "type": "project", "confidence": "high"}, {"term": "project queries", "type": "topic", "confidence": "high"}]}
118
- </example>
119
-
120
- <example>
121
- Project: sable
122
- Previous Assistant: The extraction prompt is ready. Should I add it?
123
- User Prompt: yes do it
124
-
125
- {"summary": "${name} is confirming to proceed with the extraction prompt", "should_search": false, "extractions": []}
126
- </example>
127
-
128
- <example>
129
- Project: sable
130
- Previous Assistant: Starting new session.
131
- User Prompt: What was the issue we hit with the stop hook last time?
132
-
133
- {"summary": "${name} is asking about a previous issue with the stop hook", "should_search": true, "extractions": [{"term": "stop hook", "type": "topic", "confidence": "high"}, {"term": "sable", "type": "project", "confidence": "medium"}]}
134
- </example>
77
+ const nameInstruction = userName ? `Start with "${userName}".` : "";
135
78
 
136
- Output valid JSON only. No markdown, no explanation.`;
79
+ return `Summarize what the user is asking or doing in one sentence.
80
+ ${nameInstruction}
81
+ Output JSON only: {"summary": "One sentence summary"}`;
137
82
  }
138
83
 
139
84
  /**
@@ -141,53 +86,71 @@ Output valid JSON only. No markdown, no explanation.`;
141
86
  * Note: userName param kept for API compatibility but not used in insights mode
142
87
  */
143
88
  function buildInsightsPrompt(_userName?: string): string {
144
- return `You are a session state extractor. Given a development conversation, produce a JSON snapshot of the session's current state.
89
+ return `You are a session delta extractor. Given a development conversation and the previous state snapshot, extract ONLY what is NEW since the last snapshot.
145
90
 
146
91
  <instructions>
147
- 1. Read the conversation in the <transcript> section
148
- 2. Ignore the <previous_state> section — it is background context only, not part of this session
149
- 3. Extract ONLY what happened in the transcript
150
- 4. Produce a JSON object with the fields described below
92
+ 1. Read the <previous_state> section this is what was already known
93
+ 2. Read the <transcript> section — this is what happened since
94
+ 3. Extract ONLY new information not already captured in previous_state
95
+ 4. Skip any lines containing markers (📁 CAPTURE, 📚 TEACH, 👤 OBSERVE, 🗣️, ─── REFLECT) — these are handled by a separate system
96
+ 5. Focus on: what decisions were made, what changed direction, what the user corrected, what approach was validated
97
+ 6. Produce a JSON delta object
151
98
  </instructions>
152
99
 
153
100
  <fields>
154
- - summary: One sentence describing what was accomplished this session
155
- - current_focus: The specific task or feature being worked on (omit if exploratory)
156
- - next_steps: Array of concrete next actions. Name the specific task.
157
- - decisions: Array of decisions made this session, each with rationale
158
- - patterns_used: Array of techniques or approaches applied, each with context
159
- - preferences_expressed: Array of user preferences revealed through direction or correction
160
- - problems_solved: Array of problems encountered with root cause and fix
101
+ - summary: One sentence what CHANGED since last snapshot, not a re-summary of the whole session
102
+ - current_focus: The specific task or topic right now (omit if unchanged from previous_state)
103
+ - decisions: New decisions only include the rationale ("X because Y"). Skip if already in previous_state.
104
+ - corrections: Things the user pushed back on or redirected. Quote their words when possible.
105
+ - validated: Approaches the user approved or confirmed worked. Only when non-obvious.
106
+ - next_steps: Concrete next actions that emerged THIS turn. Name specifics.
107
+ - problems_solved: New problems with root cause and fix. Skip re-statements.
161
108
  </fields>
162
109
 
163
- Include a field only when the transcript contains clear evidence. Omit empty arrays. Every value must be a complete sentence.
110
+ <rules>
111
+ - If nothing meaningful changed since previous_state, return {"summary": "continuation", "current_focus": "unchanged"}
112
+ - NEVER repeat information from previous_state — this is a delta, not a snapshot
113
+ - "User clarified X" is NOT a correction — only record corrections when the user explicitly redirects, rejects, or changes direction
114
+ - Every field value must be specific enough to be useful 6 months from now without context
115
+ </rules>
164
116
 
165
117
  <example>
166
118
  <input>
167
- <previous_state>Focus: Building authentication system</previous_state>
119
+ <previous_state>
120
+ ## Context
121
+ - **Focus:** JWT authentication implementation
122
+ - Chose JWT over sessions — eliminates Redis dependency
123
+ ## Next
124
+ - Test refresh token flow
125
+ </previous_state>
168
126
  <transcript>
169
- User Asked: Let's use JWT instead of sessions for auth
170
- Assistant Response: Switched from express-session to jsonwebtoken. JWTs are stateless so we don't need Redis for session storage anymore. Updated the middleware to verify tokens on each request.
171
- User Asked: Make sure the tokens expire after 24 hours
172
- Assistant Response: Set expiresIn to 24h in the sign options. Also added a refresh token flow so users don't get logged out mid-work.
127
+ User: Actually let's use sessions after all the team is more familiar with them and we already have Redis in prod
128
+ Assistant: Switched back to express-session with Redis store. Removed the JWT middleware.
129
+ User: Good. And make the session timeout 8 hours not the default 24.
173
130
  </transcript>
174
131
  </input>
175
132
  <output>
176
- {"summary":"Implemented JWT-based authentication replacing session-based auth, with 24-hour token expiry and refresh token flow","current_focus":"Authentication system implementation","next_steps":["Test the refresh token flow with expired tokens","Add token revocation for logout"],"decisions":["Chose JWT over sessions eliminates Redis dependency since tokens are stateless","Set 24-hour token expiry with refresh flow balances security with user convenience"],"preferences_expressed":["User directed specific token expiry of 24 hours"]}
133
+ {"summary":"Reversed JWT decision back to sessions team familiarity and existing Redis infra","current_focus":"Session-based authentication","decisions":["Reverted to express-session with Redis — team familiarity with sessions outweighs JWT's statelessness benefit, Redis already in production"],"corrections":["User reversed the JWT decision after initial implementationteam constraints weren't considered"],"next_steps":["Configure 8-hour session timeout","Remove JWT dependencies"]}
177
134
  </output>
178
135
  </example>
179
136
 
180
137
  <example>
181
138
  <input>
182
- <previous_state>Focus: Investigating test failures</previous_state>
139
+ <previous_state>
140
+ ## Context
141
+ - **Focus:** Debugging webhook test failures
142
+ - Fixed hardcoded timestamp in tests
143
+ ## Next
144
+ - Verify CI passes
145
+ </previous_state>
183
146
  <transcript>
184
- User Asked: The CI is failing on the webhook tests
185
- Assistant Response: Found the issue — the test was using a hardcoded timestamp that expired. Changed it to use a relative timestamp. Also found that the webhook handler had a race condition where two events could arrive simultaneously and both pass the idempotency check. Added a mutex lock.
186
- User Asked: Good catch on the race condition
147
+ User: CI is green now. Let's move on to the API rate limiter.
148
+ Assistant: Starting on the rate limiter. I'll use a sliding window approach with Redis.
149
+ User: Sounds good.
187
150
  </transcript>
188
151
  </input>
189
152
  <output>
190
- {"summary":"Fixed CI test failure caused by hardcoded timestamp and discovered a race condition in the webhook handler","current_focus":"Webhook test failures and handler reliability","problems_solved":["Fixed expired hardcoded timestamp in webhook tests replaced with relative timestamp calculation","Fixed race condition in webhook handler where simultaneous events bypassed idempotency check — added mutex lock"],"next_steps":["Verify CI passes with the timestamp and mutex fixes"]}
153
+ {"summary":"CI fixed, pivoted to API rate limiter","current_focus":"API rate limiter implementation","validated":["Sliding window rate limiting with Redisuser approved without pushback"],"next_steps":["Implement sliding window rate limiter with Redis"]}
191
154
  </output>
192
155
  </example>
193
156
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidwire/llm-summarize",
3
- "version": "3.9.3",
3
+ "version": "3.10.0",
4
4
  "description": "Structured session insight extraction for knowledge systems",
5
5
  "type": "module",
6
6
  "main": "./index.ts",