fix: improve error handling and logging in summary and transcript processing
- Enhanced error handling in summary generation by using fallback messages for missing assistant messages. - Updated the `buildSummaryPrompt` function to streamline the retrieval of the last assistant message. - Improved the `extractLastMessage` function to log errors when transcript files are missing or empty, and to ensure proper handling of messages without content. - Added checks to ensure that messages of the specified role are found in the transcript, with appropriate logging for missing messages. - Refactored the logging mechanism to provide clearer insights into processing failures and successes.
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "claude-mem-plugin",
|
||||||
|
"version": "7.2.1",
|
||||||
|
"private": true,
|
||||||
|
"description": "Runtime dependencies for claude-mem bundled hooks",
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0",
|
||||||
|
"bun": ">=1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -781,7 +781,7 @@ MEMORY PROCESSING START
|
|||||||
Write progress notes of what was done, what was learned, and what's next. This is a checkpoint to capture progress so far. The session is ongoing - you may receive more requests and tool executions after this summary. Write "next_steps" as the current trajectory of work (what's actively being worked on or coming up next), not as post-session future work. Always write at least a minimal summary explaining current progress, even if work is still in early stages, so that users see a summary output tied to each request.
|
Write progress notes of what was done, what was learned, and what's next. This is a checkpoint to capture progress so far. The session is ongoing - you may receive more requests and tool executions after this summary. Write "next_steps" as the current trajectory of work (what's actively being worked on or coming up next), not as post-session future work. Always write at least a minimal summary explaining current progress, even if work is still in early stages, so that users see a summary output tied to each request.
|
||||||
|
|
||||||
Claude's Full Response to User:
|
Claude's Full Response to User:
|
||||||
${vr("Missing last_assistant_message in session for summary prompt",a,a.last_assistant_message||"")}
|
${a.last_assistant_message||vr("Missing last_assistant_message in session for summary prompt",a,"")}
|
||||||
|
|
||||||
Respond in this XML format:
|
Respond in this XML format:
|
||||||
<summary>
|
<summary>
|
||||||
|
|||||||
+2
-2
@@ -177,10 +177,10 @@ export function buildObservationPrompt(obs: Observation): string {
|
|||||||
* Build prompt to generate progress summary
|
* Build prompt to generate progress summary
|
||||||
*/
|
*/
|
||||||
export function buildSummaryPrompt(session: SDKSession): string {
|
export function buildSummaryPrompt(session: SDKSession): string {
|
||||||
const lastAssistantMessage = happy_path_error__with_fallback(
|
const lastAssistantMessage = session.last_assistant_message || happy_path_error__with_fallback(
|
||||||
'Missing last_assistant_message in session for summary prompt',
|
'Missing last_assistant_message in session for summary prompt',
|
||||||
session,
|
session,
|
||||||
session.last_assistant_message || ''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
return `PROGRESS SUMMARY CHECKPOINT
|
return `PROGRESS SUMMARY CHECKPOINT
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { readFileSync, existsSync } from 'fs';
|
import { readFileSync, existsSync } from 'fs';
|
||||||
import { logger } from '../utils/logger.js';
|
import { logger } from '../utils/logger.js';
|
||||||
|
import { happy_path_error__with_fallback } from '../utils/silent-debug.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract last message of specified role from transcript JSONL file
|
* Extract last message of specified role from transcript JSONL file
|
||||||
@@ -13,19 +14,33 @@ export function extractLastMessage(
|
|||||||
stripSystemReminders: boolean = false
|
stripSystemReminders: boolean = false
|
||||||
): string {
|
): string {
|
||||||
if (!transcriptPath || !existsSync(transcriptPath)) {
|
if (!transcriptPath || !existsSync(transcriptPath)) {
|
||||||
|
happy_path_error__with_fallback(
|
||||||
|
'Transcript path missing or file does not exist',
|
||||||
|
{ transcriptPath, role }
|
||||||
|
);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const content = readFileSync(transcriptPath, 'utf-8').trim();
|
const content = readFileSync(transcriptPath, 'utf-8').trim();
|
||||||
if (!content) return '';
|
if (!content) {
|
||||||
|
happy_path_error__with_fallback(
|
||||||
|
'Transcript file exists but is empty',
|
||||||
|
{ transcriptPath, role }
|
||||||
|
);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
|
let foundMatchingRole = false;
|
||||||
|
|
||||||
for (let i = lines.length - 1; i >= 0; i--) {
|
for (let i = lines.length - 1; i >= 0; i--) {
|
||||||
try {
|
try {
|
||||||
const line = JSON.parse(lines[i]);
|
const line = JSON.parse(lines[i]);
|
||||||
if (line.type === role && line.message?.content) {
|
if (line.type === role) {
|
||||||
|
foundMatchingRole = true;
|
||||||
|
|
||||||
|
if (line.message?.content) {
|
||||||
let text = '';
|
let text = '';
|
||||||
const msgContent = line.message.content;
|
const msgContent = line.message.content;
|
||||||
|
|
||||||
@@ -43,12 +58,29 @@ export function extractLastMessage(
|
|||||||
text = text.replace(/\n{3,}/g, '\n\n').trim();
|
text = text.replace(/\n{3,}/g, '\n\n').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log if we found the role but the text is empty after processing
|
||||||
|
if (!text || text.trim() === '') {
|
||||||
|
happy_path_error__with_fallback(
|
||||||
|
'Found message but content is empty after processing',
|
||||||
|
{ role, transcriptPath, msgContentType: typeof msgContent, stripSystemReminders }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we searched the whole transcript and didn't find any message of this role
|
||||||
|
if (!foundMatchingRole) {
|
||||||
|
happy_path_error__with_fallback(
|
||||||
|
'No message found for role in transcript',
|
||||||
|
{ role, transcriptPath, totalLines: lines.length }
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('HOOK', 'Failed to read transcript', { transcriptPath }, error as Error);
|
logger.error('HOOK', 'Failed to read transcript', { transcriptPath }, error as Error);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user