@@ -153,23 +153,9 @@ export function filterUnsignedThinkingBlocks(contents: any[]): any[] {
153153}
154154
155155/**
156- * Transforms Anthropic-style thinking blocks (type: "thinking") to reasoning format.
157- */
158- function transformAnthropicThinkingBlocks ( content : any [ ] ) : any [ ] {
159- return content . map ( ( block : any ) => {
160- if ( block && typeof block === "object" && block . type === "thinking" ) {
161- return {
162- type : "reasoning" ,
163- text : block . text || "" ,
164- ...( block . signature ? { signature : block . signature } : { } ) ,
165- } ;
166- }
167- return block ;
168- } ) ;
169- }
170-
171- /**
172- * Transforms Gemini-style thought parts (thought: true) to reasoning format.
156+ * Transforms Gemini-style thought parts (thought: true) and Anthropic-style
157+ * thinking parts (type: "thinking") to reasoning format.
158+ * Claude responses through Antigravity may use candidates structure with Anthropic-style parts.
173159 */
174160function transformGeminiCandidate ( candidate : any ) : any {
175161 if ( ! candidate || typeof candidate !== "object" ) {
@@ -183,10 +169,28 @@ function transformGeminiCandidate(candidate: any): any {
183169
184170 const thinkingTexts : string [ ] = [ ] ;
185171 const transformedParts = content . parts . map ( ( part : any ) => {
186- if ( part && typeof part === "object" && part . thought === true ) {
172+ if ( ! part || typeof part !== "object" ) {
173+ return part ;
174+ }
175+
176+ // Handle Gemini-style: thought: true
177+ if ( part . thought === true ) {
187178 thinkingTexts . push ( part . text || "" ) ;
188179 return { ...part , type : "reasoning" } ;
189180 }
181+
182+ // Handle Anthropic-style in candidates: type: "thinking"
183+ if ( part . type === "thinking" ) {
184+ const thinkingText = part . thinking || part . text || "" ;
185+ thinkingTexts . push ( thinkingText ) ;
186+ return {
187+ ...part ,
188+ type : "reasoning" ,
189+ text : thinkingText ,
190+ thought : true ,
191+ } ;
192+ }
193+
190194 return part ;
191195 } ) ;
192196
@@ -200,6 +204,7 @@ function transformGeminiCandidate(candidate: any): any {
200204/**
201205 * Transforms thinking/reasoning content in response parts to OpenCode's expected format.
202206 * Handles both Gemini-style (thought: true) and Anthropic-style (type: "thinking") formats.
207+ * Also extracts reasoning_content for Anthropic-style responses.
203208 */
204209export function transformThinkingParts ( response : unknown ) : unknown {
205210 if ( ! response || typeof response !== "object" ) {
@@ -208,15 +213,38 @@ export function transformThinkingParts(response: unknown): unknown {
208213
209214 const resp = response as Record < string , unknown > ;
210215 const result : Record < string , unknown > = { ...resp } ;
216+ const reasoningTexts : string [ ] = [ ] ;
211217
218+ // Handle Anthropic-style content array (type: "thinking")
212219 if ( Array . isArray ( resp . content ) ) {
213- result . content = transformAnthropicThinkingBlocks ( resp . content ) ;
220+ const transformedContent : any [ ] = [ ] ;
221+ for ( const block of resp . content ) {
222+ if ( block && typeof block === "object" && ( block as any ) . type === "thinking" ) {
223+ const thinkingText = ( block as any ) . thinking || ( block as any ) . text || "" ;
224+ reasoningTexts . push ( thinkingText ) ;
225+ transformedContent . push ( {
226+ ...block ,
227+ type : "reasoning" ,
228+ text : thinkingText ,
229+ thought : true ,
230+ } ) ;
231+ } else {
232+ transformedContent . push ( block ) ;
233+ }
234+ }
235+ result . content = transformedContent ;
214236 }
215237
238+ // Handle Gemini-style candidates array
216239 if ( Array . isArray ( resp . candidates ) ) {
217240 result . candidates = resp . candidates . map ( transformGeminiCandidate ) ;
218241 }
219242
243+ // Add reasoning_content if we found any thinking blocks (for Anthropic-style)
244+ if ( reasoningTexts . length > 0 && ! result . reasoning_content ) {
245+ result . reasoning_content = reasoningTexts . join ( "\n\n" ) ;
246+ }
247+
220248 return result ;
221249}
222250
0 commit comments