Atomic-Germ commited on
Commit
fe8cecf
·
verified ·
1 Parent(s): 1e6426d

update for better parallel tool calling

Browse files
Files changed (1) hide show
  1. chat_template.jinja +367 -90
chat_template.jinja CHANGED
@@ -1,36 +1,126 @@
 
 
1
  {%- set image_count = namespace(value=0) %}
2
  {%- set video_count = namespace(value=0) %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  {%- macro render_content(content, do_vision_count, is_system_content=false) %}
4
  {%- if content is string %}
5
  {{- content }}
6
  {%- elif content is iterable and content is not mapping %}
7
  {%- for item in content %}
8
- {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
9
- {%- if is_system_content %}
10
- {{- raise_exception('System message cannot contain images.') }}
11
- {%- endif %}
12
- {%- if do_vision_count %}
13
- {%- set image_count.value = image_count.value + 1 %}
14
- {%- endif %}
15
- {%- if add_vision_id %}
16
- {{- 'Picture ' ~ image_count.value ~ ': ' }}
17
- {%- endif %}
18
- {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
19
- {%- elif 'video' in item or item.type == 'video' %}
20
- {%- if is_system_content %}
21
- {{- raise_exception('System message cannot contain videos.') }}
22
- {%- endif %}
23
- {%- if do_vision_count %}
24
- {%- set video_count.value = video_count.value + 1 %}
25
- {%- endif %}
26
- {%- if add_vision_id %}
27
- {{- 'Video ' ~ video_count.value ~ ': ' }}
 
 
 
 
 
 
 
28
  {%- endif %}
29
- {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
30
- {%- elif 'text' in item %}
31
- {{- item.text }}
32
  {%- else %}
33
- {{- raise_exception('Unexpected item type in content.') }}
34
  {%- endif %}
35
  {%- endfor %}
36
  {%- elif content is none or content is undefined %}
@@ -42,113 +132,300 @@
42
  {%- if not messages %}
43
  {{- raise_exception('No messages provided.') }}
44
  {%- endif %}
45
- {%- if tools and tools is iterable and tools is not mapping %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  {{- '<|im_start|>system\n' }}
47
- {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
 
 
 
48
  {%- for tool in tools %}
49
- {{- "\n" }}
50
  {{- tool | tojson }}
51
  {%- endfor %}
52
- {{- "\n</tools>" }}
53
- {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
54
- {%- if messages[0].role == 'system' %}
55
- {%- set content = render_content(messages[0].content, false, true)|trim %}
56
- {%- if content %}
57
- {{- '\n\n' + content }}
58
- {%- endif %}
 
59
  {%- endif %}
60
  {{- '<|im_end|>\n' }}
61
  {%- else %}
62
- {%- if messages[0].role == 'system' %}
63
- {%- set content = render_content(messages[0].content, false, true)|trim %}
64
- {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
 
65
  {%- endif %}
66
  {%- endif %}
67
- {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
68
- {%- for message in messages[::-1] %}
69
- {%- set index = (messages|length - 1) - loop.index0 %}
70
- {%- if ns.multi_step_tool and message.role == "user" %}
71
- {%- set content = render_content(message.content, false)|trim %}
72
- {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
 
73
  {%- set ns.multi_step_tool = false %}
74
  {%- set ns.last_query_index = index %}
75
  {%- endif %}
76
  {%- endif %}
77
  {%- endfor %}
78
  {%- if ns.multi_step_tool %}
79
- {{- raise_exception('No user query found in messages.') }}
 
 
 
 
80
  {%- endif %}
81
- {%- for message in messages %}
82
- {%- set content = render_content(message.content, true)|trim %}
83
- {%- if message.role == "system" %}
84
- {%- if not loop.first %}
85
- {{- raise_exception('System message must be at the beginning.') }}
86
- {%- endif %}
87
- {%- elif message.role == "user" %}
88
- {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
89
- {%- elif message.role == "assistant" %}
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  {%- set reasoning_content = '' %}
91
- {%- if message.reasoning_content is string %}
92
- {%- set reasoning_content = message.reasoning_content %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  {%- else %}
94
- {%- if '</think>' in content %}
95
- {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
96
- {%- set content = content.split('</think>')[-1].lstrip('\n') %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  {%- endif %}
98
  {%- endif %}
99
- {%- set reasoning_content = reasoning_content|trim %}
100
- {%- if loop.index0 > ns.last_query_index %}
101
- {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
102
  {%- else %}
103
- {{- '<|im_start|>' + message.role + '\n' + content }}
104
  {%- endif %}
105
- {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
106
  {%- for tool_call in message.tool_calls %}
107
- {%- if tool_call.function is defined %}
108
- {%- set tool_call = tool_call.function %}
 
 
109
  {%- endif %}
110
- {%- if loop.first %}
111
- {%- if content|trim %}
112
- {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
 
 
 
113
  {%- else %}
114
- {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
 
 
 
 
 
 
 
 
 
 
 
 
115
  {%- endif %}
 
116
  {%- else %}
117
- {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
118
- {%- endif %}
119
- {%- if tool_call.arguments is defined %}
120
- {%- for args_name, args_value in tool_call.arguments|items %}
121
- {{- '<parameter=' + args_name + '>\n' }}
122
- {%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
123
- {{- args_value }}
124
- {{- '\n</parameter>\n' }}
125
- {%- endfor %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  {%- endif %}
127
- {{- '</function>\n</tool_call>' }}
128
  {%- endfor %}
129
  {%- endif %}
130
  {{- '<|im_end|>\n' }}
131
- {%- elif message.role == "tool" %}
132
- {%- if loop.previtem and loop.previtem.role != "tool" %}
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  {{- '<|im_start|>user' }}
134
  {%- endif %}
135
- {{- '\n<tool_response>\n' }}
136
- {{- content }}
 
 
 
 
 
 
 
137
  {{- '\n</tool_response>' }}
138
- {%- if not loop.last and loop.nextitem.role != "tool" %}
139
- {{- '<|im_end|>\n' }}
140
- {%- elif loop.last %}
141
  {{- '<|im_end|>\n' }}
 
 
 
 
 
142
  {%- endif %}
143
  {%- else %}
144
- {{- raise_exception('Unexpected message role.') }}
145
  {%- endif %}
 
146
  {%- endfor %}
147
  {%- if add_generation_prompt %}
148
  {{- '<|im_start|>assistant\n' }}
149
- {%- if enable_thinking is defined and enable_thinking is true %}
150
- {{- '<think>\n' }}
151
- {%- else %}
152
  {{- '<think>\n\n</think>\n\n' }}
 
 
153
  {%- endif %}
154
  {%- endif %}
 
1
+ {%- set template_version = "OpenFlowLM-froggeric-v22.4-1" %}
2
+ {%- set _tool_format = tool_call_format if tool_call_format is defined else 'xml' %}
3
  {%- set image_count = namespace(value=0) %}
4
  {%- set video_count = namespace(value=0) %}
5
+ {%- set add_vision_id = add_vision_id if add_vision_id is defined else false %}
6
+ {%- set enable_thinking = enable_thinking if enable_thinking is defined else true %}
7
+ {%- set auto_disable_thinking_with_tools = auto_disable_thinking_with_tools if auto_disable_thinking_with_tools is defined else false %}
8
+ {%- if preserve_reasoning is defined and preserve_reasoning is not none %}
9
+ {%- set _preserve_thinking = preserve_reasoning %}
10
+ {%- elif preserve_thinking is defined and preserve_thinking is not none %}
11
+ {%- set _preserve_thinking = preserve_thinking %}
12
+ {%- else %}
13
+ {%- set _preserve_thinking = true %}
14
+ {%- endif %}
15
+ {%- set max_tool_arg_chars = max_tool_arg_chars if max_tool_arg_chars is defined else 0 %}
16
+ {%- set max_tool_response_chars = max_tool_response_chars if max_tool_response_chars is defined else 0 %}
17
+ {%- set _default_reasoning_effort = 'medium' %}
18
+ {%- set _has_tools = (tools is defined and tools and tools is iterable and tools is not mapping) %}
19
+ {%- set _effort_raw = (reasoning_effort | string | lower) if reasoning_effort is defined and reasoning_effort is not none else _default_reasoning_effort %}
20
+ {%- set _initial_thinking = enable_thinking %}
21
+ {%- if _effort_raw in ('none', 'off') %}
22
+ {%- set _initial_thinking = false %}
23
+ {%- set _initial_effort = 'medium' %}
24
+ {%- elif _effort_raw in ('minimal', 'low') %}
25
+ {%- set _initial_effort = 'low' %}
26
+ {%- elif _effort_raw in ('high', 'xhigh', 'max', 'ultracode', 'extreme') %}
27
+ {%- set _initial_effort = 'xhigh' %}
28
+ {%- else %}
29
+ {%- set _initial_effort = 'medium' %}
30
+ {%- endif %}
31
+ {%- set ns_state = namespace(thinking=_initial_thinking, effort=_initial_effort) %}
32
+ {%- if auto_disable_thinking_with_tools and _has_tools %}
33
+ {%- set ns_state.thinking = false %}
34
+ {%- endif %}
35
+ {%- for msg in messages %}
36
+ {%- if msg.role == 'system' or msg.role == 'developer' or msg.role == 'user' %}
37
+ {%- if msg.content is string %}
38
+ {%- if '<|think_off|>' in msg.content %}
39
+ {%- set ns_state.thinking = false %}
40
+ {%- elif '<|think_on|>' in msg.content %}
41
+ {%- set ns_state.thinking = true %}
42
+ {%- elif '<|think_xhigh|>' in msg.content or '<|think_high|>' in msg.content or '<|think_ultracode|>' in msg.content or '<|think_extreme|>' in msg.content or '<|think_max|>' in msg.content %}
43
+ {%- set ns_state.thinking = true %}
44
+ {%- set ns_state.effort = 'xhigh' %}
45
+ {%- elif '<|think_low|>' in msg.content or '<|think_minimal|>' in msg.content %}
46
+ {%- set ns_state.thinking = true %}
47
+ {%- set ns_state.effort = 'low' %}
48
+ {%- elif '<|think_medium|>' in msg.content %}
49
+ {%- set ns_state.thinking = true %}
50
+ {%- set ns_state.effort = 'medium' %}
51
+ {%- endif %}
52
+ {%- elif msg.content is iterable and msg.content is not mapping %}
53
+ {%- for item in msg.content %}
54
+ {%- if item is string %}
55
+ {%- set _item_text = item %}
56
+ {%- elif item is mapping and 'text' in item and item.text is string %}
57
+ {%- set _item_text = item.text %}
58
+ {%- else %}
59
+ {%- set _item_text = '' %}
60
+ {%- endif %}
61
+ {%- if _item_text %}
62
+ {%- if '<|think_off|>' in _item_text %}
63
+ {%- set ns_state.thinking = false %}
64
+ {%- elif '<|think_on|>' in _item_text %}
65
+ {%- set ns_state.thinking = true %}
66
+ {%- elif '<|think_xhigh|>' in _item_text or '<|think_high|>' in _item_text or '<|think_ultracode|>' in _item_text or '<|think_extreme|>' in _item_text or '<|think_max|>' in _item_text %}
67
+ {%- set ns_state.thinking = true %}
68
+ {%- set ns_state.effort = 'xhigh' %}
69
+ {%- elif '<|think_low|>' in _item_text or '<|think_minimal|>' in _item_text %}
70
+ {%- set ns_state.thinking = true %}
71
+ {%- set ns_state.effort = 'low' %}
72
+ {%- elif '<|think_medium|>' in _item_text %}
73
+ {%- set ns_state.thinking = true %}
74
+ {%- set ns_state.effort = 'medium' %}
75
+ {%- endif %}
76
+ {%- endif %}
77
+ {%- endfor %}
78
+ {%- endif %}
79
+ {%- endif %}
80
+ {%- endfor %}
81
+ {%- set reasoning_instructions = '' %}
82
+ {%- if ns_state.thinking %}
83
+ {%- if ns_state.effort == 'xhigh' %}
84
+ {%- set reasoning_instructions = 'Reasoning effort is set to xhigh. Please think carefully through the task, validate key assumptions, consider plausible alternatives, and prioritize correctness, consistency, and clarity in the final answer.' %}
85
+ {%- elif ns_state.effort == 'low' %}
86
+ {%- set reasoning_instructions = 'Reasoning effort is set to low. Keep your thinking brief and focused, moving directly to the conclusion without unnecessary elaboration.' %}
87
+ {%- endif %}
88
+ {%- endif %}
89
  {%- macro render_content(content, do_vision_count, is_system_content=false) %}
90
  {%- if content is string %}
91
  {{- content }}
92
  {%- elif content is iterable and content is not mapping %}
93
  {%- for item in content %}
94
+ {%- if item is mapping %}
95
+ {%- if item.type == 'image' or 'image' in item or 'image_url' in item %}
96
+ {%- if is_system_content %}
97
+ {{- raise_exception('System message cannot contain images.') }}
98
+ {%- endif %}
99
+ {%- if do_vision_count %}
100
+ {%- set image_count.value = image_count.value + 1 %}
101
+ {%- endif %}
102
+ {%- if add_vision_id %}
103
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
104
+ {%- endif %}
105
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
106
+ {%- elif item.type == 'video' or 'video' in item %}
107
+ {%- if is_system_content %}
108
+ {{- raise_exception('System message cannot contain videos.') }}
109
+ {%- endif %}
110
+ {%- if do_vision_count %}
111
+ {%- set video_count.value = video_count.value + 1 %}
112
+ {%- endif %}
113
+ {%- if add_vision_id %}
114
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
115
+ {%- endif %}
116
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
117
+ {%- elif 'text' in item %}
118
+ {{- item.text }}
119
+ {%- else %}
120
+ {{- raise_exception('Unexpected item type in content.') }}
121
  {%- endif %}
 
 
 
122
  {%- else %}
123
+ {{- item | string }}
124
  {%- endif %}
125
  {%- endfor %}
126
  {%- elif content is none or content is undefined %}
 
132
  {%- if not messages %}
133
  {{- raise_exception('No messages provided.') }}
134
  {%- endif %}
135
+ {%- set head = namespace(count=0, seen_non_system=false) %}
136
+ {%- for message in messages %}
137
+ {%- set _is_sys = (message.role == 'system' or message.role == 'developer') %}
138
+ {%- if _is_sys and not head.seen_non_system %}
139
+ {%- set head.count = head.count + 1 %}
140
+ {%- else %}
141
+ {%- set head.seen_non_system = true %}
142
+ {%- endif %}
143
+ {%- endfor %}
144
+ {%- set sys_state = namespace(content='') %}
145
+ {%- for message in messages[:head.count] %}
146
+ {%- set _part = render_content(message.content, false, true) | trim %}
147
+ {%- if '<|think_off|>' in _part %}{%- set _part = _part.split('<|think_off|>') | join('') | trim %}{%- endif %}
148
+ {%- if '<|think_on|>' in _part %}{%- set _part = _part.split('<|think_on|>') | join('') | trim %}{%- endif %}
149
+ {%- if '<|think_xhigh|>' in _part %}{%- set _part = _part.split('<|think_xhigh|>') | join('') | trim %}{%- endif %}
150
+ {%- if '<|think_high|>' in _part %}{%- set _part = _part.split('<|think_high|>') | join('') | trim %}{%- endif %}
151
+ {%- if '<|think_ultracode|>' in _part %}{%- set _part = _part.split('<|think_ultracode|>') | join('') | trim %}{%- endif %}
152
+ {%- if '<|think_extreme|>' in _part %}{%- set _part = _part.split('<|think_extreme|>') | join('') | trim %}{%- endif %}
153
+ {%- if '<|think_max|>' in _part %}{%- set _part = _part.split('<|think_max|>') | join('') | trim %}{%- endif %}
154
+ {%- if '<|think_medium|>' in _part %}{%- set _part = _part.split('<|think_medium|>') | join('') | trim %}{%- endif %}
155
+ {%- if '<|think_low|>' in _part %}{%- set _part = _part.split('<|think_low|>') | join('') | trim %}{%- endif %}
156
+ {%- if '<|think_minimal|>' in _part %}{%- set _part = _part.split('<|think_minimal|>') | join('') | trim %}{%- endif %}
157
+ {%- if _part %}
158
+ {%- if sys_state.content %}
159
+ {%- set sys_state.content = sys_state.content ~ '\n\n' ~ _part %}
160
+ {%- else %}
161
+ {%- set sys_state.content = _part %}
162
+ {%- endif %}
163
+ {%- endif %}
164
+ {%- endfor %}
165
+ {%- set _sc = sys_state.content %}
166
+ {%- set _msgs = messages[head.count:] %}
167
+ {%- if _has_tools %}
168
  {{- '<|im_start|>system\n' }}
169
+ {%- if reasoning_instructions %}
170
+ {{- reasoning_instructions + '\n\n' }}
171
+ {%- endif %}
172
+ {{- '# Tools\n\nYou have access to the following functions:\n\n<tools>' }}
173
  {%- for tool in tools %}
174
+ {{- '\n' }}
175
  {{- tool | tojson }}
176
  {%- endfor %}
177
+ {{- '\n</tools>' }}
178
+ {%- if _tool_format == 'json' %}
179
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<think>\nBrief explanation of tool call\n</think>\n<tool_call>\n{"name": "example_function_name", "arguments": {"example_parameter_1": "value_1", "example_parameter_2": "This is the value for the second parameter"}}\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- You can use the <think></think> block to plan your next tool call OR to synthesize data and formulate your final response to the user.\n- ALL explanation and reasoning MUST be placed strictly inside the <think></think> block.\n- Function calls MUST follow the specified format: a single JSON object with "name" and "arguments" keys inside <tool_call></tool_call> XML tags.\n- If you choose to call a tool, you MUST output the <tool_call> block IMMEDIATELY after thinking, with NO conversational text before it.\n- The <tool_call> tag MUST be at the very beginning of a new line, with NO spaces or indentation before it.\n- To call multiple functions, output a separate, completely closed <tool_call></tool_call> block for EACH function. Do NOT nest <tool_call> blocks.\n- If you have all necessary data, provide your final answer directly to the user without any tool call.\n</IMPORTANT>' }}
180
+ {%- else %}
181
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<think>\nBrief explanation of tool call\n</think>\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- You can use the <think></think> block to plan your next tool call OR to synthesize data and formulate your final response to the user.\n- ALL explanation and reasoning MUST be placed strictly inside the <think></think> block.\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags.\n- If you choose to call a tool, you MUST output the <tool_call> block IMMEDIATELY after thinking, with NO conversational text before it.\n- The <tool_call> and <function> tags MUST be at the very beginning of a new line, with NO spaces or indentation before them.\n- To call multiple functions, output a separate, completely closed <tool_call></tool_call> block for EACH function. Do NOT nest <tool_call> blocks.\n- If you have all necessary data, provide your final answer directly to the user without any tool call.\n</IMPORTANT>' }}
182
+ {%- endif %}
183
+ {%- if _sc %}
184
+ {{- '\n\n' + _sc }}
185
  {%- endif %}
186
  {{- '<|im_end|>\n' }}
187
  {%- else %}
188
+ {%- if _sc %}
189
+ {{- '<|im_start|>system\n' + (reasoning_instructions + '\n\n' if reasoning_instructions else '') + _sc + '<|im_end|>\n' }}
190
+ {%- elif reasoning_instructions %}
191
+ {{- '<|im_start|>system\n' + reasoning_instructions + '<|im_end|>\n' }}
192
  {%- endif %}
193
  {%- endif %}
194
+ {%- set _last_idx = _msgs | length - 1 %}
195
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=_last_idx) %}
196
+ {%- for message in _msgs[::-1] %}
197
+ {%- set index = (_msgs | length - 1) - loop.index0 %}
198
+ {%- if ns.multi_step_tool and message.role == 'user' %}
199
+ {%- set _rc = render_content(message.content, false) | trim %}
200
+ {%- if not (_rc.startswith('<tool_response>') and _rc.endswith('</tool_response>')) %}
201
  {%- set ns.multi_step_tool = false %}
202
  {%- set ns.last_query_index = index %}
203
  {%- endif %}
204
  {%- endif %}
205
  {%- endfor %}
206
  {%- if ns.multi_step_tool %}
207
+ {%- if _last_idx > 50 %}
208
+ {%- set ns.last_query_index = _last_idx %}
209
+ {%- else %}
210
+ {%- set ns.last_query_index = 0 %}
211
+ {%- endif %}
212
  {%- endif %}
213
+ {%- set ns2 = namespace(prev_role='', consecutive_failures=0) %}
214
+ {%- for message in _msgs %}
215
+ {%- set is_system = (message.role == "system" or message.role == "developer") %}
216
+ {%- set content = render_content(message.content, true, is_system) | trim %}
217
+ {%- if is_system or message.role == 'user' %}
218
+ {%- if '<|think_off|>' in content %}{%- set content = content.split('<|think_off|>') | join('') | trim %}{%- endif %}
219
+ {%- if '<|think_on|>' in content %}{%- set content = content.split('<|think_on|>') | join('') | trim %}{%- endif %}
220
+ {%- if '<|think_xhigh|>' in content %}{%- set content = content.split('<|think_xhigh|>') | join('') | trim %}{%- endif %}
221
+ {%- if '<|think_high|>' in content %}{%- set content = content.split('<|think_high|>') | join('') | trim %}{%- endif %}
222
+ {%- if '<|think_ultracode|>' in content %}{%- set content = content.split('<|think_ultracode|>') | join('') | trim %}{%- endif %}
223
+ {%- if '<|think_extreme|>' in content %}{%- set content = content.split('<|think_extreme|>') | join('') | trim %}{%- endif %}
224
+ {%- if '<|think_max|>' in content %}{%- set content = content.split('<|think_max|>') | join('') | trim %}{%- endif %}
225
+ {%- if '<|think_medium|>' in content %}{%- set content = content.split('<|think_medium|>') | join('') | trim %}{%- endif %}
226
+ {%- if '<|think_low|>' in content %}{%- set content = content.split('<|think_low|>') | join('') | trim %}{%- endif %}
227
+ {%- if '<|think_minimal|>' in content %}{%- set content = content.split('<|think_minimal|>') | join('') | trim %}{%- endif %}
228
+ {%- endif %}
229
+ {%- if is_system %}
230
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
231
+ {%- elif message.role == 'user' %}
232
+ {%- set ns2.consecutive_failures = 0 %}
233
+ {{- '<|im_start|>user\n' + content + '<|im_end|>\n' }}
234
+ {%- elif message.role == 'assistant' %}
235
  {%- set reasoning_content = '' %}
236
+ {%- set _explicit_reasoning = '' %}
237
+ {%- if message.reasoning_content is defined and message.reasoning_content is not none %}
238
+ {%- if message.reasoning_content is string %}
239
+ {%- set _explicit_reasoning = message.reasoning_content %}
240
+ {%- else %}
241
+ {%- set _explicit_reasoning = message.reasoning_content | string %}
242
+ {%- endif %}
243
+ {%- elif message.thinking is defined and message.thinking is not none %}
244
+ {%- if message.thinking is string %}
245
+ {%- set _explicit_reasoning = message.thinking %}
246
+ {%- else %}
247
+ {%- set _explicit_reasoning = message.thinking | string %}
248
+ {%- endif %}
249
+ {%- elif message.reasoning is defined and message.reasoning is not none %}
250
+ {%- if message.reasoning is string %}
251
+ {%- set _explicit_reasoning = message.reasoning %}
252
+ {%- else %}
253
+ {%- set _explicit_reasoning = message.reasoning | string %}
254
+ {%- endif %}
255
+ {%- endif %}
256
+ {%- if _explicit_reasoning %}
257
+ {%- set _lead_end = '' %}
258
+ {%- if content.startswith('<think>') and '</think>' in content %}
259
+ {%- set _lead_end = '</think>' %}
260
+ {%- elif content.startswith('<thinking>') and '</thinking>' in content %}
261
+ {%- set _lead_end = '</thinking>' %}
262
+ {%- elif content.startswith('</think>') %}
263
+ {%- set _lead_end = '</think>' %}
264
+ {%- elif content.startswith('</thinking>') %}
265
+ {%- set _lead_end = '</thinking>' %}
266
+ {%- endif %}
267
+ {%- if _lead_end %}
268
+ {%- set content = content.split(_lead_end)[-1].lstrip('\n') %}
269
+ {%- endif %}
270
+ {%- set reasoning_content = _explicit_reasoning %}
271
  {%- else %}
272
+ {%- set _think_end = '' %}
273
+ {%- if content.startswith('</think>') %}
274
+ {%- set _think_end = '</think>' %}
275
+ {%- elif content.startswith('</thinking>') %}
276
+ {%- set _think_end = '</thinking>' %}
277
+ {%- elif '\n</think>' in content %}
278
+ {%- set _think_end = '\n</think>' %}
279
+ {%- elif '\n</thinking>' in content %}
280
+ {%- set _think_end = '\n</thinking>' %}
281
+ {%- elif '\n</ think>' in content %}
282
+ {%- set _think_end = '\n</ think>' %}
283
+ {%- elif '\n</think >' in content %}
284
+ {%- set _think_end = '\n</think >' %}
285
+ {%- elif content.startswith('<think>') and '</think>' in content %}
286
+ {%- set _think_end = '</think>' %}
287
+ {%- elif content.startswith('<thinking>') and '</thinking>' in content %}
288
+ {%- set _think_end = '</thinking>' %}
289
+ {%- endif %}
290
+ {%- if _think_end %}
291
+ {%- if 'thinking' in _think_end %}
292
+ {%- set _think_start = '<thinking>' %}
293
+ {%- else %}
294
+ {%- set _think_start = '<think>' %}
295
+ {%- endif %}
296
+ {%- set reasoning_content = content.split(_think_end)[0].rstrip('\n') %}
297
+ {%- if _think_start in reasoning_content %}
298
+ {%- set reasoning_content = reasoning_content.split(_think_start)[-1].lstrip('\n') %}
299
+ {%- endif %}
300
+ {%- set content = content.split(_think_end)[-1].lstrip('\n') %}
301
  {%- endif %}
302
  {%- endif %}
303
+ {%- set reasoning_content = reasoning_content | trim %}
304
+ {%- if (_preserve_thinking or loop.index0 > ns.last_query_index) %}
305
+ {{- '<|im_start|>assistant\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
306
  {%- else %}
307
+ {{- '<|im_start|>assistant\n' + content }}
308
  {%- endif %}
309
+ {%- if message.tool_calls is defined and message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
310
  {%- for tool_call in message.tool_calls %}
311
+ {%- if tool_call.function is defined and tool_call.function is not none %}
312
+ {%- set tc = tool_call.function %}
313
+ {%- else %}
314
+ {%- set tc = tool_call %}
315
  {%- endif %}
316
+ {%- set tc_name = tc.name if (tc.name is defined and tc.name is not none) else '' %}
317
+ {%- if _tool_format == 'json' %}
318
+ {%- if loop.first %}
319
+ {%- if content | trim %}
320
+ {{- '\n\n' }}
321
+ {%- endif %}
322
  {%- else %}
323
+ {{- '\n' }}
324
+ {%- endif %}
325
+ {%- set _args = '{}' %}
326
+ {%- if tc.arguments is defined and tc.arguments is not none %}
327
+ {%- if tc.arguments is mapping %}
328
+ {%- set _args = tc.arguments | tojson %}
329
+ {%- elif tc.arguments is string %}
330
+ {%- if tc.arguments %}
331
+ {%- set _args = tc.arguments %}
332
+ {%- endif %}
333
+ {%- else %}
334
+ {%- set _args = tc.arguments | tojson %}
335
+ {%- endif %}
336
  {%- endif %}
337
+ {{- '<tool_call>\n{"name": ' }}{{- tc_name | tojson }}{{- ', "arguments": ' }}{{- _args }}{{- '}\n</tool_call>' }}
338
  {%- else %}
339
+ {%- if loop.first %}
340
+ {%- if content | trim %}
341
+ {{- '\n\n<tool_call>\n<function=' + tc_name + '>\n' }}
342
+ {%- else %}
343
+ {{- '<tool_call>\n<function=' + tc_name + '>\n' }}
344
+ {%- endif %}
345
+ {%- else %}
346
+ {{- '\n<tool_call>\n<function=' + tc_name + '>\n' }}
347
+ {%- endif %}
348
+ {%- if tc.arguments is defined and tc.arguments is not none %}
349
+ {%- if tc.arguments is mapping %}
350
+ {%- for args_name, args_value in tc.arguments.items() %}
351
+ {{- '<parameter=' + args_name + '>\n' }}
352
+ {%- if args_value is string %}
353
+ {%- set _av = args_value %}
354
+ {%- else %}
355
+ {%- set _av = args_value | tojson %}
356
+ {%- endif %}
357
+ {%- if max_tool_arg_chars > 0 and _av | length > max_tool_arg_chars %}
358
+ {{- _av[:max_tool_arg_chars] + '\n[TRUNCATED - original length ' ~ (_av | length | string) ~ ' chars]' }}
359
+ {%- else %}
360
+ {{- _av }}
361
+ {%- endif %}
362
+ {{- '\n</parameter>\n' }}
363
+ {%- endfor %}
364
+ {%- else %}
365
+ {%- if tc.arguments is string %}
366
+ {%- set _raw_args = tc.arguments %}
367
+ {%- else %}
368
+ {%- set _raw_args = tc.arguments | tojson %}
369
+ {%- endif %}
370
+ {%- if _raw_args %}
371
+ {%- if max_tool_arg_chars > 0 and _raw_args | length > max_tool_arg_chars %}
372
+ {{- _raw_args[:max_tool_arg_chars] + '\n[TRUNCATED - original length ' ~ (_raw_args | length | string) ~ ' chars]' }}
373
+ {%- else %}
374
+ {{- _raw_args }}
375
+ {%- endif %}
376
+ {%- endif %}
377
+ {%- endif %}
378
+ {%- endif %}
379
+ {{- '</function>\n</tool_call>' }}
380
  {%- endif %}
 
381
  {%- endfor %}
382
  {%- endif %}
383
  {{- '<|im_end|>\n' }}
384
+ {%- elif message.role == 'tool' %}
385
+ {%- set _content_lower = content | lower %}
386
+ {%- set _content_head = _content_lower[:120] %}
387
+ {%- set _is_code_or_grep = ('throw new ' in _content_lower or 'throw error' in _content_lower or 'console.error' in _content_lower or 'logger.error' in _content_lower or 'logging.error' in _content_lower or 'import ' in _content_head or 'def ' in _content_head or 'function ' in _content_head) %}
388
+ {%- set _exit_code_zero = ('exit code: 0' in _content_head or 'process exited with code 0' in _content_head) %}
389
+ {%- set _error_field_ok = ('"error": null' in _content_head or '"error":null' in _content_head or '"error": false' in _content_head or '"error":false' in _content_head or '"error": ""' in _content_head or '"error":""' in _content_head) %}
390
+ {%- set _strong_error = (('"error":' in _content_head and not _error_field_ok) or '"status": "error"' in _content_head or '"status":"error"' in _content_head or 'traceback (most recent call last):' in _content_head or 'command not found' in _content_head or 'invalid syntax' in _content_head or 'fatal:' in _content_head or (('exit code: ' in _content_head or 'process exited with code' in _content_head) and not _exit_code_zero) or _content_head.startswith('exception:') or _content_head.startswith('failed to ')) %}
391
+ {%- set _weak_error = ('error:' in _content_head or 'err!' in _content_head) %}
392
+ {%- set _weak_suppressed = ('$ ' in _content_head or 'took ' in _content_head or content | length >= 600) %}
393
+ {%- if not _is_code_or_grep and (_strong_error or (_weak_error and not _weak_suppressed)) %}
394
+ {%- set ns2.consecutive_failures = ns2.consecutive_failures + 1 %}
395
+ {%- else %}
396
+ {%- set ns2.consecutive_failures = 0 %}
397
+ {%- endif %}
398
+ {%- if ns2.prev_role != 'tool' %}
399
  {{- '<|im_start|>user' }}
400
  {%- endif %}
401
+ {%- if _tool_format != 'json' and max_tool_response_chars > 0 and content | length > max_tool_response_chars %}
402
+ {%- set content = content[:max_tool_response_chars] + '\n[TRUNCATED - original length ' ~ (content | length | string) ~ ' chars]' %}
403
+ {%- endif %}
404
+ {{- '\n<tool_response>\n' + content }}
405
+ {%- if ns2.consecutive_failures >= 2 %}
406
+ {{- '\n\n⚠️ SYSTEM WARNING: ' ~ ns2.consecutive_failures ~ ' consecutive tool errors detected. Your previous approach is incorrect. You MUST use a fundamentally different approach or corrected arguments.' }}
407
+ {%- elif ns2.consecutive_failures == 1 %}
408
+ {{- '\n\n⚠️ SYSTEM WARNING: The previous tool call returned an error. Diagnose the failure and retry with completely corrected arguments.' }}
409
+ {%- endif %}
410
  {{- '\n</tool_response>' }}
411
+ {%- if loop.last %}
 
 
412
  {{- '<|im_end|>\n' }}
413
+ {%- else %}
414
+ {%- set _next_role = _msgs[loop.index0 + 1].role %}
415
+ {%- if _next_role != 'tool' %}
416
+ {{- '<|im_end|>\n' }}
417
+ {%- endif %}
418
  {%- endif %}
419
  {%- else %}
420
+ {{- '<|im_start|>user\n[' + message.role + ']: ' + content + '<|im_end|>\n' }}
421
  {%- endif %}
422
+ {%- set ns2.prev_role = message.role %}
423
  {%- endfor %}
424
  {%- if add_generation_prompt %}
425
  {{- '<|im_start|>assistant\n' }}
426
+ {%- if not ns_state.thinking %}
 
 
427
  {{- '<think>\n\n</think>\n\n' }}
428
+ {%- else %}
429
+ {{- '<think>\n' }}
430
  {%- endif %}
431
  {%- endif %}