/** * Pure helpers shared by the chat route (server) and the chat UI (client): * token budgeting and the sliding history window. No directive, no deps, so * both sides can import it. */ /** Rough token estimate (≈4 chars per token) — good enough for budgeting. */ export function estimateTokens(text: string): number { return Math.ceil(text.length / 4); } /** How much conversation history the sliding window keeps (≈6k tokens). */ export const HISTORY_TOKEN_BUDGET = 6000; /** Keeps the most recent turns that fit the budget (sliding window). */ export function trimHistory( messages: T[], budget = HISTORY_TOKEN_BUDGET, ): T[] { const kept: T[] = []; let used = 0; for (let index = messages.length - 1; index >= 0; index -= 1) { const message = messages[index]; const cost = estimateTokens(message.content); if (kept.length > 0 && used + cost > budget) break; kept.unshift(message); used += cost; } return kept; }