chat_template.jinja
10.7 KB · 262 lines · plaintext Raw
1 [gMASK]<sop>
2 {%- set effective_reasoning_effort = reasoning_effort if reasoning_effort is defined and reasoning_effort in ['low', 'high'] else 'max' -%}
3 {%- if effective_reasoning_effort is not none -%}<|system|>Reasoning Effort: {{ effective_reasoning_effort | capitalize }}{%- endif -%}
4 {%- set clear_thinking = clear_thinking if clear_thinking is defined else false -%}
5 {%- if tools -%}
6 {%- macro tool_to_json(tool) -%}
7 {%- set ns_tool = namespace(first=true) -%}
8 {{ '{' -}}
9 {%- for k, v in tool.items() -%}
10 {%- if k != 'defer_loading' and k != 'strict' -%}
11 {%- if not ns_tool.first -%}{{- ', ' -}}{%- endif -%}
12 {%- set ns_tool.first = false -%}
13 "{{ k }}": {{ v | tojson(ensure_ascii=False) }}
14 {%- endif -%}
15 {%- endfor -%}
16 {{- '}' -}}
17 {%- endmacro -%}
18 {%- macro tool_references_to_response(refs) -%}
19 {{- '<tool_response><tools>\n' -}}
20 {%- for tr in refs -%}
21 {%- for tool in tools -%}
22 {%- if 'function' in tool -%}
23 {%- set tool = tool['function'] -%}
24 {%- endif -%}
25 {%- if tool.name == tr.name -%}
26 {{- tool_to_json(tool) + '\n' -}}
27 {%- endif -%}
28 {%- endfor -%}
29 {%- endfor -%}
30 {{- '</tools></tool_response>' -}}
31 {%- endmacro -%}
32 <|system|>
33 # Tools
34
35 You may call one or more functions to assist with the user query.
36
37 You are provided with function signatures within <tools></tools> XML tags:
38 <tools>
39 {% for tool in tools %}
40 {%- if 'function' in tool -%}
41 {%- set tool = tool['function'] -%}
42 {%- endif -%}
43 {% if tool.defer_loading is not defined or not tool.defer_loading %}
44 {{ tool_to_json(tool) }}
45 {% endif %}
46 {% endfor %}
47 </tools>
48
49 For each function call, output the function name and arguments within the following XML format:
50 <tool_call>{function-name}<arg_key>{arg-key-1}</arg_key><arg_value>{arg-value-1}</arg_value><arg_key>{arg-key-2}</arg_key><arg_value>{arg-value-2}</arg_value>...</tool_call>{%- endif -%}
51 {%- macro emit_image() -%}<|begin_of_image|><|image|><|end_of_image|>{%- endmacro -%}
52 {%- macro emit_video() -%}<|begin_of_video|><|video|><|end_of_video|>{%- endmacro -%}
53 {%- macro emit_audio() -%}<|begin_of_audio|><|end_of_audio|>{%- endmacro -%}
54 {%- macro visible_text(content) -%}
55 {%- if content is string -%}
56 {{- content -}}
57 {%- elif content is iterable and content is not mapping -%}
58 {%- for item in content -%}
59 {%- if item is mapping and item.type == 'text' -%}
60 {{- item.text -}}
61 {%- elif item is string -%}
62 {{- item -}}
63 {%- elif item is mapping and item.type in ['image', 'image_url'] -%}
64 {{- emit_image() -}}
65 {%- elif item is mapping and item.type in ['video', 'video_url'] -%}
66 {{- emit_video() -}}
67 {%- elif item is mapping and item.type in ['audio', 'audio_url', 'input_audio'] -%}
68 {{- emit_audio() -}}
69 {%- endif -%}
70 {%- endfor -%}
71 {%- elif content is not none -%}
72 {{- content -}}
73 {%- endif -%}
74 {%- endmacro -%}
75 {%- macro tool_response(text) -%}
76 {{- '<tool_response>' + text + '</tool_response>' -}}
77 {%- endmacro -%}
78 {%- macro render_tool_response(m) -%}
79 {%- if m.content is string -%}
80 {{- tool_response(m.content) -}}
81 {%- elif m.content and m.content is not mapping and m.content.0.type == "tool_reference" -%}
82 {{- tool_references_to_response(m.content) -}}
83 {%- elif is_list_of_outputs(m) -%}
84 {%- for tr in m.content -%}
85 {%- if tr.output is iterable and tr.output is not string and tr.output is not mapping and tr.output and tr.output.0.type == "tool_reference" -%}
86 {{- tool_references_to_response(tr.output) -}}
87 {%- else -%}
88 {{- tool_response(visible_text(tr.output)) -}}
89 {%- endif -%}
90 {%- endfor -%}
91 {%- else -%}
92 {{- tool_response(visible_text(m.content)) -}}
93 {%- endif -%}
94 {%- endmacro -%}
95 {%- macro id_of(obj) -%}
96 {%- if obj.tool_call_id -%}
97 {{- obj.tool_call_id -}}
98 {%- elif obj.id -%}
99 {{- obj.id -}}
100 {%- endif -%}
101 {%- endmacro -%}
102 {%- macro is_list_of_outputs(m) -%}
103 {%- if m.content and m.content.0.output is defined -%}1{%- endif -%}
104 {%- endmacro -%}
105 {%- macro has_dup_tool_result_id(lo, hi, target) -%}
106 {%- set ns_cnt = namespace(n=0) -%}
107 {%- for k in range(lo, hi + 1) -%}
108 {%- set m = messages[k] -%}
109 {%- if is_list_of_outputs(m) -%}
110 {%- for entry in m.content -%}
111 {%- if id_of(entry) == target -%}
112 {%- set ns_cnt.n = ns_cnt.n + 1 -%}
113 {%- endif -%}
114 {%- endfor -%}
115 {%- elif id_of(m) == target -%}
116 {%- set ns_cnt.n = ns_cnt.n + 1 -%}
117 {%- endif -%}
118 {%- if ns_cnt.n > 1 -%}{%- break -%}{%- endif -%}
119 {%- endfor -%}
120 {%- if ns_cnt.n > 1 -%}1{%- endif -%}
121 {%- endmacro -%}
122 {%- macro tc_id_exists(tcs, target) -%}
123 {%- set ns_f = namespace(found=false) -%}
124 {%- for tc in tcs -%}
125 {%- if id_of(tc) == target -%}
126 {%- set ns_f.found = true -%}
127 {%- break -%}
128 {%- endif -%}
129 {%- endfor -%}
130 {%- if ns_f.found -%}1{%- endif -%}
131 {%- endmacro -%}
132 {%- set ns = namespace(last_user_index=-1) -%}
133 {%- for m in messages %}
134 {%- if m.role == 'user' %}
135 {%- set ns.last_user_index = loop.index0 -%}
136 {%- endif %}
137 {%- endfor %}
138 {%- for m in messages -%}
139 {%- if m.role == 'user' -%}<|user|>{{ visible_text(m.content) }}
140 {%- elif m.role == 'assistant' -%}
141 <|assistant|>
142 {%- set content = visible_text(m.content) %}
143 {%- if m.reasoning_content is string %}
144 {%- set reasoning_content = m.reasoning_content %}
145 {%- elif '</think>' in content %}
146 {%- set reasoning_content = content.split('</think>')[0].split('<think>')[-1] %}
147 {%- set content = content.split('</think>')[-1] %}
148 {%- endif %}
149 {%- if (not clear_thinking or loop.index0 > ns.last_user_index) and reasoning_content is defined -%}
150 {{ '<think>' + reasoning_content + '</think>'}}
151 {%- else -%}
152 {{ '<think></think>' }}
153 {%- endif -%}
154 {%- if content.strip() -%}
155 {{ content.strip() }}
156 {%- endif -%}
157 {% if m.tool_calls %}
158 {% for tc in m.tool_calls %}
159 {%- if tc.function %}
160 {%- set tc = tc.function %}
161 {%- endif %}
162 {{- '<tool_call>' ~ tc.name -}}
163 {% set _args = tc.arguments %}{% for k, v in _args.items() %}<arg_key>{{ k }}</arg_key><arg_value>{{ v | tojson(ensure_ascii=False) if v is not string else v }}</arg_value>{% endfor %}</tool_call>{% endfor %}
164 {% endif %}
165 {%- elif m.role == 'tool' -%}
166 {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
167 {{- '<|observation|>' -}}
168 {%- set block_start = loop.index0 -%}
169 {%- set ns_blk = namespace(end=block_start) -%}
170 {%- for j in range(block_start, messages|length) -%}
171 {%- if messages[j].role == 'tool' -%}
172 {%- set ns_blk.end = j -%}
173 {%- else -%}
174 {%- break -%}
175 {%- endif -%}
176 {%- endfor -%}
177 {%- set ns_a = namespace(tool_calls=none) -%}
178 {%- if block_start > 0 and messages[block_start - 1].role == 'assistant' and messages[block_start - 1].tool_calls -%}
179 {%- set ns_a.tool_calls = messages[block_start - 1].tool_calls -%}
180 {%- endif -%}
181 {%- set ns_chk = namespace(can_sort=true) -%}
182 {%- if not ns_a.tool_calls -%}
183 {%- set ns_chk.can_sort = false -%}
184 {%- else -%}
185 {%- for k in range(block_start, ns_blk.end + 1) -%}
186 {%- if not ns_chk.can_sort -%}{%- break -%}{%- endif -%}
187 {%- set m = messages[k] -%}
188 {%- if is_list_of_outputs(m) -%}
189 {%- for entry in m.content -%}
190 {%- if not ns_chk.can_sort -%}{%- break -%}{%- endif -%}
191 {%- set eid = id_of(entry) -%}
192 {%- if not eid -%}
193 {%- set ns_chk.can_sort = false -%}
194 {%- elif has_dup_tool_result_id(block_start, ns_blk.end, eid) -%}
195 {%- set ns_chk.can_sort = false -%}
196 {%- elif not tc_id_exists(ns_a.tool_calls, eid) -%}
197 {%- set ns_chk.can_sort = false -%}
198 {%- endif -%}
199 {%- endfor -%}
200 {%- else -%}
201 {%- set tk_id = id_of(m) -%}
202 {%- if not tk_id -%}
203 {%- set ns_chk.can_sort = false -%}
204 {%- elif has_dup_tool_result_id(block_start, ns_blk.end, tk_id) -%}
205 {%- set ns_chk.can_sort = false -%}
206 {%- elif not tc_id_exists(ns_a.tool_calls, tk_id) -%}
207 {%- set ns_chk.can_sort = false -%}
208 {%- endif -%}
209 {%- endif -%}
210 {%- endfor -%}
211 {%- for i in range(ns_a.tool_calls | length) -%}
212 {%- if not ns_chk.can_sort -%}{%- break -%}{%- endif -%}
213 {%- set tc_id = id_of(ns_a.tool_calls[i]) -%}
214 {%- if not tc_id -%}
215 {%- set ns_chk.can_sort = false -%}
216 {%- endif -%}
217 {%- for j in range(i + 1, ns_a.tool_calls | length) -%}
218 {%- if id_of(ns_a.tool_calls[j]) == tc_id -%}
219 {%- set ns_chk.can_sort = false -%}
220 {%- break -%}
221 {%- endif -%}
222 {%- endfor -%}
223 {%- endfor -%}
224 {%- endif -%}
225 {%- if ns_chk.can_sort -%}
226 {%- for tc in ns_a.tool_calls -%}
227 {%- set tc_id = id_of(tc) -%}
228 {%- for k in range(block_start, ns_blk.end + 1) -%}
229 {%- set m = messages[k] -%}
230 {%- if is_list_of_outputs(m) -%}
231 {%- for entry in m.content -%}
232 {%- set eid = id_of(entry) -%}
233 {%- if eid == tc_id -%}
234 {%- if entry.output is iterable and entry.output is not string and entry.output is not mapping and entry.output and entry.output.0.type == "tool_reference" -%}
235 {{- tool_references_to_response(entry.output) -}}
236 {%- else -%}
237 {{- tool_response(visible_text(entry.output)) -}}
238 {%- endif -%}
239 {%- endif -%}
240 {%- endfor -%}
241 {%- else -%}
242 {%- set tk_id = id_of(m) -%}
243 {%- if tk_id == tc_id -%}
244 {{- render_tool_response(m) -}}
245 {%- endif -%}
246 {%- endif -%}
247 {%- endfor -%}
248 {%- endfor -%}
249 {%- else -%}
250 {%- for k in range(block_start, ns_blk.end + 1) -%}
251 {{- render_tool_response(messages[k]) -}}
252 {%- endfor -%}
253 {%- endif -%}
254 {% endif -%}
255 {%- elif m.role == 'system' -%}
256 <|system|>{{ visible_text(m.content) }}
257 {%- endif -%}
258 {%- endfor -%}
259 {%- if add_generation_prompt -%}
260 <|assistant|>{{- '<think>' -}}
261 {%- endif -%}
262