Skip to content

Commit 0e36761

Browse files
committed
Make a copy of the parse_json_tool_calls function for deepseek-v3.1 so
as to not accidentally introduce regressions.
1 parent bdfa87f commit 0e36761

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

common/chat.cpp

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ static std::string wrap_code_as_arguments(common_chat_msg_parser & builder, cons
670670
* Takes a prefix regex that must have 1 group to capture the function name, a closing suffix, and expects json parameters in between.
671671
* Aggregates the prefix, suffix and in-between text into the content.
672672
*/
673-
static void parse_json_tool_calls(
673+
static void parse_json_tool_calls_deepseek_v3_1(
674674
common_chat_msg_parser & builder,
675675
const std::optional<common_regex> & block_open,
676676
const std::optional<common_regex> & function_regex_start_only,
@@ -753,6 +753,83 @@ static void parse_json_tool_calls(
753753
}
754754
}
755755

756+
/**
757+
* Takes a prefix regex that must have 1 group to capture the function name, a closing suffix, and expects json parameters in between.
758+
* Aggregates the prefix, suffix and in-between text into the content.
759+
*/
760+
static void parse_json_tool_calls(
761+
common_chat_msg_parser & builder,
762+
const std::optional<common_regex> & block_open,
763+
const std::optional<common_regex> & function_regex_start_only,
764+
const std::optional<common_regex> & function_regex,
765+
const common_regex & close_regex,
766+
const std::optional<common_regex> & block_close,
767+
bool allow_raw_python = false,
768+
const std::function<std::string(const common_chat_msg_parser::find_regex_result & fres)> & get_function_name = nullptr) {
769+
770+
auto parse_tool_calls = [&]() {
771+
size_t from = std::string::npos;
772+
auto first = true;
773+
while (true) {
774+
auto res = function_regex_start_only && first
775+
? builder.try_consume_regex(*function_regex_start_only)
776+
: function_regex
777+
? builder.try_find_regex(*function_regex, from)
778+
: std::nullopt;
779+
if (res) {
780+
std::string name;
781+
if (get_function_name) {
782+
name = get_function_name(*res);
783+
} else {
784+
GGML_ASSERT(res->groups.size() == 2);
785+
name = builder.str(res->groups[1]);
786+
}
787+
first = false;
788+
if (name.empty()) {
789+
// get_function_name signalled us that we should skip this match and treat it as content.
790+
from = res->groups[0].begin + 1;
791+
continue;
792+
}
793+
from = std::string::npos;
794+
795+
auto maybe_raw_python = name == "python" && allow_raw_python;
796+
if (builder.input()[builder.pos()] == '{' || !maybe_raw_python) {
797+
if (auto arguments = builder.try_consume_json_with_dumped_args({{}})) {
798+
if (!builder.add_tool_call(name, "", arguments->value) || arguments->is_partial) {
799+
throw common_chat_msg_partial_exception("incomplete tool call");
800+
}
801+
builder.consume_regex(close_regex);
802+
}
803+
continue;
804+
}
805+
if (maybe_raw_python) {
806+
auto arguments = wrap_code_as_arguments(builder, builder.consume_rest());
807+
if (!builder.add_tool_call(name, "", arguments)) {
808+
throw common_chat_msg_partial_exception("incomplete tool call");
809+
}
810+
return;
811+
}
812+
throw common_chat_msg_partial_exception("incomplete tool call");
813+
}
814+
break;
815+
}
816+
if (block_close) {
817+
builder.consume_regex(*block_close);
818+
}
819+
builder.consume_spaces();
820+
builder.add_content(builder.consume_rest());
821+
};
822+
if (block_open) {
823+
if (auto res = builder.try_find_regex(*block_open)) {
824+
parse_tool_calls();
825+
} else {
826+
builder.add_content(builder.consume_rest());
827+
}
828+
} else {
829+
parse_tool_calls();
830+
}
831+
}
832+
756833
static void parse_prefixed_json_tool_call_array(common_chat_msg_parser & builder, const common_regex & prefix, size_t rstrip_prefix = 0) {
757834
static const std::vector<std::vector<std::string>> args_paths = {{"arguments"}};
758835
if (auto res = builder.try_find_regex(prefix)) {
@@ -1420,7 +1497,7 @@ static void common_chat_parse_deepseek_v3_1_content(common_chat_msg_parser & bui
14201497

14211498
LOG_DBG("%s: parse_tool_calls\n", __func__);
14221499

1423-
parse_json_tool_calls(
1500+
parse_json_tool_calls_deepseek_v3_1(
14241501
builder,
14251502
/* block_open= */ tool_calls_begin,
14261503
/* function_regex_start_only= */ std::nullopt,

0 commit comments

Comments
 (0)