refactor(infra): extract session cost usage types

This commit is contained in:
Peter Steinberger
2026-02-13 16:56:19 +00:00
parent 5a431f57fc
commit c256503ea1
2 changed files with 205 additions and 165 deletions

View File

@@ -4,6 +4,26 @@ import readline from "node:readline";
import type { NormalizedUsage, UsageLike } from "../agents/usage.js";
import type { OpenClawConfig } from "../config/config.js";
import type { SessionEntry } from "../config/sessions/types.js";
import type {
CostBreakdown,
CostUsageTotals,
CostUsageSummary,
DiscoveredSession,
ParsedTranscriptEntry,
ParsedUsageEntry,
SessionCostSummary,
SessionDailyLatency,
SessionDailyMessageCounts,
SessionDailyModelUsage,
SessionDailyUsage,
SessionLatencyStats,
SessionLogEntry,
SessionMessageCounts,
SessionModelUsage,
SessionToolUsage,
SessionUsageTimePoint,
SessionUsageTimeSeries,
} from "./session-cost-usage.types.js";
import { normalizeUsage } from "../agents/usage.js";
import {
resolveSessionFilePath,
@@ -12,139 +32,24 @@ import {
import { countToolResults, extractToolCallNames } from "../utils/transcript-tools.js";
import { estimateUsageCost, resolveModelCostConfig } from "../utils/usage-format.js";
type CostBreakdown = {
total?: number;
input?: number;
output?: number;
cacheRead?: number;
cacheWrite?: number;
};
type ParsedUsageEntry = {
usage: NormalizedUsage;
costTotal?: number;
costBreakdown?: CostBreakdown;
provider?: string;
model?: string;
timestamp?: Date;
};
type ParsedTranscriptEntry = {
message: Record<string, unknown>;
role?: "user" | "assistant";
timestamp?: Date;
durationMs?: number;
usage?: NormalizedUsage;
costTotal?: number;
costBreakdown?: CostBreakdown;
provider?: string;
model?: string;
stopReason?: string;
toolNames: string[];
toolResultCounts: { total: number; errors: number };
};
export type CostUsageTotals = {
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
totalTokens: number;
totalCost: number;
// Cost breakdown by token type (from actual API data when available)
inputCost: number;
outputCost: number;
cacheReadCost: number;
cacheWriteCost: number;
missingCostEntries: number;
};
export type CostUsageDailyEntry = CostUsageTotals & {
date: string;
};
export type CostUsageSummary = {
updatedAt: number;
days: number;
daily: CostUsageDailyEntry[];
totals: CostUsageTotals;
};
export type SessionDailyUsage = {
date: string; // YYYY-MM-DD
tokens: number;
cost: number;
};
export type SessionDailyMessageCounts = {
date: string; // YYYY-MM-DD
total: number;
user: number;
assistant: number;
toolCalls: number;
toolResults: number;
errors: number;
};
export type SessionLatencyStats = {
count: number;
avgMs: number;
p95Ms: number;
minMs: number;
maxMs: number;
};
export type SessionDailyLatency = SessionLatencyStats & {
date: string; // YYYY-MM-DD
};
export type SessionDailyModelUsage = {
date: string; // YYYY-MM-DD
provider?: string;
model?: string;
tokens: number;
cost: number;
count: number;
};
export type SessionMessageCounts = {
total: number;
user: number;
assistant: number;
toolCalls: number;
toolResults: number;
errors: number;
};
export type SessionToolUsage = {
totalCalls: number;
uniqueTools: number;
tools: Array<{ name: string; count: number }>;
};
export type SessionModelUsage = {
provider?: string;
model?: string;
count: number;
totals: CostUsageTotals;
};
export type SessionCostSummary = CostUsageTotals & {
sessionId?: string;
sessionFile?: string;
firstActivity?: number;
lastActivity?: number;
durationMs?: number;
activityDates?: string[]; // YYYY-MM-DD dates when session had activity
dailyBreakdown?: SessionDailyUsage[]; // Per-day token/cost breakdown
dailyMessageCounts?: SessionDailyMessageCounts[];
dailyLatency?: SessionDailyLatency[];
dailyModelUsage?: SessionDailyModelUsage[];
messageCounts?: SessionMessageCounts;
toolUsage?: SessionToolUsage;
modelUsage?: SessionModelUsage[];
latency?: SessionLatencyStats;
};
export type {
CostUsageDailyEntry,
CostUsageSummary,
CostUsageTotals,
DiscoveredSession,
SessionCostSummary,
SessionDailyLatency,
SessionDailyMessageCounts,
SessionDailyModelUsage,
SessionDailyUsage,
SessionLatencyStats,
SessionLogEntry,
SessionMessageCounts,
SessionModelUsage,
SessionToolUsage,
SessionUsageTimePoint,
SessionUsageTimeSeries,
} from "./session-cost-usage.types.js";
const emptyTotals = (): CostUsageTotals => ({
input: 0,
@@ -458,13 +363,6 @@ export async function loadCostUsageSummary(params?: {
};
}
export type DiscoveredSession = {
sessionId: string;
sessionFile: string;
mtime: number;
firstUserMessage?: string;
};
/**
* Scan all transcript files to discover sessions not in the session store.
* Returns basic metadata for each discovered session.
@@ -834,23 +732,6 @@ export async function loadSessionCostSummary(params: {
};
}
export type SessionUsageTimePoint = {
timestamp: number;
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
totalTokens: number;
cost: number;
cumulativeTokens: number;
cumulativeCost: number;
};
export type SessionUsageTimeSeries = {
sessionId?: string;
points: SessionUsageTimePoint[];
};
export async function loadSessionUsageTimeSeries(params: {
sessionId?: string;
sessionEntry?: SessionEntry;
@@ -928,14 +809,6 @@ export async function loadSessionUsageTimeSeries(params: {
return { sessionId: params.sessionId, points: sortedPoints };
}
export type SessionLogEntry = {
timestamp: number;
role: "user" | "assistant" | "tool" | "toolResult";
content: string;
tokens?: number;
cost?: number;
};
export async function loadSessionLogs(params: {
sessionId?: string;
sessionEntry?: SessionEntry;

View File

@@ -0,0 +1,167 @@
import type { NormalizedUsage } from "../agents/usage.js";
export type CostBreakdown = {
total?: number;
input?: number;
output?: number;
cacheRead?: number;
cacheWrite?: number;
};
export type ParsedUsageEntry = {
usage: NormalizedUsage;
costTotal?: number;
costBreakdown?: CostBreakdown;
provider?: string;
model?: string;
timestamp?: Date;
};
export type ParsedTranscriptEntry = {
message: Record<string, unknown>;
role?: "user" | "assistant";
timestamp?: Date;
durationMs?: number;
usage?: NormalizedUsage;
costTotal?: number;
costBreakdown?: CostBreakdown;
provider?: string;
model?: string;
stopReason?: string;
toolNames: string[];
toolResultCounts: { total: number; errors: number };
};
export type CostUsageTotals = {
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
totalTokens: number;
totalCost: number;
// Cost breakdown by token type (from actual API data when available)
inputCost: number;
outputCost: number;
cacheReadCost: number;
cacheWriteCost: number;
missingCostEntries: number;
};
export type CostUsageDailyEntry = CostUsageTotals & {
date: string;
};
export type CostUsageSummary = {
updatedAt: number;
days: number;
daily: CostUsageDailyEntry[];
totals: CostUsageTotals;
};
export type SessionDailyUsage = {
date: string; // YYYY-MM-DD
tokens: number;
cost: number;
};
export type SessionDailyMessageCounts = {
date: string; // YYYY-MM-DD
total: number;
user: number;
assistant: number;
toolCalls: number;
toolResults: number;
errors: number;
};
export type SessionLatencyStats = {
count: number;
avgMs: number;
p95Ms: number;
minMs: number;
maxMs: number;
};
export type SessionDailyLatency = SessionLatencyStats & {
date: string; // YYYY-MM-DD
};
export type SessionDailyModelUsage = {
date: string; // YYYY-MM-DD
provider?: string;
model?: string;
tokens: number;
cost: number;
count: number;
};
export type SessionMessageCounts = {
total: number;
user: number;
assistant: number;
toolCalls: number;
toolResults: number;
errors: number;
};
export type SessionToolUsage = {
totalCalls: number;
uniqueTools: number;
tools: Array<{ name: string; count: number }>;
};
export type SessionModelUsage = {
provider?: string;
model?: string;
count: number;
totals: CostUsageTotals;
};
export type SessionCostSummary = CostUsageTotals & {
sessionId?: string;
sessionFile?: string;
firstActivity?: number;
lastActivity?: number;
durationMs?: number;
activityDates?: string[]; // YYYY-MM-DD dates when session had activity
dailyBreakdown?: SessionDailyUsage[]; // Per-day token/cost breakdown
dailyMessageCounts?: SessionDailyMessageCounts[];
dailyLatency?: SessionDailyLatency[];
dailyModelUsage?: SessionDailyModelUsage[];
messageCounts?: SessionMessageCounts;
toolUsage?: SessionToolUsage;
modelUsage?: SessionModelUsage[];
latency?: SessionLatencyStats;
};
export type DiscoveredSession = {
sessionId: string;
sessionFile: string;
mtime: number;
firstUserMessage?: string;
};
export type SessionUsageTimePoint = {
timestamp: number;
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
totalTokens: number;
cost: number;
cumulativeTokens: number;
cumulativeCost: number;
};
export type SessionUsageTimeSeries = {
sessionId?: string;
points: SessionUsageTimePoint[];
};
export type SessionLogEntry = {
timestamp: number;
role: "user" | "assistant" | "tool" | "toolResult";
content: string;
tokens?: number;
cost?: number;
};