124 lines
4.4 KiB
Plaintext
124 lines
4.4 KiB
Plaintext
|
|
{#- This template extends the base model template to support tool calling.
|
||
|
|
Tools are injected into the system prompt using <tools> XML tags.
|
||
|
|
Tool calls use <tool_call> XML tags, tool responses use <tool_response> tags.
|
||
|
|
|
||
|
|
Handles all combinations:
|
||
|
|
1. tools + user system message → single system block: tool instructions + user content
|
||
|
|
2. tools + NO system message → single synthetic system block with tool instructions
|
||
|
|
3. no tools + user system message → single system block with user content
|
||
|
|
4. no tools + no system message → minimal default system block
|
||
|
|
|
||
|
|
Thinking mode: if any system message contains "thinking on", all system
|
||
|
|
blocks end with "thinking on" and the generation prompt emits an open <think>.
|
||
|
|
Otherwise "thinking off" is used and <think></think> is immediately closed.
|
||
|
|
|
||
|
|
"thinking on" / "thinking off" is stripped from user system content and
|
||
|
|
re-appended as the final line of the system block to keep it consistent.
|
||
|
|
-#}
|
||
|
|
{%- set loop_messages = messages %}
|
||
|
|
{%- set ns = namespace(thinking=false, has_tools=false, has_system=false, system_emitted=false) %}
|
||
|
|
|
||
|
|
{#- ===== Method A: Check kwarg ===== -#}
|
||
|
|
{%- if enable_thinking is defined and enable_thinking %}
|
||
|
|
{%- set ns.thinking = true %}
|
||
|
|
{%- endif %}
|
||
|
|
|
||
|
|
{#- ===== PASS 1: Scan messages to detect thinking mode and system presence ===== -#}
|
||
|
|
{%- for message in loop_messages %}
|
||
|
|
{%- if message['role'] == 'system' %}
|
||
|
|
{%- set ns.has_system = true %}
|
||
|
|
{%- if 'thinking on' in message['content'] %}
|
||
|
|
{%- set ns.thinking = true %}
|
||
|
|
{%- endif %}
|
||
|
|
{%- endif %}
|
||
|
|
{%- endfor %}
|
||
|
|
|
||
|
|
{#- ===== Build tool instruction block if tools provided ===== -#}
|
||
|
|
{%- if tools is defined and tools is not none and tools | length > 0 %}
|
||
|
|
{%- set ns.has_tools = true %}
|
||
|
|
{%- set tool_instruction %}
|
||
|
|
You are a function calling AI model. You are provided with function signatures within <tools></tools> XML tags.
|
||
|
|
You may call one or more functions to assist with the user query. Don't make assumptions about what values to plug into functions.
|
||
|
|
Here are the available tools:
|
||
|
|
<tools>
|
||
|
|
{{ tools | tojson }}
|
||
|
|
</tools>
|
||
|
|
For each function call, return a JSON object with function name and arguments within <tool_call></tool_call> XML tags as follows:
|
||
|
|
<tool_call>
|
||
|
|
{"name": <function-name>, "arguments": <args-dict>}
|
||
|
|
</tool_call>
|
||
|
|
{%- endset %}
|
||
|
|
{%- endif %}
|
||
|
|
|
||
|
|
{#- ===== Thinking mode suffix — appended to every system block ===== -#}
|
||
|
|
{%- set thinking_suffix = "thinking on" if ns.thinking else "thinking off" %}
|
||
|
|
|
||
|
|
{#- ===== SYNTHETIC SYSTEM BLOCK (only if NO system messages in conversation) ===== -#}
|
||
|
|
{%- if not ns.has_system %}
|
||
|
|
{%- if ns.has_tools %}
|
||
|
|
{{- '<extra_id_0>System\n' }}
|
||
|
|
{{- tool_instruction + '\n\n' }}
|
||
|
|
{{- thinking_suffix + '\n' }}
|
||
|
|
{%- else %}
|
||
|
|
{{- '<extra_id_0>System\n' }}
|
||
|
|
{{- thinking_suffix + '\n' }}
|
||
|
|
{%- endif %}
|
||
|
|
{%- set ns.system_emitted = true %}
|
||
|
|
{%- endif %}
|
||
|
|
|
||
|
|
{#- ===== PASS 2: Render messages ===== -#}
|
||
|
|
{%- for message in loop_messages %}
|
||
|
|
|
||
|
|
{#- ---- SYSTEM MESSAGE ---- -#}
|
||
|
|
{%- if message['role'] == 'system' %}
|
||
|
|
{#- Strip thinking directives from the content — we handle them via thinking_suffix -#}
|
||
|
|
{%- set clean_content = message['content'] | replace('thinking on', '') | replace('thinking off', '') | trim %}
|
||
|
|
{{- '<extra_id_0>System\n' }}
|
||
|
|
{%- if ns.has_tools %}
|
||
|
|
{{- tool_instruction + '\n' }}
|
||
|
|
{%- endif %}
|
||
|
|
{%- if clean_content %}
|
||
|
|
{{- clean_content + '\n' }}
|
||
|
|
{%- endif %}
|
||
|
|
{{- thinking_suffix + '\n' }}
|
||
|
|
{%- set ns.system_emitted = true %}
|
||
|
|
|
||
|
|
{#- ---- USER MESSAGE ---- -#}
|
||
|
|
{%- elif message['role'] == 'user' %}
|
||
|
|
{{- '<extra_id_1>User\n' }}
|
||
|
|
{{- message['content'] + '\n' }}
|
||
|
|
|
||
|
|
{#- ---- ASSISTANT MESSAGE ---- -#}
|
||
|
|
{%- elif message['role'] == 'assistant' %}
|
||
|
|
{%- if message.tool_calls is defined and message.tool_calls | length > 0 %}
|
||
|
|
{{- '<extra_id_1>Assistant\n' }}
|
||
|
|
{%- for tool_call in message.tool_calls %}
|
||
|
|
{{- '<tool_call>\n' }}
|
||
|
|
{{- {"name": tool_call.function.name, "arguments": tool_call.function.arguments} | tojson + '\n' }}
|
||
|
|
{{- '</tool_call>\n' }}
|
||
|
|
{%- endfor %}
|
||
|
|
{%- else %}
|
||
|
|
{{- '<extra_id_1>Assistant\n' }}
|
||
|
|
{{- message['content'] + '\n' }}
|
||
|
|
{%- endif %}
|
||
|
|
|
||
|
|
{#- ---- TOOL RESPONSE MESSAGE ---- -#}
|
||
|
|
{%- elif message['role'] == 'tool' %}
|
||
|
|
{{- '<extra_id_1>User\n' }}
|
||
|
|
{{- '<tool_response>\n' }}
|
||
|
|
{{- message['content'] + '\n' }}
|
||
|
|
{{- '</tool_response>\n' }}
|
||
|
|
|
||
|
|
{%- endif %}
|
||
|
|
{%- endfor %}
|
||
|
|
|
||
|
|
{#- ===== Generation prompt ===== -#}
|
||
|
|
{%- if add_generation_prompt %}
|
||
|
|
{{- '<extra_id_1>Assistant\n' }}
|
||
|
|
{%- if ns.thinking %}
|
||
|
|
{{- '<think>\n' }}
|
||
|
|
{%- else %}
|
||
|
|
{{- '<think>\n</think>\n\n' }}
|
||
|
|
{%- endif %}
|
||
|
|
{%- endif %}
|