





























1+import { describe, expect, it } from "vitest";
2+import {
3+makeIsolatedAgentTurnParams,
4+setupRunCronIsolatedAgentTurnSuite,
5+} from "./run.suite-helpers.js";
6+import {
7+deriveSessionTotalTokensMock,
8+loadRunCronIsolatedAgentTurn,
9+makeCronSession,
10+mockRunCronFallbackPassthrough,
11+resolveCronSessionMock,
12+runEmbeddedAgentMock,
13+} from "./run.test-harness.js";
14+15+const runCronIsolatedAgentTurn = await loadRunCronIsolatedAgentTurn();
16+17+describe("runCronIsolatedAgentTurn usage accounting", () => {
18+setupRunCronIsolatedAgentTurnSuite();
19+20+it("uses final-call usage for the stored session token snapshot", async () => {
21+const cronSession = makeCronSession();
22+resolveCronSessionMock.mockReturnValue(cronSession);
23+mockRunCronFallbackPassthrough();
24+deriveSessionTotalTokensMock.mockReturnValueOnce(56000);
25+runEmbeddedAgentMock.mockResolvedValueOnce({
26+payloads: [{ text: "done" }],
27+meta: {
28+agentMeta: {
29+usage: {
30+input: 75000,
31+output: 2000,
32+total: 56000,
33+cacheRead: 5000,
34+cacheWrite: 0,
35+},
36+lastCallUsage: {
37+input: 55000,
38+output: 1000,
39+cacheRead: 1000,
40+cacheWrite: 0,
41+},
42+},
43+},
44+});
45+46+const result = await runCronIsolatedAgentTurn(makeIsolatedAgentTurnParams());
47+48+expect(result.status).toBe("ok");
49+expect(cronSession.sessionEntry.inputTokens).toBe(75000);
50+expect(cronSession.sessionEntry.outputTokens).toBe(2000);
51+expect(cronSession.sessionEntry.totalTokens).toBe(56000);
52+expect(cronSession.sessionEntry.totalTokensFresh).toBe(true);
53+expect(result.usage).toMatchObject({
54+input_tokens: 75000,
55+output_tokens: 2000,
56+total_tokens: 82000,
57+});
58+expect(deriveSessionTotalTokensMock).toHaveBeenCalledWith({
59+usage: {
60+input: 55000,
61+output: 1000,
62+cacheRead: 1000,
63+cacheWrite: 0,
64+},
65+contextTokens: 128000,
66+promptTokens: undefined,
67+});
68+});
69+70+it("falls back to aggregate usage when final-call usage is empty", async () => {
71+const cronSession = makeCronSession();
72+resolveCronSessionMock.mockReturnValue(cronSession);
73+mockRunCronFallbackPassthrough();
74+deriveSessionTotalTokensMock.mockReturnValueOnce(undefined).mockReturnValueOnce(77000);
75+runEmbeddedAgentMock.mockResolvedValueOnce({
76+payloads: [{ text: "done" }],
77+meta: {
78+agentMeta: {
79+usage: {
80+input: 75000,
81+output: 2000,
82+cacheRead: 5000,
83+cacheWrite: 0,
84+},
85+lastCallUsage: {
86+input: 0,
87+output: 0,
88+cacheRead: 0,
89+cacheWrite: 0,
90+},
91+},
92+},
93+});
94+95+const result = await runCronIsolatedAgentTurn(makeIsolatedAgentTurnParams());
96+97+expect(result.status).toBe("ok");
98+expect(cronSession.sessionEntry.totalTokens).toBe(77000);
99+expect(cronSession.sessionEntry.totalTokensFresh).toBe(true);
100+expect(deriveSessionTotalTokensMock).toHaveBeenNthCalledWith(1, {
101+usage: {
102+input: 0,
103+output: 0,
104+cacheRead: 0,
105+cacheWrite: 0,
106+},
107+contextTokens: 128000,
108+promptTokens: undefined,
109+});
110+expect(deriveSessionTotalTokensMock).toHaveBeenNthCalledWith(2, {
111+usage: {
112+input: 75000,
113+output: 2000,
114+cacheRead: 5000,
115+cacheWrite: 0,
116+},
117+contextTokens: 128000,
118+promptTokens: undefined,
119+});
120+});
121+122+it("falls back to aggregate usage when final-call usage is output-only", async () => {
123+const cronSession = makeCronSession();
124+resolveCronSessionMock.mockReturnValue(cronSession);
125+mockRunCronFallbackPassthrough();
126+deriveSessionTotalTokensMock.mockReturnValueOnce(undefined).mockReturnValueOnce(77000);
127+runEmbeddedAgentMock.mockResolvedValueOnce({
128+payloads: [{ text: "done" }],
129+meta: {
130+agentMeta: {
131+usage: { input: 75000, output: 2000 },
132+lastCallUsage: { output: 125 },
133+},
134+},
135+});
136+137+const result = await runCronIsolatedAgentTurn(makeIsolatedAgentTurnParams());
138+139+expect(result.status).toBe("ok");
140+expect(cronSession.sessionEntry.totalTokens).toBe(77000);
141+expect(cronSession.sessionEntry.totalTokensFresh).toBe(true);
142+expect(deriveSessionTotalTokensMock).toHaveBeenNthCalledWith(1, {
143+usage: { output: 125 },
144+contextTokens: 128000,
145+promptTokens: undefined,
146+});
147+expect(deriveSessionTotalTokensMock).toHaveBeenNthCalledWith(2, {
148+usage: { input: 75000, output: 2000 },
149+contextTokens: 128000,
150+promptTokens: undefined,
151+});
152+});
153+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。