Add token usage tracking to TokenCapChatClient and display usage summary - #15
Merged
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The new usage tracking surface area is not covered by existing unit tests, increasing regression risk for the added behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds end-to-end token usage accounting to the shared IChatClient pipeline by accumulating per-call usage (input/output/total, plus reasoning tokens surfaced via UsageDetails.AdditionalCounts) and printing a final usage summary at the end of the run.
Changes:
- Extend
TokenCapChatClientto track cumulative input, output, reasoning, and total tokens and expose them via aTokenUsageSnapshot. - Capture the
TokenCapChatClientinstance when building the LLM middleware pipeline and print a “TOKEN USAGE” summary after workflow results.
File summaries
| File | Description |
|---|---|
| TokenCapChatClient.cs | Adds cumulative token counters, reasoning-token extraction from AdditionalCounts, and a UsageSnapshot accessor. |
| Program.cs | Captures the TokenCapChatClient from the pipeline and prints a final token usage summary block. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| : throw new ArgumentOutOfRangeException(nameof(maxTotalTokens), maxTotalTokens, "Token cap must be a positive number."); | ||
| } | ||
|
|
||
| /// <summary>Cumulative token usage observed across every model round-trip so far.</summary> |
Comment on lines
+76
to
+82
| Interlocked.Add(ref _inputTokens, usage.InputTokenCount ?? 0); | ||
| Interlocked.Add(ref _outputTokens, usage.OutputTokenCount ?? 0); | ||
| if (usage.AdditionalCounts is { } additionalCounts && | ||
| additionalCounts.TryGetValue(ReasoningTokenCountKey, out long reasoningTokens)) | ||
| { | ||
| Interlocked.Add(ref _reasoningTokens, reasoningTokens); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TokenCapChatClient.cs: now tracks InputTokenCount, OutputTokenCount, and cumulative TotalTokenCount from every UsageDetails, plus reasoning tokens pulled from UsageDetails.AdditionalCounts["OutputTokenDetails.ReasoningTokenCount"] (how OpenAI reasoning-model usage is surfaced). Exposes a thread-safe UsageSnapshot (TokenUsageSnapshot record) with the four totals. The existing cap-enforcement behavior is unchanged.
Program.cs: captures the TokenCapChatClient instance built into the shared llm pipeline (all agents use it), and after printing the draft/review results, prints a "TOKEN USAGE" block with input, output, reasoning, and total token counts across the whole run.