





















@@ -149,6 +149,64 @@ describe("session cost usage", () => {
149149});
150150});
151151152+it("counts token usage for an unpriced (all-zero cost) model as missing, not a confident $0", async () => {
153+const root = await makeSessionCostRoot("cost-unknown-pricing");
154+const sessionsDir = path.join(root, "agents", "main", "sessions");
155+await fs.mkdir(sessionsDir, { recursive: true });
156+157+// A real assistant turn that burned tokens. The transport recorded cost.total: 0,
158+// derived from the model's all-zero catalog pricing — exactly what codex/gpt-5.x
159+// models produce, since the Codex backend exposes no per-token price.
160+const entry = {
161+type: "message",
162+timestamp: new Date().toISOString(),
163+message: {
164+role: "assistant",
165+provider: "openai",
166+model: "gpt-5.5",
167+usage: {
168+input: 881,
169+output: 6,
170+cacheRead: 22400,
171+cacheWrite: 0,
172+totalTokens: 23287,
173+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
174+},
175+},
176+};
177+178+await fs.writeFile(
179+path.join(sessionsDir, "sess-1.jsonl"),
180+transcriptText("sess-1", entry),
181+"utf-8",
182+);
183+184+// The model resolves to an all-zero cost config, i.e. its pricing is unknown.
185+const config = {
186+models: {
187+providers: {
188+openai: {
189+models: [
190+{
191+id: "gpt-5.5",
192+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
193+},
194+],
195+},
196+},
197+},
198+} as unknown as OpenClawConfig;
199+200+await withStateDir(root, async () => {
201+const summary = await loadCostUsageSummary({ days: 30, config });
202+expect(summary.totals.totalTokens).toBe(23287);
203+expect(summary.totals.totalCost).toBe(0);
204+// Unknown pricing must be surfaced as missing rather than reported as a
205+// confident $0 that would blind budget/spike monitoring to real spend.
206+expect(summary.totals.missingCostEntries).toBe(1);
207+});
208+});
209+152210it("ignores compaction checkpoint transcript snapshots in daily totals and discovery", async () => {
153211const root = await makeSessionCostRoot("cost-checkpoint");
154212const sessionsDir = path.join(root, "agents", "main", "sessions");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。