Skip to main content
Glama
data-optimizer.js5.92 kB
/** * 數據格式優化工具 * 用於標準化和優化記憶數據結構 */ /** * 標準化時間戳字段 * 將所有時間戳統一為 ISO 字符串格式 * @param {Object} memory - 記憶對象 * @returns {Object} 標準化後的記憶對象 */ export function normalizeTimestamps(memory) { if (!memory || typeof memory !== 'object') { return memory; } const normalized = { ...memory }; // 統一短期記憶的時間戳 if (normalized.time_stamp !== undefined) { const timestamp = new Date(normalized.time_stamp); if (!isNaN(timestamp.getTime())) { normalized.timestamp = timestamp.toISOString(); } delete normalized.time_stamp; delete normalized.timeStamp; } else if (normalized.timeStamp !== undefined) { const timestamp = new Date(normalized.timeStamp); if (!isNaN(timestamp.getTime())) { normalized.timestamp = timestamp.toISOString(); } delete normalized.timeStamp; } return normalized; } /** * 移除冗餘的 attachments 字段 * 只保留 modalities,移除重複的 attachments * @param {Object} memory - 記憶對象 * @returns {Object} 優化後的記憶對象 */ export function removeAttachmentsRedundancy(memory) { if (!memory || typeof memory !== 'object') { return memory; } const optimized = { ...memory }; // 如果有 modalities,移除 attachments if (optimized.modalities !== undefined) { delete optimized.attachments; } else if (optimized.attachments !== undefined) { // 如果只有 attachments,重命名為 modalities optimized.modalities = optimized.attachments; delete optimized.attachments; } return optimized; } /** * 去除關鍵詞重複 * 合併並去重記憶和 modality 中的關鍵詞 * @param {Array<{word: string, weight: number}>} keywords - 關鍵詞列表 * @returns {Array<{word: string, weight: number}>} 去重後的關鍵詞 */ export function deduplicateKeywords(keywords) { if (!Array.isArray(keywords)) { return []; } const keywordMap = new Map(); for (const kw of keywords) { if (!kw || typeof kw.word !== 'string') { continue; } const word = kw.word.trim().toLowerCase(); if (!word) { continue; } const weight = Number.isFinite(kw.weight) ? kw.weight : 1; if (keywordMap.has(word)) { // 如果關鍵詞已存在,取最大權重 const existing = keywordMap.get(word); existing.weight = Math.max(existing.weight, weight); } else { keywordMap.set(word, { word: kw.word, weight }); } } return Array.from(keywordMap.values()) .sort((a, b) => b.weight - a.weight); } /** * 優化記憶對象 * 應用所有優化策略 * @param {Object} memory - 記憶對象 * @param {Object} [options] - 優化選項 * @param {boolean} [options.normalizeTimestamps=true] - 是否標準化時間戳 * @param {boolean} [options.removeAttachmentsRedundancy=true] - 是否移除 attachments 冗餘 * @param {boolean} [options.deduplicateKeywords=true] - 是否去重關鍵詞 * @returns {Object} 優化後的記憶對象 */ export function optimizeMemory(memory, options = {}) { if (!memory || typeof memory !== 'object') { return memory; } const { normalizeTimestamps: shouldNormalizeTimestamps = true, removeAttachmentsRedundancy: shouldRemoveAttachmentsRedundancy = true, deduplicateKeywords: shouldDeduplicateKeywords = true } = options; let optimized = { ...memory }; // 標準化時間戳 if (shouldNormalizeTimestamps) { optimized = normalizeTimestamps(optimized); } // 移除 attachments 冗餘 if (shouldRemoveAttachmentsRedundancy) { optimized = removeAttachmentsRedundancy(optimized); } // 去重關鍵詞 if (shouldDeduplicateKeywords && Array.isArray(optimized.keywords)) { optimized.keywords = deduplicateKeywords(optimized.keywords); } return optimized; } /** * 批量優化記憶列表 * @param {Array<Object>} memories - 記憶列表 * @param {Object} [options] - 優化選項 * @returns {Array<Object>} 優化後的記憶列表 */ export function optimizeMemories(memories, options = {}) { if (!Array.isArray(memories)) { return []; } return memories.map(memory => optimizeMemory(memory, options)); } /** * 計算優化節省的空間 * @param {Object} original - 原始數據 * @param {Object} optimized - 優化後的數據 * @returns {{originalSize: number, optimizedSize: number, saved: number, savedPercent: number}} */ export function calculateSpaceSavings(original, optimized) { const originalSize = JSON.stringify(original).length; const optimizedSize = JSON.stringify(optimized).length; const saved = originalSize - optimizedSize; const savedPercent = originalSize > 0 ? (saved / originalSize) * 100 : 0; return { originalSize, optimizedSize, saved, savedPercent: Math.round(savedPercent * 100) / 100 }; } /** * 遷移舊格式數據到新格式 * @param {Object} legacyMemory - 舊格式記憶 * @returns {Object} 新格式記憶 */ export function migrateLegacyFormat(legacyMemory) { if (!legacyMemory || typeof legacyMemory !== 'object') { return legacyMemory; } const migrated = optimizeMemory(legacyMemory, { normalizeTimestamps: true, removeAttachmentsRedundancy: true, deduplicateKeywords: true }); // 添加遷移元數據 if (!migrated._migrated) { migrated._migrated = { at: new Date().toISOString(), version: '0.2.0' }; } return migrated; } export default { normalizeTimestamps, removeAttachmentsRedundancy, deduplicateKeywords, optimizeMemory, optimizeMemories, calculateSpaceSavings, migrateLegacyFormat };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/win10ogod/memory-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server