add usage info to branch summary, compaction and tool result entries (#6671)
* add usage info to branch summary entries * add usage to compaction entries * allow custom tools to report llm usage in tool results * allow observing and patching usage in tool_result hooks * agent-harness: save usage in entries for compaction, branch summaries and tool results
This commit is contained in:
@@ -3,6 +3,7 @@ import { type Component, truncateToWidth, visibleWidth } from "@earendil-works/p
|
||||
import type { AgentSession } from "../../../core/agent-session.ts";
|
||||
import { areExperimentalFeaturesEnabled } from "../../../core/experimental.ts";
|
||||
import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.ts";
|
||||
import { addUsageToTotals, createUsageTotals } from "../../../core/usage-totals.ts";
|
||||
import { theme } from "../theme/theme.ts";
|
||||
|
||||
/**
|
||||
@@ -84,25 +85,21 @@ export class FooterComponent implements Component {
|
||||
const state = this.session.state;
|
||||
|
||||
// Calculate cumulative usage from ALL session entries (not just post-compaction messages)
|
||||
let totalInput = 0;
|
||||
let totalOutput = 0;
|
||||
let totalCacheRead = 0;
|
||||
let totalCacheWrite = 0;
|
||||
let totalCost = 0;
|
||||
const usageTotals = createUsageTotals();
|
||||
let latestCacheHitRate: number | undefined;
|
||||
|
||||
for (const entry of this.session.sessionManager.getEntries()) {
|
||||
if (entry.type === "message" && entry.message.role === "assistant") {
|
||||
totalInput += entry.message.usage.input;
|
||||
totalOutput += entry.message.usage.output;
|
||||
totalCacheRead += entry.message.usage.cacheRead;
|
||||
totalCacheWrite += entry.message.usage.cacheWrite;
|
||||
totalCost += entry.message.usage.cost.total;
|
||||
addUsageToTotals(usageTotals, entry.message.usage);
|
||||
|
||||
const latestPromptTokens =
|
||||
entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite;
|
||||
latestCacheHitRate =
|
||||
latestPromptTokens > 0 ? (entry.message.usage.cacheRead / latestPromptTokens) * 100 : undefined;
|
||||
} else if (entry.type === "message" && entry.message.role === "toolResult" && entry.message.usage) {
|
||||
addUsageToTotals(usageTotals, entry.message.usage);
|
||||
} else if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
|
||||
addUsageToTotals(usageTotals, entry.usage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,19 +127,20 @@ export class FooterComponent implements Component {
|
||||
|
||||
// Build stats line
|
||||
const statsParts = [];
|
||||
if (totalInput) statsParts.push(`↑${formatTokens(totalInput)}`);
|
||||
if (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);
|
||||
if (totalCacheRead) statsParts.push(`R${formatTokens(totalCacheRead)}`);
|
||||
if (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);
|
||||
if ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined) {
|
||||
if (usageTotals.input) statsParts.push(`↑${formatTokens(usageTotals.input)}`);
|
||||
if (usageTotals.output) statsParts.push(`↓${formatTokens(usageTotals.output)}`);
|
||||
if (usageTotals.cacheRead) statsParts.push(`R${formatTokens(usageTotals.cacheRead)}`);
|
||||
if (usageTotals.cacheWrite) statsParts.push(`W${formatTokens(usageTotals.cacheWrite)}`);
|
||||
if ((usageTotals.cacheRead > 0 || usageTotals.cacheWrite > 0) && latestCacheHitRate !== undefined) {
|
||||
statsParts.push(`CH${latestCacheHitRate.toFixed(1)}%`);
|
||||
}
|
||||
|
||||
// Kimi Coding is subscription-backed despite using API-key authentication.
|
||||
const usingSubscription = state.model
|
||||
? state.model.provider === "kimi-coding" || this.session.modelRuntime.isUsingOAuth(state.model.provider)
|
||||
: false;
|
||||
if (totalCost || usingSubscription) {
|
||||
const costStr = `$${totalCost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`;
|
||||
if (usageTotals.cost || usingSubscription) {
|
||||
const costStr = `$${usageTotals.cost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`;
|
||||
statsParts.push(costStr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user