Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions Releases/v4.0.3/.claude/hooks/RelationshipMemory.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { join } from 'path';
import { getPaiDir } from './lib/paths';
import { getPSTComponents } from './lib/time';
import { getDAName, getPrincipalName } from './lib/identity';
import { parseTranscript } from '../PAI/Tools/TranscriptParser';
import { parseTranscript, contentToText } from '../PAI/Tools/TranscriptParser';

interface HookInput {
session_id: string;
Expand Down Expand Up @@ -74,14 +74,31 @@ function readTranscriptEntries(path: string): TranscriptEntry[] {

try {
const parsed = parseTranscript(path);
// Combine user prompts and assistant completions into entry pairs
const entries: TranscriptEntry[] = [];
if (parsed.userPrompt) {
entries.push({ type: 'user', text: parsed.userPrompt });
}
if (parsed.plainCompletion) {
entries.push({ type: 'assistant', text: parsed.plainCompletion });

// Parse user and assistant messages from the raw JSONL transcript.
// parsed.userPrompt does not exist on ParsedTranscript; the previous
// code silently returned no user entries. parsed.plainCompletion is a
// short tab-title string, too small for the relationship regexes.
// Instead, iterate the raw JSONL lines (same approach TranscriptParser
// uses internally in parseLastAssistantMessage / collectCurrentResponseText).
const lines = parsed.raw.split('\n');
for (const line of lines) {
if (!line.trim()) continue;
try {
const entry = JSON.parse(line) as any;
if ((entry.type === 'human' || entry.type === 'user') && entry.message?.content) {
const text = contentToText(entry.message.content);
if (text) entries.push({ type: 'user', text });
} else if (entry.type === 'assistant' && entry.message?.content) {
const text = contentToText(entry.message.content);
if (text) entries.push({ type: 'assistant', text });
}
} catch {
// Skip invalid JSON lines
}
}

return entries;
} catch {
return [];
Expand Down