anthropics / anthropics/anthropic-sdk-csharp

MEAI adapter: ToUsageDetails drops Usage.OutputTokensDetails.ThinkingTokens (UsageDetails.ReasoningTokenCount never populated)

Aperta
#245 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
C#
Stelle
322
Fork
105
Merge medio
1g 6h
PR unite (30g)
9

Descrizione

The Microsoft.Extensions.AI adapter (AnthropicClientExtensions.AnthropicChatClient, verified on 12.40.0) never forwards Usage.OutputTokensDetails.ThinkingTokens. The response model carries the count (final Usage and streaming MessageDeltaUsage both), but ToUsageDetails forwards only input/output/cache-creation/cache-read and the two server-tool counters. So a consumer on the MEAI abstraction cannot meter reasoning tokens (for example, the OTel GenAI gen_ai.usage.reasoning.output_tokens attribute, added in semconv v1.41.0, is unreachable from this surface).

UsageDetails has had a first-class home for this since M.E.AI.Abstractions 10.1.x: ReasoningTokenCount (dotnet/extensions#7122), documented as counted within OutputTokenCount; the same semantics as the Anthropic field (thinking_tokens is documented as always ≤ output_tokens, with output_tokens remaining the inclusive billing total). The peer OpenAI adapter already populates it (OpenAIChatClient.FromOpenAIUsage: ReasoningTokenCount = tokenUsage.OutputTokenDetails?.ReasoningTokenCount), and the 12.40.0 package already depends on M.E.AI.Abstractions >= 10.5.1, so the fix looks like a one-liner: ReasoningTokenCount = usage.OutputTokensDetails?.ThinkingTokens plus the streaming-delta merge path.

Context: #221 is adjacent request-side reasoning evidence (the adapter's ChatOptions.Reasoning mapping).

Happy to PR this. Our downstream currently records the count as unreachable, with a pinned boundary test that alerts us if/when a release fixes it.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.