@@ -46,6 +46,41 @@ func TestConvertMessagesToResponseInput_OrphanedFunctionCall(t *testing.T) {
4646 assert .Contains (t , outputIDs , "call_2" )
4747}
4848
49+ func TestConvertMessagesToResponseInput_AssistantTextWithToolCalls (t * testing.T ) {
50+ // When an assistant message has both text content and tool calls,
51+ // the text must not be silently discarded.
52+ messages := []chat.Message {
53+ {Role : chat .MessageRoleUser , Content : "hello" },
54+ {
55+ Role : chat .MessageRoleAssistant ,
56+ Content : "Let me search that for you." ,
57+ ToolCalls : []tools.ToolCall {
58+ {ID : "call_1" , Type : "function" , Function : tools.FunctionCall {Name : "search" , Arguments : `{"q":"test"}` }},
59+ },
60+ },
61+ {Role : chat .MessageRoleTool , Content : "result" , ToolCallID : "call_1" },
62+ }
63+
64+ input := convertMessagesToResponseInput (messages )
65+
66+ // We expect: user message, assistant text message, function call, function call output.
67+ var foundAssistantText bool
68+ var foundFunctionCall bool
69+ for _ , item := range input {
70+ if item .OfMessage != nil && item .OfMessage .Role == "assistant" {
71+ if item .OfMessage .Content .OfString .Valid () && item .OfMessage .Content .OfString .Value == "Let me search that for you." {
72+ foundAssistantText = true
73+ }
74+ }
75+ if item .OfFunctionCall != nil && item .OfFunctionCall .CallID == "call_1" {
76+ foundFunctionCall = true
77+ }
78+ }
79+
80+ assert .True (t , foundFunctionCall , "function call should be present" )
81+ assert .True (t , foundAssistantText , "assistant text content should not be discarded when tool calls are present" )
82+ }
83+
4984func TestConvertMessagesToResponseInput_NoOrphans (t * testing.T ) {
5085 // All tool calls have matching results — no placeholder needed.
5186 messages := []chat.Message {
0 commit comments