fix(compression): address PR #1717 review feedback

- chatCore: remove shadowed const, update estimatedTokens after compression
- aggressive: fix techniquesUsed overwrite (.push), use estimateTokens() for savings
- toolResultCompressor: add estimateTokens helper, convert all saved: to token math
- progressiveAging: add estimateTokens helper, convert all saved += to token math
This commit is contained in:
oyi77
2026-04-28 20:54:54 +07:00
parent 6bf7b9601d
commit 4f7a0c265d
4 changed files with 44 additions and 17 deletions

View File

@@ -1226,7 +1226,7 @@ export async function handleChatCore({
const allMessages =
body?.messages || body?.input || body?.contents || body?.request?.contents || [];
if (body && Array.isArray(allMessages) && allMessages.length > 0) {
const estimatedTokens = estimateTokens(JSON.stringify(allMessages));
let estimatedTokens = estimateTokens(JSON.stringify(allMessages));
let contextLimit = getTokenLimit(provider, effectiveModel);
if (isCombo && comboName) {
@@ -1271,7 +1271,7 @@ export async function handleChatCore({
// Prompt compression pipeline — Phase 1 (lite) + Phase 2 (standard/caveman)
try {
const compressionConfig = getCompressionSettings();
const estimatedTokens = estimateCompressionTokens(body);
estimatedTokens = estimateCompressionTokens(body);
const mode = selectCompressionStrategy(compressionConfig, comboName ?? null, estimatedTokens);
if (mode !== "off") {
const compressionResult = applyCompression(body as Record<string, unknown>, mode, {
@@ -1281,6 +1281,7 @@ export async function handleChatCore({
if (compressionResult.compressed && compressionResult.stats) {
body = compressionResult.body as typeof body;
const s = compressionResult.stats;
estimatedTokens = s.compressedTokens;
log?.info?.(
"COMPRESSION",
`Prompt compression (${s.mode}): ${s.originalTokens}${s.compressedTokens} tokens (${s.savingsPercent}% savings, ${s.durationMs ?? 0}ms${

View File

@@ -121,7 +121,7 @@ export function compressAggressive(
preserveCode: true,
});
if (summary && summary.length < text.length) {
summarizerSavings += text.length - summary.length;
summarizerSavings += estimateTokens(text) - estimateTokens(summary);
return setContent(msg, `[COMPRESSED:summary] ${summary}`);
}
return msg;
@@ -172,11 +172,11 @@ export function compressAggressive(
}
}
resultStats.techniquesUsed = [
resultStats.techniquesUsed.push(
...(toolResultSavings > 0 ? ["toolResult"] : []),
...(agingSavings > 0 ? ["aging"] : []),
...(summarizerSavings > 0 ? ["summarizer"] : []),
];
...(summarizerSavings > 0 ? ["summarizer"] : [])
);
resultStats.aggressive = {
summarizerSavings,

View File

@@ -5,6 +5,10 @@ import { cavemanCompress } from "./caveman.ts";
const COMPRESSED_MARKER_RE = /^\[COMPRESSED:/;
function estimateTokens(text: string): number {
return Math.ceil(text.length / 4);
}
interface ChatMessage {
role: string;
content?: string | Array<{ type: string; text?: string }>;
@@ -73,7 +77,7 @@ export function applyAging(
? compressed.body.messages[0].content
: extractText(compressed.body.messages[0].content);
const tagged = `[COMPRESSED:aging:light] ${newContent}`;
saved += text.length - tagged.length;
saved += estimateTokens(text) - estimateTokens(tagged);
result.push(setContent(msg, tagged));
} else {
result.push(msg);
@@ -86,7 +90,7 @@ export function applyAging(
? compressed.body.messages[0].content
: extractText(compressed.body.messages[0].content);
const tagged = `[COMPRESSED:aging:moderate] ${newContent}`;
saved += text.length - tagged.length;
saved += estimateTokens(text) - estimateTokens(tagged);
result.push(setContent(msg, tagged));
} else {
result.push(msg);
@@ -95,12 +99,12 @@ export function applyAging(
if (msg.role === "assistant") {
const summary = sum.summarize([msg]);
const tagged = `[COMPRESSED:aging:fullSummary] ${summary}`;
saved += text.length - tagged.length;
saved += estimateTokens(text) - estimateTokens(tagged);
result.push(setContent(msg, tagged));
} else if (msg.role === "user") {
const firstLine = text.split("\n")[0]?.slice(0, 120) ?? "";
const tagged = `[COMPRESSED:aging:fullSummary] ${firstLine}`;
saved += text.length - tagged.length;
saved += estimateTokens(text) - estimateTokens(tagged);
result.push(setContent(msg, tagged));
} else {
result.push(msg);

View File

@@ -110,41 +110,63 @@ function compressErrorMessage(content: string): string | null {
return result;
}
export function compressToolResult(content: string, opts: ToolStrategiesConfig): CompressionResult {
const originalLen = content.length;
function estimateTokens(text: string): number {
return Math.ceil(text.length / 4);
}
export function compressToolResult(content: string, opts: ToolStrategiesConfig): CompressionResult {
if (opts.fileContent) {
const result = compressFileContent(content);
if (result !== null) {
return { compressed: result, strategy: "fileContent", saved: originalLen - result.length };
return {
compressed: result,
strategy: "fileContent",
saved: estimateTokens(content) - estimateTokens(result),
};
}
}
if (opts.grepSearch) {
const result = compressGrepSearch(content);
if (result !== null) {
return { compressed: result, strategy: "grepSearch", saved: originalLen - result.length };
return {
compressed: result,
strategy: "grepSearch",
saved: estimateTokens(content) - estimateTokens(result),
};
}
}
if (opts.shellOutput) {
const result = compressShellOutput(content);
if (result !== null) {
return { compressed: result, strategy: "shellOutput", saved: originalLen - result.length };
return {
compressed: result,
strategy: "shellOutput",
saved: estimateTokens(content) - estimateTokens(result),
};
}
}
if (opts.json) {
const result = compressJson(content);
if (result !== null) {
return { compressed: result, strategy: "json", saved: originalLen - result.length };
return {
compressed: result,
strategy: "json",
saved: estimateTokens(content) - estimateTokens(result),
};
}
}
if (opts.errorMessage) {
const result = compressErrorMessage(content);
if (result !== null) {
return { compressed: result, strategy: "errorMessage", saved: originalLen - result.length };
return {
compressed: result,
strategy: "errorMessage",
saved: estimateTokens(content) - estimateTokens(result),
};
}
}