/** * Persist portal direct-chat transcripts before Goosed escalation wipes snapshot cache. */ import { extractConversationMessageText } from './conversation-memory.mjs'; export function filterNonemptyUserVisibleMessages(messages) { if (!Array.isArray(messages)) return []; return messages.filter((message) => { if (message?.metadata?.userVisible === false) return false; return Boolean(extractConversationMessageText(message)); }); } export async function loadSnapshotMessages(sessionSnapshotService, sessionId) { if (!sessionSnapshotService?.get || !sessionId) return []; const snapshot = await sessionSnapshotService.get(sessionId).catch(() => null); return Array.isArray(snapshot?.messages) ? snapshot.messages : []; } export async function persistSessionTranscriptMessages({ conversationMemoryService, sessionId, userId, messages, } = {}) { if (!conversationMemoryService?.saveConversationMessages || !sessionId || !userId) { return { saved: 0, skipped: true }; } const persistable = filterNonemptyUserVisibleMessages(messages); if (!persistable.length) return { saved: 0, skipped: true }; const saved = await conversationMemoryService.saveConversationMessages( sessionId, userId, persistable, ); return { saved: Array.isArray(saved) ? saved.length : persistable.length, skipped: false }; } export async function persistSessionTranscriptFromSnapshot({ sessionSnapshotService, conversationMemoryService, sessionId, userId, sourceSessionId = null, } = {}) { const sourceIds = [...new Set([sourceSessionId, sessionId].filter(Boolean))]; let totalSaved = 0; for (const sourceId of sourceIds) { const messages = await loadSnapshotMessages(sessionSnapshotService, sourceId); const result = await persistSessionTranscriptMessages({ conversationMemoryService, sessionId, userId, messages, }); totalSaved += result.saved; } return { saved: totalSaved }; }