@@ -48,7 +48,20 @@ export function toGemini(messages: OpenAIMessage[], options: ConvertOptions = {}
4848 let j = i ;
4949 while ( j < rest . length && rest [ j ] . role === 'tool' ) {
5050 const tool = rest [ j ] as OpenAIToolMessage ;
51- const name = idToName . get ( tool . tool_call_id ) ;
51+ const matchingName = idToName . get ( tool . tool_call_id ) ;
52+ if ( typeof tool . is_error === 'boolean' ) {
53+ reporter . warn (
54+ 'dropped-metadata' ,
55+ `Tool message is_error=${ tool . is_error } has no Gemini functionResponse equivalent; dropped.` ,
56+ ) ;
57+ }
58+ if ( typeof tool . name === 'string' && matchingName && tool . name !== matchingName ) {
59+ reporter . warn (
60+ 'dropped-metadata' ,
61+ `Tool message name '${ tool . name } ' differs from matching tool call '${ matchingName } '; used the tool-call function name for Gemini.` ,
62+ ) ;
63+ }
64+ const name = matchingName ?? tool . name ;
5265 if ( ! name ) {
5366 reporter . warn (
5467 'unmapped-tool-result' ,
@@ -70,10 +83,12 @@ export function toGemini(messages: OpenAIMessage[], options: ConvertOptions = {}
7083 }
7184
7285 if ( message . role === 'user' ) {
86+ warnDroppedName ( 'User' , message . name , 'Gemini' , reporter ) ;
7387 contents . push ( { role : 'user' , parts : userParts ( message . content , reporter ) } ) ;
7488 continue ;
7589 }
7690
91+ warnDroppedName ( 'Assistant' , message . name , 'Gemini' , reporter ) ;
7792 contents . push ( { role : 'model' , parts : assistantParts ( message , reporter ) } ) ;
7893 }
7994
@@ -123,6 +138,11 @@ function assistantParts(message: OpenAIAssistantMessage, reporter: Reporter): Ge
123138 return parts . length > 0 ? parts : [ { text : '' } ] ;
124139}
125140
141+ function warnDroppedName ( role : string , name : string | undefined , provider : string , reporter : Reporter ) : void {
142+ if ( typeof name !== 'string' ) return ;
143+ reporter . warn ( 'dropped-metadata' , `${ role } message name '${ name } ' has no ${ provider } equivalent; dropped.` ) ;
144+ }
145+
126146/** Merges adjacent same-role contents by concatenating their `parts` arrays. */
127147function mergeConsecutive ( contents : GeminiContent [ ] , reporter : Reporter ) : GeminiContent [ ] {
128148 const result : GeminiContent [ ] = [ ] ;
@@ -196,8 +216,13 @@ export function fromGemini(conversation: GeminiConversation, options: ConvertOpt
196216 for ( const part of parts ) {
197217 if ( isRecord ( part ) && isRecord ( part . functionResponse ) ) {
198218 const fr = part . functionResponse as { id ?: string ; name : string ; response ?: Record < string , unknown > } ;
199- const id = resolveResponseId ( fr , pending , reporter , generateId ) ;
200- out . push ( { role : 'tool' , tool_call_id : id , content : unwrapResponse ( fr . response ?? { } ) } ) ;
219+ const { id, matched } = resolveResponseId ( fr , pending , reporter , generateId ) ;
220+ out . push ( {
221+ role : 'tool' ,
222+ tool_call_id : id ,
223+ content : unwrapResponse ( fr . response ?? { } ) ,
224+ ...( matched ? { } : { name : fr . name } ) ,
225+ } ) ;
201226 continue ;
202227 }
203228 const image = imageFromGemini ( part ) ;
@@ -224,7 +249,7 @@ export function fromGemini(conversation: GeminiConversation, options: ConvertOpt
224249 out . push ( { role : 'user' , content : contentParts } ) ;
225250 } else {
226251 const text = textOf ( contentParts ) ;
227- if ( text ) out . push ( { role : 'user' , content : text } ) ;
252+ out . push ( { role : 'user' , content : text } ) ;
228253 }
229254 }
230255 }
@@ -237,22 +262,22 @@ function resolveResponseId(
237262 pending : { id : string ; name : string } [ ] ,
238263 reporter : Reporter ,
239264 generateId : ( name : string ) => string ,
240- ) : string {
265+ ) : { id : string ; matched : boolean } {
241266 if ( response . id ) {
242267 const index = pending . findIndex ( ( p ) => p . id === response . id ) ;
243268 if ( index >= 0 ) pending . splice ( index , 1 ) ;
244- return response . id ;
269+ return { id : response . id , matched : index >= 0 } ;
245270 }
246271 const index = pending . findIndex ( ( p ) => p . name === response . name ) ;
247272 if ( index >= 0 ) {
248273 const { id } = pending [ index ] ;
249274 pending . splice ( index , 1 ) ;
250- return id ;
275+ return { id , matched : true } ;
251276 }
252277 const id = generateId ( response . name ) ;
253278 reporter . warn (
254279 'unmapped-tool-result' ,
255280 `Gemini functionResponse for '${ response . name } ' had no matching call; generated '${ id } '.` ,
256281 ) ;
257- return id ;
282+ return { id , matched : false } ;
258283}
0 commit comments