Repository navigation
Description
Summary
GitHub Copilot session costs are significantly under-reported. Copilot's /models API exposes cache_write_price and long_context prices, and its usage payloads report cache_write_tokens, but opencode ignores all three. Cache writes are priced at $0 for Claude models and billed as plain input for GPT models, and long-context pricing is never applied.
Environment
- opencode version: 2.0.19
- OS: Darwin 25.6.0 (arm64)
- Terminal: Ghostty (TERM=xterm-ghostty, COLORTERM=truecolor)
- Shell: /bin/zsh
- Install/channel: latest
- Active plugins: local/internal plugins only (none touch provider pricing or usage)
Reproduction
- Log in with GitHub Copilot and run a session with
claude-opus-5.5(or any Claude model) that creates prompt-cache entries. - Run
opencode models(or inspect the model): every Copilot model hascost.cache.write: 0. - Compare the session
costwith the GitHub pricing table (https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing). - Run any GPT-5.6 / GPT-6 session and check the token stats:
cache.writeis always0.
Expected Behavior
Session cost matches GitHub's per-token pricing, including cache writes and long-context tiers.
Actual Behavior
Example Opus 5.5 session:
| Tokens | Count | opencode rate | GitHub rate |
|---|---|---|---|
| input | 104 | $4 | $4 |
| output + reasoning | 21,123 | $20 | $20 |
| cache read | 3,478,395 | $0.20 | $0.20 |
| cache write | 235,970 | $0 | $5 |
opencode reports $1.12; the correct cost is $2.30.
A controlled check against Copilot's quota counter (/copilot_internal/user → quota_snapshots.premium_interactions) over a ~10 minute window showed GitHub consuming ~140 credits while opencode recorded ~6.6 credits of cost.
Additional Context
1. packages/core/src/github-copilot/models.ts drops prices
GET {api}/models (with X-GitHub-Api-Version: 2026-08-01) returns, for example:
"token_prices": {
"batch_size": 1000000,
"default": { "input_price": 400, "cache_read_price": 20, "cache_write_price": 500, "output_price": 2000, "max_prompt_tokens": 272000 },
"long_context": { "input_price": 800, "cache_read_price": 80, "cache_write_price": 1000, "output_price": 3000, "max_prompt_tokens": 922000 }
}(that one is gpt-5.6-sol). But build() hardcodes:
write: Money.USDPerMillionTokens.zero,and the schema has no cache_write_price, long_context, or cache_write_1h_price. SessionUsage.calculateCost already supports context tiers, so long_context could map to { tier: { type: "context", size: default.max_prompt_tokens } }.
2. Copilot Responses/Chat adapters ignore cache_write_tokens
Copilot /responses reports cache writes:
1st call: input_tokens 8273, input_tokens_details: { cache_write_tokens: 8270, cached_tokens: 0 }
2nd call: input_tokens 8273, input_tokens_details: { cache_write_tokens: 0, cached_tokens: 8270 }
github-copilot/responses/openai-responses-language-model.ts only reads cached_tokens and sets cacheWrite: undefined (both the generate and stream paths; the stream usage schema only declares cached_tokens). chat/openai-compatible-chat-language-model.ts does the same. Cache writes therefore land in noCache and are billed at the input price (GPT-5.6 / GPT-6 charge 1.25x input for cache writes). noCache should also subtract cache_write_tokens.
Across a month of usage, every GPT model in opencode stats shows cache.write: 0.
Related: session/usage.ts has TODO(#35765): Use Copilot's reported billed amount....
Activity
github-actions commentedon Sep 29, 2026
This issue might be a duplicate of existing issues. Please check:
opencodejr commentedon Oct 28, 2026
Thanks for the detailed report. I've confirmed both parts on 2.0.19 and on the latest
dev(86ce19d), using a local mock of Copilot's/modelsand/responsesendpoints built from the payloads in your report:/modelsentry withcache_write_price: 500and along_contextblock, the model ends up withcost.cache.write: 0and no long-context tier./responsesresult reportingcache_write_tokens: 8270, both the streaming and non-streaming paths returncacheWriteas undefined andnoCache: 8273, so cache writes are billed at the plain input price.The script below reproduces it without credentials. The Chat Completions adapter has the same
cacheWrite: undefinedcode, though I didn't run it. Related: #35765, which would prefer Copilot's own reported billed amount when it is available.Reproduction script (repro.ts)
Run it:
bun repro.tsgolfromeo-fr commentedon Oct 28, 2026
Opened #59803 covering both halves of this issue: the builder now parses cache_write_price and the optional long_context tier (its own prices and max_prompt_tokens) from the /models payload and emits a context-tier cost entry — SessionUsage.calculateCost already selected tiers per request, so no calculator change was needed. Both usage adapters map cache_write_tokens into cacheWrite instead of dropping it, and the non-cached input stays consistent with the total. Tested against the Claude Haiku 5.5 rate card, including the ≤100K boundary.
rekram1-node commentedon Nov 10, 2026
Fixed in v2.2.7 by #62034. Session cost for GitHub Copilot now uses the amount Copilot reports it charged for each request (copilot_usage) instead of the catalog estimate, so cache writes and long-context pricing are included. If you still see a cost that doesn't match Copilot's billing on 2.2.7, let me know and I'll reopen.