| {% set image_count = namespace(value=0) %} |
| {% set video_count = namespace(value=0) %} |
| |
| {%- set role_indicators = { |
| 'user': '<|user|>\n', |
| 'assistant': '<|assistant|>\n', |
| 'system': '<|system|>\n', |
| 'tool': '<|tool|>\n', |
| 'tool_declare': '<|tool_declare|>\n' |
| } %} |
| {%- set end_of_turn = '<|endofturn|>\n' %} |
| |
| |
| {%- macro declare_available_tools(tools) %} |
| {{- "# Tools" }} |
| {{- "\n" }} |
| {%- for tool in tools %} |
| {{- "<tool>" }} |
| {{- tool | tojson(ensure_ascii=False) | safe }} |
| {{- "</tool>\n" }} |
| {%- endfor %} |
| {%- endmacro %} |
| |
| |
| {%- set ns = namespace(last_query_index = messages|length - 1, last_query_index_not_yet_determined = true) %} |
| {%- for message in messages[::-1] %} |
| {%- set index = (messages|length - 1) - loop.index0 %} |
| {%- if ns.last_query_index_not_yet_determined and message.role == "user" and message.content is string %} |
| {%- set ns.last_query_index = index -%} |
| {%- set ns.last_query_index_not_yet_determined = false -%} |
| {%- endif %} |
| {%- endfor %} |
| |
| {%- if tools is defined and tools %} |
| {{- role_indicators['tool_declare'] }} |
| {{- declare_available_tools(tools) }} |
| {{- end_of_turn -}} |
| {%- endif %} |
| |
| {%- for i in range(messages | length) %} |
| {%- set msg = messages[i] %} |
| {%- set role = msg.role %} |
| {%- if role not in role_indicators %} |
| {{- raise_exception('Unknown role: ' ~ role) }} |
| {%- endif %} |
| |
| {%- if i == 0 %} |
| {%- if role == 'system' %} |
| {{- role_indicators['system'] }} |
| {{- msg.content }} |
| {{- end_of_turn -}} |
| {%- continue %} |
| {%- endif %} |
| {%- endif %} |
| |
| {%- if role == 'assistant' %} |
| {{- role_indicators['assistant'] }} |
| |
| {%- set content = (msg.content if (msg.content is defined and msg.content) else "") -%} |
| {%- set reasoning = none -%} |
| |
| {%- if msg.reasoning_content is defined and msg.reasoning_content%} |
| {%- set reasoning = msg.reasoning_content.strip() -%} |
| {%- elif content and "</think>" in content %} |
| {%- set _parts = content.split('</think>') -%} |
| {%- set reasoning = _parts[0].lstrip('<think>').strip() -%} |
| {%- set content = _parts[-1].strip() -%} |
| {%- endif %} |
| |
| {%- if not (reasoning and i > ns.last_query_index) or (skip_think is defined and skip_think) %} |
| {%- set reasoning = none %} |
| {%- endif %} |
| |
| {%- set content = content.strip() -%} |
| |
| {{- "<think>\n" }} |
| {{- (reasoning if reasoning is not none else "") }} |
| {{- "\n</think>\n\n" }} |
| |
| {{- content }} |
| |
| {%- if msg.tool_calls %} |
| {%- if content is defined and content %} |
| {{- "\n" }} |
| {%- endif %} |
| {%- for tool_call in msg.tool_calls %} |
| {%- if tool_call.function is defined %} |
| {%- set tool_call = tool_call.function %} |
| {%- endif %} |
| |
| {%- if tool_call.arguments is defined %} |
| {%- set arguments = tool_call.arguments %} |
| {%- elif tool_call.parameters is defined %} |
| {%- set arguments = tool_call.parameters %} |
| {%- else %} |
| {{- raise_exception('arguments or parameters are mandatory: ' ~ tool_call) }} |
| {%- endif %} |
| {%- if arguments is string %} |
| {{- "<tool_call>" }}{"name": "{{- tool_call.name }}", "arguments": {{ arguments }}}{{- "</tool_call>" }} |
| {%- else %} |
| {{- "<tool_call>" }}{"name": "{{- tool_call.name }}", "arguments": {{ arguments | tojson(ensure_ascii=False) | safe }}}{{- "</tool_call>" }} |
| {%- endif %} |
| {%- if not loop.last %} |
| {{- "\n" }} |
| {%- endif %} |
| |
| {%- endfor %} |
| {%- endif %} |
| {{- end_of_turn -}} |
| |
| {%- elif role == "tool" %} |
| {%- if i == 0 or messages[i - 1].role != "tool" %} |
| {{- role_indicators['tool'] }} |
| {%- endif %} |
| {%- if msg.content is defined %} |
| {%- if msg.content is string %} |
| {{- "<tool_result>" }}{{ msg.content }}{{- "</tool_result>" }} |
| {%- else %} |
| {{- "<tool_result>" }}{{ msg.content | tojson(ensure_ascii=False) | safe }}{{- "</tool_result>" }} |
| {%- endif %} |
| {%- endif %} |
| {%- if loop.last or messages[i + 1].role != "tool" %} |
| {{- end_of_turn -}} |
| {%- else %} |
| {{- "\n" }} |
| {%- endif %} |
| |
| {%- else %} |
| {{- role_indicators[role] }} |
| {%- if msg.content is string %} |
| {{- msg.content }} |
| {%- else %} |
| {%- for content in msg.content %} |
| {%- if content.type == 'image' %} |
| {%- set image_count.value = image_count.value + 1 %} |
| {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif %} |
| {{- "<vision><|image_pad|></vision>\n" }} |
| {%- elif content.type == 'video' %} |
| {%- set video_count.value = video_count.value + 1 %} |
| {%- if add_vision_id %}Video {{ video_count.value }}: {% endif %} |
| {{- "<vision><|video_pad|></vision>\n" }} |
| {%- elif content.type == 'text' %} |
| {{- content.text }} |
| {%- else %} |
| {{- content.text }} |
| {%- endif %} |
| {%- endfor %} |
| {%- endif %} |
| {{- end_of_turn -}} |
| {%- endif %} |
| {% endfor %} |
| |
| |
| {%- if add_generation_prompt %} |
| {{- role_indicators['assistant'] }} |
| {%- if enable_thinking is not defined or enable_thinking is true %} |
| {{- "<think>\n" }} |
| {%- else %} |
| {{- "<think>\n\n</think>\n\n" }} |
| {%- endif %} |
| {%- endif %} |
| |