Skip to content

fix(opencode): report $0 for free models and expose cost like other engines - #156

Open
namanarora00 wants to merge 2 commits into
kalil0321:mainfrom
namanarora00:fix/opencode-cost
Open

namanarora00 wants to merge 2 commits into
kalil0321:mainfrom
namanarora00:fix/opencode-cost

Conversation

@namanarora00

@namanarora00 namanarora00 commented Nov 2, 2026 •

Copy link
Copy Markdown

Why

Two problems with how OpenCode runs report cost:

  1. Free and local models are charged Sonnet prices. When OpenCode reports a step cost of 0, OpenCodeEngineer estimates the cost with calculate_cost. For any model missing from MODEL_PRICING, calculate_cost falls back to Claude Sonnet 4.6 prices. So the default opencode/big-pickle, which is free, and local Ollama models were shown as costing money: $4.50 per 1M input / 100k output tokens. The same happened to the short names in MODEL_MAP (sonnet, opus, haiku), because they were priced before being mapped.
  2. The cost is missing everywhere except the OpenCode summary. OpenCode keeps its cost only under usage.cost. --json usage (total_cost_usd), /history and /resume's session cost all read estimated_cost_usd, which the other engines write. OpenCode's cache writes (cache_creation_tokens) also never reached cache_write_tokens in --json.

What

  • In the step-finish handler, resolve the model through MODEL_MAP, and estimate a zero API cost only when get_model_pricing knows the model. Unknown models stay at $0 instead of borrowing Sonnet prices. Known models keep the local estimate added in fix opencode pricing #10 (for example a subscription that reports $0).
  • Record the running total under estimated_cost_usd as well. usage.cost is kept, so the OpenCode session summary and existing history are unchanged.
  • Add cache_creation_tokens to the cache_write_tokens candidates in _STABLE_USAGE_KEYS.
  • README: the agent --json table listed usage.total_cost. The field is total_cost_usd, next to the cache token counts and raw, as scripted-usage.mdx already says.
  • test_step_finish_calculates_cost_when_zero now sets a priced model. With the default free big-pickle, the correct estimate is $0.
  • CHANGELOG entries under Unreleased → Fixed.

Verification

  • Checked that big-pickle and an Ollama model now record $0, opus is priced as claude-opus-4-6, estimated_cost_usd accumulates across steps, and _normalize_usage maps OpenCode's keys.
  • pytest: 1231 passed, 10 skipped, same as main. ruff check src tests and mypy src are clean.

One behavior to call out: a paid model that is not in MODEL_PRICING (and not in LiteLLM, when installed), on a provider that reports $0, now shows $0 instead of a Sonnet-priced guess. That seemed more honest than a guess, but say if you'd rather keep a fallback there.

This PR and #155 (list/show cost) each add lines in the same CHANGELOG section, so whichever merges second will need a small conflict resolution there.


Summary by cubic

Fixes OpenCode cost reporting so free and local models show $0, and so cost and cache write usage reach the same places other engines report them.

  • Prices a $0 step only when the model has known pricing, resolving short names like opus through MODEL_MAP first; unknown models (opencode/big-pickle, Ollama) stay at $0 instead of getting Sonnet 4.6 prices.
  • Records cost under estimated_cost_usd alongside usage.cost, so --json, /history, and /resume see it.
  • Maps OpenCode's cache_creation_tokens to cache_write_tokens in --json usage, and notes in the README that usage fields appear only when the SDK reports them.
  • Corrects the README's agent --json usage field from total_cost to total_cost_usd.
  • Adds tests for free/Ollama models, alias pricing, cost accumulation across steps, and usage key normalization.

Written for commit 288d4bd. Summary will update on new commits.

View guided diff

RetriggerView in GreptileConfidence Score: 5/5

The reviewed cost-accounting and usage-export changes are safe to merge; no blocking issues were found.

Summary

Fixes OpenCode cost reporting and exposes its cost and cache writes through the existing JSON fields.

  • OpenCode keeps free models at zero and reports running costs consistently.
  • OpenCode cache writes appear in the shared JSON usage fields.

namanarora00 explicitly acknowledged that unknown paid models reporting $0 will now show $0, rather than a Sonnet-priced guess. This is intentional to avoid presenting an unknown cost as a known price.

No blocking issues were found in the reviewed changes. The changes are safe to merge within the reviewed scope.

Reviews (1) · Last reviewed commit: "fix(opencode): report $0 for free models..." · Reviewed by Greptile

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review completed against the latest diff

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread tests/test_opencode_engineer.py Resolved
Comment thread src/reverse_api/opencode_engineer.py Resolved
Comment thread README.md Resolved
Comment thread CHANGELOG.md Resolved
…ngines

When OpenCode reported a step cost of 0, rae estimated it with calculate_cost,
which prices any unknown model as Claude Sonnet 4.6. Free models such as the
default opencode/big-pickle and local Ollama models were shown as costing
Sonnet prices. Estimate only for models with known prices, and resolve short
names (sonnet, opus, haiku) through MODEL_MAP before pricing.

OpenCode also kept its cost only under usage.cost, which --json usage,
/history and /resume do not read. Record it under estimated_cost_usd as well,
and map OpenCode's cache_creation_tokens to cache_write_tokens in --json.

The README's agent --json table listed usage.total_cost; the field is
total_cost_usd.
@greptile-apps

greptile-apps Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings could not be posted inline.

  • P2 Duplicate step-finish events count the same cost and tokens again ▶

    • Bug
      • Confirmed pre-existing defect, not a PR fix(opencode): report $0 for free models and expose cost like other engines #156 regression. In both direct handler execution and mocked SSE delivery, three distinct step-finish parts costing $0.05, $0.10, and $0.025 produce the correct $0.175 total. Delivering an exact copy of the second part raises the total to $0.275 and input tokens from 3,000 to 4,000. On head, cost and estimated_cost_usd agree but both contain the inflated total. Base exhibits the same overcount.
    • Cause
      • src/reverse_api/opencode_engineer.py:726-737 processes step-finish parts without checking or recording their part_id in seen_parts. Lines 758-763 unconditionally add their tokens and cost; line 765 copies the resulting inflated total into estimated_cost_usd.
    • Fix
      • Make step-finish accounting idempotent by tracking accounted part IDs and ignoring exact duplicate deliveries before updating totals. If updates to an existing finished part must be supported, account only the change from its previously recorded contribution. Add a repeated-part regression test through the SSE dispatcher.

This branch has not been deployed

No deployments
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