{{- bos_token }}
{%- if custom_tools is defined %}
    {%- set tools = custom_tools %}
{%- endif %}
{%- if not tools_in_user_message is defined %}
    {%- set tools_in_user_message = false %}
{%- endif %}
{%- if not tools is defined %}
    {%- set tools = none %}
{%- endif %}

{#- This block extracts the system message, so we can slot it into the right place. #}
{%- if messages[0]['role'] == 'system' %}
    {%- if messages[0]['content'] is string %}
        {%- set system_message = messages[0]['content']|trim %}
    {%- else %}
        {%- set system_message = messages[0]['content'][0]['text']|trim %}
    {%- endif %}
    {%- set messages = messages[1:] %}
{%- else %}
    {%- if tools is not none %}
        {#- Add default tool system message when tools are provided #}
        {%- set system_message = "You are a helpful assistant with tool calling "
            "capabilities. Only reply with a tool call if the function exists in the "
            "library provided by the user. If it doesn't exist, just reply directly in "
            "natural language. When you receive a tool call response, use the output to "
            "format an answer to the original user question." %}
    {%- else %}
        {%- set system_message = "" %}
    {%- endif %}
{%- endif %}

{#- System message if the user supplied one, or if tools are used (default tool system message) #}
{%- if system_message %}
    {#- always use user provided system message to override default tool system message #}
    {{- "<|header_start|>system<|header_end|>\n\n" }}
    {{- system_message }}
    {%- if tools is not none and not tools_in_user_message %}
        {{- "Tools: You have access to the following tools. You might need to use one "
            "or more function/tool calls to fulfill the task. \n"
            "If none are needed, then proceed to the response.\n\n"
            "Tool Call Syntax: You can call tools using the following syntax:\n"
            "[func_name1(params_name1=params_value1, params_name2=params_value2, ...), ...]\n"
            "Do not include anything else when calling the tools with the syntax above.\n\n"
            "Here is a list of functions in JSON format that you can invoke.\n " }}
        {%- for t in tools %}
            {{- t | tojson(indent=4) }}
            {{- "\n\n" }}
        {%- endfor %}
    {%- endif %}
    {{- "<|eot|>" }}
{%- endif %}

{#- Custom tools are passed in a user message with some extra guidance #}
{%- if tools_in_user_message and tools is not none %}
    {#- Extract the first user message so we can plug it in here #}
    {%- if messages | length != 0 %}
        {%- if messages[0]['content'] is string %}
            {%- set first_user_message = messages[0]['content']|trim %}
        {%- else %}
            {%- set first_user_message = messages[0]['content'] | selectattr('type', 'equalto', 'text') | map(attribute='text') | map('trim') | join('\n') %}
        {%- endif %}
        {%- set messages = messages[1:] %}
    {%- else %}
        {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
    {%- endif %}
    {{- '<|header_start|>user<|header_end|>\n\n' -}}
    {{- first_user_message}}
    {{- "\nHere is a list of functions in JSON format that you can invoke:"}}
    {%- for t in tools %}
        {{- t | tojson(indent=4) }}
        {{- "\n\n" }}
    {%- endfor %}
    {{- "Should you decide to return the function call(s), put them in the format "
        "of [func_name1(params_name1=params_value1, params_name2=params_value2, "
        "...), ...]\nDo not include anything else when calling the tools with the "
        "syntax above." }}
{%- endif %}

{%- for message in messages %}
    {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
    {{- '<|header_start|>' + message['role'] + '<|header_end|>\n\n' }}
        {%- if message['content'] is string %}
            {{- message['content'] }}
        {%- else %}
            {%- for content in message['content'] %}
                {%- if content['type'] == 'image' %}
                    {{- '<|image|>' }}
                {%- elif content['type'] == 'text' %}
                    {{- content['text'] | trim }}
                {%- endif %}
            {%- endfor %}
        {%- endif %}
        {{- "<|eot|>" }}
    {%- elif 'tool_calls' in message and message.tool_calls|length > 0 %}
        {%- set tool_call = message.tool_calls[0].function %}
        {{- '<|header_start|>assistant<|header_end|>\n\n' -}}
        {%- if message['content'] is string %}
            {{- message['content'] }}
        {%- else %}
            {%- for content in message['content'] %}
                {%- if content['type'] == 'image' %}
                    {{- '<|image|>' }}
                {%- elif content['type'] == 'text' %}
                    {{- content['text'] }}
                {%- endif %}
            {%- endfor %}
        {%- endif %}
        {%- for tool_call in message.tool_calls %}
            {%- if tool_call.function is defined %}
                {%- set tool_call = tool_call.function %}
            {%- endif %}
            {{- tool_call.name + '(' -}}
            {%- for param in tool_call.arguments %}
                {{- param + '=' -}}
                {{- "%s" | format(tool_call.arguments[param]) -}}
                {% if not loop.last %}, {% endif %}
            {%- endfor %}
            {{- ')' -}}
            {% if not loop.last %}, {% endif %}
        {%- endfor %}
        {{- "<|eom|>" }}
    {%- elif message.role == "tool" or message.role == "ipython" %}
        {{- "<|header_start|>ipython<|header_end|>\n\n" }}
        {%- if message.content is string %}
            {{- message.content | tojson }}
        {%- else %}
            {%- for content in message['content']  %}
                {%- if content['type']  == 'text' %}
                    {{- content['text'] | tojson }}
                {%- endif %}
            {%- endfor %}
        {%- endif %}
        {{- "<|eom|>" }}
    {%- endif %}
{%- endfor %}
{%- if add_generation_prompt %}
    {{- '<|header_start|>assistant<|header_end|>\n\n' }}
{%- endif %}
