Skip to content

fix(opencode): prevent negative cost when cache tokens exceed input#24572

Open
Felix-Hz wants to merge 4 commits into
anomalyco:devfrom
Felix-Hz:fix/prevent-negative-cost
Open

fix(opencode): prevent negative cost when cache tokens exceed input#24572
Felix-Hz wants to merge 4 commits into
anomalyco:devfrom
Felix-Hz:fix/prevent-negative-cost

Conversation

@Felix-Hz
Copy link
Copy Markdown

Issue for this PR

Closes #22618

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

I noticed a bug where the "$ spent" indicator in the TUI sidebar would decrease after a request. This was most visible when switching from a paid model (like Claude 3.5 Opus) to a free model (like MiniMax 2.5).

The root cause is in the getUsage function in session.ts. It calculates adjustedInputTokens by subtracting cached tokens from the reported inputTokens:
adjustedInputTokens = inputTokens - cacheReadTokens - cacheWriteTokens

Some providers report inputTokens as the total (including cache), while others report it as only the new tokens. In the latter case, subtracting the cache tokens results in a negative number. If the model being used has any cost associated with it (either through its own definition or a fallback), this negative value is multiplied by the price and added to the session total, effectively "refunding" the user and causing the spent amount to drop.

I've updated the local safe helper in getUsage to ensure it always returns at least 0, preventing negative token counts and costs regardless of the provider's reporting format.

How did you verify your code works?

  1. I added a new test case to packages/opencode/test/session/compaction.test.ts that simulates a scenario where cacheReadTokens exceeds inputTokens.
  2. Verified that without the fix, the test fails with a negative cost, and with the fix, it correctly returns 0.
  3. Ran the full session test suite (bun test test/session/) and verified all 315 tests pass.
  4. Ran bun run typecheck and oxlint to ensure the changes follow project standards and type safety.

Screenshots / recordings

N/A (Logic fix for the "spent" display in the sidebar).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Found a potential duplicate:

PR #24336: fix(session): clamp token usage counts
#24336

This PR appears to address the same root issue - clamping token usage counts to prevent negative values. It's highly likely this is either an existing fix for the same bug or a related attempt to solve the negative cost problem.

@Felix-Hz
Copy link
Copy Markdown
Author

The following comment was made by an LLM, it may be inaccurate:

Found a potential duplicate:

PR #24336: fix(session): clamp token usage counts #24336

This PR appears to address the same root issue - clamping token usage counts to prevent negative values. It's highly likely this is either an existing fix for the same bug or a related attempt to solve the negative cost problem.

I noticed #24336 also addresses this. My approach fixes the negative value at the token calculation level (with the safe helper in getUsage) to ensure that we don't store negative token counts in the session history, which provides cleaner data for compaction and stats

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.

context spent amount goes down after model switch

1 participant