Skip to content

Copilot: count every agent round and bill exact credits in VS Code chat sessions - #1752

Merged
iamtoruk merged 3 commits into
mainfrom
fix/copilot-agent-totals
Oct 12, 2026
Merged

iamtoruk merged 3 commits into
mainfrom
fix/copilot-agent-totals

Conversation

@iamtoruk

Copy link
Copy Markdown
Member

In agent mode one Copilot message runs many model rounds. VS Code stores the last round in result.metadata.outputTokens/promptTokens and the request totals in completionTokens, modelTotals and copilotCredits; the chat-session parsers read the last-round fields first, so long agent chats undercounted output badly (a user saw 3.6K output vs 129K, $6.91 vs ~$19.30 billed).

  • Output from modelTotals → root completionTokens → metadata.outputTokens; input and cache read from modelTotals when present.
  • copilotCredits is carried as nanoAiu; when present, USD = credits × $0.01 via costFromBilling (GitHub usage-based billing rate). Requests without credits stay token-priced. Agent-host path unchanged.
  • Twin guard at serve time: a chat-session request is dropped only when the same session id has billed agent-host usage (events.jsonl or session store), so nothing counts twice.
  • Plan math rates chat requests one by one; credit-less requests keep their estimate.
  • DAILY_CACHE_VERSION 75 and Copilot re-derive version 75, so settled days pick up the fix.
  • claude-sonnet-4-6 now displays as Sonnet 4.6 (display matching only; pricing lookup unchanged).
  • Docs and CHANGELOG updated.

Checks: tsc clean; full suite 5211 passed, 0 failed; real-data before/after identical for every non-Copilot provider (16 at 30 days, 22 all-time) and identical overview totals after the v74 → v75 cache migration. Independent review of the money logic and the delta: safe to merge.

…ssions

Copilot Chat 0.69 keeps only the last model call of an agent request in result.metadata. Read the request's modelTotals (input, cache reads, output over every call) first, then root completionTokens, then metadata. Carry copilotCredits as nanoAiu so plan credits are exact. Bump the copilot parse tag so cached chat sessions re-parse.

modelKeyMatches no longer lets claude-sonnet-4 capture claude-sonnet-4-6.
A chat-session request that records copilotCredits now costs credits x $0.01 through costFromBilling; requests without it stay priced from tokens. A chat session whose id matches a session-state dir is left to the agent-host path so it is counted once.
…by one, re-derive past days

A chat-session journal request is left out when the same session has billed agent-host usage (session-state calls with tokens or nanoAiu, or session-store rows). Plan credits rate chat-session requests individually, so older requests in a mixed session keep their estimate. DAILY_CACHE_VERSION 75 with copilot pending re-derive so settled days pick up the new counts.
@iamtoruk
iamtoruk merged commit 354492e into main Oct 12, 2026
23 checks passed
@iamtoruk
iamtoruk deleted the fix/copilot-agent-totals branch October 12, 2026 23:02
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