UNPKG

@ai2070/l0

Version:

L0: The Missing Reliability Substrate for AI

137 lines 4.59 kB
import { normalizeForModel } from "../utils/normalize"; export function formatMemory(memory, options = {}) { if (typeof memory === "string") { return formatMemoryString(memory, options); } if (!memory || memory.length === 0) { return ""; } const { maxEntries, includeTimestamps = false, includeMetadata = false, style = "conversational", normalize = true, } = options; const entries = maxEntries ? memory.slice(-maxEntries) : memory; switch (style) { case "conversational": return formatConversationalMemory(entries, includeTimestamps, includeMetadata, normalize); case "structured": return formatStructuredMemory(entries, includeTimestamps, includeMetadata, normalize); case "compact": return formatCompactMemory(entries, normalize); default: return formatConversationalMemory(entries, includeTimestamps, includeMetadata, normalize); } } function formatConversationalMemory(entries, includeTimestamps, includeMetadata, normalize) { const lines = []; for (const entry of entries) { const content = normalize ? normalizeForModel(entry.content) : entry.content; const roleLabel = getRoleLabel(entry.role); let line = `${roleLabel}: ${content}`; if (includeTimestamps && entry.timestamp) { const date = new Date(entry.timestamp); line = `[${date.toISOString()}] ${line}`; } if (includeMetadata && entry.metadata) { const meta = Object.entries(entry.metadata) .map(([k, v]) => `${k}=${v}`) .join(", "); if (meta) { line += ` (${meta})`; } } lines.push(line); } return lines.join("\n\n"); } function formatStructuredMemory(entries, includeTimestamps, includeMetadata, normalize) { const lines = ["<conversation_history>"]; for (const entry of entries) { const content = normalize ? normalizeForModel(entry.content) : entry.content; let attrs = `role="${entry.role}"`; if (includeTimestamps && entry.timestamp) { attrs += ` timestamp="${entry.timestamp}"`; } if (includeMetadata && entry.metadata) { const metaStr = JSON.stringify(entry.metadata); attrs += ` metadata='${metaStr}'`; } lines.push(` <message ${attrs}>`); lines.push(` ${content}`); lines.push(` </message>`); } lines.push("</conversation_history>"); return lines.join("\n"); } function formatCompactMemory(entries, normalize) { return entries .map((entry) => { const content = normalize ? normalizeForModel(entry.content) : entry.content; const role = (entry.role[0] ?? "U").toUpperCase(); return `${role}: ${content}`; }) .join("\n"); } function formatMemoryString(memory, options) { const { normalize = true } = options; if (normalize) { return normalizeForModel(memory); } return memory; } function getRoleLabel(role) { switch (role) { case "user": return "User"; case "assistant": return "Assistant"; case "system": return "System"; default: return role.charAt(0).toUpperCase() + role.slice(1); } } export function createMemoryEntry(role, content, metadata) { return { role, content, timestamp: Date.now(), metadata, }; } export function mergeMemory(...memories) { return memories.flat().sort((a, b) => { const timeA = a.timestamp || 0; const timeB = b.timestamp || 0; return timeA - timeB; }); } export function filterMemoryByRole(memory, role) { return memory.filter((entry) => entry.role === role); } export function getLastNEntries(memory, n) { return memory.slice(-n); } export function calculateMemorySize(memory) { return memory.reduce((sum, entry) => sum + entry.content.length, 0); } export function truncateMemory(memory, maxSize) { const result = []; let currentSize = 0; for (let i = memory.length - 1; i >= 0; i--) { const entry = memory[i]; const entrySize = entry.content.length; if (currentSize + entrySize <= maxSize) { result.unshift(entry); currentSize += entrySize; } else { break; } } return result; } //# sourceMappingURL=memory.js.map