149 lines
5.0 KiB
Django/Jinja
149 lines
5.0 KiB
Django/Jinja
{{ 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 -%} |