File size: 8,597 Bytes
493df70 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | {%- 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 -%}
{# Extract system content without tool flags #}
{%- 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 -%}
{# Check for video content in all messages #}
{%- 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 -%}
{# Error out if video is present and reasoning is explicitly requested #}
{%- 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 -%}
{# Automatically disable reasoning if video is present (without explicit /think request) #}
{%- 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 -%}
{# Prevent no user or assistant message #}
{%- 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 %}
|