fix(agents): cap new prompt projection output

This commit is contained in:
Vincent Koc
2026-06-21 22:26:22 +08:00
parent ef6dc8f7e5
commit 79fac9fda9
2 changed files with 61 additions and 0 deletions

View File

@@ -496,6 +496,31 @@ describe("truncateOversizedToolResultsInMessages", () => {
);
expect(stableFirst.truncatedCount).toBe(0);
expect(stableSecond.messages.slice(0, stableHistory.length)).toEqual(stableFirst.messages);
const stableThird = truncateOversizedToolResultsInMessages(
[
...stableHistory,
makeToolResult("c".repeat(15_000), "stable_3"),
makeToolResult("d".repeat(15_000), "stable_4"),
],
128_000,
12_000,
12_000,
stableState,
);
const stableFourth = truncateOversizedToolResultsInMessages(
[
...stableHistory,
makeToolResult("c".repeat(15_000), "stable_3"),
makeToolResult("d".repeat(15_000), "stable_4"),
makeToolResult("e".repeat(15_000), "stable_5"),
],
128_000,
12_000,
12_000,
stableState,
);
const lastText = stableFourth.messages.at(-1);
expect(lastText && getToolResultTextLength(lastText)).toBeLessThanOrEqual(12_000);
});
it("does not restore filtered image blocks when reusing a projection", () => {

View File

@@ -588,9 +588,45 @@ function buildAggregateToolResultReplacements(params: {
remainingReduction -= actualReduction;
}
if (remainingReduction > 0) {
for (const candidate of candidates.filter((item) => item.aggregateEligible)) {
if (remainingReduction <= 0) {
break;
}
if (replacements.some((replacement) => replacement.entryId === candidate.entryId)) {
continue;
}
const emptyMessage = clearToolResultText(candidate.message);
const actualReduction = Math.max(
0,
candidate.textLength - getToolResultTextLength(emptyMessage),
);
if (actualReduction <= 0) {
continue;
}
replacements.push({ entryId: candidate.entryId, message: emptyMessage });
remainingReduction -= actualReduction;
}
}
return replacements;
}
function clearToolResultText(message: AgentMessage): AgentMessage {
const content = (message as { content?: unknown }).content;
if (!Array.isArray(content)) {
return message;
}
return {
...message,
content: content.map((block) =>
block && typeof block === "object" && (block as { type?: unknown }).type === "text"
? { ...block, text: "" }
: block,
),
} as AgentMessage;
}
function buildOversizedToolResultReplacements(params: {
branch: ToolResultBranchEntry[];
maxChars: number;