wiwiway / src /lib /memory /summarization.ts
Claude Code
Sync gateway codebase without binaries
116b4cb
Raw
History Blame Contribute Delete
2.86 kB
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(". ") + ".";
}