|
|
{%- set ns = namespace(enable_thinking=false, has_sys_prompt=false, non_tool_system_content='', has_video=false, explicit_think_requested=false) -%}
|
|
|
{%- set msg = namespace(content='') -%}
|
|
|
{%- for message in messages -%}
|
|
|
{%- if message['role'] == 'system' -%}
|
|
|
{%- set ns.has_sys_prompt = true -%}
|
|
|
|
|
|
{%- if message['content'] is string -%}
|
|
|
{%- set ns.non_tool_system_content = message['content'].replace('</think>', '<_end_think>').replace('/think', '').replace('/no_think', '').replace('<_end_think>', '</think>').strip() -%}
|
|
|
{%- else -%}
|
|
|
{%- set ns.non_tool_system_content = '' -%}
|
|
|
{%- for content in message['content'] -%}
|
|
|
{%- if content['type'] == 'text' -%}
|
|
|
{%- set ns.non_tool_system_content = ns.non_tool_system_content + content['text'].replace('</think>', '<_end_think>').replace('/think', '').replace('/no_think', '').replace('<_end_think>', '</think>') -%}
|
|
|
{%- endif -%}
|
|
|
{%- endfor -%}
|
|
|
{%- set ns.non_tool_system_content = ns.non_tool_system_content.strip() -%}
|
|
|
{%- endif -%}
|
|
|
{%- endif -%}
|
|
|
|
|
|
{%- if message['content'] is not string -%}
|
|
|
{%- for content in message['content'] -%}
|
|
|
{%- if content['type'] == 'video' or content['type'] == 'video_url' -%}
|
|
|
{%- set ns.has_video = true -%}
|
|
|
{%- endif -%}
|
|
|
{%- endfor -%}
|
|
|
{%- endif -%}
|
|
|
{%- if message['content'] is string -%}
|
|
|
{%- if message['role'] == 'user' or message['role'] == 'system' -%}
|
|
|
{%- if '/think' in message['content'].replace('</think>', '') -%}
|
|
|
{%- set ns.enable_thinking = true -%}
|
|
|
{%- set ns.explicit_think_requested = true -%}
|
|
|
{%- elif '/no_think' in message['content'] -%}
|
|
|
{%- set ns.enable_thinking = false -%}
|
|
|
{%- endif -%}
|
|
|
{%- endif -%}
|
|
|
{%- else -%}
|
|
|
{%- for content in message['content'] -%}
|
|
|
{%- if content['type'] == 'text' -%}
|
|
|
{%- if message['role'] == 'user' or message['role'] == 'system' -%}
|
|
|
{%- if '/think' in content['text'].replace('</think>', '') -%}
|
|
|
{%- set ns.enable_thinking = true -%}
|
|
|
{%- set ns.explicit_think_requested = true -%}
|
|
|
{%- elif '/no_think' in content['text'] -%}
|
|
|
{%- set ns.enable_thinking = false -%}
|
|
|
{%- endif -%}
|
|
|
{%- endif -%}
|
|
|
{%- endif -%}
|
|
|
{%- endfor -%}
|
|
|
{%- endif -%}
|
|
|
{%- endfor -%}
|
|
|
|
|
|
|
|
|
{%- if ns.has_video and ns.explicit_think_requested -%}
|
|
|
{{ raise_exception('Video inputs are not supported with reasoning mode. Please remove /think flag or remove video content.') }}
|
|
|
{%- endif -%}
|
|
|
|
|
|
|
|
|
{%- if ns.has_video and not ns.explicit_think_requested -%}
|
|
|
{%- set ns.enable_thinking = false -%}
|
|
|
{%- endif -%}
|
|
|
|
|
|
{%- if messages[0]['role'] != 'system' -%}
|
|
|
{{- '<SPECIAL_10>System\n' -}}
|
|
|
{%- else -%}
|
|
|
{{- '<SPECIAL_10>System\n' + ns.non_tool_system_content }}
|
|
|
{%- endif -%}
|
|
|
|
|
|
{%- if tools -%}
|
|
|
{%- if ns.non_tool_system_content != '' -%}
|
|
|
{{- '\n\n' -}}
|
|
|
{%- endif -%}
|
|
|
{{- 'You can use the following tools to assist the user if required:\n' -}}
|
|
|
{{- '<AVAILABLE_TOOLS>[' -}}
|
|
|
{%- for tool in tools -%}
|
|
|
{{- (tool.function if tool.function is defined else tool) | tojson -}}
|
|
|
{{- ', ' if not loop.last else '' -}}
|
|
|
{%- endfor -%}
|
|
|
{{- ']</AVAILABLE_TOOLS>\n\n' -}}
|
|
|
|
|
|
{{- 'If you decide to call any tool(s), use the following format:\n' -}}
|
|
|
{{- '<TOOLCALL>[{"name": "tool_name1", "arguments": "tool_args1"}, ' -}}
|
|
|
{{- '{"name": "tool_name2", "arguments": "tool_args2"}]</TOOLCALL>\n\n' -}}
|
|
|
|
|
|
{{- 'The user will execute tool-calls and return responses from tool(s) in this format:\n' -}}
|
|
|
{{- '<TOOL_RESPONSE>[{"response": "tool_response1"}, ' -}}
|
|
|
{{- '{"response": "tool_response2"}]</TOOL_RESPONSE>\n\n' -}}
|
|
|
|
|
|
{{- 'Based on the tool responses, you can call additional tools if needed, ' -}}
|
|
|
{{- 'correct tool calls if any errors are found, or just respond to the user.' -}}
|
|
|
{%- endif -%}
|
|
|
{{- '\n' -}}
|
|
|
|
|
|
{%- set messages = messages[1:] if messages[0]['role'] == 'system' else messages -%}
|
|
|
|
|
|
|
|
|
{%- if messages|length == 0 -%}
|
|
|
{%- set messages = [{'role': 'user', 'content': ''}] -%}
|
|
|
{%- endif -%}
|
|
|
|
|
|
{%- for message in messages %}
|
|
|
{%- if message['content'] is string -%}
|
|
|
{%- set msg.content = message['content'].replace('</think>', '<_end_think>').replace('/think', '').replace('/no_think', '').replace('<_end_think>', '</think>').strip() -%}
|
|
|
{%- else -%}
|
|
|
{%- set msg.content = '' -%}
|
|
|
{%- set mm_content = '' -%}
|
|
|
{%- set counters = namespace(images=0, videos=0) -%}
|
|
|
|
|
|
{%- for content in message['content'] -%}
|
|
|
{%- if content['type'] == 'image' -%}
|
|
|
{%- set counters.images = counters.images + 1 -%}
|
|
|
{%- elif content['type'] == 'video' -%}
|
|
|
{%- set counters.videos = counters.videos + 1 -%}
|
|
|
{%- elif content['type'] == 'text' -%}
|
|
|
{%- set msg.content = msg.content + content['text'] -%}
|
|
|
{%- endif -%}
|
|
|
{%- endfor -%}
|
|
|
{%- if '<image>' in msg.content -%}
|
|
|
{%- set counters.images = 0 -%}
|
|
|
{%- endif -%}
|
|
|
{%- if '<video>' in msg.content -%}
|
|
|
{%- set counters.videos = 0 -%}
|
|
|
{%- endif -%}
|
|
|
{%- if counters.images > 1 -%}
|
|
|
{%- set image_tags = namespace(tags=[]) -%}
|
|
|
{%- for i in range(counters.images) -%}
|
|
|
{%- set image_tags.tags = image_tags.tags + ['<image ' + (i + 1)|string + '><image>'] -%}
|
|
|
{%- endfor -%}
|
|
|
{%- set mm_content = ' '.join(image_tags.tags) + '\n' -%}
|
|
|
{%- elif counters.images == 1 -%}
|
|
|
{%- set mm_content = '<image>\n' -%}
|
|
|
{%- endif -%}
|
|
|
{%- set mm_content = mm_content + '<video>\n' * counters.videos -%}
|
|
|
{%- set msg.content = mm_content + msg.content.lstrip('\n') -%}
|
|
|
{%- endif -%}
|
|
|
|
|
|
{%- if message['role'] == 'user' %}
|
|
|
{{- '<SPECIAL_11>User\n' + msg.content.replace('</think>', '<_end_think>').replace('/think', '').replace('/no_think', '').replace('<_end_think>', '</think>').strip() + '\n' }}
|
|
|
{%- elif message['role'] == 'tool' %}
|
|
|
{%- if loop.first or (messages[loop.index0 - 1].role != 'tool') -%}
|
|
|
{{- '<SPECIAL_11>User\n' + '<TOOL_RESPONSE>[' }}
|
|
|
{%- endif -%}
|
|
|
{{- msg.content -}}
|
|
|
{{- ', ' if not loop.last and (messages[loop.index0 + 1].role == 'tool') else '' -}}
|
|
|
{%- if loop.last or (messages[loop.index0 + 1].role != 'tool') -%}
|
|
|
{{- ']</TOOL_RESPONSE>\n' -}}
|
|
|
{%- endif -%}
|
|
|
{%- elif message['role'] == 'assistant' %}
|
|
|
{%- if '</think>' in msg.content %}
|
|
|
{%- set msg.content = msg.content.split('</think>')[1].strip() %}
|
|
|
{%- endif %}
|
|
|
{{- '<SPECIAL_11>Assistant\n' + msg.content.strip() }}
|
|
|
{%- if message.tool_calls -%}
|
|
|
{%- if msg.content.strip() != '' -%}
|
|
|
{{- '\n\n' -}}
|
|
|
{%- endif -%}
|
|
|
{{- '<TOOLCALL>[' -}}
|
|
|
{%- for call in message.tool_calls -%}
|
|
|
{%- set fn = call.function if call.function is defined else call -%}
|
|
|
{{- '{"name": "' + fn.name + '", "arguments": ' -}}
|
|
|
{%- if fn.arguments is string -%}
|
|
|
{{- fn.arguments -}}
|
|
|
{%- else -%}
|
|
|
{{- fn.arguments | tojson -}}
|
|
|
{%- endif -%}
|
|
|
{{- '}' + (', ' if not loop.last else '') -}}
|
|
|
{%- endfor -%}
|
|
|
{{- ']</TOOLCALL>' -}}
|
|
|
{%- endif -%}
|
|
|
{{- '\n<SPECIAL_12>\n' -}}
|
|
|
{%- endif %}
|
|
|
{%- endfor -%}
|
|
|
{%- if add_generation_prompt %}
|
|
|
{{- '<SPECIAL_11>Assistant\n' }}
|
|
|
{%- if ns.enable_thinking is defined and ns.enable_thinking is false %}
|
|
|
{{- '<think></think>' }}
|
|
|
{%- else %}
|
|
|
{{- '<think>\n' }}
|
|
|
{%- endif %}
|
|
|
{%- endif %}
|
|
|
|