@@ -345,6 +345,7 @@ public struct AnthropicLanguageModel: LanguageModel {
345345 )
346346
347347 var entries : [ Transcript . Entry ] = [ ]
348+ let usage = message. usage? . languageModelUsage
348349
349350 // Handle tool calls, if present
350351 let toolUses : [ AnthropicToolUse ] = message. content. compactMap { block in
@@ -363,6 +364,7 @@ public struct AnthropicLanguageModel: LanguageModel {
363364 return LanguageModelSession . Response (
364365 content: empty. content,
365366 rawContent: empty. rawContent,
367+ usage: usage,
366368 transcriptEntries: ArraySlice ( entries)
367369 )
368370 case . invocations( let invocations) :
@@ -386,6 +388,7 @@ public struct AnthropicLanguageModel: LanguageModel {
386388 return LanguageModelSession . Response (
387389 content: text as! Content ,
388390 rawContent: GeneratedContent ( text) ,
391+ usage: usage,
389392 transcriptEntries: ArraySlice ( entries)
390393 )
391394 }
@@ -395,6 +398,7 @@ public struct AnthropicLanguageModel: LanguageModel {
395398 return LanguageModelSession . Response (
396399 content: content,
397400 rawContent: rawContent,
401+ usage: usage,
398402 transcriptEntries: ArraySlice ( entries)
399403 )
400404 }
@@ -445,30 +449,48 @@ public struct AnthropicLanguageModel: LanguageModel {
445449
446450 var accumulatedText = " "
447451 let expectsStructuredResponse = type != String . self
452+ var latestUsage = LanguageModelUsage ( )
453+ var lastSnapshot : LanguageModelSession . ResponseStream < Content > . Snapshot ?
448454
449455 for try await event in events {
450456 switch event {
457+ case . messageStart( let start) :
458+ latestUsage. merge ( start. message. usage? . languageModelUsage)
451459 case . contentBlockDelta( let delta) :
452460 if case . textDelta( let textDelta) = delta. delta {
453461 accumulatedText += textDelta. text
454462
455463 if expectsStructuredResponse {
456- if let snapshot: LanguageModelSession . ResponseStream < Content > . Snapshot =
464+ if var snapshot: LanguageModelSession . ResponseStream < Content > . Snapshot =
457465 try ? partialSnapshot ( from: accumulatedText)
458466 {
467+ snapshot. usage = latestUsage. normalized
468+ lastSnapshot = snapshot
459469 continuation. yield ( snapshot)
460470 }
461471 } else {
462472 let raw = GeneratedContent ( accumulatedText)
463473 let content : Content . PartiallyGenerated = ( accumulatedText as! Content )
464474 . asPartiallyGenerated ( )
465- continuation. yield ( . init( content: content, rawContent: raw) )
475+ let snapshot = LanguageModelSession . ResponseStream< Content> . Snapshot(
476+ content: content,
477+ rawContent: raw,
478+ usage: latestUsage. normalized
479+ )
480+ lastSnapshot = snapshot
481+ continuation. yield ( snapshot)
466482 }
467483 }
484+ case . messageDelta( let delta) :
485+ latestUsage. merge ( delta. usage? . languageModelUsage)
468486 case . messageStop:
487+ if var lastSnapshot, lastSnapshot. usage != latestUsage. normalized {
488+ lastSnapshot. usage = latestUsage. normalized
489+ continuation. yield ( lastSnapshot)
490+ }
469491 continuation. finish ( )
470492 return
471- case . messageStart , . contentBlockStart, . contentBlockStop, . messageDelta , . ping, . ignored:
493+ case . contentBlockStart, . contentBlockStop, . ping, . ignored:
472494 break
473495 }
474496 }
@@ -995,9 +1017,10 @@ private struct AnthropicMessageResponse: Codable, Sendable {
9951017 let content : [ AnthropicContent ]
9961018 let model : String
9971019 let stopReason : StopReason ?
1020+ let usage : AnthropicUsage ?
9981021
9991022 enum CodingKeys : String , CodingKey {
1000- case id, type, role, content, model
1023+ case id, type, role, content, model, usage
10011024 case stopReason = " stop_reason "
10021025 }
10031026
@@ -1012,6 +1035,20 @@ private struct AnthropicMessageResponse: Codable, Sendable {
10121035 }
10131036}
10141037
1038+ private struct AnthropicUsage : Codable , Sendable {
1039+ let inputTokens : Int ?
1040+ let outputTokens : Int ?
1041+ let cacheCreationInputTokens : Int ?
1042+ let cacheReadInputTokens : Int ?
1043+
1044+ enum CodingKeys : String , CodingKey {
1045+ case inputTokens = " input_tokens "
1046+ case outputTokens = " output_tokens "
1047+ case cacheCreationInputTokens = " cache_creation_input_tokens "
1048+ case cacheReadInputTokens = " cache_read_input_tokens "
1049+ }
1050+ }
1051+
10151052private struct AnthropicErrorResponse : Codable { let error : AnthropicErrorDetail }
10161053private struct AnthropicErrorDetail : Codable {
10171054 let type : String
@@ -1157,6 +1194,7 @@ private enum AnthropicStreamEvent: Codable, Sendable {
11571194 struct MessageDeltaEvent : Codable , Sendable {
11581195 let type : String
11591196 let delta : Delta
1197+ let usage : AnthropicUsage ?
11601198
11611199 struct Delta : Codable , Sendable {
11621200 let stopReason : String ?
@@ -1169,3 +1207,14 @@ private enum AnthropicStreamEvent: Codable, Sendable {
11691207 }
11701208 }
11711209}
1210+
1211+ private extension AnthropicUsage {
1212+ var languageModelUsage : LanguageModelUsage ? {
1213+ LanguageModelUsage (
1214+ inputTokens: inputTokens,
1215+ outputTokens: outputTokens,
1216+ cachedInputTokens: cacheReadInputTokens,
1217+ cacheCreationInputTokens: cacheCreationInputTokens
1218+ ) . normalized
1219+ }
1220+ }
0 commit comments