Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e816ea8
Add files via upload
hksdpc255 Nov 2, 2025
5a2ac74
fix unit test
hksdpc255 Nov 2, 2025
22fc731
fix crashes for --reasoning-format=none
hksdpc255 Nov 2, 2025
af5216e
Patch buggy official MiniMax-M2 chat template
hksdpc255 Nov 3, 2025
a21f05a
add upstream minja fix: https://github.com/ochafik/minja/pull/7
hksdpc255 Nov 3, 2025
836ab26
Fix <think> token not generated
hksdpc255 Nov 3, 2025
87c1ed9
add test copied from https://github.com/ggml-org/llama.cpp/pull/16946
hksdpc255 Nov 3, 2025
e77f013
Merge branch 'master' into xml_toolcall
hksdpc255 Nov 3, 2025
d83c976
cleanup
hksdpc255 Nov 3, 2025
f27a06f
Hopes to fix the compilation error on CI
hksdpc255 Nov 3, 2025
c0f2f52
Delete chat template patching since it’s fixed by upstream Minja
hksdpc255 Nov 3, 2025
d483cfd
Remove undeeded Minimax-M2 template patch
hksdpc255 Nov 3, 2025
522f84e
Add proper handling of optional parameters with test
hksdpc255 Nov 5, 2025
74bd9b0
Fix making all tool parameters optional
hksdpc255 Nov 5, 2025
bd6f27c
Merge branch 'ggml-org:master' into xml_toolcall
hksdpc255 Nov 6, 2025
83181f2
Move xml tool parser to separate file
hksdpc255 Nov 6, 2025
e5529dd
cleanup & add tests for GLM4.5
hksdpc255 Nov 7, 2025
29ef8f0
add streaming tests & enhancement & cleanups
hksdpc255 Nov 9, 2025
82345e9
Merge branch 'ggml-org:master' into xml_toolcall
hksdpc255 Nov 9, 2025
3682ab7
cleanup & add support for Kimi-K2 Qwen3-Coder Apriel-1.5 Xiaomi-MiMo
hksdpc255 Nov 13, 2025
aa66837
apply suggestions from reviewers
hksdpc255 Nov 13, 2025
374c061
fix a misuse for data.grammar_lazy
hksdpc255 Nov 13, 2025
7273f76
fix grammar when tool have no argument
hksdpc255 Nov 14, 2025
534ee13
Fix `no triggers set for lazy grammar!` for GLM4.5/4.6. Insert additi…
hksdpc255 Nov 14, 2025
d220670
update chat.cpp
hksdpc255 Nov 14, 2025
9c706f2
fix grammar for GLM 4.5/4.6
hksdpc255 Nov 15, 2025
cda4498
Merge branch 'ggml-org:master' into xml_toolcall
hksdpc255 Nov 15, 2025
ea4f0ac
Try fix Jinja template for GLM
hksdpc255 Nov 15, 2025
b93a015
Try fix GLM-4.6.jinja
hksdpc255 Nov 15, 2025
a036626
Update common/chat-parser-xml-toolcall.cpp
hksdpc255 Nov 16, 2025
75c7e62
Update tests/test-chat.cpp
hksdpc255 Nov 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ add_library(${TARGET} STATIC
base64.hpp
chat-parser.cpp
chat-parser.h
chat-parser-xml-toolcall.h
chat-parser-xml-toolcall.cpp
chat.cpp
chat.h
common.cpp
Expand Down
864 changes: 864 additions & 0 deletions common/chat-parser-xml-toolcall.cpp

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions common/chat-parser-xml-toolcall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "chat.h"

#include <nlohmann/json.hpp>

#include <optional>
#include <string>
#include <vector>


// Sample config:
// MiniMax-M2 (left): <minimax:tool_call>\n<invoke name="tool-name">\n<parameter name="key">value</parameter>\n...</invoke>\n...</minimax:tool_call>
// GLM 4.5 (right): <tool_call>function_name\n<arg_key>key</arg_key>\n<arg_value>value</arg_value>\n</tool_call>
struct xml_tool_call_format {
std::string scope_start; // <minimax:tool_call>\n // \n // can be empty
std::string tool_start; // <invoke name=\" // <tool_call>
std::string tool_sep; // \">\n // \n // can be empty only for parse_xml_tool_calls
std::string key_start; // <parameter name=\" // <arg_key>
std::string key_val_sep; // \"> // </arg_key>\n<arg_value>
std::string val_end; // </parameter>\n // </arg_value>\n
std::string tool_end; // </invoke>\n // </tool_call>\n
std::string scope_end; // </minimax:tool_call> // // can be empty
// Set this if there can be dynamic spaces inside key_val_sep.
// e.g. key_val_sep=</arg_key> key_val_sep2=<arg_value> for GLM4.5
std::optional<std::string> key_val_sep2 = std::nullopt;
// Set true if argval should only be raw string. e.g. Hello "world" hi
// Set false if argval should only be json string. e.g. "Hello \"world\" hi"
// Defaults to std::nullopt, both will be allowed.
std::optional<bool> raw_argval = std::nullopt;
std::optional<std::string> last_val_end = std::nullopt;
std::optional<std::string> last_tool_end = std::nullopt;
bool trim_raw_argval = false;
bool allow_toolcall_in_think = false; // TODO: UNTESTED!!!
};

// make a GBNF that accept any strings except those containing any of the forbidden strings.
std::string make_gbnf_excluding(std::vector<std::string> forbids);

/**
* Build grammar for xml-style tool call
* form.scope_start and form.scope_end can be empty.
* Requires data.format for model-specific hacks.
*/
void build_grammar_xml_tool_call(common_chat_params & data, const nlohmann::ordered_json & tools, const struct xml_tool_call_format & form);
10 changes: 10 additions & 0 deletions common/chat-parser.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "chat.h"
#include "chat-parser-xml-toolcall.h"
#include "json-partial.h"
#include "regex-partial.h"

Expand Down Expand Up @@ -119,5 +120,14 @@ class common_chat_msg_parser {
const std::vector<std::vector<std::string>> & content_paths = {}
);

/**
* Parse XML-Style tool call for given xml_tool_call_format. Return false for invalid syntax and get the position untouched.
* form.scope_start, form.tool_sep and form.scope_end can be empty.
*/
bool try_consume_xml_tool_calls(const struct xml_tool_call_format & form);

// Parse content uses reasoning and XML-Style tool call
void consume_reasoning_with_xml_tool_calls(const struct xml_tool_call_format & form, const std::string & start_think = "<think>", const std::string & end_think = "</think>");

void clear_tools();
};
Loading
Loading