peculiar-ragdoll commited on
Commit
301d54d
·
verified ·
1 Parent(s): e18e763

Add MMLU-Pro header plate (stock vs Sharp Qwen3.8-27B) + v1 archive; proofread README

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ plates/sharp_template_plate.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -18,13 +18,24 @@ tags:
18
  - token-efficient
19
  ---
20
 
21
- # Qwen-Sharp-Chat-Templates
22
 
23
- froggeric's [Qwen-Fixed-Chat-Templates](https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates)
24
- `v22`, with a terseness system prompt spliced in. Model-agnostic: it names no model, so it
25
- drops into any Qwen3.5, 3.6, or 3.8 build without claiming to be something it isn't.
26
 
27
- > **v22 (the Qwen 3.8 update).** Upstream now covers Qwen 3.8 alongside 3.5/3.6 and adds
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  > prompt-directed reasoning-effort steering (`xhigh`/`high`/`medium`/`low`), which upstream
29
  > **defaults to `xhigh`** — it injects a "think at maximum effort" system line even when the
30
  > caller asks for nothing. That default is a behavioral change from `v21.3`, so this Sharp build
@@ -40,7 +51,7 @@ drops into any Qwen3.5, 3.6, or 3.8 build without claiming to be something it is
40
 
41
  [Dagger-Qwen3.6-27B](https://huggingface.co/peculiar-ragdoll/Dagger-Qwen3.6-27B-MLX) and
42
  [Nail-Qwen3.6-35B-A3B](https://huggingface.co/peculiar-ragdoll/Nail-Qwen3.6-35B-A3B-MLX) shipped with
43
- the **v1** template baked into their weights — that is the exact template embedded in those GGUF and
44
  MLX builds (`template_version = "qwen3.6-froggeric-v21.3"`, terseness, no reasoning-effort steering),
45
  and it lives here in [`archive/v1-qwen3.6-froggeric-v21.3/`](archive/v1-qwen3.6-froggeric-v21.3). The
46
  `chat_template.jinja` at the root of this repo is the newer **v22** described above; drop it in to
@@ -88,7 +99,7 @@ prompt and nothing else. Measured on ThinkingCap-Qwen3.6-27B, MLX 6-bit, temp 1.
88
  Green is better in both directions: accuracy up, tokens down. Accuracy changes are absolute
89
  differences in score, token changes are relative.
90
 
91
- Roughly: **the same answers, in a bit over half the words.** The accuracy column moves *up* rather
92
  than down, which is the part that matters — terseness that costs correctness is just truncation.
93
 
94
  These figures come from one 27B model on two benchmarks. They are evidence that the prompt does
@@ -231,8 +242,9 @@ with the bare top-level field it does not.
231
  the brevity and not the retention.
232
  - **It is not tuned per model.** Every model responds a little differently to a terseness
233
  instruction; measure yours. The numbers above are from a 27B; a 4B may need firmer wording.
234
- - **The benchmarks are Qwen3.6.** The template covers 3.5, 3.6, and 3.8 alike — upstream unified
235
- them into one file — but every figure in the table was measured on a 3.6 model.
 
236
 
237
  ## Credits
238
 
 
18
  - token-efficient
19
  ---
20
 
21
+ # Qwen Sharp Chat Templates
22
 
23
+ This is a drop-in fix for any Qwen3.5, 3.6, or 3.8 model, optimizing the models for knowledge work and coding.
 
 
24
 
25
+ <div align="center">
26
+ <img src="plates/sharp_template_plate.png" alt="Qwen3.8-27b gets more accurate and uses fewer tokens with the template applied" width="100%">
27
+ </div>
28
+
29
+ With the *Sharp* template, Qwen3.8-27b (medium effort) gets smarter **and** uses fewer thinking tokens before it answers, and the effect is comparable for other compatible models.
30
+
31
+ *Sharp* makes Qwen's models *more intelligent per token*, and makes them communicate *more information per token*, saving time and effort for both the model and the user.
32
+
33
+ ## Straight to the point
34
+
35
+ This is froggeric's [Qwen-Fixed-Chat-Templates](https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates)
36
+ `v22`, with a force-appended system prompt spliced in. The base fixes issues, the addition makes it better.
37
+
38
+ > **v22 (the Qwen 3.8 update).** Now covers Qwen 3.8 alongside 3.5/3.6 and adds
39
  > prompt-directed reasoning-effort steering (`xhigh`/`high`/`medium`/`low`), which upstream
40
  > **defaults to `xhigh`** — it injects a "think at maximum effort" system line even when the
41
  > caller asks for nothing. That default is a behavioral change from `v21.3`, so this Sharp build
 
51
 
52
  [Dagger-Qwen3.6-27B](https://huggingface.co/peculiar-ragdoll/Dagger-Qwen3.6-27B-MLX) and
53
  [Nail-Qwen3.6-35B-A3B](https://huggingface.co/peculiar-ragdoll/Nail-Qwen3.6-35B-A3B-MLX) shipped with
54
+ the **v1** template baked into those builds — that is the exact template embedded in those GGUF and
55
  MLX builds (`template_version = "qwen3.6-froggeric-v21.3"`, terseness, no reasoning-effort steering),
56
  and it lives here in [`archive/v1-qwen3.6-froggeric-v21.3/`](archive/v1-qwen3.6-froggeric-v21.3). The
57
  `chat_template.jinja` at the root of this repo is the newer **v22** described above; drop it in to
 
99
  Green is better in both directions: accuracy up, tokens down. Accuracy changes are absolute
100
  differences in score, token changes are relative.
101
 
102
+ Roughly: **the same answers, in a bit over 40% of the words.** The accuracy column moves *up* rather
103
  than down, which is the part that matters — terseness that costs correctness is just truncation.
104
 
105
  These figures come from one 27B model on two benchmarks. They are evidence that the prompt does
 
242
  the brevity and not the retention.
243
  - **It is not tuned per model.** Every model responds a little differently to a terseness
244
  instruction; measure yours. The numbers above are from a 27B; a 4B may need firmer wording.
245
+ - **The table's figures are Qwen3.6 (the plate above is the 3.8 result).** The template covers 3.5,
246
+ 3.6, and 3.8 alike — upstream unified them into one file — but every figure in the table was
247
+ measured on a 3.6 model.
248
 
249
  ## Credits
250
 
archive/v1-qwen3.6-froggeric-v21.3/README.md ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: froggeric/Qwen-Fixed-Chat-Templates
4
+ base_model_relation: finetune
5
+ tags:
6
+ - jinja
7
+ - chat-template
8
+ - qwen
9
+ - qwen3.5
10
+ - qwen3.6
11
+ - mlx
12
+ - llama.cpp
13
+ - lm-studio
14
+ - vllm
15
+ - tool-calling
16
+ - thinking
17
+ - token-efficient
18
+ ---
19
+
20
+ # Qwen-Sharp-Chat-Templates
21
+
22
+ froggeric's [Qwen-Fixed-Chat-Templates](https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates)
23
+ `v21.3`, with a terseness system prompt spliced in. Model-agnostic: it names no model, so it
24
+ drops into any Qwen3.5 or Qwen3.6 build without claiming to be something it isn't.
25
+
26
+ This is the template used by [Dagger-Qwen3.6-27B](https://huggingface.co/peculiar-ragdoll/Dagger-Qwen3.6-27B-MLX)
27
+ and [Nail-Qwen3.6-35B-A3B](https://huggingface.co/peculiar-ragdoll/Nail-Qwen3.6-35B-A3B-MLX),
28
+ published separately because the template is the portable part — the thing worth reusing is not
29
+ tied to either model.
30
+
31
+ ## What it changes
32
+
33
+ Eleven inserted lines. Everything else is byte-identical to upstream v21.3.
34
+
35
+ ```jinja
36
+ {%- set _terse %}
37
+ Answer directly, after thinking. Lead with the answer, then only what it needs to be correct and usable.
38
+ Never: open with preamble or pleasantries; restate the question; add filler transitions; hedge with niceties; or repeat a point you've already made.
39
+ Always: keep essential steps, caveats, uncertainties, and specifics — never drop correctness or a needed warning for brevity. Keep the final answer lean. Use the least structure that conveys it (plain prose when short; lists or code only when they earn their place). If genuinely uncertain, say so and explain why — never omit uncertainty for the sake of brevity.
40
+ If a user request is genuinely ambiguous, ask a sharp question, don't guess.
41
+ {%- endset %}
42
+ {%- if not _sc %}
43
+ {%- set _sc = _terse | trim %}
44
+ {%- else %}
45
+ {%- set _sc = (_sc | trim) ~ '\n\n' ~ (_terse | trim) %}
46
+ {%- endif %}
47
+ ```
48
+
49
+ Note the `else` branch: **your own system prompt is kept**, and the terseness block is appended
50
+ after it. Nothing you pass in is replaced.
51
+
52
+ ## What it does, measured
53
+
54
+ Every row below is the *same weights* with only the template swapped, so the difference is the
55
+ prompt and nothing else. Measured on ThinkingCap-Qwen3.6-27B, MLX 6-bit, temp 1.0, n=3 seeds.
56
+
57
+ | | stock template | Sharp template | change |
58
+ |---|--:|--:|:--|
59
+ | Claw-Eval, answer component | 59.3 | **66.7** | ![+7.4%](https://img.shields.io/badge/%2B7.4%25-brightgreen) |
60
+ | Claw-Eval, overall | 55.0 | **58.8** | ![+3.8%](https://img.shields.io/badge/%2B3.8%25-brightgreen) |
61
+ | Claw-Eval answer tokens | 5393 | **2217** | ![-59%](https://img.shields.io/badge/--59%25-brightgreen) |
62
+ | MMLU-Pro tokens per correct answer | 1601 | **1248** | ![-22%](https://img.shields.io/badge/--22%25-brightgreen) |
63
+
64
+ Green is better in both directions: accuracy up, tokens down. Accuracy changes are absolute
65
+ differences in score, token changes are relative.
66
+
67
+ Roughly: **the same answers, in a bit over half the words.** The accuracy column moves *up* rather
68
+ than down, which is the part that matters — terseness that costs correctness is just truncation.
69
+
70
+ These figures come from one 27B model on two benchmarks. They are evidence that the prompt does
71
+ something, not a promise of a specific number on your model.
72
+
73
+ **Both benchmarks are single-turn, and that matters.** froggeric's template defaults
74
+ `preserve_thinking` to `true`, so reasoning from earlier turns stays in the context. With one
75
+ turn there is nothing to preserve and it costs nothing. In a multi-turn agentic loop the prompt
76
+ grows every step, and you can end up paying more in prefill than the shorter outputs save — one
77
+ user measured a 19% wall-clock *regression* on a multi-turn coding and audit workload while
78
+ output quality held. If that is your shape of work, pass `preserve_thinking=false` in
79
+ `chat_template_kwargs` and measure both ways.
80
+
81
+ The terseness instruction targets prose padding: preamble, restating the question, filler
82
+ transitions. Where the deliverable is mostly code or a structured artifact there is less padding
83
+ to remove, so expect less from it — and the prompt deliberately protects those (*"lists or code
84
+ only when they earn their place"*, *"never drop correctness for brevity"*).
85
+
86
+ ## Use
87
+
88
+ **MLX / transformers** — drop `chat_template.jinja` into the model directory.
89
+
90
+ ```bash
91
+ hf download peculiar-ragdoll/Qwen-Sharp-Chat-Templates chat_template.jinja \
92
+ --local-dir /path/to/your-model
93
+ ```
94
+
95
+ > **Two places can hold a template, and old runtimes disagree about which wins.** A model
96
+ > directory can carry it as `chat_template.jinja` *and* as a `chat_template` key inside
97
+ > `tokenizer_config.json`. Anything on transformers ≥ 4.51 — which includes current oMLX and
98
+ > LM Studio — prefers the `.jinja` file, so the drop-in just works. Older runtimes read only
99
+ > the embedded key and ignore the file, and then the drop-in silently does nothing.
100
+ >
101
+ > If the directory has both and you are unsure of your runtime, patch both — that is what
102
+ > `chat_template_oneline.txt` is for: paste it as the `chat_template` value. Or run
103
+ > `scripts/check_applied.py` (below), which reports every source and flags a mismatch.
104
+
105
+ **oMLX** — drop `chat_template.jinja` into the model directory and rescan. Verified on oMLX
106
+ (transformers 5.12.1) by loading a model with the Sharp template as `chat_template.jinja` *and*
107
+ a deliberately different template embedded in `tokenizer_config.json`: the `.jinja` file won,
108
+ and the model reported the terseness rules with the caller's own system prompt still in force.
109
+
110
+ **GGUF** — rewrite the embedded template without requantizing:
111
+
112
+ ```bash
113
+ pip install gguf
114
+ gguf-new-metadata \
115
+ --chat-template-file chat_template.jinja \
116
+ input.gguf output.gguf
117
+ ```
118
+
119
+ **tokenizer_config.json** — use `chat_template_oneline.txt`, the minified single-line form. It
120
+ renders identically to the full template (verified by `scripts/verify_template.py`).
121
+
122
+ **llama.cpp at runtime, without touching the file** — pass it per-run instead:
123
+
124
+ ```bash
125
+ llama-server -m model.gguf --chat-template-file chat_template.jinja -ngl 99
126
+ llama-cli -m model.gguf --chat-template-file chat_template.jinja -ngl 99
127
+ ```
128
+
129
+ Same effect, and it fully replaces whatever is embedded in the GGUF — verified against a build
130
+ whose embedded template names a specific model: with the flag, the served template is
131
+ byte-identical to this file and the model name is gone. Check it yourself with
132
+ `curl localhost:8080/props | jq -r .chat_template`, or render a prompt through
133
+ `POST /apply-template`.
134
+
135
+ Two caveats. `--jinja` is enabled by default in current llama.cpp, so you usually do not need
136
+ it — on older builds you do, and it must come *before* `--chat-template-file`. And the flag is
137
+ per-invocation: forget it once and you silently get the embedded template back. Rewriting the
138
+ GGUF with `gguf-new-metadata` is the durable version; the flag is right for trying it out or for
139
+ running one template across several models.
140
+
141
+ ## Did it actually apply?
142
+
143
+ Point `check_applied.py` at a model directory or a `.gguf`. It finds every template source,
144
+ renders each, and tells you whether they agree — exits non-zero if the prompt is missing or the
145
+ two sources disagree.
146
+
147
+ ```bash
148
+ python3 scripts/check_applied.py /path/to/model-dir
149
+ python3 scripts/check_applied.py model.gguf
150
+ ```
151
+
152
+ ```
153
+ [chat_template.jinja] 17143 bytes
154
+ terseness prompt ......... yes
155
+ keeps your system prompt . yes
156
+
157
+ [tokenizer_config.json] 110 bytes
158
+ terseness prompt ......... NO (found 0x)
159
+
160
+ *** THE TWO SOURCES DISAGREE ***
161
+ Recent transformers uses chat_template.jinja; oMLX and others read the
162
+ copy embedded in tokenizer_config.json. Right now those differ, so what
163
+ you get depends on your runtime. Patch both to the same content.
164
+ ```
165
+
166
+ That case — a fresh `.jinja` dropped in next to a stale embedded copy — is the most common way
167
+ this silently does nothing. It also warns if the template names a specific model, which happens
168
+ when the file was taken from a model repo rather than from here.
169
+
170
+ ## What it doesn't do
171
+
172
+ - **It is not a fine-tune**, despite the `base_model_relation: finetune` tag — that is the closest
173
+ vocabulary HuggingFace offers for "derived from," and it exists so this repo is linked from
174
+ froggeric's. No weights are involved. It changes what the model is asked for, not what it knows.
175
+ - **It does not fix thinking retention by itself** — that comes from froggeric's upstream template,
176
+ which this builds on. If you splice only the terseness block into a stock Qwen template, you get
177
+ the brevity and not the retention.
178
+ - **It is not tuned per model.** Every model responds a little differently to a terseness
179
+ instruction; measure yours. The numbers above are from a 27B; a 4B may need firmer wording.
180
+ - **The benchmarks are Qwen3.6.** The template covers 3.5 and 3.6 alike — upstream unified them
181
+ into one file in v17 — but every figure in the table was measured on a 3.6 model.
182
+
183
+ ## Credits
184
+
185
+ Everything structural here is [froggeric](https://huggingface.co/froggeric)'s work — the retention
186
+ fix, the tool-calling handling, the whole template. This repo adds a system prompt and nothing
187
+ else. `scripts/minify_jinja.py` is froggeric's, with one patch: it now preserves newlines inside
188
+ `{% set %}…{% endset %}` blocks, which upstream's template doesn't contain and this one does.
189
+
190
+ Apache-2.0, matching upstream.
archive/v1-qwen3.6-froggeric-v21.3/chat_template.jinja ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set template_version = "qwen3.6-froggeric-v21.3" %}
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
+ {%- set _preserve_thinking = preserve_thinking if preserve_thinking is defined else true %}
9
+ {%- set max_tool_arg_chars = max_tool_arg_chars if max_tool_arg_chars is defined else 0 %}
10
+ {%- set max_tool_response_chars = max_tool_response_chars if max_tool_response_chars is defined else 0 %}
11
+ {%- set _has_tools = (tools is defined and tools and tools is iterable and tools is not mapping) %}
12
+ {%- set ns_state = namespace(thinking=enable_thinking) %}
13
+ {%- if auto_disable_thinking_with_tools and _has_tools %}
14
+ {%- set ns_state.thinking = false %}
15
+ {%- endif %}
16
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
17
+ {%- if content is string %}
18
+ {{- content }}
19
+ {%- elif content is iterable and content is not mapping %}
20
+ {%- for item in content %}
21
+ {%- if item is mapping %}
22
+ {%- if item.type == 'image' or 'image' in item or 'image_url' in item %}
23
+ {%- if is_system_content %}
24
+ {{- raise_exception('System message cannot contain images.') }}
25
+ {%- endif %}
26
+ {%- if do_vision_count %}
27
+ {%- set image_count.value = image_count.value + 1 %}
28
+ {%- endif %}
29
+ {%- if add_vision_id %}
30
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
31
+ {%- endif %}
32
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
33
+ {%- elif item.type == 'video' or 'video' in item %}
34
+ {%- if is_system_content %}
35
+ {{- raise_exception('System message cannot contain videos.') }}
36
+ {%- endif %}
37
+ {%- if do_vision_count %}
38
+ {%- set video_count.value = video_count.value + 1 %}
39
+ {%- endif %}
40
+ {%- if add_vision_id %}
41
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
42
+ {%- endif %}
43
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
44
+ {%- elif 'text' in item %}
45
+ {{- item.text }}
46
+ {%- else %}
47
+ {{- raise_exception('Unexpected item type in content.') }}
48
+ {%- endif %}
49
+ {%- else %}
50
+ {{- item | string }}
51
+ {%- endif %}
52
+ {%- endfor %}
53
+ {%- elif content is none or content is undefined %}
54
+ {{- '' }}
55
+ {%- else %}
56
+ {{- raise_exception('Unexpected content type.') }}
57
+ {%- endif %}
58
+ {%- endmacro %}
59
+ {%- if not messages %}
60
+ {{- raise_exception('No messages provided.') }}
61
+ {%- endif %}
62
+ {%- set _first_role = messages[0].role %}
63
+ {%- if _first_role == 'system' or _first_role == 'developer' %}
64
+ {%- set _sys_msg = messages[0] %}
65
+ {%- set _msgs = messages[1:] %}
66
+ {%- else %}
67
+ {%- set _sys_msg = none %}
68
+ {%- set _msgs = messages %}
69
+ {%- endif %}
70
+ {%- set _sc = '' %}
71
+ {%- if _sys_msg is not none %}
72
+ {%- set _sc = render_content(_sys_msg.content, false, true) | trim %}
73
+ {%- if '<|think_off|>' in _sc %}
74
+ {%- set ns_state.thinking = false %}
75
+ {%- set _sc = _sc.split('<|think_off|>') | join('') | trim %}
76
+ {%- elif '<|think_on|>' in _sc %}
77
+ {%- set ns_state.thinking = true %}
78
+ {%- set _sc = _sc.split('<|think_on|>') | join('') | trim %}
79
+ {%- endif %}
80
+ {%- endif %}
81
+ {%- set _terse %}
82
+ Answer directly, after thinking. Lead with the answer, then only what it needs to be correct and usable.
83
+ Never: open with preamble or pleasantries; restate the question; add filler transitions; hedge with niceties; or repeat a point you've already made.
84
+ Always: keep essential steps, caveats, uncertainties, and specifics — never drop correctness or a needed warning for brevity. Keep the final answer lean. Use the least structure that conveys it (plain prose when short; lists or code only when they earn their place). If genuinely uncertain, say so and explain why — never omit uncertainty for the sake of brevity.
85
+ If a user request is genuinely ambiguous, ask a sharp question, don't guess.
86
+ {%- endset %}
87
+ {%- if not _sc %}
88
+ {%- set _sc = _terse | trim %}
89
+ {%- else %}
90
+ {%- set _sc = (_sc | trim) ~ '\n\n' ~ (_terse | trim) %}
91
+ {%- endif %}
92
+ {%- if _has_tools %}
93
+ {{- '<|im_start|>system\n' }}
94
+ {{- '# Tools\n\nYou have access to the following functions:\n\n<tools>' }}
95
+ {%- for tool in tools %}
96
+ {{- '\n' }}
97
+ {{- tool | tojson }}
98
+ {%- endfor %}
99
+ {{- '\n</tools>' }}
100
+ {%- set tool_instructions %}
101
+ If you choose to call a function ONLY reply in the following format with NO suffix:
102
+
103
+ {%- if _tool_format == 'json' %}
104
+ <think>
105
+ Brief explanation of tool call
106
+ </think>
107
+ <tool_call>
108
+ {"name": "example_function_name", "arguments": {"example_parameter_1": "value_1", "example_parameter_2": "This is the value for the second parameter"}}
109
+ </tool_call>
110
+ {%- else %}
111
+ <think>
112
+ Brief explanation of tool call
113
+ </think>
114
+ <tool_call>
115
+ <function=example_function_name>
116
+ <parameter=example_parameter_1>
117
+ value_1
118
+ </parameter>
119
+ <parameter=example_parameter_2>
120
+ This is the value for the second parameter
121
+ that can span
122
+ multiple lines
123
+ </parameter>
124
+ </function>
125
+ </tool_call>
126
+ {%- endif %}
127
+
128
+ <IMPORTANT>
129
+ Reminder:
130
+ - 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.
131
+ - ALL explanation and reasoning MUST be placed strictly inside the <think></think> block.
132
+ {%- if _tool_format == 'json' %}
133
+ - Function calls MUST follow the specified format: a single JSON object with "name" and "arguments" keys inside <tool_call></tool_call> XML tags.
134
+ {%- else %}
135
+ - Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags.
136
+ {%- endif %}
137
+ - If you choose to call a tool, you MUST output the <tool_call> block IMMEDIATELY after thinking, with NO conversational text before it.
138
+ {%- if _tool_format == 'json' %}
139
+ - The <tool_call> tag MUST be at the very beginning of a new line, with NO spaces or indentation before it.
140
+ {%- else %}
141
+ - The <tool_call> and <function> tags MUST be at the very beginning of a new line, with NO spaces or indentation before them.
142
+ {%- endif %}
143
+ - To call multiple functions, output a separate, completely closed <tool_call></tool_call> block for EACH function. Do NOT nest <tool_call> blocks.
144
+ - If you have all necessary data, provide your final answer directly to the user without any tool call.
145
+ </IMPORTANT>
146
+ {%- endset %}
147
+ {{- '\n\n' ~ tool_instructions | trim }}
148
+ {%- if _sc %}
149
+ {{- '\n\n' + _sc }}
150
+ {%- endif %}
151
+ {{- '<|im_end|>\n' }}
152
+ {%- else %}
153
+ {%- if _sc %}
154
+ {{- '<|im_start|>system\n' + _sc + '<|im_end|>\n' }}
155
+ {%- endif %}
156
+ {%- endif %}
157
+ {%- set _last_idx = _msgs | length - 1 %}
158
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=_last_idx) %}
159
+ {%- for message in _msgs[::-1] %}
160
+ {%- set index = (_msgs | length - 1) - loop.index0 %}
161
+ {%- if ns.multi_step_tool and message.role == 'user' %}
162
+ {%- set _rc = render_content(message.content, false) | trim %}
163
+ {%- if not (_rc.startswith('<tool_response>') and _rc.endswith('</tool_response>')) %}
164
+ {%- set ns.multi_step_tool = false %}
165
+ {%- set ns.last_query_index = index %}
166
+ {%- endif %}
167
+ {%- endif %}
168
+ {%- endfor %}
169
+ {%- if ns.multi_step_tool %}
170
+ {%- if _last_idx > 50 %}
171
+ {%- set ns.last_query_index = _last_idx %}
172
+ {%- else %}
173
+ {%- set ns.last_query_index = 0 %}
174
+ {%- endif %}
175
+ {%- endif %}
176
+ {%- set ns2 = namespace(prev_role='', consecutive_failures=0) %}
177
+ {%- for message in _msgs %}
178
+ {%- set is_system = (message.role == "system" or message.role == "developer") %}
179
+ {%- set content = render_content(message.content, true, is_system) | trim %}
180
+ {%- if is_system or message.role == 'user' %}
181
+ {%- if '<|think_off|>' in content %}
182
+ {%- set ns_state.thinking = false %}
183
+ {%- set content = content.split('<|think_off|>') | join('') | trim %}
184
+ {%- elif '<|think_on|>' in content %}
185
+ {%- set ns_state.thinking = true %}
186
+ {%- set content = content.split('<|think_on|>') | join('') | trim %}
187
+ {%- endif %}
188
+ {%- endif %}
189
+ {%- if is_system %}
190
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
191
+ {%- elif message.role == 'user' %}
192
+ {%- set ns2.consecutive_failures = 0 %}
193
+ {{- '<|im_start|>user\n' + content + '<|im_end|>\n' }}
194
+ {%- elif message.role == 'assistant' %}
195
+ {%- set reasoning_content = '' %}
196
+ {%- if message.reasoning_content is defined and message.reasoning_content is not none %}
197
+ {%- if message.reasoning_content is string %}
198
+ {%- set reasoning_content = message.reasoning_content %}
199
+ {%- else %}
200
+ {%- set reasoning_content = message.reasoning_content | string %}
201
+ {%- endif %}
202
+ {%- elif message.thinking is defined and message.thinking is not none %}
203
+ {%- if message.thinking is string %}
204
+ {%- set reasoning_content = message.thinking %}
205
+ {%- else %}
206
+ {%- set reasoning_content = message.thinking | string %}
207
+ {%- endif %}
208
+ {%- else %}
209
+ {%- set _think_end = '' %}
210
+ {%- if content.startswith('</think>') %}
211
+ {%- set _think_end = '</think>' %}
212
+ {%- elif content.startswith('</thinking>') %}
213
+ {%- set _think_end = '</thinking>' %}
214
+ {%- elif '\n</think>' in content %}
215
+ {%- set _think_end = '\n</think>' %}
216
+ {%- elif '\n</thinking>' in content %}
217
+ {%- set _think_end = '\n</thinking>' %}
218
+ {%- elif '\n</ think>' in content %}
219
+ {%- set _think_end = '\n</ think>' %}
220
+ {%- elif '\n</think >' in content %}
221
+ {%- set _think_end = '\n</think >' %}
222
+ {%- endif %}
223
+ {%- if _think_end %}
224
+ {%- if 'thinking' in _think_end %}
225
+ {%- set _think_start = '<thinking>' %}
226
+ {%- else %}
227
+ {%- set _think_start = '<think>' %}
228
+ {%- endif %}
229
+ {%- set reasoning_content = content.split(_think_end)[0].rstrip('\n') %}
230
+ {%- if _think_start in reasoning_content %}
231
+ {%- set reasoning_content = reasoning_content.split(_think_start)[-1].lstrip('\n') %}
232
+ {%- endif %}
233
+ {%- set content = content.split(_think_end)[-1].lstrip('\n') %}
234
+ {%- endif %}
235
+ {%- endif %}
236
+ {%- set reasoning_content = reasoning_content | trim %}
237
+ {%- if (_preserve_thinking or loop.index0 > ns.last_query_index) and reasoning_content %}
238
+ {{- '<|im_start|>assistant\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
239
+ {%- else %}
240
+ {{- '<|im_start|>assistant\n' + content }}
241
+ {%- endif %}
242
+ {%- if message.tool_calls is defined and message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
243
+ {%- for tool_call in message.tool_calls %}
244
+ {%- if tool_call.function is defined and tool_call.function is not none %}
245
+ {%- set tc = tool_call.function %}
246
+ {%- else %}
247
+ {%- set tc = tool_call %}
248
+ {%- endif %}
249
+ {%- if _tool_format == 'json' %}
250
+ {%- if not loop.first or content | trim %}
251
+ {{- '\n\n' }}
252
+ {%- endif %}
253
+ {%- set _args = '{}' %}
254
+ {%- if tc.arguments is defined and tc.arguments is not none %}
255
+ {%- if tc.arguments is mapping %}
256
+ {%- set _args = tc.arguments | tojson %}
257
+ {%- elif tc.arguments is string and tc.arguments %}
258
+ {%- set _args = tc.arguments %}
259
+ {%- endif %}
260
+ {%- endif %}
261
+ {{- '<tool_call>\n{"name": ' }}{{- tc.name | tojson }}{{- ', "arguments": ' }}{{- _args }}{{- '}\n</tool_call>' }}
262
+ {%- else %}
263
+ {%- if loop.first %}
264
+ {%- if content | trim %}
265
+ {{- '\n\n<tool_call>\n<function=' + tc.name + '>\n' }}
266
+ {%- else %}
267
+ {{- '<tool_call>\n<function=' + tc.name + '>\n' }}
268
+ {%- endif %}
269
+ {%- else %}
270
+ {{- '\n\n<tool_call>\n<function=' + tc.name + '>\n' }}
271
+ {%- endif %}
272
+ {%- if tc.arguments is defined and tc.arguments is not none %}
273
+ {%- if tc.arguments is mapping %}
274
+ {%- for args_name, args_value in tc.arguments.items() %}
275
+ {{- '<parameter=' + args_name + '>\n' }}
276
+ {%- if args_value is mapping or (args_value is sequence and args_value is not string) %}
277
+ {%- set _av = args_value | tojson %}
278
+ {%- else %}
279
+ {%- set _av = args_value | string %}
280
+ {%- endif %}
281
+ {%- if max_tool_arg_chars > 0 and _av | length > max_tool_arg_chars %}
282
+ {{- _av[:max_tool_arg_chars] + '\n[TRUNCATED — original length ' ~ (_av | length | string) ~ ' chars]' }}
283
+ {%- else %}
284
+ {{- _av }}
285
+ {%- endif %}
286
+ {{- '\n</parameter>\n' }}
287
+ {%- endfor %}
288
+ {%- elif tc.arguments is string and tc.arguments %}
289
+ {{- tc.arguments }}
290
+ {%- endif %}
291
+ {%- endif %}
292
+ {{- '</function>\n</tool_call>' }}
293
+ {%- endif %}
294
+ {%- endfor %}
295
+ {%- endif %}
296
+ {{- '<|im_end|>\n' }}
297
+ {%- elif message.role == 'tool' %}
298
+ {%- set _content_lower = content | lower %}
299
+ {%- set _content_head = _content_lower[:80] %}
300
+ {%- if content | length < 500 and '$ ' not in content and 'took ' not in _content_lower and ('"error":' in _content_head or 'error:' in _content_head or 'err!' in _content_head or 'fatal:' in _content_head or 'exception:' in _content_head or 'traceback' in _content_head or 'command not found' in _content_head or 'invalid syntax' in _content_head or 'failed to' in _content_head) %}
301
+ {%- set ns2.consecutive_failures = ns2.consecutive_failures + 1 %}
302
+ {%- else %}
303
+ {%- set ns2.consecutive_failures = 0 %}
304
+ {%- endif %}
305
+ {%- if ns2.prev_role != 'tool' %}
306
+ {{- '<|im_start|>user' }}
307
+ {%- endif %}
308
+ {%- if max_tool_response_chars > 0 and content | length > max_tool_response_chars %}
309
+ {%- set content = content[:max_tool_response_chars] + '\n[TRUNCATED — original length ' ~ (content | length | string) ~ ' chars]' %}
310
+ {%- endif %}
311
+ {{- '\n<tool_response>\n' + content }}
312
+ {%- if ns2.consecutive_failures >= 2 %}
313
+ {{- '\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.' }}
314
+ {%- elif ns2.consecutive_failures == 1 %}
315
+ {{- '\n\n⚠️ SYSTEM WARNING: The previous tool call returned an error. Diagnose the failure and retry with completely corrected arguments.' }}
316
+ {%- endif %}
317
+ {{- '\n</tool_response>' }}
318
+ {%- if loop.last %}
319
+ {{- '<|im_end|>\n' }}
320
+ {%- else %}
321
+ {%- set _next_role = _msgs[loop.index0 + 1].role %}
322
+ {%- if _next_role != 'tool' %}
323
+ {{- '<|im_end|>\n' }}
324
+ {%- endif %}
325
+ {%- endif %}
326
+ {%- else %}
327
+ {{- '<|im_start|>user\n[' + message.role + ']: ' + content + '<|im_end|>\n' }}
328
+ {%- endif %}
329
+ {%- set ns2.prev_role = message.role %}
330
+ {%- endfor %}
331
+ {%- if add_generation_prompt %}
332
+ {{- '<|im_start|>assistant\n' }}
333
+ {%- if not ns_state.thinking %}
334
+ {{- '<think>\n\n</think>\n\n' }}
335
+ {%- elif ns2.consecutive_failures >= 2 %}
336
+ {{- '<think>\n\n</think>\n\n' }}
337
+ {%- else %}
338
+ {{- '<think>\n' }}
339
+ {%- endif %}
340
+ {%- endif %}
archive/v1-qwen3.6-froggeric-v21.3/chat_template_oneline.txt ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set template_version = "qwen3.6-froggeric-v21.3" %}{%- set _tool_format = tool_call_format if tool_call_format is defined else 'xml' %}{%- set image_count = namespace(value=0) %}{%- set video_count = namespace(value=0) %}{%- set add_vision_id = add_vision_id if add_vision_id is defined else false %}{%- set enable_thinking = enable_thinking if enable_thinking is defined else true %}{%- set auto_disable_thinking_with_tools = auto_disable_thinking_with_tools if auto_disable_thinking_with_tools is defined else false %}{%- set _preserve_thinking = preserve_thinking if preserve_thinking is defined else true %}{%- set max_tool_arg_chars = max_tool_arg_chars if max_tool_arg_chars is defined else 0 %}{%- set max_tool_response_chars = max_tool_response_chars if max_tool_response_chars is defined else 0 %}{%- set _has_tools = (tools is defined and tools and tools is iterable and tools is not mapping) %}{%- set ns_state = namespace(thinking=enable_thinking) %}{%- if auto_disable_thinking_with_tools and _has_tools %}{%- set ns_state.thinking = false %}{%- endif %}{%- macro render_content(content, do_vision_count, is_system_content=false) %}{%- if content is string %}{{- content }}{%- elif content is iterable and content is not mapping %}{%- for item in content %}{%- if item is mapping %}{%- if item.type == 'image' or 'image' in item or 'image_url' in item %}{%- if is_system_content %}{{- raise_exception('System message cannot contain images.') }}{%- endif %}{%- if do_vision_count %}{%- set image_count.value = image_count.value + 1 %}{%- endif %}{%- if add_vision_id %}{{- 'Picture ' ~ image_count.value ~ ': ' }}{%- endif %}{{- '<|vision_start|><|image_pad|><|vision_end|>' }}{%- elif item.type == 'video' or 'video' in item %}{%- if is_system_content %}{{- raise_exception('System message cannot contain videos.') }}{%- endif %}{%- if do_vision_count %}{%- set video_count.value = video_count.value + 1 %}{%- endif %}{%- if add_vision_id %}{{- 'Video ' ~ video_count.value ~ ': ' }}{%- endif %}{{- '<|vision_start|><|video_pad|><|vision_end|>' }}{%- elif 'text' in item %}{{- item.text }}{%- else %}{{- raise_exception('Unexpected item type in content.') }}{%- endif %}{%- else %}{{- item | string }}{%- endif %}{%- endfor %}{%- elif content is none or content is undefined %}{{- '' }}{%- else %}{{- raise_exception('Unexpected content type.') }}{%- endif %}{%- endmacro %}{%- if not messages %}{{- raise_exception('No messages provided.') }}{%- endif %}{%- set _first_role = messages[0].role %}{%- if _first_role == 'system' or _first_role == 'developer' %}{%- set _sys_msg = messages[0] %}{%- set _msgs = messages[1:] %}{%- else %}{%- set _sys_msg = none %}{%- set _msgs = messages %}{%- endif %}{%- set _sc = '' %}{%- if _sys_msg is not none %}{%- set _sc = render_content(_sys_msg.content, false, true) | trim %}{%- if '<|think_off|>' in _sc %}{%- set ns_state.thinking = false %}{%- set _sc = _sc.split('<|think_off|>') | join('') | trim %}{%- elif '<|think_on|>' in _sc %}{%- set ns_state.thinking = true %}{%- set _sc = _sc.split('<|think_on|>') | join('') | trim %}{%- endif %}{%- endif %} {%- set _terse %}
2
+ Answer directly, after thinking. Lead with the answer, then only what it needs to be correct and usable.
3
+ Never: open with preamble or pleasantries; restate the question; add filler transitions; hedge with niceties; or repeat a point you've already made.
4
+ Always: keep essential steps, caveats, uncertainties, and specifics — never drop correctness or a needed warning for brevity. Keep the final answer lean. Use the least structure that conveys it (plain prose when short; lists or code only when they earn their place). If genuinely uncertain, say so and explain why — never omit uncertainty for the sake of brevity.
5
+ If a user request is genuinely ambiguous, ask a sharp question, don't guess.
6
+ {%- endset %} {%- if not _sc %}{%- set _sc = _terse | trim %}{%- else %}{%- set _sc = (_sc | trim) ~ '\n\n' ~ (_terse | trim) %}{%- endif %}{%- if _has_tools %}{{- '<|im_start|>system\n' }}{{- '# Tools\n\nYou have access to the following functions:\n\n<tools>' }}{%- for tool in tools %}{{- '\n' }}{{- tool | tojson }}{%- endfor %}{{- '\n</tools>' }} {%- set tool_instructions %}
7
+ If you choose to call a function ONLY reply in the following format with NO suffix:
8
+
9
+ {%- if _tool_format == 'json' %}
10
+ <think>
11
+ Brief explanation of tool call
12
+ </think>
13
+ <tool_call>
14
+ {"name": "example_function_name", "arguments": {"example_parameter_1": "value_1", "example_parameter_2": "This is the value for the second parameter"}}
15
+ </tool_call>
16
+ {%- else %}
17
+ <think>
18
+ Brief explanation of tool call
19
+ </think>
20
+ <tool_call>
21
+ <function=example_function_name>
22
+ <parameter=example_parameter_1>
23
+ value_1
24
+ </parameter>
25
+ <parameter=example_parameter_2>
26
+ This is the value for the second parameter
27
+ that can span
28
+ multiple lines
29
+ </parameter>
30
+ </function>
31
+ </tool_call>
32
+ {%- endif %}
33
+
34
+ <IMPORTANT>
35
+ Reminder:
36
+ - 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.
37
+ - ALL explanation and reasoning MUST be placed strictly inside the <think></think> block.
38
+ {%- if _tool_format == 'json' %}
39
+ - Function calls MUST follow the specified format: a single JSON object with "name" and "arguments" keys inside <tool_call></tool_call> XML tags.
40
+ {%- else %}
41
+ - Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags.
42
+ {%- endif %}
43
+ - If you choose to call a tool, you MUST output the <tool_call> block IMMEDIATELY after thinking, with NO conversational text before it.
44
+ {%- if _tool_format == 'json' %}
45
+ - The <tool_call> tag MUST be at the very beginning of a new line, with NO spaces or indentation before it.
46
+ {%- else %}
47
+ - The <tool_call> and <function> tags MUST be at the very beginning of a new line, with NO spaces or indentation before them.
48
+ {%- endif %}
49
+ - To call multiple functions, output a separate, completely closed <tool_call></tool_call> block for EACH function. Do NOT nest <tool_call> blocks.
50
+ - If you have all necessary data, provide your final answer directly to the user without any tool call.
51
+ </IMPORTANT>
52
+ {%- endset %} {{- '\n\n' ~ tool_instructions | trim }}{%- if _sc %}{{- '\n\n' + _sc }}{%- endif %}{{- '<|im_end|>\n' }}{%- else %}{%- if _sc %}{{- '<|im_start|>system\n' + _sc + '<|im_end|>\n' }}{%- endif %}{%- endif %}{%- set _last_idx = _msgs | length - 1 %}{%- set ns = namespace(multi_step_tool=true, last_query_index=_last_idx) %}{%- for message in _msgs[::-1] %}{%- set index = (_msgs | length - 1) - loop.index0 %}{%- if ns.multi_step_tool and message.role == 'user' %}{%- set _rc = render_content(message.content, false) | trim %}{%- if not (_rc.startswith('<tool_response>') and _rc.endswith('</tool_response>')) %}{%- set ns.multi_step_tool = false %}{%- set ns.last_query_index = index %}{%- endif %}{%- endif %}{%- endfor %}{%- if ns.multi_step_tool %}{%- if _last_idx > 50 %}{%- set ns.last_query_index = _last_idx %}{%- else %}{%- set ns.last_query_index = 0 %}{%- endif %}{%- endif %}{%- set ns2 = namespace(prev_role='', consecutive_failures=0) %}{%- for message in _msgs %}{%- set is_system = (message.role == "system" or message.role == "developer") %}{%- set content = render_content(message.content, true, is_system) | trim %}{%- if is_system or message.role == 'user' %}{%- if '<|think_off|>' in content %}{%- set ns_state.thinking = false %}{%- set content = content.split('<|think_off|>') | join('') | trim %}{%- elif '<|think_on|>' in content %}{%- set ns_state.thinking = true %}{%- set content = content.split('<|think_on|>') | join('') | trim %}{%- endif %}{%- endif %}{%- if is_system %}{{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}{%- elif message.role == 'user' %}{%- set ns2.consecutive_failures = 0 %}{{- '<|im_start|>user\n' + content + '<|im_end|>\n' }}{%- elif message.role == 'assistant' %}{%- set reasoning_content = '' %}{%- if message.reasoning_content is defined and message.reasoning_content is not none %}{%- if message.reasoning_content is string %}{%- set reasoning_content = message.reasoning_content %}{%- else %}{%- set reasoning_content = message.reasoning_content | string %}{%- endif %}{%- elif message.thinking is defined and message.thinking is not none %}{%- if message.thinking is string %}{%- set reasoning_content = message.thinking %}{%- else %}{%- set reasoning_content = message.thinking | string %}{%- endif %}{%- else %}{%- set _think_end = '' %}{%- if content.startswith('</think>') %}{%- set _think_end = '</think>' %}{%- elif content.startswith('</thinking>') %}{%- set _think_end = '</thinking>' %}{%- elif '\n</think>' in content %}{%- set _think_end = '\n</think>' %}{%- elif '\n</thinking>' in content %}{%- set _think_end = '\n</thinking>' %}{%- elif '\n</ think>' in content %}{%- set _think_end = '\n</ think>' %}{%- elif '\n</think >' in content %}{%- set _think_end = '\n</think >' %}{%- endif %}{%- if _think_end %}{%- if 'thinking' in _think_end %}{%- set _think_start = '<thinking>' %}{%- else %}{%- set _think_start = '<think>' %}{%- endif %}{%- set reasoning_content = content.split(_think_end)[0].rstrip('\n') %}{%- if _think_start in reasoning_content %}{%- set reasoning_content = reasoning_content.split(_think_start)[-1].lstrip('\n') %}{%- endif %}{%- set content = content.split(_think_end)[-1].lstrip('\n') %}{%- endif %}{%- endif %}{%- set reasoning_content = reasoning_content | trim %}{%- if (_preserve_thinking or loop.index0 > ns.last_query_index) and reasoning_content %}{{- '<|im_start|>assistant\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}{%- else %}{{- '<|im_start|>assistant\n' + content }}{%- endif %}{%- if message.tool_calls is defined and message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}{%- for tool_call in message.tool_calls %}{%- if tool_call.function is defined and tool_call.function is not none %}{%- set tc = tool_call.function %}{%- else %}{%- set tc = tool_call %}{%- endif %}{%- if _tool_format == 'json' %}{%- if not loop.first or content | trim %}{{- '\n\n' }}{%- endif %}{%- set _args = '{}' %}{%- if tc.arguments is defined and tc.arguments is not none %}{%- if tc.arguments is mapping %}{%- set _args = tc.arguments | tojson %}{%- elif tc.arguments is string and tc.arguments %}{%- set _args = tc.arguments %}{%- endif %}{%- endif %}{{- '<tool_call>\n{"name": ' }}{{- tc.name | tojson }}{{- ', "arguments": ' }}{{- _args }}{{- '}\n</tool_call>' }}{%- else %}{%- if loop.first %}{%- if content | trim %}{{- '\n\n<tool_call>\n<function=' + tc.name + '>\n' }}{%- else %}{{- '<tool_call>\n<function=' + tc.name + '>\n' }}{%- endif %}{%- else %}{{- '\n\n<tool_call>\n<function=' + tc.name + '>\n' }}{%- endif %}{%- if tc.arguments is defined and tc.arguments is not none %}{%- if tc.arguments is mapping %}{%- for args_name, args_value in tc.arguments.items() %}{{- '<parameter=' + args_name + '>\n' }}{%- if args_value is mapping or (args_value is sequence and args_value is not string) %}{%- set _av = args_value | tojson %}{%- else %}{%- set _av = args_value | string %}{%- endif %}{%- if max_tool_arg_chars > 0 and _av | length > max_tool_arg_chars %}{{- _av[:max_tool_arg_chars] + '\n[TRUNCATED — original length ' ~ (_av | length | string) ~ ' chars]' }}{%- else %}{{- _av }}{%- endif %}{{- '\n</parameter>\n' }}{%- endfor %}{%- elif tc.arguments is string and tc.arguments %}{{- tc.arguments }}{%- endif %}{%- endif %}{{- '</function>\n</tool_call>' }}{%- endif %}{%- endfor %}{%- endif %}{{- '<|im_end|>\n' }}{%- elif message.role == 'tool' %}{%- set _content_lower = content | lower %}{%- set _content_head = _content_lower[:80] %}{%- if content | length < 500 and '$ ' not in content and 'took ' not in _content_lower and ('"error":' in _content_head or 'error:' in _content_head or 'err!' in _content_head or 'fatal:' in _content_head or 'exception:' in _content_head or 'traceback' in _content_head or 'command not found' in _content_head or 'invalid syntax' in _content_head or 'failed to' in _content_head) %}{%- set ns2.consecutive_failures = ns2.consecutive_failures + 1 %}{%- else %}{%- set ns2.consecutive_failures = 0 %}{%- endif %}{%- if ns2.prev_role != 'tool' %}{{- '<|im_start|>user' }}{%- endif %}{%- if max_tool_response_chars > 0 and content | length > max_tool_response_chars %}{%- set content = content[:max_tool_response_chars] + '\n[TRUNCATED — original length ' ~ (content | length | string) ~ ' chars]' %}{%- endif %}{{- '\n<tool_response>\n' + content }}{%- if ns2.consecutive_failures >= 2 %}{{- '\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.' }}{%- elif ns2.consecutive_failures == 1 %}{{- '\n\n⚠️ SYSTEM WARNING: The previous tool call returned an error. Diagnose the failure and retry with completely corrected arguments.' }}{%- endif %}{{- '\n</tool_response>' }}{%- if loop.last %}{{- '<|im_end|>\n' }}{%- else %}{%- set _next_role = _msgs[loop.index0 + 1].role %}{%- if _next_role != 'tool' %}{{- '<|im_end|>\n' }}{%- endif %}{%- endif %}{%- else %}{{- '<|im_start|>user\n[' + message.role + ']: ' + content + '<|im_end|>\n' }}{%- endif %}{%- set ns2.prev_role = message.role %}{%- endfor %}{%- if add_generation_prompt %}{{- '<|im_start|>assistant\n' }}{%- if not ns_state.thinking %}{{- '<think>\n\n</think>\n\n' }}{%- elif ns2.consecutive_failures >= 2 %}{{- '<think>\n\n</think>\n\n' }}{%- else %}{{- '<think>\n' }}{%- endif %}{%- endif %}
plates/sharp_template_plate.png ADDED

Git LFS Details

  • SHA256: d8b975441e50c31b8af39f3357e2fa84788409f8434ddc08946925042a22e0bb
  • Pointer size: 131 Bytes
  • Size of remote file: 250 kB