Skip to content

fix(stats): track ImageGen / VideoGen costs in usage insights#13

Merged
1bcMax merged 1 commit intomainfrom
fix/track-media-generation-costs
Apr 25, 2026
Merged

fix(stats): track ImageGen / VideoGen costs in usage insights#13
1bcMax merged 1 commit intomainfrom
fix/track-media-generation-costs

Conversation

@KillerQueen-Z
Copy link
Copy Markdown
Collaborator

Summary

Before this, only chat LLM calls flowed through recordUsage(). The ImageGen and VideoGen tools wrote to the content library but never reported to the global stats file, so:

  • franklin insights undercounted total 30-day spend by the exact amount spent on image + video generation.
  • The "Top models" breakdown never surfaced openai/gpt-image-1, bytedance/seedance-2.0, xai/grok-imagine-video, etc. even when they were the dominant cost in a session.
  • Monthly projections in insights were similarly low.

Changes

On successful generation each tool now fires a fire-and-forget recordUsage(model, 0, 0, costUsd, 0):

  • Input/output tokens stay at 0 — image/video models don't bill by token.
  • The cost is pulled from the live gateway catalog via findModel + estimateCostUsd, the same path the AskUser cost preview uses, so the recorded amount matches the amount the user was quoted.
  • When the catalog lookup fails (offline / stale cache), the tools fall back to a hardcoded estimate (ImageGen: 0, VideoGen: the legacy $0.05/s) so stats still get an entry — under-approximate is better than missing.

Design notes

  • Fire-and-forget, error-swallowing on purpose. A ~/.blockrun/stats.json write failure must not turn a paid generation into a user-visible error, and stats accuracy matters less than not losing the output.
  • No schema change. The existing recordUsage signature handles inputTokens=0 + outputTokens=0 + explicit costUsd fine; nothing in the stats tracker or the insights engine needs to learn about media models specifically.
  • Scope deliberately small — only the two tools, +33 lines across 2 files, zero net changes to any chat flow.

Test plan

  1. Run franklin insights → note baseline Total Cost and Top Models list.
  2. Generate one image with a known-cost model, e.g.
    franklin --prompt "use zai/cogview-4 to generate a tiny red dot"
    
    (cogview-4 is catalog-priced at $0.015/img.)
  3. Run franklin insights again.
    • Total Cost should increase by ~$0.0158 (0.015 + 5% gateway margin).
    • Top Models should contain a new row for zai/cogview-4 with 1 request.
  4. Repeat for VideoGen with any Seedance variant and confirm a per-second entry is written.

Verified locally on Base chain. The VS Code extension's Insights panel (which reads the same stats.json) also immediately reflected the new entries.

Related

  • The same stats.json is consumed by the VS Code extension's Insights panel (via generateInsights), so this fix lands media costs in both the CLI and the extension with a single change.

Before this, only chat LLM calls flowed through `recordUsage()`. The
ImageGen and VideoGen tools wrote to the content library but never
reported to the global stats file, so:

- `franklin insights` undercounted total 30-day spend by the exact
  amount spent on image + video generation.
- The "Top models" breakdown never surfaced `openai/gpt-image-1`,
  `bytedance/seedance-2.0`, `xai/grok-imagine-video`, etc. even when
  they were the dominant cost in a session.
- Monthly projections in insights were similarly low.

On successful generation each tool now fires a fire-and-forget
`recordUsage(model, 0, 0, costUsd, 0)`. Input/output tokens stay at 0
because image/video models don't bill by token; the cost is pulled
from the live gateway catalog via `findModel` + `estimateCostUsd`, the
same path the AskUser cost preview uses. When the catalog lookup fails
the tools fall back to hardcoded estimates so stats still get an
entry (under-approximate rather than missing).

The stats write is intentionally fire-and-forget and error-swallowing:
a `~/.blockrun/stats.json` write failure must not turn a paid generation
into a user-visible error.

Scope is deliberately small — only the two tools, +33 lines, zero
schema or behavior change to the existing tracker / insights engine.
Any record already written by chat flows continues to work unchanged.
@1bcMax 1bcMax merged commit f8f289b into main Apr 25, 2026
2 checks passed
KillerQueen-Z added a commit that referenced this pull request Apr 28, 2026
Before this, only chat LLM calls flowed through `recordUsage()`. The
ImageGen and VideoGen tools wrote to the content library but never
reported to the global stats file, so:

- `franklin insights` undercounted total 30-day spend by the exact
  amount spent on image + video generation.
- The "Top models" breakdown never surfaced `openai/gpt-image-1`,
  `bytedance/seedance-2.0`, `xai/grok-imagine-video`, etc. even when
  they were the dominant cost in a session.
- Monthly projections in insights were similarly low.

On successful generation each tool now fires a fire-and-forget
`recordUsage(model, 0, 0, costUsd, 0)`. Input/output tokens stay at 0
because image/video models don't bill by token; the cost is pulled
from the live gateway catalog via `findModel` + `estimateCostUsd`, the
same path the AskUser cost preview uses. When the catalog lookup fails
the tools fall back to hardcoded estimates so stats still get an
entry (under-approximate rather than missing).

The stats write is intentionally fire-and-forget and error-swallowing:
a `~/.blockrun/stats.json` write failure must not turn a paid generation
into a user-visible error.

Scope is deliberately small — only the two tools, +33 lines, zero
schema or behavior change to the existing tracker / insights engine.
Any record already written by chat flows continues to work unchanged.
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.

1 participant