| {{ bos_token }} |
| {%- if enable_thinking is defined -%} |
| {%- if enable_thinking is sameas true -%} |
| {%- set _reasoning_mode = "/think" -%} |
| {%- elif enable_thinking is sameas false -%} |
| {%- set _reasoning_mode = "/nothink" -%} |
| {%- else -%} |
| {%- set _reasoning_mode = enable_thinking -%} |
| {%- endif -%} |
| {%- else -%} |
| {%- set _reasoning_mode = none -%} |
| {%- endif -%} |
| {%- set _custom_instructions = custom_instructions | default(None, true) -%} |
| {%- set _xml_tools_list = xml_tools | default([], true) -%} |
| {%- if tools is defined and tools -%} |
| {%- set _xml_tools_list = tools -%} |
| {%- endif -%} |
| {%- set _python_tools = python_tools | default([], true) -%} |
| {%- set _has_aux_header = (_reasoning_mode is not none) or _custom_instructions or (_xml_tools_list) or (_python_tools) -%} |
| {%- if _has_aux_header -%} |
| <|start_header_id|>system<|end_header_id|> |
| {%- if _reasoning_mode is not none -%} |
| Reasoning: {{ _reasoning_mode }} |
| {%- endif %} |
| {%- if _custom_instructions %} |
| {{ _custom_instructions | trim }} |
| {%- endif %} |
| {% if _xml_tools_list or _python_tools %} |
| {{ " |
| ### Tools |
| " }} |
| You may call one or more functions to assist with the user query. |
| {% if _xml_tools_list %} |
| You are provided with function signatures within <tools> </tools> tags: |
| |
| <tools> |
| {% for tool in _xml_tools_list %} |
| {{ tool | string }}{% if not loop.last %} |
| {% endif %} |
| {% endfor %} |
| </tools> |
| |
| For each function call, pass a json object with function name and arguments within <tool_call> </tool_call> tags: |
| <tool_call> |
| {"name": <function-name>, "arguments": <args-json-object>} |
| </tool_call> |
| |
| {% endif %} |
| {% if _python_tools %} |
| When you send a message containing Python code between <|python_tag|> and <|eom_id|> tags, it will be executed in a stateful Jupyter notebook environment, and you will then be given the output. |
| |
| You can use the following tools in your python code like regular functions: |
| <tools> |
| {% for tool in _python_tools %} |
| {{ tool | string }}{% if not loop.last %} |
| {% endif %} |
| {% endfor %} |
| </tools> |
| {% endif %} |
| {% endif %} |
| <|eot_id|> |
| {%- endif -%} |
| {%- for message in messages -%} |
| {%- set has_tool_calls = message.get('tool_calls') is not none and message.get('tool_calls') -%} |
| {%- if not (message.get('role') in ['tool', 'ipython'] or has_tool_calls) -%} |
| {%- if message.get('role') == 'assistant' -%} |
| <|start_header_id|>assistant<|end_header_id|> |
| {% set content = message.get('content') %} |
| {% if content is string %} |
| {% generation %}{{- content | trim }}<|eot_id|>{% endgeneration %} |
| {% elif content is mapping %} |
| {% generation %}{{- content.get('text', '') | trim }}<|eot_id|>{% endgeneration %} |
| {% elif content is iterable %} |
| {% generation %} |
| {%- for chunk in content -%} |
| {%- if chunk.get('type') == 'text' -%} |
| {{ chunk.get('text', '') | trim }} |
| {%- endif -%} |
| {%- endfor -%} |
| <|eot_id|> |
| {% endgeneration %} |
| {% else %} |
| {% generation %}{% endgeneration %}<|eot_id|> |
| {% endif %} |
| {%- else -%} |
| <|start_header_id|>{{ message['role'] }}<|end_header_id|> |
| {% set content = message.get('content') %} |
| {% if content is string %} |
| {{ content | trim }}<|eot_id|> |
| {% elif content is mapping %} |
| {{ content.get('text', '') | trim }}<|eot_id|> |
| {% elif content is iterable %} |
| {%- for chunk in content -%} |
| {%- if chunk.get('type') == 'text' -%} |
| {{ chunk.get('text', '') | trim }} |
| {%- endif -%} |
| {%- endfor -%}<|eot_id|> |
| {% else %} |
| <|eot_id|> |
| {% endif %} |
| {%- endif -%} |
| |
| {%- elif message.get('role') == 'tool' -%} |
| {%- set _tool_name = message.get('name') -%} |
| {%- set _tool_id = message.get('tool_call_id') -%} |
| {%- set _attr_name = ' name="' ~ _tool_name ~ '"' if _tool_name else '' -%} |
| {%- set _attr_id = ' id="' ~ _tool_id ~ '"' if _tool_id else '' -%} |
| <|start_header_id|>tool<|end_header_id|> |
| <tool_response{{ _attr_name }}{{ _attr_id }}> |
| {%- set tool_content = message.get('content') -%} |
| {%- if tool_content is mapping or (tool_content is iterable and tool_content is not string) -%} |
| {{- tool_content | tojson }} |
| {%- else -%} |
| {{- tool_content if tool_content is not none else '' }} |
| {%- endif -%} |
| </tool_response><|eot_id|> |
| {{- " |
| " -}} |
| {%- elif message.get('role') == 'ipython' -%} |
| <|start_header_id|>ipython<|end_header_id|> |
| {% set ipy_content = message.get('content') %} |
| {% if ipy_content is string %} |
| {{- { "output": ipy_content } | tojson -}} |
| {% elif ipy_content is iterable %} |
| {%- for chunk in ipy_content -%} |
| {%- if chunk.get('type') == 'text' -%} |
| {{- { "output": chunk.get('text', '') } | tojson -}} |
| {%- endif -%} |
| {%- endfor -%} |
| {% else %} |
| {{- { "output": ipy_content } | tojson -}} |
| {% endif %} |
| <|eot_id|> |
| {% elif has_tool_calls -%} |
| {%- if message.tool_calls|length != 1 -%} |
| {{- raise_exception("This template expects exactly one tool call per assistant turn.") -}} |
| {%- endif -%} |
| {%- set tool_call = message.tool_calls[0].function -%} |
| <|start_header_id|>assistant<|end_header_id|> |
| {% generation %} |
| {{- '{"name": "' + tool_call.name + '", "arguments": ' -}} |
| {{- tool_call.arguments | tojson -}} |
| {{- "}" -}}<|eot_id|> |
| {% endgeneration %} |
| {%- endif -%} |
| {%- endfor -%} |
| {%- if add_generation_prompt -%} |
| <|start_header_id|>assistant<|end_header_id|> |
| {% endif -%} |