Spaces:
Paused
Paused
File size: 2,862 Bytes
35743bd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 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(". ") + ".";
}
|