MCPcopy Create free account
hub / github.com/Tiiny-AI/PowerInfer / parse_json_tool_calls

Function parse_json_tool_calls

smallthinker/common/chat.cpp:625–696  ·  view source on GitHub ↗

* Takes a prefix regex that must have 1 group to capture the function name, a closing suffix, and expects json parameters in between. * Aggregates the prefix, suffix and in-between text into the content. */

Source from the content-addressed store, hash-verified

623 * Aggregates the prefix, suffix and in-between text into the content.
624 */
625static void parse_json_tool_calls(
626 common_chat_msg_parser & builder,
627 const std::optional<common_regex> & block_open,
628 const std::optional<common_regex> & function_regex_start_only,
629 const std::optional<common_regex> & function_regex,
630 const common_regex & close_regex,
631 const std::optional<common_regex> & block_close,
632 bool allow_raw_python = false,
633 const std::function<std::string(const common_chat_msg_parser::find_regex_result & fres)> & get_function_name = nullptr) {
634
635 auto parse_tool_calls = [&]() {
636 size_t from = std::string::npos;
637 auto first = true;
638 while (true) {
639 auto res = function_regex_start_only && first
640 ? builder.try_consume_regex(*function_regex_start_only)
641 : function_regex
642 ? builder.try_find_regex(*function_regex, from)
643 : std::nullopt;
644 if (res) {
645 std::string name;
646 if (get_function_name) {
647 name = get_function_name(*res);
648 } else {
649 GGML_ASSERT(res->groups.size() == 2);
650 name = builder.str(res->groups[1]);
651 }
652 first = false;
653 if (name.empty()) {
654 // get_function_name signalled us that we should skip this match and treat it as content.
655 from = res->groups[0].begin + 1;
656 continue;
657 }
658 from = std::string::npos;
659
660 auto maybe_raw_python = name == "python" && allow_raw_python;
661 if (builder.input()[builder.pos()] == '{' || !maybe_raw_python) {
662 if (auto arguments = builder.try_consume_json_with_dumped_args({{}})) {
663 if (!builder.add_tool_call(name, "", arguments->value) || arguments->is_partial) {
664 throw common_chat_msg_partial_exception("incomplete tool call");
665 }
666 builder.consume_regex(close_regex);
667 }
668 continue;
669 }
670 if (maybe_raw_python) {
671 auto arguments = wrap_code_as_arguments(builder, builder.consume_rest());
672 if (!builder.add_tool_call(name, "", arguments)) {
673 throw common_chat_msg_partial_exception("incomplete tool call");
674 }
675 return;
676 }
677 throw common_chat_msg_partial_exception("incomplete tool call");
678 }
679 break;
680 }
681 if (block_close) {
682 builder.consume_regex(*block_close);

Calls 14

wrap_code_as_argumentsFunction · 0.85
try_consume_regexMethod · 0.80
try_find_regexMethod · 0.80
add_tool_callMethod · 0.80
consume_regexMethod · 0.80
consume_restMethod · 0.80
consume_spacesMethod · 0.80
add_contentMethod · 0.80
sizeMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected