Skip to content

Conversation

@processtrader
Copy link
Contributor

@processtrader processtrader commented Dec 28, 2025

Summary

This PR enhances the stats command to provide granular visibility into model usage. It introduces a new "MODEL USAGE" section that displays message counts, a breakdown of input vs. output tokens, and historical accumulated costs for each model used across sessions.

Changes

  • Interface Update: Extended SessionStats to include a modelUsage record.
  • Aggregation Logic: Updated aggregateSessionStats to collect and sum usage metrics (messages, tokens, cost) per provider/model from assistant messages.
  • New Flag: Added --models X, when given will show the models and the top X, if X is not given will show them all, sorted by total messages
  • UI Enhancement: Modified displayStats to render a sorted table of model usage, showing:
    • Message count
    • Input Token count
    • Output Token count
    • Total Cost

Example Output

image image

@rekram1-node
Copy link
Collaborator

/review

console.log("┌────────────────────────────────────────────────────────┐")
console.log("│ MODEL USAGE │")
console.log("├────────────────────────────────────────────────────────┤")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Long model names (e.g., openrouter/anthropic/claude-3.5-sonnet:beta) could exceed 54 characters and break the table layout. Consider truncating similar to how tool names are handled in the TOOL USAGE section below (see lines 287-289).

let sessionCost = 0
let sessionTokens = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
let sessionToolUsage: Record<string, number> = {}
let sessionModelUsage: Record<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion: This type definition duplicates the one in SessionStats.modelUsage. You could extract a named type like type ModelUsageStats = { messages: number; tokens: { input: number; output: number }; cost: number } and reuse it. This is optional - the current approach works fine too.

@rekram1-node
Copy link
Collaborator

should prolly require a flag to output this btw, and maybe a flag to limit # of models cause mine is huge

@processtrader
Copy link
Contributor Author

should prolly require a flag to output this btw, and maybe a flag to limit # of models cause mine is huge

that sounds fair! yeah sure, perhaps

stats --days X --models Y

just to follow the convention about days followed by the number of models we want to display? and if so, what sorting would we need? top Y in terms of usage?

@processtrader
Copy link
Contributor Author

@rekram1-node I pushed a change, so it is a flag now, with the option to also limit the amount of models sorted by top messages

@rekram1-node
Copy link
Collaborator

/review

let modelLimit: number | undefined
if (args.models === true) {
modelLimit = Infinity
} else if (typeof args.models === "number") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style guide suggests avoiding let statements. Consider using an IIFE or ternary to avoid the let:

Suggested change
} else if (typeof args.models === "number") {
const modelLimit = (() => {
if (args.models === true) return Infinity
if (typeof args.models === "number") return args.models
return undefined
})()

This is just a suggestion - the current code is perfectly readable and functional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants