Custom / chat_template.jinja
igorktech's picture
Training in progress, step 200
e12281e verified
{{ bos_token }}
{%- if messages[0]['role'] == 'system' -%}
{%- if messages[0]['content'] is string -%}
{%- set first_user_prefix = messages[0]['content'] + '
' -%}
{%- else -%}
{%- set first_user_prefix = messages[0]['content'][0]['text'] + '
' -%}
{%- endif -%}
{%- set loop_messages = messages[1:] -%}
{%- else -%}
{%- set first_user_prefix = '' -%}
{%- set loop_messages = messages -%}
{%- endif -%}
{# Inject tools definitions here if available #}
{%- if tools -%}
{#– Serialize all tools into one JSON blob, separated by newlines –#}
{%- set tools_json = tools | map('tojson') | join('
') -%}
{#– Append the entire block to first_user_prefix in one go –#}
{%- set first_user_prefix = first_user_prefix
~ "# Tools
"
~ "You may call one or more functions to assist with the user query.
"
~ "You are provided with function signatures within `<tools>` XML tags:
"
~ "<tools>
"
~ tools_json
~ "
</tools>
"
~ "For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
"
~ "<tool_call>
"
~ '{"name": <function-name>, "arguments": <args-json-object>}'
~ "
</tool_call>
"
-%}
{%- endif -%}
{# Identify where to insert optional tool segments #}
{%- set ns = namespace(multi_step_tool=true, last_query_index=loop_messages|length - 1) -%}
{%- for msg in loop_messages[::-1] -%}
{%- set idx = (loop_messages|length - 1) - loop.index0 -%}
{%- if ns.multi_step_tool and msg['role']=='user' and msg['content'] is string and not (msg['content'].startswith('<tool_response>') and msg['content'].endswith('</tool_response>')) -%}
{%- set ns.multi_step_tool = false -%}
{%- set ns.last_query_index = idx -%}
{%- endif -%}
{%- endfor -%}
{# Render each message turn #}
{%- for message in loop_messages -%}
{%- set role = "model" if message.role == 'assistant' else message.role -%}
{{ '<start_of_turn>' ~ role ~ "
" ~ (first_user_prefix if loop.first else "") -}}
{%- if message.content is string -%}
{%- set content = message.content -%}
{%- elif message.content is iterable -%}
{%- set content = '' -%}
{%- for item in message.content -%}
{%- if item.type == 'text' -%}
{%- set content = content + item.text -%}
{%- elif item.type == 'image' -%}
{%- set content = content + '<image_soft_token>' -%}
{%- elif item.type == 'audio' -%}
{%- set content = content + '<audio_soft_token>' -%}
{%- endif -%}
{%- endfor -%}
{%- else -%}
{{ raise_exception("Invalid content type: " ~ message.role) }}
{%- endif -%}
{# Render by role #}
{%- if message.role == 'tool' -%}
{{ '<tool_response>
' + content + '
</tool_response>' }}
{%- elif message.role == 'assistant' -%}
{{ content }}
{# Append any tool_calls #}
{%- if message.tool_calls -%}
{%- for tool_call in message.tool_calls -%}
{%- if (loop.first and content) or (not loop.first) -%}
{{- '
' }}
{%- endif -%}
{%- if tool_call.function -%}
{%- set tool_call = tool_call.function -%}
{%- endif -%}
{{- '<tool_call>
{"name": "' }}
{{- tool_call.name }}
{{- '", "arguments": ' }}
{%- if tool_call.arguments is string -%}
{{- tool_call.arguments }}
{%- else -%}
{{- tool_call.arguments | tojson }}
{%- endif -%}
{{- '}
</tool_call>' }}
{%- endfor -%}
{%- endif -%}
{%- else -%}
{{ content }}
{%- endif -%}
{{ '<end_of_turn>
' }}
{%- endfor -%}
{%- if add_generation_prompt -%}
{{ '<start_of_turn>model
' }}
{%- endif -%}