File tree Expand file tree Collapse file tree 2 files changed +33
-1
lines changed
Expand file tree Collapse file tree 2 files changed +33
-1
lines changed Original file line number Diff line number Diff line change @@ -225,6 +225,36 @@ describe("convertToOpenAiMessages", () => {
225225 expect ( assistantMessage . tool_calls ! [ 0 ] . id ) . toBe ( "custom_toolu_123" )
226226 } )
227227
228+ it ( "should use empty string for content when assistant message has only tool calls (Gemini compatibility)" , ( ) => {
229+ // This test ensures that assistant messages with only tool_use blocks (no text)
230+ // have content set to "" instead of undefined. Gemini (via OpenRouter) requires
231+ // every message to have at least one "parts" field, which fails if content is undefined.
232+ // See: ROO-425
233+ const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
234+ {
235+ role : "assistant" ,
236+ content : [
237+ {
238+ type : "tool_use" ,
239+ id : "tool-123" ,
240+ name : "read_file" ,
241+ input : { path : "test.ts" } ,
242+ } ,
243+ ] ,
244+ } ,
245+ ]
246+
247+ const openAiMessages = convertToOpenAiMessages ( anthropicMessages )
248+ expect ( openAiMessages ) . toHaveLength ( 1 )
249+
250+ const assistantMessage = openAiMessages [ 0 ] as OpenAI . Chat . ChatCompletionAssistantMessageParam
251+ expect ( assistantMessage . role ) . toBe ( "assistant" )
252+ // Content should be an empty string, NOT undefined
253+ expect ( assistantMessage . content ) . toBe ( "" )
254+ expect ( assistantMessage . tool_calls ) . toHaveLength ( 1 )
255+ expect ( assistantMessage . tool_calls ! [ 0 ] . id ) . toBe ( "tool-123" )
256+ } )
257+
228258 describe ( "mergeToolResultText option" , ( ) => {
229259 it ( "should merge text content into last tool message when mergeToolResultText is true" , ( ) => {
230260 const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
Original file line number Diff line number Diff line change @@ -223,7 +223,9 @@ export function convertToOpenAiMessages(
223223 reasoning_details ?: any [ ]
224224 } = {
225225 role : "assistant" ,
226- content,
226+ // Use empty string instead of undefined for providers like Gemini (via OpenRouter)
227+ // that require every message to have content in the "parts" field
228+ content : content ?? "" ,
227229 }
228230
229231 // Pass through reasoning_details to preserve the original shape from the API.
You can’t perform that action at this time.
0 commit comments