llama_cpp_bindings/tool_call_template_overrides/
detect.rs1use llama_cpp_bindings_types::ToolCallMarkers;
2
3use crate::tool_call_template_overrides::gemma4_call_block::Gemma4CallBlockOverride;
4use crate::tool_call_template_overrides::glm47_key_value_tags::Glm47KeyValueTagsOverride;
5use crate::tool_call_template_overrides::mistral3_arrow_args::Mistral3ArrowArgsOverride;
6use crate::tool_call_template_overrides::qwen_xml_tags::QwenXmlTagsOverride;
7use crate::tool_call_template_overrides::qwen3_json_inside_tool_call::Qwen3JsonInsideToolCallOverride;
8
9#[must_use]
10pub fn detect(template: &str) -> Option<ToolCallMarkers> {
11 let detectors: [fn(&str) -> Option<ToolCallMarkers>; 5] = [
12 Gemma4CallBlockOverride::detect,
13 Glm47KeyValueTagsOverride::detect,
14 Mistral3ArrowArgsOverride::detect,
15 Qwen3JsonInsideToolCallOverride::detect,
16 QwenXmlTagsOverride::detect,
17 ];
18 detectors
19 .into_iter()
20 .find_map(|detector| detector(template))
21}
22
23#[cfg(test)]
24mod tests {
25 use super::Gemma4CallBlockOverride;
26 use super::Mistral3ArrowArgsOverride;
27 use super::QwenXmlTagsOverride;
28 use super::detect;
29
30 #[test]
31 fn dispatches_to_gemma4_override() {
32 let template = "{{- '<|tool_call>call:' + function['name'] + '{' -}}";
33 let markers = detect(template).expect("must dispatch to Gemma 4");
34
35 assert_eq!(markers, Gemma4CallBlockOverride::markers());
36 }
37
38 #[test]
39 fn dispatches_to_mistral3_override() {
40 let template = "{{- name + '[ARGS]' + arguments }}";
41 let markers = detect(template).expect("must dispatch to Mistral 3");
42
43 assert_eq!(markers, Mistral3ArrowArgsOverride::markers());
44 }
45
46 #[test]
47 fn dispatches_to_qwen_xml_tags_override() {
48 let template = "{{- '<tool_call>\\n<function=' + tool_call.name + '>\\n' }}";
49 let markers = detect(template).expect("must dispatch to Qwen XML tags");
50
51 assert_eq!(markers, QwenXmlTagsOverride::markers());
52 }
53
54 #[test]
55 fn returns_none_when_no_override_matches() {
56 assert!(detect("plain unrelated template").is_none());
57 }
58}