From 51648707906c7c0fa9bb3f671a1351ef9478335d Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Fri, 9 Jan 2026 14:16:59 -0300 Subject: [PATCH 1/2] Ensure Usage is reported in streaming We were not surfacing usage in chat streaming as expected by MS.E.AI: it expects a UsageContent to be present in the response updates, which signals consumption tokens during streaming. The extension method ToChatResponse then aggregates that into the response.Usage property, which we now verify in our sanity check. --- src/xAI.Tests/SanityChecks.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xAI.Tests/SanityChecks.cs b/src/xAI.Tests/SanityChecks.cs index 3540cea..aaf3ad0 100644 --- a/src/xAI.Tests/SanityChecks.cs +++ b/src/xAI.Tests/SanityChecks.cs @@ -255,6 +255,7 @@ void AssertIntegrationTest(ChatResponse response, Func getDateCalls) Assert.NotNull(response); Assert.NotNull(response.ModelId); Assert.NotEmpty(response.Messages); + Assert.NotNull(response.Usage); // Verify client-side tool was invoked Assert.True(getDateCalls() >= 1); From 75e08086b9d5e3b1656142e1f1411d791f1e7dfa Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Fri, 9 Jan 2026 14:17:49 -0300 Subject: [PATCH 2/2] IMPL --- src/xAI/GrokChatClient.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/xAI/GrokChatClient.cs b/src/xAI/GrokChatClient.cs index 27d5ed2..04694e1 100644 --- a/src/xAI/GrokChatClient.cs +++ b/src/xAI/GrokChatClient.cs @@ -94,8 +94,10 @@ async IAsyncEnumerable CompleteChatStreamingCore(IEnumerable ((List)update.Contents).AddRange(output.Delta.ToolCalls.AsContents(text, citations)); - if (update.Contents.Any()) - yield return update; + if (MapToUsage(chunk.Usage) is { } usage) + update.Contents.Add(new UsageContent(usage) { RawRepresentation = chunk.Usage }); + + yield return update; } } } @@ -277,6 +279,8 @@ codeResult.RawRepresentation is ToolCall codeToolCall && { InputTokenCount = usage.PromptTokens, OutputTokenCount = usage.CompletionTokens, + CachedInputTokenCount = usage.CachedPromptTextTokens, + ReasoningTokenCount = usage.ReasoningTokens, TotalTokenCount = usage.TotalTokens };