mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-02 17:54:22 +10:00
fix(api): prune superseded read_letter snapshots
SNAPSHOT_TOOL_NAMES lacked read_letter, and the snapshot check looked for the resume key on every result other than read_resume's, so each cover letter read stayed in the model context. The superseded note now names both read tools.
This commit is contained in:
@@ -4,11 +4,11 @@ import { estimateTokens, pruneAgentModelContext } from "./context";
|
||||
|
||||
const BIG_RESUME = { basics: { name: "Alice" }, sections: { summary: { content: "x".repeat(2_000) } } };
|
||||
|
||||
function readResumeExchange(callId: string): ModelMessage[] {
|
||||
function readResumeExchange(callId: string, toolName = "read_resume"): ModelMessage[] {
|
||||
return [
|
||||
{
|
||||
role: "assistant",
|
||||
content: [{ type: "tool-call", toolCallId: callId, toolName: "read_resume", input: {} }],
|
||||
content: [{ type: "tool-call", toolCallId: callId, toolName, input: {} }],
|
||||
},
|
||||
{
|
||||
role: "tool",
|
||||
@@ -16,7 +16,7 @@ function readResumeExchange(callId: string): ModelMessage[] {
|
||||
{
|
||||
type: "tool-result",
|
||||
toolCallId: callId,
|
||||
toolName: "read_resume",
|
||||
toolName,
|
||||
output: { type: "json", value: { id: "resume-1", data: BIG_RESUME } },
|
||||
},
|
||||
],
|
||||
@@ -64,10 +64,23 @@ describe("pruneAgentModelContext — tier 0 (snapshot supersession)", () => {
|
||||
const pruned = pruneAgentModelContext(messages, 1_000_000);
|
||||
|
||||
expect(snapshotValue(pruned[2])).not.toHaveProperty("data");
|
||||
expect(snapshotValue(pruned[2]).note).toContain("Superseded resume snapshot");
|
||||
expect(snapshotValue(pruned[2]).note).toContain("Superseded document snapshot");
|
||||
expect(snapshotValue(pruned[4])).toHaveProperty("resume");
|
||||
});
|
||||
|
||||
it("keeps only the last cover letter snapshot too", () => {
|
||||
const messages = [
|
||||
user("hi"),
|
||||
...readResumeExchange("call-1", "read_letter"),
|
||||
...readResumeExchange("call-2", "read_letter"),
|
||||
];
|
||||
|
||||
const pruned = pruneAgentModelContext(messages, 1_000_000);
|
||||
|
||||
expect(snapshotValue(pruned[2])).not.toHaveProperty("data");
|
||||
expect(snapshotValue(pruned[4])).toHaveProperty("data");
|
||||
});
|
||||
|
||||
it("returns the same array reference when there is at most one snapshot", () => {
|
||||
const messages = [user("hi"), ...readResumeExchange("call-1")];
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ import { estimateTokenCount as estimateTextTokenCount } from "tokenx";
|
||||
|
||||
const AGENT_CONTEXT_TOKEN_BUDGET = 40_000;
|
||||
|
||||
const SNAPSHOT_TOOL_NAMES = new Set(["read_resume", "apply_resume_patch"]);
|
||||
const SNAPSHOT_TOOL_NAMES = new Set(["read_resume", "read_letter", "apply_resume_patch"]);
|
||||
const SUPERSEDED_SNAPSHOT_NOTE =
|
||||
"Superseded resume snapshot removed. Base further edits on the resume state in the latest read_resume or apply_resume_patch result.";
|
||||
"Superseded document snapshot removed. Base further edits on the latest read_resume, read_letter or apply_resume_patch result.";
|
||||
const PRUNED_TOOL_RESULT_NOTE = "Older tool result pruned to fit the context budget.";
|
||||
|
||||
type LoosePart = Record<string, unknown> & { type: string };
|
||||
@@ -69,7 +69,7 @@ function isSnapshotResultPart(part: LoosePart): boolean {
|
||||
const value = unwrapToolOutput(part.output);
|
||||
if (!value || typeof value !== "object") return false;
|
||||
|
||||
return part.toolName === "read_resume" ? "data" in value : "resume" in value;
|
||||
return part.toolName === "apply_resume_patch" ? "resume" in value : "data" in value;
|
||||
}
|
||||
|
||||
function supersedeSnapshotPart(part: LoosePart): LoosePart {
|
||||
|
||||
Reference in New Issue
Block a user