qgallouedec HF Staff commited on
Commit
b39bd41
·
verified ·
1 Parent(s): 3d9abbb

Upload BeamForCausalLM

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
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ tags:
4
+ - trl
5
+ ---
6
+
7
+ # Tiny BeamForCausalLM
8
+
9
+ This is a minimal model built for unit tests in the [TRL](https://github.com/huggingface/trl) library.
chat_template.jinja ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {#-
2
+ harmony_xml: Harmony wire format with XML tool-call bodies.
3
+
4
+ Channels are `analysis` and `final`; there is no commentary channel. Tools
5
+ are declared as flat TypeScript under `# Tools` and called with
6
+ `<|constrain|>xml` and `rfl:parameter` bodies.
7
+
8
+ Kwargs:
9
+ - model_identity: defaults to "You are Beam, an AI assistant trained by
10
+ Reflection."
11
+ - reasoning_effort: emits `Reasoning effort: N` after the identity line;
12
+ defaults to 512 (`max`) when unset or null. Accepts an int, or the labels
13
+ `minimal`/`low`/`medium`/`high`/`xhigh`/`max` mapped to
14
+ 8/32/64/128/256/512. Other strings raise. `minimal` is 8, the smallest
15
+ effort training sampled: a smaller budget is not respected.
16
+ - builtin_tools: names from `tools=` to render in the system `# Tools` block,
17
+ with their own definitions. Only name `search` and `browse`, and only with
18
+ the definitions Beam was trained with. Every other tool, including a
19
+ `search` or `browse` with a different definition, belongs in the developer
20
+ block, where `tools=` renders it by default.
21
+ Exception: a `bash` tool whose only parameter is an unconstrained `command`
22
+ string is always declared in the system block with the trained definition,
23
+ without this kwarg; its own descriptions are not rendered. A `bash` with
24
+ any other call shape follows the rule above.
25
+ - allow_missing_thinking: defaults to true. When false, a generation prompt
26
+ raises when any assistant turn has empty or no reasoning, since dropping it
27
+ degrades the model's output. Setting it to false is highly recommended for
28
+ serving.
29
+
30
+ OpenAI roles "system" and "developer" are equivalent and map to the developer
31
+ `# Instructions` block. Consecutive ones at the start of `messages` join into
32
+ that one block, a blank line apart; empty content is omitted. A system or
33
+ developer message after the first message of another role is not rendered.
34
+ The Reflection system block is injected before the developer block.
35
+
36
+ Tool wire:
37
+ - Calls: `to={name}` + analysis + `<|constrain|>xml` + rfl: body
38
+ - Results: `{recipient} to=assistant` on analysis
39
+ - Parallel calls: `<|end|>` between calls, `<|call|>` on the last
40
+ - `function.arguments` must be a dict (parse JSON strings before apply)
41
+ -#}
42
+
43
+ {%- macro ts_type_name(type_val) -%}
44
+ {%- if type_val == "integer" -%}
45
+ {{- "number" -}}
46
+ {%- elif type_val in ["string", "number", "boolean"] -%}
47
+ {{- type_val -}}
48
+ {%- else -%}
49
+ {{- "any" -}}
50
+ {%- endif -%}
51
+ {%- endmacro -%}
52
+
53
+ {#- Property defaults render enum strings bare. Generic `oneOf` variants pass
54
+ false because the reference renderer quotes them in that path. #}
55
+ {%- macro render_default(schema, bare_enum_string=true) -%}
56
+ {%- set is_enum = schema.get("enum") is sequence and schema.get("enum") is not string and schema.get("enum") -%}
57
+ {%- if schema.default is string and (not is_enum or not bare_enum_string) -%}
58
+ {{- '"' + schema.default + '"' -}}
59
+ {%- elif schema.default is string -%}
60
+ {{- schema.default -}}
61
+ {%- else -%}
62
+ {{- schema.default | tojson(separators=(",", ":")) -}}
63
+ {%- endif -%}
64
+ {%- endmacro -%}
65
+
66
+ {#- The reference renderer checks the complete rendered text for `null`, so
67
+ this intentionally does the same rather than inspecting schema members. #}
68
+ {%- macro render_nullable_type(schema, indent) -%}
69
+ {%- set rendered = json_schema_to_typescript(schema, indent) -%}
70
+ {{- rendered -}}
71
+ {%- if schema is mapping and schema.get("nullable") and "null" not in rendered -%}
72
+ {{- " | null" -}}
73
+ {%- endif -%}
74
+ {%- endmacro -%}
75
+
76
+ {#- Render a JSON-schema node as a TypeScript type.
77
+
78
+ `indent` is the leading spaces for properties inside an object; nested
79
+ objects bump it by 4. Use `schema["items"]` (not `schema.items`), since
80
+ attribute access would hit dict.items. #}
81
+ {%- macro json_schema_to_typescript(schema, indent=0) -%}
82
+ {%- if schema is mapping and schema.get("oneOf") is sequence and schema.get("oneOf") is not string -%}
83
+ {%- for variant in schema.oneOf -%}
84
+ {{- "\n" + (" " * indent) + " | " -}}
85
+ {{- render_nullable_type(variant, indent + 3) -}}
86
+ {%- if variant is mapping and variant.get("description") is string -%}
87
+ {{- " // " + variant.description -}}
88
+ {%- if "default" in variant -%}
89
+ {{- " default: " + render_default(variant, false) -}}
90
+ {%- endif -%}
91
+ {%- elif variant is mapping and "default" in variant -%}
92
+ {{- " // default: " + render_default(variant, false) -}}
93
+ {%- endif -%}
94
+ {%- endfor -%}
95
+ {#- Only a string enum becomes a literal union. An integer or untyped enum
96
+ falls through to its plain type, or to `any` when it has none. #}
97
+ {%- elif schema is mapping and schema.get("enum") is sequence and schema.get("enum") is not string and schema.get("enum") and schema.get("type") == "string" -%}
98
+ {%- set rendered_enum = namespace(any=false) -%}
99
+ {%- for val in schema.enum -%}
100
+ {%- if val is string -%}
101
+ {%- if rendered_enum.any %} | {% endif -%}
102
+ {{- val | tojson -}}
103
+ {%- set rendered_enum.any = true -%}
104
+ {%- endif -%}
105
+ {%- endfor -%}
106
+ {%- if not rendered_enum.any %}string{%- endif -%}
107
+ {%- elif schema is mapping and schema.get("type") == "object" -%}
108
+ {%- if schema.get("description") is string -%}
109
+ {{- (" " * indent) + "// " + schema.description + "\n" -}}
110
+ {%- endif -%}
111
+ {{- "{\n" -}}
112
+ {%- set required = schema.required if schema.get("required") else [] -%}
113
+ {%- if schema.get("properties") -%}
114
+ {#- Properties render in insertion order, so a schema controls the
115
+ order its parameters appear in. #}
116
+ {%- for prop_name, prop_spec in schema.properties.items() -%}
117
+ {%- if prop_spec is mapping and prop_spec.get("title") is string -%}
118
+ {{- (" " * indent) + "// " + prop_spec.title + "\n" -}}
119
+ {{- (" " * indent) + "//\n" -}}
120
+ {%- endif -%}
121
+ {%- if prop_spec is mapping and "oneOf" not in prop_spec and prop_spec.get("description") is string -%}
122
+ {{- (" " * indent) + "// " + prop_spec.description + "\n" -}}
123
+ {%- endif -%}
124
+ {%- if prop_spec is mapping and prop_spec.get("examples") is sequence and prop_spec.get("examples") is not string and prop_spec.get("examples") -%}
125
+ {{- (" " * indent) + "// Examples:\n" -}}
126
+ {%- for example in prop_spec.examples -%}
127
+ {%- if example is string -%}
128
+ {{- (" " * indent) + '// - "' + example + '"\n' -}}
129
+ {%- endif -%}
130
+ {%- endfor -%}
131
+ {%- endif -%}
132
+ {%- if prop_spec is mapping and prop_spec.get("oneOf") is sequence and prop_spec.get("oneOf") is not string -%}
133
+ {%- set property_description = prop_spec.get("description") if prop_spec.get("description") is string else none -%}
134
+ {%- set first_variant = prop_spec.oneOf[0] if prop_spec.oneOf else {} -%}
135
+ {%- set first_description = first_variant.get("description") if first_variant is mapping and first_variant.get("description") is string else none -%}
136
+ {%- set render_property_description = property_description and property_description != first_description -%}
137
+ {%- if render_property_description -%}
138
+ {{- (" " * indent) + "// " + property_description + "\n" -}}
139
+ {%- endif -%}
140
+ {%- if "default" in prop_spec -%}
141
+ {{- (" " * indent) + "// default: " + render_default(prop_spec) + "\n" -}}
142
+ {%- endif -%}
143
+ {{- (" " * indent) + prop_name -}}
144
+ {%- if prop_name not in required -%}?{%- endif -%}
145
+ {{- ":\n" -}}
146
+ {%- for variant in prop_spec.oneOf -%}
147
+ {{- (" " * indent) + " | " -}}
148
+ {{- render_nullable_type(variant, indent + 3) -}}
149
+ {%- set render_variant_description = variant is mapping and variant.get("description") is string and variant.description != property_description and not (loop.first and render_property_description) -%}
150
+ {%- if render_variant_description -%}
151
+ {{- " // " + variant.description -}}
152
+ {%- if "default" in variant -%}
153
+ {{- " default: " + render_default(variant) -}}
154
+ {%- endif -%}
155
+ {%- elif variant is mapping and "default" in variant -%}
156
+ {{- " // default: " + render_default(variant) -}}
157
+ {%- endif -%}
158
+ {{- "\n" -}}
159
+ {%- endfor -%}
160
+ {{- (" " * indent) + ",\n" -}}
161
+ {%- else -%}
162
+ {{- (" " * indent) + prop_name -}}
163
+ {%- if prop_name not in required -%}?{%- endif -%}
164
+ {{- ": " -}}
165
+ {{- render_nullable_type(prop_spec, indent + 4) -}}
166
+ {{- "," -}}
167
+ {%- if prop_spec is mapping and "default" in prop_spec -%}
168
+ {{- " // default: " + render_default(prop_spec) -}}
169
+ {%- endif -%}
170
+ {{- "\n" -}}
171
+ {%- endif -%}
172
+ {%- endfor -%}
173
+ {%- endif -%}
174
+ {{- (" " * indent) + "}" -}}
175
+ {%- elif schema is mapping and schema.get("type") == "array" -%}
176
+ {%- if schema.get("items") -%}
177
+ {{- json_schema_to_typescript(schema["items"], indent) + "[]" -}}
178
+ {%- else -%}
179
+ {{- "Array<any>" -}}
180
+ {%- endif -%}
181
+ {%- elif schema is mapping and schema.get("type") is string -%}
182
+ {{- ts_type_name(schema.type) -}}
183
+ {%- elif schema is mapping and schema.get("type") is sequence -%}
184
+ {%- set rendered_types = namespace(any=false) -%}
185
+ {%- for ty in schema.type -%}
186
+ {%- if ty is string -%}
187
+ {%- if rendered_types.any %} | {% endif -%}
188
+ {%- if ty == "integer" %}number{%- else %}{{ ty }}{%- endif -%}
189
+ {%- set rendered_types.any = true -%}
190
+ {%- endif -%}
191
+ {%- endfor -%}
192
+ {%- if not rendered_types.any %}any{%- endif -%}
193
+ {%- else -%}
194
+ {{- "any" -}}
195
+ {%- endif -%}
196
+ {%- endmacro -%}
197
+
198
+ {#- String-schema tools declare as `## name`; every other tool declares as
199
+ `type name = (_: {...}) => any;`. Call sites emit XML either way. #}
200
+ {%- macro render_tool_declaration(tool) -%}
201
+ {%- set tool = tool.function if tool.function is defined else tool -%}
202
+ {%- if tool.parameters is mapping and tool.parameters.get("type") == "string" and (not tool.parameters.get("properties")) -%}
203
+ {{- "## " + tool.name + "\n\n" -}}
204
+ {{- tool.description or "" -}}
205
+ {%- else -%}
206
+ {%- if tool.description -%}
207
+ {%- for line in tool.description.split("\n") -%}
208
+ {{- "// " + line + "\n" -}}
209
+ {%- endfor -%}
210
+ {%- endif -%}
211
+ {#- A tool with no parameters keeps the `(_: ...)` form and renders
212
+ `(_: any)`. #}
213
+ {{- "type " + tool.name + " = (_: " + json_schema_to_typescript(tool.parameters) + ") => any;" -}}
214
+ {%- endif -%}
215
+ {%- endmacro -%}
216
+
217
+ {%- macro render_tools_section(tools) -%}
218
+ {{- "# Tools\n\n" -}}
219
+ {%- for tool in tools -%}
220
+ {{- render_tool_declaration(tool) -}}
221
+ {%- if not loop.last -%}
222
+ {{- "\n\n" -}}
223
+ {%- endif -%}
224
+ {%- endfor -%}
225
+ {%- endmacro -%}
226
+
227
+ {#- String values go out as-is; non-strings are JSON-encoded in their given
228
+ order, at every depth. Jinja's `tojson` sorts keys by default, so mappings
229
+ and sequences recurse through this macro instead of being handed to it. #}
230
+ {%- macro render_json_value(value) -%}
231
+ {%- if value is mapping -%}
232
+ {{- "{" -}}
233
+ {%- for k, v in value.items() -%}
234
+ {{- k | tojson }}: {{ render_json_value(v) -}}
235
+ {%- if not loop.last %}, {% endif -%}
236
+ {%- endfor -%}
237
+ {{- "}" -}}
238
+ {%- elif value is sequence and value is not string -%}
239
+ {{- "[" -}}
240
+ {%- for item in value -%}
241
+ {{- render_json_value(item) -}}
242
+ {%- if not loop.last %}, {% endif -%}
243
+ {%- endfor -%}
244
+ {{- "]" -}}
245
+ {%- else -%}
246
+ {{- value | tojson -}}
247
+ {%- endif -%}
248
+ {%- endmacro -%}
249
+
250
+ {%- macro render_parameter_value(value) -%}
251
+ {%- if value is string -%}
252
+ {{- value -}}
253
+ {%- else -%}
254
+ {{- render_json_value(value) -}}
255
+ {%- endif -%}
256
+ {%- endmacro -%}
257
+
258
+ {%- macro render_tool_call_body(tool_call) -%}
259
+ {%- set fn = tool_call.function if tool_call.function is defined else tool_call -%}
260
+ {%- set args = fn.arguments if fn.arguments is defined else tool_call.arguments -%}
261
+ {%- if args is mapping -%}
262
+ {%- for param_name in args -%}
263
+ {%- set value_text = render_parameter_value(args[param_name]) -%}
264
+ {%- if "</rfl:parameter>" in value_text -%}
265
+ {{- raise_exception("Tool-call parameter '" + (param_name | string) + "' contains the reserved delimiter </rfl:parameter>") }}
266
+ {%- endif -%}
267
+ {%- if not loop.first %}{{- "\n" }}{%- endif -%}
268
+ {{- '<rfl:parameter name="' + param_name + '">\n' -}}
269
+ {{- value_text -}}
270
+ {{- '\n</rfl:parameter>' -}}
271
+ {%- endfor -%}
272
+ {%- elif args is defined and args is not none -%}
273
+ {{- raise_exception("function.arguments must be a dict; parse JSON strings before apply_chat_template") }}
274
+ {%- endif -%}
275
+ {%- endmacro -%}
276
+
277
+ {%- macro build_system_message(builtin_tool_definitions) -%}
278
+ {%- if model_identity is not defined %}
279
+ {%- set model_identity = "You are Beam, an AI assistant trained by Reflection." %}
280
+ {%- endif %}
281
+ {{- model_identity -}}
282
+ {#- Served default: effort 512 (`max`) when the kwarg is unset or null. #}
283
+ {%- if reasoning_effort is not defined or reasoning_effort is none %}
284
+ {%- set reasoning_effort = 512 %}
285
+ {%- endif %}
286
+ {%- if reasoning_effort is string %}
287
+ {%- if reasoning_effort == "minimal" %}
288
+ {%- set reasoning_effort = 8 %}
289
+ {%- elif reasoning_effort == "low" %}
290
+ {%- set reasoning_effort = 32 %}
291
+ {%- elif reasoning_effort == "medium" %}
292
+ {%- set reasoning_effort = 64 %}
293
+ {%- elif reasoning_effort == "high" %}
294
+ {%- set reasoning_effort = 128 %}
295
+ {%- elif reasoning_effort == "xhigh" %}
296
+ {%- set reasoning_effort = 256 %}
297
+ {%- elif reasoning_effort == "max" %}
298
+ {%- set reasoning_effort = 512 %}
299
+ {%- else %}
300
+ {{- raise_exception("reasoning_effort must be an int or one of: minimal, low, medium, high, xhigh, max") }}
301
+ {%- endif %}
302
+ {%- endif %}
303
+ {{- "\n\nReasoning effort: " + (reasoning_effort | string) }}
304
+ {%- if builtin_tool_definitions -%}
305
+ {{- "\n\n" -}}
306
+ {{- render_tools_section(builtin_tool_definitions) -}}
307
+ {%- endif -%}
308
+ {{- "\n\n# Valid channels: analysis, final. Channel must be included for every message." -}}
309
+ {%- endmacro -%}
310
+
311
+ {%- if not messages %}{{ raise_exception("messages cannot be empty") }}{%- endif %}
312
+
313
+ {#- `tools=` remains the serving engine's complete tool registry. The names in
314
+ `builtin_tools` only select which definitions move into the system block. #}
315
+ {%- set builtin_tool_names = builtin_tools | default([], true) -%}
316
+ {#- Training declares `bash` in the system block with this definition, so a
317
+ `bash` whose only parameter is an unconstrained `command` string is declared
318
+ with it. Only descriptions and `additionalProperties` may differ, since they
319
+ leave the accepted calls the same; any schema key that constrains the call
320
+ keeps the supplied definition in the developer block. An omitted `required`
321
+ is declared as required: every call the trained declaration invites is one
322
+ the supplied schema accepts. #}
323
+ {%- set trained_bash_tool = {
324
+ "name": "bash",
325
+ "description": "Execute a bash command. The output contains the command's stdout and stderr.\nCommands time out after 10 minutes. You can set a shorter timeout within the bash command.",
326
+ "parameters": {
327
+ "type": "object",
328
+ "properties": {"command": {"type": "string", "description": "The command to execute"}},
329
+ "required": ["command"],
330
+ },
331
+ } -%}
332
+ {%- set tool_groups = namespace(builtin=[], regular=[]) -%}
333
+ {%- for tool in tools | default([], true) -%}
334
+ {%- set tool_definition = tool.function if tool.function is defined else tool -%}
335
+ {%- set tool_name = tool_definition.name -%}
336
+ {%- set tool_parameters = tool_definition.parameters if tool_definition.parameters is mapping else {} -%}
337
+ {%- set tool_properties = tool_parameters.properties if tool_parameters.properties is mapping else {} -%}
338
+ {%- set bash_shape = namespace(plain=true) -%}
339
+ {%- for key in tool_parameters -%}
340
+ {%- if key not in ["type", "properties", "required", "additionalProperties", "description"] -%}
341
+ {%- set bash_shape.plain = false -%}
342
+ {%- endif -%}
343
+ {%- endfor -%}
344
+ {%- set command_schema = tool_properties.command if tool_properties.command is mapping else {} -%}
345
+ {%- for key in command_schema -%}
346
+ {%- if key not in ["type", "description"] -%}
347
+ {%- set bash_shape.plain = false -%}
348
+ {%- endif -%}
349
+ {%- endfor -%}
350
+ {%- set is_trained_bash = tool_name == "bash"
351
+ and bash_shape.plain
352
+ and tool_parameters.get("type") == "object"
353
+ and (tool_properties | list) == ["command"]
354
+ and command_schema.get("type") == "string"
355
+ and tool_parameters.get("required", ["command"]) == ["command"] -%}
356
+ {%- if is_trained_bash -%}
357
+ {%- set tool_groups.builtin = tool_groups.builtin + [trained_bash_tool] -%}
358
+ {%- elif tool_name in builtin_tool_names -%}
359
+ {%- set tool_groups.builtin = tool_groups.builtin + [tool] -%}
360
+ {%- else -%}
361
+ {%- set tool_groups.regular = tool_groups.regular + [tool] -%}
362
+ {%- endif -%}
363
+ {%- endfor -%}
364
+
365
+ {{- "<|start|>system<|message|>" }}
366
+ {{- build_system_message(tool_groups.builtin) }}
367
+ {{- "<|end|>" }}
368
+
369
+ {#- The leading run of system/developer messages joins, a blank line apart,
370
+ into the one `# Instructions` block. Empty content counts as absent, so a
371
+ run with no content emits no `# Instructions`. #}
372
+ {%- set leading_instructions = namespace(count=0, parts=[]) %}
373
+ {%- for message in messages %}
374
+ {%- if loop.index0 == leading_instructions.count and message.role in ["system", "developer"] %}
375
+ {%- set leading_instructions.count = leading_instructions.count + 1 %}
376
+ {%- if message.content %}
377
+ {%- set leading_instructions.parts = leading_instructions.parts + [message.content] %}
378
+ {%- endif %}
379
+ {%- endif %}
380
+ {%- endfor %}
381
+ {%- set developer_message = leading_instructions.parts | join("\n\n") %}
382
+ {%- set loop_messages = messages[leading_instructions.count:] %}
383
+
384
+ {%- if add_generation_prompt and allow_missing_thinking is defined and allow_missing_thinking == false %}
385
+ {%- for message in loop_messages %}
386
+ {%- if message.role == 'assistant' and not (message.thinking or message.reasoning_content or message.reasoning) %}
387
+ {{- raise_exception("The assistant turn at messages[" + ((loop.index0 + leading_instructions.count) | string) + "] is missing its reasoning. Dropping reasoning from earlier turns degrades this model's output. Send it back in 'reasoning_content', or set allow_missing_thinking=true to skip this check.") }}
388
+ {%- endif %}
389
+ {%- endfor %}
390
+ {%- endif %}
391
+
392
+ {%- set has_tools = tool_groups.regular %}
393
+
394
+ {%- if developer_message or has_tools %}
395
+ {{- "<|start|>developer<|message|>" }}
396
+ {%- if developer_message %}
397
+ {{- "# Instructions\n\n" }}
398
+ {{- developer_message }}
399
+ {%- if has_tools %}
400
+ {{- "\n\n" }}
401
+ {%- endif %}
402
+ {%- endif %}
403
+ {%- if has_tools %}
404
+ {{- render_tools_section(tool_groups.regular) }}
405
+ {%- endif %}
406
+ {{- "<|end|>" }}
407
+ {%- endif %}
408
+
409
+ {%- set tool_call_registry = namespace(entries=[]) %}
410
+
411
+ {%- for message in loop_messages -%}
412
+ {%- if message.role == 'assistant' -%}
413
+ {%- if message.content %}
414
+ {%- if "<|channel|>analysis<|message|>" in message.content or "<|channel|>final<|message|>" in message.content %}
415
+ {{- raise_exception("Pass plain text in API fields, not Harmony wire tags. Use 'thinking' for analysis and 'content' for final.") }}
416
+ {%- endif %}
417
+ {%- endif %}
418
+ {%- set thinking_text = message.thinking or message.reasoning_content or message.reasoning %}
419
+ {%- if thinking_text %}
420
+ {%- if "<|channel|>analysis<|message|>" in thinking_text or "<|channel|>final<|message|>" in thinking_text %}
421
+ {{- raise_exception("Pass plain text in 'thinking'/'reasoning_content'/'reasoning' without Harmony wire tags.") }}
422
+ {%- endif %}
423
+ {%- endif %}
424
+ {{- "<|start|>assistant" }}
425
+ {%- generation %}
426
+ {{- "<|channel|>analysis<|message|>" + (thinking_text or "") + "<|end|>" }}
427
+ {%- if message.tool_calls %}
428
+ {%- for tool_call in message.tool_calls %}
429
+ {%- set fn = tool_call.function if tool_call.function is defined else tool_call %}
430
+ {%- set tool_name = fn.name if fn.name is defined else tool_call.name %}
431
+ {%- set call_id = tool_call.id if tool_call.id is defined else (fn.id if fn.id is defined else none) %}
432
+ {%- if call_id and tool_name %}
433
+ {%- set tool_call_registry.entries = tool_call_registry.entries + [{"id": call_id, "name": tool_name}] %}
434
+ {%- endif %}
435
+ {{- "<|start|>assistant to=" + tool_name + "<|channel|>analysis <|constrain|>xml<|message|>" }}
436
+ {{- render_tool_call_body(tool_call) }}
437
+ {%- if loop.last %}
438
+ {{- "<|call|>" }}
439
+ {%- else %}
440
+ {{- "<|end|>" }}
441
+ {%- endif %}
442
+ {%- endfor %}
443
+ {%- else %}
444
+ {{- "<|start|>assistant<|channel|>final<|message|>" + (message.content or "") + "<|return|>" }}
445
+ {%- endif %}
446
+ {%- endgeneration %}
447
+ {%- elif message.role == 'tool' -%}
448
+ {%- set resolved_tool = namespace(name=none) %}
449
+ {%- if message.name is defined and message.name %}
450
+ {%- set resolved_tool.name = message.name %}
451
+ {%- elif message.tool_call_id is defined %}
452
+ {%- for entry in tool_call_registry.entries %}
453
+ {%- if entry.id == message.tool_call_id %}
454
+ {%- set resolved_tool.name = entry.name %}
455
+ {%- endif %}
456
+ {%- endfor %}
457
+ {%- endif %}
458
+ {%- if resolved_tool.name is none %}
459
+ {{- raise_exception("Tool message needs 'name' or a matching prior tool_call 'id' / 'tool_call_id'.") }}
460
+ {%- endif %}
461
+ {{- "<|start|>" + resolved_tool.name + " to=assistant<|channel|>analysis<|message|>" + (message.content or "") + "<|end|>" }}
462
+ {%- elif message.role == 'user' -%}
463
+ {{- "<|start|>user<|message|>" + (message.content or "") + "<|end|>" }}
464
+ {%- endif -%}
465
+ {%- endfor -%}
466
+
467
+ {%- if add_generation_prompt -%}
468
+ <|start|>assistant
469
+ {%- endif -%}
config.json ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "BeamForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": null,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": null,
10
+ "final_logit_softcapping": 30.0,
11
+ "head_dim": 16,
12
+ "hidden_act": "silu",
13
+ "hidden_size": 16,
14
+ "initializer_range": 0.02,
15
+ "intermediate_size": 32,
16
+ "layer_types": [
17
+ "sliding_attention",
18
+ "sliding_attention",
19
+ "sliding_attention",
20
+ "full_attention"
21
+ ],
22
+ "max_position_embeddings": 1048576,
23
+ "mlp_layer_types": [
24
+ "dense",
25
+ "sparse",
26
+ "sparse",
27
+ "sparse"
28
+ ],
29
+ "model_type": "beam",
30
+ "moe_intermediate_size": 8,
31
+ "n_group": 2,
32
+ "norm_topk_prob": true,
33
+ "num_attention_heads": 4,
34
+ "num_experts": 8,
35
+ "num_experts_per_tok": 2,
36
+ "num_hidden_layers": 4,
37
+ "num_key_value_heads": 2,
38
+ "output_router_logits": false,
39
+ "pad_token_id": null,
40
+ "rms_norm_eps": 1e-06,
41
+ "rope_parameters": {
42
+ "full_attention": null,
43
+ "sliding_attention": {
44
+ "rope_theta": 10000.0,
45
+ "rope_type": "default"
46
+ }
47
+ },
48
+ "routed_scaling_factor": 2.5,
49
+ "sliding_window": 4,
50
+ "tie_word_embeddings": false,
51
+ "topk_group": 1,
52
+ "transformers_version": "5.20.1",
53
+ "use_cache": true,
54
+ "vocab_size": 151936
55
+ }
generation_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "do_sample": true,
3
+ "eos_token_id": [
4
+ 151674,
5
+ 151675
6
+ ],
7
+ "pad_token_id": 151643,
8
+ "repetition_penalty": 1.0,
9
+ "temperature": 0.7,
10
+ "top_p": 0.99,
11
+ "transformers_version": "5.20.1"
12
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:811108f9e0c659bd3eabd37be34cf05e3260161dc87ee3d07b860aee87413cb4
3
+ size 9795072
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5b212650ed1a8f4a303b4e9aa3be080f44bf5cc1a2b0ee7828f3be7d5211a130
3
+ size 11424939
tokenizer_config.json ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": null,
4
+ "eos_token": "<|return|>",
5
+ "extra_special_tokens": [],
6
+ "is_local": false,
7
+ "local_files_only": false,
8
+ "model_max_length": 1048576,
9
+ "pad_token": "<|endoftext|>",
10
+ "reflection_grammar_version": "harmony_xml",
11
+ "response_template": {
12
+ "defaults": {
13
+ "role": "assistant"
14
+ },
15
+ "fields": {
16
+ "content": {
17
+ "close": [
18
+ "<|return|>",
19
+ "<|end|>",
20
+ "<|call|>"
21
+ ],
22
+ "content": "text",
23
+ "open": "<|channel|>final<|message|>"
24
+ },
25
+ "thinking": {
26
+ "close": [
27
+ "<|end|><|start|>assistant",
28
+ "<|constrain|><|start|>assistant",
29
+ "<|start|>assistant"
30
+ ],
31
+ "content": "text",
32
+ "open": "<|channel|>analysis<|message|>"
33
+ },
34
+ "tool_calls": {
35
+ "close": [
36
+ "<|end|><|start|>assistant",
37
+ "<|call|>"
38
+ ],
39
+ "content": "xml-inline",
40
+ "content_args": {
41
+ "tag_pattern": "<rfl:parameter name=\"(?P<key>[^\"]+)\">\\n(?P<value>.*?)\\n(?:</rfl:parameter>|(?=<rfl:parameter name=\"))",
42
+ "value_parser": {
43
+ "args": {
44
+ "strip": false
45
+ },
46
+ "name": "text"
47
+ }
48
+ },
49
+ "open_pattern": " to=(?P<name>[^\\s<]+)<\\|channel\\|>analysis <\\|constrain\\|>xml<\\|message\\|>",
50
+ "repeats": true,
51
+ "transform": {
52
+ "function": {
53
+ "arguments": "{content}",
54
+ "name": "{name}"
55
+ },
56
+ "type": "function"
57
+ }
58
+ }
59
+ },
60
+ "start_anchor_pattern": "<\\|start\\|>assistant"
61
+ },
62
+ "tokenizer_class": "TokenizersBackend",
63
+ "unk_token": null
64
+ }