@@ -60,11 +60,12 @@ defmodule Nous.Messages.Gemini do
6060 content_data = Map . get ( candidate , "content" , % { } )
6161 parts_data = Map . get ( content_data , "parts" , [ ] )
6262
63- { content_parts , tool_calls } = parse_content ( parts_data )
63+ { content_parts , reasoning_content , tool_calls } = parse_content ( parts_data )
6464
6565 attrs = % {
6666 role: :assistant ,
6767 content: consolidate_content_parts ( content_parts ) ,
68+ reasoning_content: consolidate_content_parts ( reasoning_content ) ,
6869 metadata: % {
6970 model_name: "gemini-model" ,
7071 usage: parse_usage ( usage_data ) ,
@@ -91,9 +92,15 @@ defmodule Nous.Messages.Gemini do
9192 end
9293
9394 parts = Map . get ( msg , "parts" , [ ] )
94- { text_content , tool_calls } = parse_parts ( parts )
95+ { text_content , reasoning_content , tool_calls } = parse_parts ( parts )
9596
9697 attrs = % { role: role , content: text_content }
98+
99+ attrs =
100+ if reasoning_content != "" ,
101+ do: Map . put ( attrs , :reasoning_content , reasoning_content ) ,
102+ else: attrs
103+
97104 attrs = if length ( tool_calls ) > 0 , do: Map . put ( attrs , :tool_calls , tool_calls ) , else: attrs
98105
99106 Message . new! ( attrs )
@@ -111,11 +118,21 @@ defmodule Nous.Messages.Gemini do
111118 % { "role" => "user" , "parts" => gemini_parts }
112119 end
113120
114- defp message_to_gemini ( % Message { role: :assistant , content: content , tool_calls: tool_calls } ) do
121+ defp message_to_gemini ( % Message {
122+ role: :assistant ,
123+ content: content ,
124+ reasoning_content: reasoning ,
125+ tool_calls: tool_calls
126+ } ) do
115127 parts = [ ]
116128
117129 parts = if content && content != "" , do: [ % { "text" => content } | parts ] , else: parts
118130
131+ parts =
132+ if reasoning && reasoning != "" ,
133+ do: [ % { "text" => reasoning , "thought" => true } | parts ] ,
134+ else: parts
135+
119136 parts =
120137 if length ( tool_calls ) > 0 do
121138 tool_parts =
@@ -168,11 +185,15 @@ defmodule Nous.Messages.Gemini do
168185 end
169186
170187 defp parse_content ( parts_data ) when is_list ( parts_data ) do
171- { content_parts , tool_calls } =
172- Enum . reduce ( parts_data , { [ ] , [ ] } , fn item , { parts , tools } ->
188+ { content_parts , reasoning_content , tool_calls } =
189+ Enum . reduce ( parts_data , { [ ] , [ ] , [ ] } , fn item , { parts , reasoning , tools } ->
173190 case item do
174191 % { "text" => text } ->
175- { [ ContentPart . text ( text ) | parts ] , tools }
192+ if Map . get ( item , "thought" ) do
193+ { parts , [ ContentPart . thinking ( text ) | reasoning ] , tools }
194+ else
195+ { [ ContentPart . text ( text ) | parts ] , reasoning , tools }
196+ end
176197
177198 % { "functionCall" => % { "name" => name , "args" => args } } ->
178199 tool_call = % {
@@ -181,23 +202,28 @@ defmodule Nous.Messages.Gemini do
181202 "arguments" => args
182203 }
183204
184- { parts , [ tool_call | tools ] }
205+ { parts , reasoning , [ tool_call | tools ] }
185206
186207 _ ->
187- { parts , tools }
208+ { parts , reasoning , tools }
188209 end
189210 end )
190211
191- { Enum . reverse ( content_parts ) , Enum . reverse ( tool_calls ) }
212+ { Enum . reverse ( content_parts ) , Enum . reverse ( reasoning_content ) , Enum . reverse ( tool_calls ) }
192213 end
193214
194215 defp parse_parts ( parts ) when is_list ( parts ) do
195- { text_parts , tool_calls } =
196- Enum . reduce ( parts , { [ ] , [ ] } , fn part , { texts , tools } ->
216+ { text_parts , reasoning_parts , tool_calls } =
217+ Enum . reduce ( parts , { [ ] , [ ] , [ ] } , fn part , { texts , reasoning , tools } ->
197218 cond do
198219 Map . has_key? ( part , "text" ) ->
199220 text = Map . get ( part , "text" , "" )
200- { [ text | texts ] , tools }
221+
222+ if Map . get ( part , "thought" ) do
223+ { texts , [ text | reasoning ] , tools }
224+ else
225+ { [ text | texts ] , reasoning , tools }
226+ end
201227
202228 Map . has_key? ( part , "functionCall" ) ->
203229 function_call = Map . get ( part , "functionCall" )
@@ -209,14 +235,15 @@ defmodule Nous.Messages.Gemini do
209235 "arguments" => Map . get ( function_call , "args" , % { } )
210236 }
211237
212- { texts , [ tool_call | tools ] }
238+ { texts , reasoning , [ tool_call | tools ] }
213239
214240 true ->
215- { texts , tools }
241+ { texts , reasoning , tools }
216242 end
217243 end )
218244
219245 text_content = text_parts |> Enum . reverse ( ) |> Enum . join ( " " ) |> String . trim ( )
246+ reasoning_content = reasoning_parts |> Enum . reverse ( ) |> Enum . join ( " " ) |> String . trim ( )
220247 # Add space after text if there are tool calls
221248 text_content =
222249 if text_content != "" and length ( tool_calls ) > 0 do
@@ -225,7 +252,7 @@ defmodule Nous.Messages.Gemini do
225252 text_content
226253 end
227254
228- { text_content , Enum . reverse ( tool_calls ) }
255+ { text_content , reasoning_content , Enum . reverse ( tool_calls ) }
229256 end
230257
231258 defp parse_usage ( usage_data ) when is_map ( usage_data ) do
@@ -240,5 +267,6 @@ defmodule Nous.Messages.Gemini do
240267
241268 defp consolidate_content_parts ( [ ] ) , do: ""
242269 defp consolidate_content_parts ( [ % ContentPart { type: :text , content: content } ] ) , do: content
270+ defp consolidate_content_parts ( [ % ContentPart { type: :thinking , content: content } ] ) , do: content
243271 defp consolidate_content_parts ( parts ) when is_list ( parts ) , do: parts
244272end
0 commit comments