{{ bos_token }} {%- set first_is_system = (messages and messages[0]['role'] == 'system') -%} {# ---------- SYSTEM TURN WITH TOOL INSTRUCTIONS (GEMMA STYLE) ---------- #} {%- if first_is_system -%} system {%- if messages[0]['content'] is string -%} {{ messages[0]['content'] | trim }} {%- else -%} {{ messages[0]['content'][0]['text'] | trim }} {%- endif %} You can call external tools ("functions") to get real-time data or to take actions. TOOL CALL PROTOCOL: 1. When a tool is needed, respond with only one or more ... blocks in that turn. 2. Each block must be valid JSON: { "id": "", "type": "function", "function": { "name": "", "arguments": { ... } } } 3. "arguments" must be valid JSON and match the schema. 4. After tool responses (...) arrive, continue the conversation using those results. 5. If no tool is needed, answer normally. AVAILABLE TOOLS: {%- if tools is defined and tools|length > 0 %} {%- for t in tools %} - {{ t["function"]["name"] }} : {{ t["function"]["description"] }} params: {{ t["function"]["parameters"] | tojson }} {%- endfor %} {%- else %} (no tools provided) {%- endif %} {%- set loop_messages = messages[1:] -%} {%- else -%} system You are a helpful AI assistant. You can call external tools ("functions") to get real-time data or to take actions. TOOL CALL PROTOCOL: 1. When a tool is needed, respond with only one or more ... blocks in that turn. 2. Each block must be valid JSON: { "id": "", "type": "function", "function": { "name": "", "arguments": { ... } } } 3. "arguments" must be valid JSON and match the schema. 4. After tool responses (...) arrive, continue the conversation using those results. 5. If no tool is needed, answer normally. AVAILABLE TOOLS: {%- if tools is defined and tools|length > 0 %} {%- for t in tools %} - {{ t["function"]["name"] }} : {{ t["function"]["description"] }} params: {{ t["function"]["parameters"] | tojson }} {%- endfor %} {%- else %} (no tools provided) {%- endif %} {%- set loop_messages = messages -%} {%- endif %} {# ---------- OTHER MESSAGES ---------- #} {%- for message in loop_messages -%} {# assistant turn that issues tool calls #} {%- if message['role'] == 'assistant' and ('tool_calls' in message) and message['tool_calls'] %} model {%- for c in message['tool_calls'] %} {{ { "id": c["id"], "type": c.get("type", "function"), "function": { "name": c["function"]["name"], "arguments": ( c["function"]["arguments"] if c["function"]["arguments"] is not none else {} ) } } | tojson }} {%- endfor %} {# tool result turn (fed back to model as user) #} {%- elif message['role'] == 'tool' %} user {{ message['content'] }} {# normal user/model turns #} {%- else -%} {%- if message['role'] == 'assistant' -%} {%- set role = "model" -%} {%- else -%} {%- set role = message['role'] -%} {%- endif -%} {{ role }} {%- if message['content'] is string -%} {{ message['content'] | trim }} {%- elif message['content'] is iterable -%} {%- for item in message['content'] -%} {%- if item['type'] == 'image' -%} {%- elif item['type'] == 'text' -%} {{ item['text'] | trim }} {%- endif -%} {%- endfor -%} {%- endif -%} {%- endif -%} {%- endfor -%} {# ---------- GENERATION PROMPT ---------- #} {%- if add_generation_prompt -%} model {%- endif -%}