






















@@ -976,6 +976,123 @@ describe("updateSessionStoreAfterAgentRun", () => {
976976});
977977});
978978979+it("prefers fresh CLI usage over zero compaction tokensAfter", async () => {
980+await withTempSessionStore(async ({ storePath }) => {
981+const cfg = {} as OpenClawConfig;
982+const sessionKey = "agent:main:explicit:test-zero-compaction-with-usage";
983+const sessionId = "test-zero-compaction-with-usage-session";
984+const sessionStore: Record<string, SessionEntry> = {
985+[sessionKey]: {
986+ sessionId,
987+updatedAt: 1,
988+totalTokens: 1_794_391,
989+totalTokensFresh: true,
990+inputTokens: 20,
991+outputTokens: 10_855,
992+cacheRead: 1_761_324,
993+cacheWrite: 33_047,
994+},
995+};
996+await fs.writeFile(storePath, JSON.stringify(sessionStore, null, 2));
997+998+await updateSessionStoreAfterAgentRun({
999+ cfg,
1000+ sessionId,
1001+ sessionKey,
1002+ storePath,
1003+ sessionStore,
1004+defaultProvider: "claude-cli",
1005+defaultModel: "claude-opus-4-7",
1006+result: {
1007+meta: {
1008+durationMs: 500,
1009+agentMeta: {
1010+ sessionId,
1011+provider: "claude-cli",
1012+model: "claude-opus-4-7",
1013+usage: {
1014+input: 20,
1015+output: 10_855,
1016+cacheRead: 1_761_324,
1017+cacheWrite: 33_047,
1018+},
1019+lastCallUsage: {
1020+input: 20,
1021+output: 10_855,
1022+cacheRead: 1_761_324,
1023+cacheWrite: 33_047,
1024+},
1025+compactionCount: 1,
1026+compactionTokensAfter: 0,
1027+},
1028+},
1029+} as EmbeddedAgentRunResult,
1030+});
1031+1032+expect(sessionStore[sessionKey]?.totalTokens).toBe(1_794_391);
1033+expect(sessionStore[sessionKey]?.totalTokensFresh).toBe(true);
1034+expect(sessionStore[sessionKey]?.inputTokens).toBe(20);
1035+expect(sessionStore[sessionKey]?.outputTokens).toBe(10_855);
1036+expect(sessionStore[sessionKey]?.cacheRead).toBe(1_761_324);
1037+expect(sessionStore[sessionKey]?.cacheWrite).toBe(33_047);
1038+});
1039+});
1040+1041+it("prefers fresh usage over positive compaction tokensAfter", async () => {
1042+await withTempSessionStore(async ({ storePath }) => {
1043+const cfg = {} as OpenClawConfig;
1044+const sessionKey = "agent:main:explicit:test-positive-compaction-with-usage";
1045+const sessionId = "test-positive-compaction-with-usage-session";
1046+const sessionStore: Record<string, SessionEntry> = {
1047+[sessionKey]: {
1048+ sessionId,
1049+updatedAt: 1,
1050+totalTokens: 180_000,
1051+totalTokensFresh: true,
1052+},
1053+};
1054+await fs.writeFile(storePath, JSON.stringify(sessionStore, null, 2));
1055+1056+await updateSessionStoreAfterAgentRun({
1057+ cfg,
1058+ sessionId,
1059+ sessionKey,
1060+ storePath,
1061+ sessionStore,
1062+defaultProvider: "openai",
1063+defaultModel: "gpt-5.5",
1064+result: {
1065+meta: {
1066+durationMs: 500,
1067+agentMeta: {
1068+ sessionId,
1069+provider: "openai",
1070+model: "gpt-5.5",
1071+usage: {
1072+input: 100_000,
1073+output: 3_000,
1074+cacheRead: 20_000,
1075+},
1076+lastCallUsage: {
1077+input: 91_000,
1078+output: 1_000,
1079+cacheRead: 4_000,
1080+},
1081+compactionCount: 1,
1082+compactionTokensAfter: 80_000,
1083+},
1084+},
1085+} as EmbeddedAgentRunResult,
1086+});
1087+1088+expect(sessionStore[sessionKey]?.totalTokens).toBe(120_000);
1089+expect(sessionStore[sessionKey]?.totalTokensFresh).toBe(true);
1090+expect(sessionStore[sessionKey]?.inputTokens).toBe(100_000);
1091+expect(sessionStore[sessionKey]?.outputTokens).toBe(3_000);
1092+expect(sessionStore[sessionKey]?.cacheRead).toBe(20_000);
1093+});
1094+});
1095+9791096it("accepts zero compaction tokensAfter when provider usage is unavailable", async () => {
9801097await withTempSessionStore(async ({ storePath }) => {
9811098const cfg = {} as OpenClawConfig;
@@ -987,6 +1104,29 @@ describe("updateSessionStoreAfterAgentRun", () => {
9871104updatedAt: 1,
9881105totalTokens: 12_000,
9891106totalTokensFresh: true,
1107+inputTokens: 20,
1108+outputTokens: 10_855,
1109+cacheRead: 1_761_324,
1110+cacheWrite: 33_047,
1111+contextBudgetStatus: {
1112+schemaVersion: 1,
1113+source: "pre-prompt-estimate",
1114+updatedAt: 1,
1115+provider: "claude-cli",
1116+model: "claude-opus-4-7",
1117+route: "compact_only",
1118+shouldCompact: true,
1119+estimatedPromptTokens: 1_794_391,
1120+contextTokenBudget: 1_048_576,
1121+promptBudgetBeforeReserve: 1_044_480,
1122+reserveTokens: 4_096,
1123+effectiveReserveTokens: 4_096,
1124+remainingPromptBudgetTokens: 0,
1125+overflowTokens: 749_911,
1126+toolResultReducibleChars: 0,
1127+messageCount: 0,
1128+unwindowedMessageCount: 0,
1129+},
9901130},
9911131};
9921132await fs.writeFile(storePath, JSON.stringify(sessionStore, null, 2));
@@ -1016,6 +1156,11 @@ describe("updateSessionStoreAfterAgentRun", () => {
10161156expect(sessionStore[sessionKey]?.totalTokens).toBe(0);
10171157expect(sessionStore[sessionKey]?.totalTokensFresh).toBe(true);
10181158expect(sessionStore[sessionKey]?.compactionCount).toBe(1);
1159+expect(sessionStore[sessionKey]?.inputTokens).toBeUndefined();
1160+expect(sessionStore[sessionKey]?.outputTokens).toBeUndefined();
1161+expect(sessionStore[sessionKey]?.cacheRead).toBeUndefined();
1162+expect(sessionStore[sessionKey]?.cacheWrite).toBeUndefined();
1163+expect(sessionStore[sessionKey]?.contextBudgetStatus).toBeUndefined();
10191164});
10201165});
10211166此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。