fix: prune context and compact earlier
This commit is contained in:
@@ -14,8 +14,8 @@ function buildPolicy(recentUserTurns = 4) {
|
||||
};
|
||||
}
|
||||
|
||||
test("pruneContextMessages replaces old bulky tool results with distilled summaries instead of deleting them", () => {
|
||||
const policy = buildPolicy(2);
|
||||
test("pruneContextMessages replaces bulky tool results with distilled summaries inside older kept turns", () => {
|
||||
const policy = buildPolicy(3);
|
||||
const bulkyFailure = [
|
||||
"Build failed while compiling focus parser",
|
||||
"Error: missing export createFocusMatcher from ./summary-focus.ts",
|
||||
@@ -23,11 +23,13 @@ test("pruneContextMessages replaces old bulky tool results with distilled summar
|
||||
].join("\n");
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "toolResult", toolName: "bash", content: bulkyFailure },
|
||||
{ role: "assistant", content: "observed turn 1" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "toolResult", toolName: "bash", content: bulkyFailure },
|
||||
{ role: "assistant", content: "observed turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
{ role: "assistant", content: "observed turn 3" },
|
||||
{ role: "user", content: "turn 4" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
@@ -38,7 +40,7 @@ test("pruneContextMessages replaces old bulky tool results with distilled summar
|
||||
assert.doesNotMatch(distilled!.content, /stack frame\nstack frame\nstack frame/);
|
||||
});
|
||||
|
||||
test("aggressive mode distills an older bulky tool result sooner than conservative mode", () => {
|
||||
test("aggressive mode drops older turns sooner than conservative mode", () => {
|
||||
const conservative = resolvePolicy({ mode: "conservative", contextWindow: 200_000 });
|
||||
const aggressive = resolvePolicy({ mode: "aggressive", contextWindow: 200_000 });
|
||||
const messages = [
|
||||
@@ -50,17 +52,18 @@ test("aggressive mode distills an older bulky tool result sooner than conservati
|
||||
{ role: "user", content: "turn 3" },
|
||||
{ role: "assistant", content: "after turn 3" },
|
||||
{ role: "user", content: "turn 4" },
|
||||
{ role: "assistant", content: "after turn 4" },
|
||||
{ role: "user", content: "turn 5" },
|
||||
];
|
||||
|
||||
const conservativePruned = pruneContextMessages(messages, conservative);
|
||||
const aggressivePruned = pruneContextMessages(messages, aggressive);
|
||||
|
||||
assert.equal(conservativePruned[1]?.content, bulky);
|
||||
assert.notEqual(aggressivePruned[1]?.content, bulky);
|
||||
assert.match(aggressivePruned[1]?.content ?? "", /^\[distilled read output\]/);
|
||||
assert.ok(conservativePruned.some((message) => message.role === "toolResult"));
|
||||
assert.ok(aggressivePruned.every((message) => message.role !== "toolResult"));
|
||||
});
|
||||
|
||||
test("pruneContextMessages keeps recent bulky tool results inside the recent-turn window", () => {
|
||||
test("pruneContextMessages keeps newest-turn bulky tool results lossless", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
@@ -68,7 +71,6 @@ test("pruneContextMessages keeps recent bulky tool results inside the recent-tur
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "toolResult", toolName: "read", content: bulky },
|
||||
{ role: "assistant", content: "observed turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
@@ -76,7 +78,7 @@ test("pruneContextMessages keeps recent bulky tool results inside the recent-tur
|
||||
assert.deepEqual(pruned, messages);
|
||||
});
|
||||
|
||||
test("pruneContextMessages keeps old non-bulky tool results outside the recent-turn window", () => {
|
||||
test("pruneContextMessages drops old non-bulky tool results outside the recent-turn window", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
@@ -89,43 +91,67 @@ test("pruneContextMessages keeps old non-bulky tool results outside the recent-t
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.deepEqual(pruned, messages);
|
||||
});
|
||||
|
||||
test("pruneContextMessages keeps exactly-150-line tool results with a trailing newline", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "toolResult", toolName: "read", content: thresholdWithTrailingNewline },
|
||||
{ role: "assistant", content: "after threshold output" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "assistant", content: "after turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.deepEqual(pruned, messages);
|
||||
});
|
||||
|
||||
test("pruneContextMessages honors the recent-user-turn boundary", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "toolResult", toolName: "read", content: bulky },
|
||||
{ role: "assistant", content: "after turn 1" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "toolResult", toolName: "read", content: boundaryBulky },
|
||||
{ role: "assistant", content: "after turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.equal(pruned[1]?.role, "toolResult");
|
||||
assert.match(pruned[1]?.content ?? "", /^\[distilled read output\]/);
|
||||
assert.deepEqual(
|
||||
pruned.map((message) => message.content),
|
||||
["turn 1", pruned[1]!.content, "after turn 1", "turn 2", boundaryBulky, "after turn 2", "turn 3"]
|
||||
["turn 2", "observed turn 2", "turn 3"],
|
||||
);
|
||||
});
|
||||
|
||||
test("pruneContextMessages keeps exactly-150-line tool results with a trailing newline inside a kept older turn", () => {
|
||||
const policy = buildPolicy(3);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "assistant", content: "after turn 1" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "toolResult", toolName: "read", content: thresholdWithTrailingNewline },
|
||||
{ role: "assistant", content: "after threshold output" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
{ role: "assistant", content: "after turn 3" },
|
||||
{ role: "user", content: "turn 4" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.equal(pruned[1]?.content, thresholdWithTrailingNewline);
|
||||
});
|
||||
|
||||
test("pruneContextMessages drops turns older than the kept suffix", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "assistant", content: "after turn 1" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "assistant", content: "after turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.deepEqual(
|
||||
pruned.map((message) => message.content),
|
||||
["turn 2", "after turn 2", "turn 3"],
|
||||
);
|
||||
});
|
||||
|
||||
test("pruneContextMessages distills bulky tool results only inside older kept turns", () => {
|
||||
const policy = buildPolicy(2);
|
||||
const messages = [
|
||||
{ role: "user", content: "turn 1" },
|
||||
{ role: "assistant", content: "after turn 1" },
|
||||
{ role: "user", content: "turn 2" },
|
||||
{ role: "toolResult", toolName: "read", content: bulky },
|
||||
{ role: "assistant", content: "after turn 2" },
|
||||
{ role: "user", content: "turn 3" },
|
||||
{ role: "toolResult", toolName: "read", content: boundaryBulky },
|
||||
{ role: "assistant", content: "after turn 3" },
|
||||
];
|
||||
|
||||
const pruned = pruneContextMessages(messages, policy);
|
||||
|
||||
assert.deepEqual(
|
||||
pruned.map((message) => message.role),
|
||||
["user", "toolResult", "assistant", "user", "toolResult", "assistant"],
|
||||
);
|
||||
assert.match(pruned[1]?.content ?? "", /^\[distilled read output\]/);
|
||||
assert.equal(pruned[4]?.content, boundaryBulky);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user