77//
88#include " ../src/llama-grammar.h"
99#include " ../src/unicode.h"
10+ #include " ../tools/server/server-chat.h"
1011#include " chat-auto-parser.h"
1112#include " chat.h"
1213#include " common.h"
@@ -1514,6 +1515,117 @@ static void test_tools_oaicompat_json_conversion() {
15141515 common_chat_tools_to_json_oaicompat ({ special_function_tool }).dump (2 ));
15151516}
15161517
1518+ static void test_convert_responses_to_chatcmpl () {
1519+ LOG_DBG (" %s\n " , __func__);
1520+
1521+ // Test basic conversion with input messages (user/assistant alternating)
1522+ {
1523+ json input = json::parse (R"( {
1524+ "input": [
1525+ {
1526+ "type": "message",
1527+ "role": "user",
1528+ "content": "hi wassup"
1529+ },
1530+ {
1531+ "type": "message",
1532+ "role": "assistant",
1533+ "content": "Hey! 👋 Not much, just here ready to chat. What's up with you? Anything I can help you with today?"
1534+ },
1535+ {
1536+ "type": "message",
1537+ "role": "user",
1538+ "content": "hi"
1539+ }
1540+ ],
1541+ "model": "gpt-5-mini",
1542+ "stream": false,
1543+ "text": {},
1544+ "reasoning": {
1545+ "effort": "medium"
1546+ }
1547+ })" );
1548+
1549+ json result = server_chat_convert_responses_to_chatcmpl (input);
1550+
1551+ // Verify messages were converted correctly
1552+ assert_equals (true , result.contains (" messages" ));
1553+ assert_equals (true , result.at (" messages" ).is_array ());
1554+ assert_equals ((size_t )3 , result.at (" messages" ).size ());
1555+
1556+ // Check first message (user)
1557+ const auto & msg0 = result.at (" messages" )[0 ];
1558+ assert_equals (std::string (" user" ), msg0.at (" role" ).get <std::string>());
1559+ assert_equals (true , msg0.at (" content" ).is_array ());
1560+ assert_equals (std::string (" text" ), msg0.at (" content" )[0 ].at (" type" ).get <std::string>());
1561+ assert_equals (std::string (" hi wassup" ), msg0.at (" content" )[0 ].at (" text" ).get <std::string>());
1562+
1563+ // Check second message (assistant)
1564+ const auto & msg1 = result.at (" messages" )[1 ];
1565+ assert_equals (std::string (" assistant" ), msg1.at (" role" ).get <std::string>());
1566+ assert_equals (true , msg1.at (" content" ).is_array ());
1567+ assert_equals (std::string (" text" ), msg1.at (" content" )[0 ].at (" type" ).get <std::string>());
1568+ assert_equals (std::string (" Hey! 👋 Not much, just here ready to chat. What's up with you? Anything I can help you with today?" ), msg1.at (" content" )[0 ].at (" text" ).get <std::string>());
1569+
1570+ // Check third message (user)
1571+ const auto & msg2 = result.at (" messages" )[2 ];
1572+ assert_equals (std::string (" user" ), msg2.at (" role" ).get <std::string>());
1573+ assert_equals (true , msg2.at (" content" ).is_array ());
1574+ assert_equals (std::string (" text" ), msg2.at (" content" )[0 ].at (" type" ).get <std::string>());
1575+ assert_equals (std::string (" hi" ), msg2.at (" content" )[0 ].at (" text" ).get <std::string>());
1576+
1577+ // Verify other fields preserved
1578+ assert_equals (std::string (" gpt-5-mini" ), result.at (" model" ).get <std::string>());
1579+ assert_equals (false , result.at (" stream" ).get <bool >());
1580+ }
1581+
1582+ // Test string input
1583+ {
1584+ json input = json::parse (R"( {
1585+ "input": "Hello, world!",
1586+ "model": "test-model"
1587+ })" );
1588+
1589+ json result = server_chat_convert_responses_to_chatcmpl (input);
1590+
1591+ assert_equals ((size_t )1 , result.at (" messages" ).size ());
1592+ const auto & msg = result.at (" messages" )[0 ];
1593+ assert_equals (std::string (" user" ), msg.at (" role" ).get <std::string>());
1594+ assert_equals (std::string (" Hello, world!" ), msg.at (" content" ).get <std::string>());
1595+ }
1596+
1597+ // Test with instructions (system message)
1598+ {
1599+ json input = json::parse (R"( {
1600+ "input": "Hello",
1601+ "instructions": "You are a helpful assistant.",
1602+ "model": "test-model"
1603+ })" );
1604+
1605+ json result = server_chat_convert_responses_to_chatcmpl (input);
1606+
1607+ assert_equals ((size_t )2 , result.at (" messages" ).size ());
1608+ const auto & sys_msg = result.at (" messages" )[0 ];
1609+ assert_equals (std::string (" system" ), sys_msg.at (" role" ).get <std::string>());
1610+ assert_equals (std::string (" You are a helpful assistant." ), sys_msg.at (" content" ).get <std::string>());
1611+ }
1612+
1613+ // Test with max_output_tokens conversion
1614+ {
1615+ json input = json::parse (R"( {
1616+ "input": "Hello",
1617+ "model": "test-model",
1618+ "max_output_tokens": 100
1619+ })" );
1620+
1621+ json result = server_chat_convert_responses_to_chatcmpl (input);
1622+
1623+ assert_equals (true , result.contains (" max_tokens" ));
1624+ assert_equals (false , result.contains (" max_output_tokens" ));
1625+ assert_equals (100 , result.at (" max_tokens" ).get <int >());
1626+ }
1627+ }
1628+
15171629static void test_template_output_peg_parsers (bool detailed_debug) {
15181630 LOG_DBG (" %s\n " , __func__);
15191631
@@ -4291,7 +4403,7 @@ int main(int argc, char ** argv) {
42914403 bool detailed_debug = false ;
42924404 bool only_run_filtered = false ;
42934405
4294- // Check for --template flag
4406+ // Check for --template and --detailed flags
42954407 for (int i = 1 ; i < argc; i++) {
42964408 std::string arg = argv[i];
42974409 if (arg == " --template" && i + 1 < argc) {
@@ -4316,7 +4428,20 @@ int main(int argc, char ** argv) {
43164428 }
43174429
43184430#ifndef _WIN32
4319- if (argc > 1 ) {
4431+ // Check if any argument is a .jinja file (for template format detection mode)
4432+ bool has_jinja_files = false ;
4433+ for (int i = 1 ; i < argc; i++) {
4434+ std::string arg = argv[i];
4435+ if (arg == " --detailed" ) {
4436+ continue ;
4437+ }
4438+ if (arg.size () >= 6 && arg.rfind (" .jinja" ) == arg.size () - 6 ) {
4439+ has_jinja_files = true ;
4440+ break ;
4441+ }
4442+ }
4443+
4444+ if (has_jinja_files) {
43204445 common_chat_templates_inputs inputs;
43214446 common_chat_msg msg;
43224447 msg.role = " user" ;
@@ -4349,6 +4474,7 @@ int main(int argc, char ** argv) {
43494474 test_msg_diffs_compute ();
43504475 test_msgs_oaicompat_json_conversion ();
43514476 test_tools_oaicompat_json_conversion ();
4477+ test_convert_responses_to_chatcmpl ();
43524478 test_developer_role_to_system_workaround ();
43534479 test_reka_edge_common_path ();
43544480 test_template_output_peg_parsers (detailed_debug);
0 commit comments