Skip to content

Commit f384822

Browse files
ochafikclaude
andcommitted
Sync minja vendor: ReasoningFormat detection and tojson separators
- Rename requires_typed_content → requires_typed_content_blocks - Rename ReasoningFormat enum values for clarity - Add tojson(separators=...) support for Kimi K2 template - Sync from google/minja#89 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent fa874b0 commit f384822

File tree

3 files changed

+389
-103
lines changed

3 files changed

+389
-103
lines changed

common/chat.cpp

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,50 +1021,12 @@ static common_chat_params common_chat_params_init_lfm2(const common_chat_templat
10211021
static common_chat_params common_chat_params_init_ministral_3(const common_chat_template & tmpl, const struct templates_params & inputs) {
10221022
common_chat_params data;
10231023

1024-
// Build up messages to follow the format: https://huggingface.co/mistralai/Ministral-3-14B-Reasoning-2512/blob/main/chat_template.jinja
1025-
auto adjusted_messages = json::array();
1026-
for (const auto & msg : inputs.messages) {
1027-
auto role = msg.value("role", "");
1028-
if (role != "system" && role != "assistant") {
1029-
// Only adjust system and assistant messages. Interestingly, the system message may contain thinking.
1030-
adjusted_messages.push_back(msg);
1031-
continue;
1032-
}
1033-
1034-
auto content = json::array();
1035-
1036-
// If message contains `reasoning_content`, add it as a block of type `thinking`
1037-
if (msg.contains("reasoning_content") && msg.at("reasoning_content").is_string()) {
1038-
content.push_back({
1039-
{"type", "thinking"},
1040-
{"thinking", msg.at("reasoning_content").get<std::string>()},
1041-
});
1042-
}
1043-
1044-
// If message contains `content`, add it as a block of type `text`
1045-
if (msg.contains("content")) {
1046-
if (msg.at("content").is_string()) {
1047-
content.push_back({
1048-
{"type", "text"},
1049-
{"text", msg.at("content").get<std::string>()},
1050-
});
1051-
} else if (msg.at("content").is_array()) {
1052-
auto blocks = msg.at("content");
1053-
content.insert(content.end(), blocks.begin(), blocks.end());
1054-
}
1055-
}
1056-
1057-
auto adjusted = msg;
1058-
adjusted["content"] = content;
1059-
adjusted.erase("reasoning_content");
1060-
adjusted_messages.push_back(adjusted);
1061-
}
1062-
1024+
// Note: minja now handles reasoning_content → content blocks polyfill automatically (CONTENT_BLOCK_THINKING format)
10631025
auto has_tools = inputs.tools.is_array() && !inputs.tools.empty();
10641026
auto extract_reasoning = inputs.reasoning_format != COMMON_REASONING_FORMAT_NONE;
10651027
auto include_grammar = true;
10661028

1067-
data.prompt = apply(tmpl, inputs, /* messages_override = */ adjusted_messages);
1029+
data.prompt = apply(tmpl, inputs);
10681030
data.format = COMMON_CHAT_FORMAT_PEG_NATIVE;
10691031
data.preserved_tokens = {
10701032
"[THINK]",
@@ -1191,20 +1153,8 @@ static common_chat_params common_chat_params_init_magistral(const common_chat_te
11911153
static common_chat_params common_chat_params_init_command_r7b(const common_chat_template & tmpl, const struct templates_params & inputs) {
11921154
common_chat_params data;
11931155

1194-
auto adjusted_messages = json::array();
1195-
for (const auto & msg : inputs.messages) {
1196-
auto has_reasoning_content = msg.contains("reasoning_content") && msg.at("reasoning_content").is_string();
1197-
auto has_tool_calls = msg.contains("tool_calls") && msg.at("tool_calls").is_array();
1198-
if (has_reasoning_content && has_tool_calls) {
1199-
auto adjusted_message = msg;
1200-
adjusted_message["tool_plan"] = msg.at("reasoning_content");
1201-
adjusted_message.erase("reasoning_content");
1202-
adjusted_messages.push_back(adjusted_message);
1203-
} else {
1204-
adjusted_messages.push_back(msg);
1205-
}
1206-
}
1207-
data.prompt = apply(tmpl, inputs, /* messages_override= */ adjusted_messages);
1156+
// Note: minja now handles reasoning_content → tool_plan polyfill automatically
1157+
data.prompt = apply(tmpl, inputs);
12081158
data.format = COMMON_CHAT_FORMAT_COMMAND_R7B;
12091159
if (string_ends_with(data.prompt, "<|START_THINKING|>")) {
12101160
if (!inputs.enable_thinking) {
@@ -1940,22 +1890,8 @@ static common_chat_params common_chat_params_init_xiaomi_mimo(const common_chat_
19401890
static common_chat_params common_chat_params_init_gpt_oss(const common_chat_template & tmpl, const struct templates_params & inputs) {
19411891
common_chat_params data;
19421892

1943-
// Copy reasoning to the "thinking" field as expected by the gpt-oss template
1944-
auto adjusted_messages = json::array();
1945-
for (const auto & msg : inputs.messages) {
1946-
auto has_reasoning_content = msg.contains("reasoning_content") && msg.at("reasoning_content").is_string();
1947-
auto has_tool_calls = msg.contains("tool_calls") && msg.at("tool_calls").is_array();
1948-
1949-
if (has_reasoning_content && has_tool_calls) {
1950-
auto adjusted_message = msg;
1951-
adjusted_message["thinking"] = msg.at("reasoning_content");
1952-
adjusted_messages.push_back(adjusted_message);
1953-
} else {
1954-
adjusted_messages.push_back(msg);
1955-
}
1956-
}
1957-
1958-
auto prompt = apply(tmpl, inputs, /* messages_override= */ adjusted_messages);
1893+
// Note: minja now handles reasoning_content → thinking polyfill automatically
1894+
auto prompt = apply(tmpl, inputs);
19591895

19601896
// Check if we need to replace the return token with end token during
19611897
// inference and without generation prompt. For more details see:
@@ -2598,7 +2534,7 @@ static common_chat_params common_chat_templates_apply_jinja(
25982534
: *tmpls->template_default;
25992535
const auto & src = tmpl.source();
26002536
const auto & caps = tmpl.original_caps();
2601-
params.messages = common_chat_msgs_to_json_oaicompat<json>(inputs.messages, /* concat_text= */ !tmpl.original_caps().requires_typed_content);
2537+
params.messages = common_chat_msgs_to_json_oaicompat<json>(inputs.messages, /* concat_text= */ !tmpl.original_caps().requires_typed_content_blocks);
26022538
params.add_generation_prompt = inputs.add_generation_prompt;
26032539
params.tool_choice = inputs.tool_choice;
26042540
params.reasoning_format = inputs.reasoning_format;

0 commit comments

Comments
 (0)