openclaw/src/agents/usage.test.ts
Vladimir Peshekhonov 957b883082
fix(agents): stabilize overflow compaction retries and session context accounting (openclaw#14102) thanks @vpesh
Verified:
- CI checks for commit 86a7ecb45ebf0be61dce9261398000524fd9fab6
- Rebase conflict resolution for compatibility with latest main

Co-authored-by: vpesh <9496634+vpesh@users.noreply.github.com>
2026-02-12 17:53:13 -06:00

93 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { deriveSessionTotalTokens, hasNonzeroUsage, normalizeUsage } from "./usage.js";
describe("normalizeUsage", () => {
it("normalizes Anthropic-style snake_case usage", () => {
const usage = normalizeUsage({
input_tokens: 1200,
output_tokens: 340,
cache_creation_input_tokens: 200,
cache_read_input_tokens: 50,
total_tokens: 1790,
});
expect(usage).toEqual({
input: 1200,
output: 340,
cacheRead: 50,
cacheWrite: 200,
total: 1790,
});
});
it("normalizes OpenAI-style prompt/completion usage", () => {
const usage = normalizeUsage({
prompt_tokens: 987,
completion_tokens: 123,
total_tokens: 1110,
});
expect(usage).toEqual({
input: 987,
output: 123,
cacheRead: undefined,
cacheWrite: undefined,
total: 1110,
});
});
it("returns undefined for empty usage objects", () => {
expect(normalizeUsage({})).toBeUndefined();
});
it("guards against empty/zero usage overwrites", () => {
expect(hasNonzeroUsage(undefined)).toBe(false);
expect(hasNonzeroUsage(null)).toBe(false);
expect(hasNonzeroUsage({})).toBe(false);
expect(hasNonzeroUsage({ input: 0, output: 0 })).toBe(false);
expect(hasNonzeroUsage({ input: 1 })).toBe(true);
expect(hasNonzeroUsage({ total: 1 })).toBe(true);
});
it("caps derived session total tokens to the context window", () => {
expect(
deriveSessionTotalTokens({
usage: {
input: 27,
cacheRead: 2_400_000,
cacheWrite: 0,
total: 2_402_300,
},
contextTokens: 200_000,
}),
).toBe(200_000);
});
it("uses prompt tokens when within context window", () => {
expect(
deriveSessionTotalTokens({
usage: {
input: 1_200,
cacheRead: 300,
cacheWrite: 50,
total: 2_000,
},
contextTokens: 200_000,
}),
).toBe(1_550);
});
it("prefers explicit prompt token overrides", () => {
expect(
deriveSessionTotalTokens({
usage: {
input: 1_200,
cacheRead: 300,
cacheWrite: 50,
total: 9_999,
},
promptTokens: 65_000,
contextTokens: 200_000,
}),
).toBe(65_000);
});
});