Spaces:
Paused
Paused
| import { Memory, MemoryType } from "./types"; | |
| import { getDbInstance } from "../db/core"; | |
| export interface SummarizationResult { | |
| originalCount: number; | |
| summarizedCount: number; | |
| tokensSaved: number; | |
| } | |
| export async function summarizeMemories( | |
| apiKeyId: string, | |
| sessionId?: string, | |
| maxTokens: number = 4000 | |
| ): Promise<SummarizationResult> { | |
| const db = getDbInstance(); | |
| const whereClause = sessionId | |
| ? "WHERE api_key_id = ? AND session_id = ?" | |
| : "WHERE api_key_id = ?"; | |
| const params = sessionId ? [apiKeyId, sessionId] : [apiKeyId]; | |
| const memories = db | |
| .prepare(`SELECT * FROM memories ${whereClause} ORDER BY created_at DESC`) | |
| .all(...params) as any[]; | |
| if (memories.length === 0) { | |
| return { originalCount: 0, summarizedCount: 0, tokensSaved: 0 }; | |
| } | |
| let totalTokens = 0; | |
| const toSummarize: Memory[] = []; | |
| const toKeep: Memory[] = []; | |
| for (const mem of memories) { | |
| const tokens = estimateTokens(mem.content); | |
| if (totalTokens + tokens <= maxTokens) { | |
| toKeep.push({ | |
| id: mem.id, | |
| apiKeyId: mem.api_key_id, | |
| sessionId: mem.session_id, | |
| type: mem.type as MemoryType, | |
| key: mem.key, | |
| content: mem.content, | |
| metadata: mem.metadata ? JSON.parse(mem.metadata) : {}, | |
| createdAt: new Date(mem.created_at), | |
| updatedAt: new Date(mem.updated_at), | |
| expiresAt: mem.expires_at ? new Date(mem.expires_at) : null, | |
| }); | |
| totalTokens += tokens; | |
| } else { | |
| toSummarize.push({ | |
| id: mem.id, | |
| apiKeyId: mem.api_key_id, | |
| sessionId: mem.session_id, | |
| type: mem.type as MemoryType, | |
| key: mem.key, | |
| content: mem.content, | |
| metadata: mem.metadata ? JSON.parse(mem.metadata) : {}, | |
| createdAt: new Date(mem.created_at), | |
| updatedAt: new Date(mem.updated_at), | |
| expiresAt: mem.expires_at ? new Date(mem.expires_at) : null, | |
| }); | |
| } | |
| } | |
| const summarizedCount = toSummarize.length; | |
| let tokensSaved = 0; | |
| for (const mem of toSummarize) { | |
| const summary = generateSummary(mem.content); | |
| const oldTokens = estimateTokens(mem.content); | |
| const newTokens = estimateTokens(summary); | |
| tokensSaved += oldTokens - newTokens; | |
| db.prepare("UPDATE memories SET content = ?, updated_at = ? WHERE id = ?").run( | |
| summary, | |
| new Date().toISOString(), | |
| mem.id | |
| ); | |
| } | |
| return { | |
| originalCount: memories.length, | |
| summarizedCount, | |
| tokensSaved, | |
| }; | |
| } | |
| function estimateTokens(text: string): number { | |
| return Math.ceil(text.length / 4); | |
| } | |
| function generateSummary(content: string): string { | |
| const sentences = content | |
| .split(/[.!?]+/) | |
| .map((sentence) => sentence.trim()) | |
| .filter((sentence) => sentence.length > 0); | |
| if (sentences.length <= 3) { | |
| return content; | |
| } | |
| return sentences.slice(0, 3).join(". ") + "."; | |
| } | |