@@ -1209,6 +1209,73 @@ def test_content_conversion_carries_function_response_media() -> None:
12091209 ]
12101210
12111211
1212+ def test_content_conversion_keeps_text_alongside_function_response () -> None :
1213+ """Text sent with a tool result follows the tool message as a user turn."""
1214+ part = types .Part .from_function_response (
1215+ name = 'lookup' , response = {'status' : 'ok' }
1216+ )
1217+ assert part .function_response is not None
1218+ part .function_response .id = 'call_1'
1219+ content = types .Content (
1220+ role = 'user' ,
1221+ parts = [part , types .Part .from_text (text = 'Summarize it in French.' )],
1222+ )
1223+
1224+ client = CompletionsHTTPClient (base_url = 'http://test' )
1225+ messages = client ._content_to_messages (content )
1226+
1227+ assert messages == [
1228+ {
1229+ 'role' : 'tool' ,
1230+ 'tool_call_id' : 'call_1' ,
1231+ 'content' : '{"status": "ok"}' ,
1232+ },
1233+ {'role' : 'user' , 'content' : 'Summarize it in French.' },
1234+ ]
1235+
1236+
1237+ def test_content_conversion_keeps_text_alongside_function_response_media () -> (
1238+ None
1239+ ):
1240+ """Tool media and accompanying text share one follow-up user message."""
1241+ part = types .Part .from_function_response (
1242+ name = 'draw_chart' ,
1243+ response = {'title' : 'Revenue' },
1244+ parts = [
1245+ types .FunctionResponsePart .from_bytes (
1246+ data = b'chart' , mime_type = 'image/png'
1247+ )
1248+ ],
1249+ )
1250+ assert part .function_response is not None
1251+ part .function_response .id = 'call_1'
1252+ content = types .Content (
1253+ role = 'user' ,
1254+ parts = [part , types .Part .from_text (text = 'Describe the chart.' )],
1255+ )
1256+
1257+ client = CompletionsHTTPClient (base_url = 'http://test' )
1258+ messages = client ._content_to_messages (content )
1259+
1260+ assert messages == [
1261+ {
1262+ 'role' : 'tool' ,
1263+ 'tool_call_id' : 'call_1' ,
1264+ 'content' : '{"title": "Revenue"}' ,
1265+ },
1266+ {
1267+ 'role' : 'user' ,
1268+ 'content' : [
1269+ {
1270+ 'type' : 'image_url' ,
1271+ 'image_url' : {'url' : 'data:image/png;base64,Y2hhcnQ=' },
1272+ },
1273+ {'type' : 'text' , 'text' : 'Describe the chart.' },
1274+ ],
1275+ },
1276+ ]
1277+
1278+
12121279def test_content_conversion_without_function_response_media () -> None :
12131280 """A response carrying no media still converts to a lone tool message."""
12141281 part = types .Part .from_function_response (
0 commit comments