Add workaround for templates requiring non-null content

This commit is contained in:
Piotr Wilkin 2026-01-23 20:18:25 +01:00 committed by Piotr Wilkin
parent ada90bf2ba
commit 9a3ac05157
2 changed files with 78 additions and 4 deletions

View File

@ -2960,6 +2960,15 @@ static void system_message_not_supported(json & messages) {
}
}
static void requires_non_null_content(json & messages) {
GGML_ASSERT(messages.is_array());
for (auto & message : messages) {
if (message.contains("tool_calls") && !messages.contains("content")) {
messages["content"] = "";
}
}
}
static void func_args_not_string(json & messages) {
GGML_ASSERT(messages.is_array());
for (auto & message : messages) {
@ -3065,6 +3074,10 @@ static common_chat_params common_chat_templates_apply_jinja(
workaround::system_message_not_supported(params.messages);
}
if (!tmpl.original_caps().requires_non_null_content) {
workaround::requires_non_null_content(params.messages);
}
params.extra_context = json::object();
for (auto el : inputs.chat_template_kwargs) {
params.extra_context[el.first] = json::parse(el.second);

View File

@ -165,7 +165,7 @@ caps caps_get(jinja::program & prog) {
{"content", "Assistant message"},
{"tool_calls", json::array({
{
{"id", "call1"},
{"id", "call0001"},
{"type", "function"},
{"function", {
{"name", "tool1"},
@ -175,10 +175,10 @@ caps caps_get(jinja::program & prog) {
}}
},
{
{"id", "call2"},
{"id", "call0002"},
{"type", "function"},
{"function", {
{"name", "tool2"},
{"name", "tool1"},
{"arguments", {
{"arg", "value"}
}}
@ -199,7 +199,7 @@ caps caps_get(jinja::program & prog) {
{"name", "tool"},
{"type", "function"},
{"function", {
{"name", "tool"},
{"name", "tool1"},
{"description", "Tool description"},
{"parameters", {
{"type", "object"},
@ -243,6 +243,67 @@ caps caps_get(jinja::program & prog) {
}
);
// case: requires non-null content in tool calls
caps_try_execute(
prog,
[&]() {
// messages
return json::array({
{
{"role", "user"},
{"content", "User message"},
},
{
{"role", "assistant"},
{"tool_calls", json::array({
{
{"id", "call0001"},
{"type", "function"},
{"function", {
{"name", "tool1"},
{"arguments", {
{"arg", "value"}
}}
}}
},
})}
},
{
{"role", "user"},
{"content", "User message"},
},
});
},
[&]() {
// tools
return json::array({
{
{"name", "tool"},
{"type", "function"},
{"function", {
{"name", "tool1"},
{"description", "Tool description"},
{"parameters", {
{"type", "object"},
{"properties", {
{"arg", {
{"type", "string"},
{"description", "Arg description"},
}},
}},
{"required", json::array({ "arg" })},
}},
}},
},
});
},
[&](bool success, value & messages, value & tools) {
if (!success) {
result.requires_non_null_content = true;
}
}
);
// case: preserve reasoning content in chat history
caps_try_execute(
prog,