| {# ============================================================================ #} |
| {# Hermes-3 Tool Calling Chat Template (ChatML + XML) #} |
| {# ============================================================================ #} |
| {# #} |
| {# Use this template with VLLM when you need custom tool call handling. #} |
| {# For most use cases, VLLM's built-in templates work fine. #} |
| {# #} |
| {# Usage with VLLM: #} |
| {# --chat-template chat_templates/hermes3_tool_calling.j2 #} |
| {# #} |
| {# Format: #} |
| {# <|im_start|>system ... <|im_end|> (ChatML system message) #} |
| {# <|im_start|>assistant #} |
| {# <tool_call>{"name": "...", "arguments": {...}}</tool_call> #} |
| {# <|im_end|> #} |
| {# <|im_start|>tool #} |
| {# <tool_response>...result...</tool_response> #} |
| {# <|im_end|> #} |
| {# ============================================================================ #} |
| |
| {# ---- Safe defaults: use default(..., true) so None -> fallback ---- #} |
| {% set _messages = messages | default([], true) %} |
| {% set _tools = tools | default([], true) %} |
| {% set _add_gen = add_generation_prompt | default(true, true) %} |
| |
| <|im_start|>system |
| You are a function-calling AI model. If tools are provided in <tools></tools>, you may call them to help the user. |
| Return tool calls inside <tool_call></tool_call> blocks. Return tool outputs inside <tool_response></tool_response> blocks. |
| |
| {# ---- Tools inventory (only if non-empty) ---- #} |
| {% if (_tools | length) > 0 %} |
| Here are the available tools: |
| <tools> |
| {{ _tools | tojson }} |
| </tools> |
| {% endif %} |
| <|im_end|> |
| |
| {# ---- Prior turns ---- #} |
| {% for m in _messages %} |
| {% set role = (m.role | default('user', true)) %} |
| |
| {# User/system turns, or assistant turns WITHOUT tool_calls #} |
| {% if role in ['system','user'] or (role == 'assistant' and not (m.tool_calls is defined and m.tool_calls)) %} |
| <|im_start|>{{ role }} |
| {{ m.content | default('', true) }}<|im_end|> |
| |
| {# Assistant turn WITH tool_calls: re-emit as Hermes <tool_call> blocks #} |
| {% elif role == 'assistant' and (m.tool_calls is defined and m.tool_calls) %} |
| <|im_start|>assistant |
| {% for tc in m.tool_calls %} |
| <tool_call> |
| {% set call = (tc.function if tc.function is defined else tc) %} |
| {"name":"{{ call.name }}"{% if call.arguments is defined %}, "arguments": {% if call.arguments is string %}{{ call.arguments }}{% else %}{{ call.arguments | tojson }}{% endif %}{% endif %}} |
| </tool_call> |
| {% endfor %} |
| <|im_end|> |
| |
| {# Tool responses #} |
| {% elif role == 'tool' %} |
| <|im_start|>tool |
| <tool_response> |
| {{ m.content | default('', true) }} |
| </tool_response> |
| <|im_end|> |
| {% endif %} |
| {% endfor %} |
| |
| {# ---- Generation prompt for assistant ---- #} |
| {% if _add_gen %} |
| <|im_start|>assistant |
| {% endif %} |
| |