import type { ClientChatMessage } from "./messages"; export type AssistantChatMessage = { role: "user" | "assistant"; content: string; imageUrl?: string; toolCalls?: Array<{ name: string; status: number }>; }; const STORAGE_VERSION = "v2"; const MAX_MESSAGES = 40; function storageKey(userId: string) { return `assistant-chat:${STORAGE_VERSION}:${userId}`; } function isValidMessage(value: unknown): value is AssistantChatMessage { if (!value || typeof value !== "object") return false; const row = value as Record; if (row.role !== "user" && row.role !== "assistant") return false; if (typeof row.content !== "string" || row.content.trim().length === 0) return false; if (row.imageUrl !== undefined && typeof row.imageUrl !== "string") return false; if (row.toolCalls !== undefined) { if (!Array.isArray(row.toolCalls)) return false; for (const call of row.toolCalls) { if (!call || typeof call !== "object") return false; const entry = call as Record; if (typeof entry.name !== "string" || typeof entry.status !== "number") return false; } } return true; } export function toClientChatMessage(message: AssistantChatMessage): ClientChatMessage { if (!message.imageUrl) { return { role: message.role, content: message.content }; } return { role: message.role, content: message.content, attachments: [{ type: "image", url: message.imageUrl }], }; } export function loadAssistantChat(userId: string): AssistantChatMessage[] { try { const raw = localStorage.getItem(storageKey(userId)); if (!raw) return []; const parsed: unknown = JSON.parse(raw); if (!Array.isArray(parsed)) return []; return parsed.filter(isValidMessage).slice(-MAX_MESSAGES); } catch { return []; } } export function saveAssistantChat(userId: string, messages: AssistantChatMessage[]): void { try { const trimmed = messages.slice(-MAX_MESSAGES); if (trimmed.length === 0) { localStorage.removeItem(storageKey(userId)); return; } localStorage.setItem(storageKey(userId), JSON.stringify(trimmed)); } catch { // Private browsing, quota exceeded, or disabled storage. } } export function clearAssistantChat(userId: string): void { try { localStorage.removeItem(storageKey(userId)); } catch { // Ignore storage errors. } }