{#- Begin-of-sequence token to start the model prompt -#} {{ bos_token }} {#- Extracts the system message. Gemma does not support system messages so it will be prepended to first user message. -#} {%- if messages[0]['role'] == 'system' -%} {%- if messages[0]['content'] is string -%} {%- set first_user_prefix = messages[0]['content'] -%} {%- else -%} {%- set first_user_prefix = messages[0]['content'][0]['text'] -%} {%- endif -%} {%- set loop_messages = messages[1:] -%} {%- else -%} {%- set first_user_prefix = "You are a helpful assistant named Typhoon created by SCB 10X to be helpful, harmless, and honest." -%} {%- set loop_messages = messages -%} {%- endif -%} {%- if enable_thinking is defined and enable_thinking is true %} {%- set first_user_prefix = first_user_prefix + " First, think through the reasoning internally, then present the reasoning within .... After thinking, clearly state a response that addresses the user's request and aligns with their preferences, not just providing a direct answer." -%} {%- endif %} {%- set first_user_prefix = first_user_prefix + '\n\n' -%} {#- Set tools to none if not defined for this ChatCompletion request (helps avoid errors later) -#} {%- if not tools is defined %} {%- set tools = none %} {%- endif %} {#- If given only system message -#} {%- if loop_messages|length == 0 -%} {{ 'user\n' -}} {{ first_user_prefix }} {#- Append system message with tool information if using tools in message request. -#} {%- if tools is not none -%} {{- "Tools (functions) are available. If you decide to invoke one or more of the tools, you must respond with a python list of the function calls.\n" -}} {{- "Example Format: [func_name1(params_name1=params_value1, params_name2=params_value2...), func_name2(params)] \n" -}} {{- "Do not use variables. DO NOT USE MARKDOWN SYNTAX. You SHOULD NOT include any other text in the response if you call a function. If none of the functions can be used, point it out. If you lack the parameters required by the function, also point it out.\n" -}} {{- "Here is a list of functions in JSON format that you can invoke.\n" -}} {{- tools | tojson(indent=4) -}} {{- "\n\n" -}} {%- endif -%} {%- endif %} {#- Main loop over all messages in the conversation history -#} {%- for message in loop_messages -%} {#- Normalize roles for model prompt formatting -#} {%- if (message['role'] == 'assistant') -%} {%- set role = "model" -%} {%- elif (message['role'] == 'tool') -%} {%- set role = "user" -%} {%- else -%} {%- set role = message['role'] -%} {%- endif -%} {#- Mark the start of a message block with the appropriate role -#} {{ '' + role + '\n' -}} {#- Insert system message content (if present) at the beginning of the first message. -#} {%- if loop.first -%} {{ first_user_prefix }} {#- Append system message with tool information if using tools in message request. -#} {%- if tools is not none -%} {{- "Tools (functions) are available. If you decide to invoke one or more of the tools, you must respond with a python list of the function calls.\n" -}} {{- "Example Format: [func_name1(params_name1=params_value1, params_name2=params_value2...), func_name2(params)] \n" -}} {{- "Do not use variables. DO NOT USE MARKDOWN SYNTAX. You SHOULD NOT include any other text in the response if you call a function. If none of the functions can be used, point it out. If you lack the parameters required by the function, also point it out.\n" -}} {{- "Here is a list of functions in JSON format that you can invoke.\n" -}} {{- tools | tojson(indent=4) -}} {{- "\n\n" -}} {%- endif -%} {%- endif -%} {#- Format model tool calls (turns where model indicates they want to call a tool) -#} {%- if 'tool_calls' in message -%} {#- Opening bracket for tool call list. -#} {{- '[' -}} {#- For each tool call -#} {%- for tool_call in message.tool_calls -%} {#- Function name & opening parenthesis. -#} {%- if tool_call.function is defined -%} {%- set tool_call = tool_call.function -%} {%- endif -%} {{- tool_call.name + '(' -}} {#-- Handle arguments as list (positional) or dict (named) --#} {#-- Named arguments (dict) --#} {%- if tool_call.arguments is iterable and tool_call.arguments is mapping -%} {%- set first = true -%} {%- for key, val in tool_call.arguments.items() -%} {%- if not first %}, {% endif -%} {{ key }}={{ val | tojson }} {%- set first = false -%} {%- endfor -%} {#-- Positional arguments (list) --#} {%- elif tool_call.arguments is iterable -%} {{- tool_call.arguments | map('tojson') | join(', ') -}} {#-- Fallback: single positional value --#} {%- else -%} {{- tool_call.arguments | tojson -}} {#-- Closing parenthesis. --#} {%- endif -%} {{- ')' -}} {#-- If more than one tool call, place comma and move to formatting next tool call --#} {%- if not loop.last -%}, {% endif -%} {%- endfor -%} {#- Closing bracket for tool call list. -#} {{- ']' -}} {%- endif -%} {#- Tool response start tag (for messages from a tool) -#} {%- if (message['role'] == 'tool') -%} {{ '\n' -}} {%- endif -%} {#- Render the message content: handle plain string or multimodal content like image/text -#} {%- if message['content'] is string -%} {%- set content = message['content'] -%} {%- if '' in content -%} {%- set content = content.split('')[-1] -%} {%- endif -%} {{ content | trim }} {%- elif message['content'] is iterable -%} {%- for item in message['content'] -%} {%- if item['type'] == 'image' -%} {{ '' }} {%- elif item['type'] == 'text' -%} {%- set content = item['text'] -%} {%- if '' in content -%} {%- set content = content.split('')[-1] -%} {%- endif -%} {{ content | trim }} {%- endif -%} {%- endfor -%} {%- else -%} {{ raise_exception("Invalid content type") }} {%- endif -%} {#- Tool response end tag -#} {%- if (message['role'] == 'tool') -%} {{ '' -}} {%- endif -%} {#- Mark end of a single turn -#} {{ '\n' }} {%- endfor -%} {#- If generation is to be triggered, add model prompt prefix -#} {%- if add_generation_prompt -%} {{'model\n'}} {%- if enable_thinking is defined and enable_thinking is true -%} {{- '' -}} {%- endif %} {%- endif -%}