Skip to content

GitHub Copilot cache-write tokens are omitted from session cost estimates #51845

Closed

Description

@Jeremyltw

Description

Summary

OpenCode’s estimated cost for GitHub Copilot models appears to price cache reads but assign cache writes a zero rate. This significantly underestimates costs for models that bill cache writes, such as Claude Opus 5.5.

Environment

OpenCode v2.0.18
Provider: GitHub Copilot
Model: Claude Opus 5.5

Example

For one session, OpenChamber reported:

Input: 162 tokens
Output: 63,032 tokens
Reasoning: 21,893 tokens
Cache read: 11,375,466 tokens
Cache write: 1,492,725 tokens
OpenCode estimated cost: $3.974241
Using GitHub’s published Claude Opus 5.5 rates—input $4/M, cached input $0.20/M, cache write $5/M, output $20/M—the cache-write tokens alone cost about $7.463625. Including them gives an estimated total of about $11.437866, before any account-specific billing adjustments.

A smaller session showed the same pattern: OpenCode estimated $0.012289 with 23,052 cache-write tokens. At GitHub’s $5/M cache-write rate, those writes add $0.115260, giving about $0.127549—consistent with the 13 AI Credits shown in GitHub usage.

Likely cause

The GitHub Copilot model mapping appears to set cache.write to zero in packages/core/src/github-copilot/models.ts, while the Anthropic Messages usage parser records cache-creation tokens from cache_creation_input_tokens in packages/ai/src/protocols/anthropic-messages.ts.

Expected behavior

When the provider reports cache-write usage, OpenCode should apply the corresponding model’s cache-write price in its session estimate—or clearly indicate that cache-write pricing is unavailable and excluded.

GitHub’s Copilot model pricing lists cache-write pricing for Claude Opus 5.5. OpenCode’s session estimate is not expected to equal the final organization invoice exactly, but omitting the cache-write component produces a substantial mismatch.

Plugins

No response

OpenCode version

2.0.18

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. github-actions commented on Sep 28, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • #30706: Tracks GitHub Copilot cache-write pricing being dropped in the token-based cost fallback.
  2. gr0maqny commented on Oct 27, 2026

    @gr0maqny

    I can relate to the issue. I am using haiku 5.5 xhigh on opencode V2 with github copilot credits and the amount in dollars in opencode is largely underreported compared to my quota emptying faster in the github copilot interface.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report and the numbers. I could reproduce this.

    The script below starts a mock Copilot /models endpoint that lists Claude Opus 5.5 with cache_write_price set to $5/M. It then loads the model the way OpenCode does and prices your first session's token counts. The model comes out with a cache-write price of 0, and the session estimate is $3.974241, exactly the figure you saw. Pricing the cache writes would give about $11.437866.

    The cause looks like the line you pointed to: in packages/core/src/github-copilot/models.ts the cache-write price is always set to zero, even though the Copilot model list includes a cache-write price. That code is the same in v2.0.18 and on the latest dev (86ce19d), so it still happens there. One caveat: the model list here is mocked, so I haven't confirmed what Copilot's live API sends for this model.

    Reproduction script (copilot-cache-write.ts)
    // Reproduces #51845: Copilot cache-write tokens priced at $0.
    // Run from an opencode checkout: bun /workspace/repro/copilot-cache-write.ts [/path/to/repo]
    const repo = process.argv[2] ?? "/workspace/repo"
    const { CopilotModels } = await import(`${repo}/packages/core/src/github-copilot/models.ts`)
    const { SessionUsage } = await import(`${repo}/packages/core/src/session/usage.ts`)
    
    // Mock Copilot /models: Claude Opus 5.5 at $4/M input, $0.20/M cache read, $5/M cache write, $20/M output
    // (prices in cents per batch_size tokens, same convention as packages/core/test/github-copilot/models.test.ts).
    const server = Bun.serve({
      port: 0,
      fetch: () =>
        Response.json({
          data: [{
            model_picker_enabled: true,
            id: "claude-opus-5.5",
            name: "Claude Opus 5.5",
            version: "claude-opus-5.5",
            supported_endpoints: ["/v1/messages"],
            billing: { token_prices: { batch_size: 1_000_000, default: {
              input_price: 400, output_price: 2000, cache_read_price: 20, cache_write_price: 500 } } },
            capabilities: { family: "claude-opus", limits: { max_output_tokens: 64000, max_prompt_tokens: 200000 },
              supports: { tool_calls: true } },
          }],
        }),
    })
    try {
      const models = await CopilotModels.get(server.url.origin, {}, [])
      const cost = [...models.values()][0].cost
      console.log("model cost:", JSON.stringify(cost[0]))
      const usage = { input: 162, output: 63_032, reasoning: 21_893, cache: { read: 11_375_466, write: 1_492_725 } }
      const got = SessionUsage.calculateCost(cost, usage)
      const expected = (162 * 4 + (63_032 + 21_893) * 20 + 11_375_466 * 0.2 + 1_492_725 * 5) / 1e6
      console.log("estimated cost:", got.toFixed(6), " expected:", expected.toFixed(6))
      if (cost[0].cache.write === 0) { console.log("BUG: cache_write_price advertised but cache.write priced at 0"); process.exitCode = 1 }
    } finally {
      server.stop(true)
    }

    Run it: bun copilot-cache-write.ts

  4. rekram1-node commented on Nov 10, 2026

    @rekram1-node
    Collaborator

    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.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions