

























@@ -16,6 +16,10 @@ import {
1616import type { SessionEntry } from "../../config/sessions/types.js";
1717import type { OpenClawConfig } from "../../config/types.openclaw.js";
1818import { loadProviderUsageSummary } from "../../infra/provider-usage.js";
19+import {
20+addCostUsageTotals,
21+createEmptyCostUsageTotals,
22+} from "../../infra/session-cost-usage-totals.js";
1923import type {
2024CostUsageSummary,
2125CostUsageTotals,
@@ -77,36 +81,6 @@ type CostUsageCacheEntry = {
77817882const costUsageCache = new Map<string, CostUsageCacheEntry>();
798380-function createEmptyCostUsageTotals(): CostUsageTotals {
81-return {
82-input: 0,
83-output: 0,
84-cacheRead: 0,
85-cacheWrite: 0,
86-totalTokens: 0,
87-totalCost: 0,
88-inputCost: 0,
89-outputCost: 0,
90-cacheReadCost: 0,
91-cacheWriteCost: 0,
92-missingCostEntries: 0,
93-};
94-}
95-96-function addCostUsageTotals(target: CostUsageTotals, source: CostUsageTotals): void {
97-target.input += source.input;
98-target.output += source.output;
99-target.cacheRead += source.cacheRead;
100-target.cacheWrite += source.cacheWrite;
101-target.totalTokens += source.totalTokens;
102-target.totalCost += source.totalCost;
103-target.inputCost += source.inputCost;
104-target.outputCost += source.outputCost;
105-target.cacheReadCost += source.cacheReadCost;
106-target.cacheWriteCost += source.cacheWriteCost;
107-target.missingCostEntries += source.missingCostEntries;
108-}
109-11084function findCostUsageCacheEvictionKey(): string | undefined {
11185for (const [key, entry] of costUsageCache) {
11286// Prefer evicting settled entries so duplicate callers can still join active loads.
@@ -522,32 +496,12 @@ function maybeMergeFamilyEntry(params: {
522496523497function createEmptySessionCostSummary(): SessionCostSummary {
524498return {
525-input: 0,
526-output: 0,
527-cacheRead: 0,
528-cacheWrite: 0,
529-totalTokens: 0,
530-totalCost: 0,
531-inputCost: 0,
532-outputCost: 0,
533-cacheReadCost: 0,
534-cacheWriteCost: 0,
535-missingCostEntries: 0,
499+ ...createEmptyCostUsageTotals(),
536500};
537501}
538502539503function mergeSessionUsageInto(target: SessionCostSummary, source: SessionCostSummary): void {
540-target.input += source.input;
541-target.output += source.output;
542-target.cacheRead += source.cacheRead;
543-target.cacheWrite += source.cacheWrite;
544-target.totalTokens += source.totalTokens;
545-target.totalCost += source.totalCost;
546-target.inputCost += source.inputCost;
547-target.outputCost += source.outputCost;
548-target.cacheReadCost += source.cacheReadCost;
549-target.cacheWriteCost += source.cacheWriteCost;
550-target.missingCostEntries += source.missingCostEntries;
504+addCostUsageTotals(target, source);
551505target.firstActivity =
552506target.firstActivity === undefined
553507 ? source.firstActivity
@@ -687,19 +641,6 @@ function mergeModelUsage(
687641right: SessionCostSummary["modelUsage"],
688642): SessionCostSummary["modelUsage"] {
689643const map = new Map<string, SessionModelUsage>();
690-const mergeTotals = (target: CostUsageSummary["totals"], source: CostUsageSummary["totals"]) => {
691-target.input += source.input;
692-target.output += source.output;
693-target.cacheRead += source.cacheRead;
694-target.cacheWrite += source.cacheWrite;
695-target.totalTokens += source.totalTokens;
696-target.totalCost += source.totalCost;
697-target.inputCost += source.inputCost;
698-target.outputCost += source.outputCost;
699-target.cacheReadCost += source.cacheReadCost;
700-target.cacheWriteCost += source.cacheWriteCost;
701-target.missingCostEntries += source.missingCostEntries;
702-};
703644for (const entry of [...(left ?? []), ...(right ?? [])]) {
704645const key = `${entry.provider ?? "unknown"}::${entry.model ?? "unknown"}`;
705646const existing =
@@ -711,7 +652,7 @@ function mergeModelUsage(
711652totals: createEmptySessionCostSummary(),
712653} as SessionModelUsage);
713654existing.count += entry.count;
714-mergeTotals(existing.totals, entry.totals);
655+addCostUsageTotals(existing.totals, entry.totals);
715656map.set(key, existing);
716657}
717658return map.size > 0 ? Array.from(map.values()) : undefined;
@@ -1210,19 +1151,7 @@ export const usageHandlers: GatewayRequestHandlers = {
1210115112111152// Load usage for each session
12121153const sessions: SessionUsageEntry[] = [];
1213-const aggregateTotals = {
1214-input: 0,
1215-output: 0,
1216-cacheRead: 0,
1217-cacheWrite: 0,
1218-totalTokens: 0,
1219-totalCost: 0,
1220-inputCost: 0,
1221-outputCost: 0,
1222-cacheReadCost: 0,
1223-cacheWriteCost: 0,
1224-missingCostEntries: 0,
1225-};
1154+const aggregateTotals = createEmptyCostUsageTotals();
12261155const aggregateMessages: SessionMessageCounts = {
12271156total: 0,
12281157user: 0,
@@ -1261,36 +1190,6 @@ export const usageHandlers: GatewayRequestHandlers = {
12611190const modelDailyMap = new Map<string, SessionDailyModelUsage>();
12621191let cacheStatus: UsageCacheStatus | undefined;
126311921264-const emptyTotals = (): CostUsageSummary["totals"] => ({
1265-input: 0,
1266-output: 0,
1267-cacheRead: 0,
1268-cacheWrite: 0,
1269-totalTokens: 0,
1270-totalCost: 0,
1271-inputCost: 0,
1272-outputCost: 0,
1273-cacheReadCost: 0,
1274-cacheWriteCost: 0,
1275-missingCostEntries: 0,
1276-});
1277-const mergeTotals = (
1278-target: CostUsageSummary["totals"],
1279-source: CostUsageSummary["totals"],
1280-) => {
1281-target.input += source.input;
1282-target.output += source.output;
1283-target.cacheRead += source.cacheRead;
1284-target.cacheWrite += source.cacheWrite;
1285-target.totalTokens += source.totalTokens;
1286-target.totalCost += source.totalCost;
1287-target.inputCost += source.inputCost;
1288-target.outputCost += source.outputCost;
1289-target.cacheReadCost += source.cacheReadCost;
1290-target.cacheWriteCost += source.cacheWriteCost;
1291-target.missingCostEntries += source.missingCostEntries;
1292-};
1293-12941193const usageByEntryIndex: Array<SessionCostSummary | null> = Array.from(
12951194{ length: mergedEntries.length },
12961195() => null,
@@ -1409,17 +1308,7 @@ export const usageHandlers: GatewayRequestHandlers = {
14091308const usage = usageByEntryIndex[entryIndex];
1410130914111310if (usage) {
1412-aggregateTotals.input += usage.input;
1413-aggregateTotals.output += usage.output;
1414-aggregateTotals.cacheRead += usage.cacheRead;
1415-aggregateTotals.cacheWrite += usage.cacheWrite;
1416-aggregateTotals.totalTokens += usage.totalTokens;
1417-aggregateTotals.totalCost += usage.totalCost;
1418-aggregateTotals.inputCost += usage.inputCost;
1419-aggregateTotals.outputCost += usage.outputCost;
1420-aggregateTotals.cacheReadCost += usage.cacheReadCost;
1421-aggregateTotals.cacheWriteCost += usage.cacheWriteCost;
1422-aggregateTotals.missingCostEntries += usage.missingCostEntries;
1311+addCostUsageTotals(aggregateTotals, usage);
14231312}
1424131314251314const channel = merged.storeEntry?.channel ?? merged.storeEntry?.origin?.provider;
@@ -1450,10 +1339,10 @@ export const usageHandlers: GatewayRequestHandlers = {
14501339provider: entry.provider,
14511340model: entry.model,
14521341count: 0,
1453-totals: emptyTotals(),
1342+totals: createEmptyCostUsageTotals(),
14541343} as SessionModelUsage);
14551344modelExisting.count += entry.count;
1456-mergeTotals(modelExisting.totals, entry.totals);
1345+addCostUsageTotals(modelExisting.totals, entry.totals);
14571346byModelMap.set(modelKey, modelExisting);
1458134714591348const providerKey = entry.provider ?? "unknown";
@@ -1463,10 +1352,10 @@ export const usageHandlers: GatewayRequestHandlers = {
14631352provider: entry.provider,
14641353model: undefined,
14651354count: 0,
1466-totals: emptyTotals(),
1355+totals: createEmptyCostUsageTotals(),
14671356} as SessionModelUsage);
14681357providerExisting.count += entry.count;
1469-mergeTotals(providerExisting.totals, entry.totals);
1358+addCostUsageTotals(providerExisting.totals, entry.totals);
14701359byProviderMap.set(providerKey, providerExisting);
14711360}
14721361}
@@ -1495,14 +1384,14 @@ export const usageHandlers: GatewayRequestHandlers = {
14951384}
1496138514971386if (agentId) {
1498-const agentTotals = byAgentMap.get(agentId) ?? emptyTotals();
1499-mergeTotals(agentTotals, usage);
1387+const agentTotals = byAgentMap.get(agentId) ?? createEmptyCostUsageTotals();
1388+addCostUsageTotals(agentTotals, usage);
15001389byAgentMap.set(agentId, agentTotals);
15011390}
1502139115031392if (channel) {
1504-const channelTotals = byChannelMap.get(channel) ?? emptyTotals();
1505-mergeTotals(channelTotals, usage);
1393+const channelTotals = byChannelMap.get(channel) ?? createEmptyCostUsageTotals();
1394+addCostUsageTotals(channelTotals, usage);
15061395byChannelMap.set(channel, channelTotals);
15071396}
15081397此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。