diff --git a/open-sse/rtk/headroom.js b/open-sse/rtk/headroom.js index 880195ff..2b15eed2 100644 --- a/open-sse/rtk/headroom.js +++ b/open-sse/rtk/headroom.js @@ -25,9 +25,17 @@ function messagePayload(body) { function captureSizeSnapshot(body) { const messages = messagePayload(body); + const toolHistory = messages?.filter((message) => + message?.role === "tool" + || message?.role === "function" + || message?.tool_calls?.length + || message?.content?.some?.((part) => part?.type === "tool_use" || part?.type === "tool_result") + ) || []; return { bodyBytes: jsonBytes(body), messageBytes: messages ? jsonBytes(messages) : 0, + toolSchemaBytes: jsonBytes(body?.tools || []), + toolHistoryBytes: jsonBytes(toolHistory), }; } @@ -336,7 +344,10 @@ export function formatHeadroomSizeLog(diagnostics) { const before = diagnostics?.before; const after = diagnostics?.after; if (!before || !after) return ""; - return `body=${before.bodyBytes}B→${after.bodyBytes}B messages=${before.messageBytes}B→${after.messageBytes}B`; + const effective = before.bodyBytes > 0 + ? (((before.bodyBytes - after.bodyBytes) / before.bodyBytes) * 100).toFixed(1) + : "0.0"; + return `body=${before.bodyBytes}B→${after.bodyBytes}B messages=${before.messageBytes}B→${after.messageBytes}B tools=${before.toolSchemaBytes || 0}B→${after.toolSchemaBytes || 0}B toolHistory=${before.toolHistoryBytes || 0}B→${after.toolHistoryBytes || 0}B effective=${effective}%`; } export function isHeadroomPhantomSavings(stats, diagnostics, minShrinkRatio = 0.05) { diff --git a/tests/unit/headroom.test.js b/tests/unit/headroom.test.js index b7c414d0..a5d28112 100644 --- a/tests/unit/headroom.test.js +++ b/tests/unit/headroom.test.js @@ -1,5 +1,5 @@ import { describe, it, expect, vi, afterEach } from "vitest"; -import { compressWithHeadroom, formatHeadroomLog } from "../../open-sse/rtk/headroom.js"; +import { compressWithHeadroom, formatHeadroomLog, formatHeadroomSizeLog } from "../../open-sse/rtk/headroom.js"; afterEach(() => { vi.restoreAllMocks(); @@ -209,4 +209,11 @@ describe("formatHeadroomLog", () => { expect(formatHeadroomLog({ tokens_before: 100, tokens_after: 25, tokens_saved: 75 })) .toBe("reported token delta=75 before=100 after=25 (75.0%)"); }); + + it("reports effective payload, tool-schema, and tool-history sizes", () => { + expect(formatHeadroomSizeLog({ + before: { bodyBytes: 1000, messageBytes: 800, toolSchemaBytes: 100, toolHistoryBytes: 500 }, + after: { bodyBytes: 900, messageBytes: 700, toolSchemaBytes: 100, toolHistoryBytes: 400 }, + })).toContain("tools=100B→100B toolHistory=500B→400B effective=10.0%"); + }); });