{#
Harness-neutral nanochat chat template.
Training adapters normalize tool turns into assistant content parts:
text, tool_call (JSON text), and tool_output (JSON text). The call JSON keeps
the source call ID, tool name, and arguments; the tool menu comes from `tools`.
<|bos|> is added by the tokenizer and must not be emitted here.
#}
{%- set system = messages[0]['content'] if messages and messages[0]['role'] == 'system' else '' -%}
{%- set ns = namespace(first_user=true) -%}
{%- for message in messages -%}
{%- if message['role'] == 'user' -%}
{{ '<|user_start|>' }}{%- if ns.first_user and tools %}{{ tools|tojson }}{{ '\n\n' }}{%- endif -%}{%- if ns.first_user and system %}{{ system + '\n\n' }}{%- endif -%}{{ message['content'] }}{{ '<|user_end|>' }}{%- set ns.first_user = false -%}
{%- elif message['role'] == 'assistant' -%}
{{ '<|assistant_start|>' }}{%- if message['content'] is string -%}{{ message['content'] }}{%- else -%}{%- for part in message['content'] -%}{%- if part['type'] == 'text' -%}{{ part['text'] }}{%- elif part['type'] == 'python' -%}{{ '<|python_start|>' + part['text'] + '<|python_end|>' }}{%- elif part['type'] == 'python_output' -%}{{ '<|output_start|>' + part['text'] + '<|output_end|>' }}{%- elif part['type'] == 'tool_call' -%}{{ '' + part['text'] + '' }}{%- elif part['type'] == 'tool_output' -%}{{ '<|output_start|>' + part['text'] + '<|output_end|>' }}{%- endif -%}{%- endfor -%}{%- endif -%}{{ '<|assistant_end|>' }}
{%- endif -%}
{%- endfor -%}
{%- if add_generation_prompt -%}{{ '<|assistant_start|>' }}{%- endif -%}