| 564 | }; |
| 565 | |
| 566 | static void test_peg_parser(common_chat_templates * tmpls, const std::function<void(peg_test_case &)> & init) { |
| 567 | peg_test_case tc; |
| 568 | init(tc); |
| 569 | if (tc.params.messages.empty()) { |
| 570 | tc.params.messages = {message_user}; |
| 571 | } |
| 572 | if (tc.expect.role.empty()) { |
| 573 | tc.expect.role = "assistant"; |
| 574 | } |
| 575 | |
| 576 | auto parser = make_peg_parser(tmpls, tc.params); |
| 577 | |
| 578 | common_chat_msg msg_accum; |
| 579 | common_chat_msg msg_prev; |
| 580 | msg_accum.role = msg_prev.role = "assistant"; |
| 581 | |
| 582 | for (size_t i = 1; i <= tc.input.size(); ++i) { |
| 583 | auto is_partial = i < tc.input.size(); |
| 584 | common_chat_msg msg_current = parser.parse(tc.input.substr(0, i), is_partial); |
| 585 | |
| 586 | for (const auto & diff : common_chat_msg_diff::compute_diffs(msg_prev, msg_current)) { |
| 587 | if (!diff.reasoning_content_delta.empty()) { |
| 588 | msg_accum.reasoning_content += diff.reasoning_content_delta; |
| 589 | } |
| 590 | if (!diff.content_delta.empty()) { |
| 591 | msg_accum.content += diff.content_delta; |
| 592 | } |
| 593 | if (diff.tool_call_index != std::string::npos) { |
| 594 | if (!diff.tool_call_delta.name.empty()) { |
| 595 | msg_accum.tool_calls.push_back({diff.tool_call_delta.name, "", diff.tool_call_delta.id}); |
| 596 | } |
| 597 | if (!diff.tool_call_delta.arguments.empty()) { |
| 598 | msg_accum.tool_calls.back().arguments += diff.tool_call_delta.arguments; |
| 599 | } |
| 600 | } |
| 601 | } |
| 602 | assert_msg_equals(msg_current, msg_accum, true); |
| 603 | msg_prev = msg_current; |
| 604 | } |
| 605 | |
| 606 | assert_msg_equals(tc.expect, parser.parse(tc.input, false), true); |
| 607 | assert_msg_equals(tc.expect, msg_accum, true); |
| 608 | } |
| 609 | |
| 610 | static void test_msgs_oaicompat_json_conversion() { |
| 611 | printf("[%s]\n", __func__); |
no test coverage detected