@@ -170,12 +170,10 @@ struct GeminiUsageMetadata: Decodable {
170170 let cachedContentTokenCount : Int ?
171171
172172 var tokenUsage : TokenUsage {
173- let thoughts = thoughtsTokenCount ?? 0
174- let candidates = candidatesTokenCount ?? 0
175- return TokenUsage (
173+ TokenUsage (
176174 input: promptTokenCount ?? 0 ,
177- output: max ( 0 , candidates - thoughts ) ,
178- reasoning: thoughts ,
175+ output: candidatesTokenCount ?? 0 ,
176+ reasoning: thoughtsTokenCount ?? 0 ,
179177 cacheRead: cachedContentTokenCount
180178 )
181179 }
@@ -191,6 +189,38 @@ struct GeminiErrorDetail: Decodable {
191189 let status : String
192190}
193191
192+ enum GeminiReasoningDetail {
193+ private static let functionCallSignatureType = " gemini.function_call "
194+
195+ static func functionCallSignature(
196+ toolCallID: String ,
197+ signature: String
198+ ) -> JSONValue {
199+ . object( [
200+ " type " : . string( functionCallSignatureType) ,
201+ " tool_call_id " : . string( toolCallID) ,
202+ " thought_signature " : . string( signature)
203+ ] )
204+ }
205+
206+ static func functionCallSignatures(
207+ from details: [ JSONValue ]
208+ ) -> [ String : String ] {
209+ var signatures : [ String : String ] = [ : ]
210+ for detail in details {
211+ guard case let . object( dict) = detail,
212+ case . string( functionCallSignatureType) = dict [ " type " ] ,
213+ case let . string( toolCallID) = dict [ " tool_call_id " ] ,
214+ case let . string( signature) = dict [ " thought_signature " ]
215+ else {
216+ continue
217+ }
218+ signatures [ toolCallID] = signature
219+ }
220+ return signatures
221+ }
222+ }
223+
194224enum GeminiMessageMapper {
195225 static func mapMessages(
196226 _ messages: [ ChatMessage ]
@@ -253,6 +283,9 @@ enum GeminiMessageMapper {
253283 _ msg: AssistantMessage
254284 ) throws -> GeminiContent {
255285 var parts : [ GeminiPart ] = [ ]
286+ let functionCallSignatures = GeminiReasoningDetail . functionCallSignatures (
287+ from: msg. reasoningDetails ?? [ ]
288+ )
256289
257290 if let details = msg. reasoningDetails {
258291 for detail in details {
@@ -282,7 +315,8 @@ enum GeminiMessageMapper {
282315 parts. append ( GeminiPart (
283316 functionCall: GeminiFunctionCall (
284317 id: call. id, name: call. name, args: args
285- )
318+ ) ,
319+ thoughtSignature: functionCallSignatures [ call. id]
286320 ) )
287321 }
288322
0 commit comments