返回 DeepSeek-Reasonix
controllerTurnUsage.ts
根目录 / desktop / frontend / src / lib / controllerTurnUsage.ts
1 import type { WireUsage, TurnUsage } from "./types";
2
3 // Failed-attempt estimates remain billable but cannot replace calibrated
4 // context occupancy. Context* counters describe only the latest attempt.
5 export function measuredContextPromptTokens(usage?: WireUsage): number | undefined {
6 if (!usage || usage.estimated) return undefined;
7 return (usage.contextPromptTokens ?? 0) > 0 ? usage.contextPromptTokens : usage.promptTokens ?? 0;
8 }
9
10 export function usageTotalTokens(usage?: WireUsage): number {
11 if (!usage) return 0;
12 if (usage.totalTokens > 0) return usage.totalTokens;
13 const promptTokens = usage.promptTokens || usage.cacheHitTokens + usage.cacheMissTokens;
14 return Math.max(0, promptTokens + usage.completionTokens);
15 }
16
17 export function mergeChatTurnUsage(current: TurnUsage | undefined, usage: WireUsage | undefined): TurnUsage | undefined {
18 if (!usage) return current;
19 const route = usage.costQuote?.modelRef?.trim();
20 const routes = current?.routes ? [...current.routes] : [];
21 if (route && !routes.includes(route)) routes.push(route);
22 const hasCacheBuckets = usage.cacheHitTokens > 0 || usage.cacheMissTokens > 0;
23 return {
24 uncachedInputTokens: (current?.uncachedInputTokens ?? 0) + (hasCacheBuckets ? usage.cacheMissTokens : usage.promptTokens),
25 outputTokens: (current?.outputTokens ?? 0) + usage.completionTokens,
26 totalTokens: (current?.totalTokens ?? 0) + usageTotalTokens(usage),
27 cacheReadTokens: (current?.cacheReadTokens ?? 0) + usage.cacheHitTokens,
28 reasoningTokens: (current?.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0),
29 routes: routes.length ? routes : undefined,
30 };
31 }
32
32 lines TYPESCRIPT