Created
June 13, 2026 15:20
-
-
Save bantya/c9bb74b890fa0d52398570bcff0e45dc to your computer and use it in GitHub Desktop.
Default prompt templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='', is_first_sp=true, is_last_user=false) %}{%- for message in messages %}{%- if message['role'] == 'system' %}{%- if ns.is_first_sp %}{% set ns.system_prompt = ns.system_prompt + message['content'] %}{% set ns.is_first_sp = false %}{%- else %}{% set ns.system_prompt = ns.system_prompt + ' | |
| ' + message['content'] %}{%- endif %}{%- endif %}{%- endfor %}{{ bos_token }}{{ ns.system_prompt }}{%- for message in messages %}{% set content = message['content'] %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{%- set ns.is_first = false -%}{%- set ns.is_last_user = true -%}{{'<|User|>' + content + '<|Assistant|>'}}{%- endif %}{%- if message['role'] == 'assistant' %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{% endif %}{%- if message['role'] == 'assistant' and message['tool_calls'] is defined and message['tool_calls'] is not none %}{%- set ns.is_last_user = false -%}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{%- endif %}{%- set ns.is_first = false %}{%- set ns.is_tool = false -%}{%- set ns.is_output_first = true %}{%- for tool in message['tool_calls'] %}{%- if not ns.is_first %}{%- if content is none %}{{'<|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + ' | |
| ' + '```json' + ' | |
| ' + (tool['function']['arguments'] if tool['function']['arguments'] is string else tool['function']['arguments'] | tojson) + ' | |
| ' + '```' + '<|tool▁call▁end|>'}}{%- else %}{{content + '<|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + ' | |
| ' + '```json' + ' | |
| ' + (tool['function']['arguments'] if tool['function']['arguments'] is string else tool['function']['arguments'] | tojson) + ' | |
| ' + '```' + '<|tool▁call▁end|>'}}{%- endif %}{%- set ns.is_first = true -%}{%- else %}{{' | |
| ' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + ' | |
| ' + '```json' + ' | |
| ' + (tool['function']['arguments'] if tool['function']['arguments'] is string else tool['function']['arguments'] | tojson) + ' | |
| ' + '```' + '<|tool▁call▁end|>'}}{%- endif %}{%- endfor %}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- if message['role'] == 'assistant' and (message['tool_calls'] is not defined or message['tool_calls'] is none)%}{%- set ns.is_last_user = false -%}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + content + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{{content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_last_user = false -%}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + content + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{' | |
| <|tool▁output▁begin|>' + content + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_last_user and not ns.is_tool %}{{'<|Assistant|>'}}{% endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {%- macro format_type_argument(type_value) -%} | |
| {%- if type_value is string -%} | |
| {{- '<|"|>' + (type_value | upper) + '<|"|>' -}} | |
| {%- elif type_value is iterable -%} | |
| [ | |
| {%- for item in type_value -%} | |
| <|"|>{{- item | upper -}}<|"|> | |
| {%- if not loop.last %},{% endif -%} | |
| {%- endfor -%} | |
| ] | |
| {%- else -%} | |
| {{- format_argument(type_value) -}} | |
| {%- endif -%} | |
| {%- endmacro -%} | |
| {%- macro format_parameters(properties, required, filter_keys=false) -%} | |
| {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%} | |
| {%- set ns = namespace(found_first=false) -%} | |
| {%- for key, value in properties | dictsort -%} | |
| {%- set add_comma = false -%} | |
| {%- if not filter_keys or key not in standard_keys -%} | |
| {%- if ns.found_first %},{% endif -%} | |
| {%- set ns.found_first = true -%} | |
| {{ key }}:{ | |
| {%- if value['description'] -%} | |
| description:<|"|>{{ value['description'] }}<|"|> | |
| {%- set add_comma = true -%} | |
| {%- endif -%} | |
| {%- if value['type'] and ('string' in value['type'] or 'STRING' in value['type']) -%} | |
| {%- if value['enum'] -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| enum:{{ format_argument(value['enum']) }} | |
| {%- endif -%} | |
| {%- elif value['type'] and ('array' in value['type'] or 'ARRAY' in value['type']) -%} | |
| {%- if value['items'] is mapping and value['items'] -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| items:{ | |
| {%- set ns_items = namespace(found_first=false) -%} | |
| {%- for item_key, item_value in value['items'] | dictsort -%} | |
| {%- if item_value is not none -%} | |
| {%- if ns_items.found_first %},{% endif -%} | |
| {%- set ns_items.found_first = true -%} | |
| {%- if item_key == 'properties' -%} | |
| properties:{ | |
| {%- if item_value is mapping -%} | |
| {{- format_parameters(item_value, value['items']['required'] | default([])) -}} | |
| {%- endif -%} | |
| } | |
| {%- elif item_key == 'required' -%} | |
| required:[ | |
| {%- for req_item in item_value -%} | |
| <|"|>{{- req_item -}}<|"|> | |
| {%- if not loop.last %},{% endif -%} | |
| {%- endfor -%} | |
| ] | |
| {%- elif item_key == 'type' -%} | |
| type:{{ format_type_argument(item_value) }} | |
| {%- else -%} | |
| {{ item_key }}:{{ format_argument(item_value) }} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| } | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- if value['nullable'] %} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| nullable:true | |
| {%- endif -%} | |
| {%- if value['type'] and ('object' in value['type'] or 'OBJECT' in value['type']) -%} | |
| {%- if value['properties'] is defined and value['properties'] is mapping -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| properties:{ | |
| {{- format_parameters(value['properties'], value['required'] | default([])) -}} | |
| } | |
| {%- elif value is mapping -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| properties:{ | |
| {{- format_parameters(value, value['required'] | default([]), filter_keys=true) -}} | |
| } | |
| {%- endif -%} | |
| {%- if value['required'] -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| required:[ | |
| {%- for item in value['required'] | default([]) -%} | |
| <|"|>{{- item -}}<|"|> | |
| {%- if not loop.last %},{% endif -%} | |
| {%- endfor -%} | |
| ] | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%} | |
| type:{{ format_type_argument(value['type']) }}} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endmacro -%} | |
| {%- macro format_function_declaration(tool_data) -%} | |
| declaration:{{- tool_data['function']['name'] -}}{description:<|"|>{{- tool_data['function']['description'] -}}<|"|> | |
| {%- set params = tool_data['function']['parameters'] -%} | |
| {%- if params -%} | |
| ,parameters:{ | |
| {%- set ns_params = namespace(found_first=false) -%} | |
| {%- if params['properties'] -%} | |
| properties:{ {{- format_parameters(params['properties'], params['required']) -}} } | |
| {%- set ns_params.found_first = true -%} | |
| {%- endif -%} | |
| {%- if params['required'] -%} | |
| {%- if ns_params.found_first %},{% endif -%} | |
| required:[ | |
| {%- for item in params['required'] -%} | |
| <|"|>{{- item -}}<|"|> | |
| {{- ',' if not loop.last -}} | |
| {%- endfor -%} | |
| ] | |
| {%- set ns_params.found_first = true -%} | |
| {%- endif -%} | |
| {%- if params['type'] -%} | |
| {%- if ns_params.found_first %},{% endif -%} | |
| type:{{- format_type_argument(params['type']) -}} | |
| {%- endif -%} | |
| } | |
| {%- endif -%} | |
| {%- if 'response' in tool_data['function'] -%} | |
| {%- set response_declaration = tool_data['function']['response'] -%} | |
| ,response:{ | |
| {%- set ns_response = namespace(found_first=false) -%} | |
| {%- if response_declaration['description'] -%} | |
| description:<|"|>{{- response_declaration['description'] -}}<|"|> | |
| {%- set ns_response.found_first = true -%} | |
| {%- endif -%} | |
| {%- if response_declaration['type'] and ('object' in response_declaration['type'] or 'OBJECT' in response_declaration['type']) -%} | |
| {%- if ns_response.found_first %},{% endif -%} | |
| type:{{- format_type_argument(response_declaration['type']) -}} | |
| {%- endif -%} | |
| } | |
| {%- endif -%} | |
| } | |
| {%- endmacro -%} | |
| {%- macro format_argument(argument, escape_keys=True) -%} | |
| {%- if argument is string -%} | |
| {{- '<|"|>' + argument + '<|"|>' -}} | |
| {%- elif argument is boolean -%} | |
| {{- 'true' if argument else 'false' -}} | |
| {%- elif argument is mapping -%} | |
| {{- '{' -}} | |
| {%- set ns = namespace(found_first=false) -%} | |
| {%- for key, value in argument | dictsort -%} | |
| {%- if ns.found_first %},{% endif -%} | |
| {%- set ns.found_first = true -%} | |
| {%- if escape_keys -%} | |
| {{- '<|"|>' + key + '<|"|>' -}} | |
| {%- else -%} | |
| {{- key -}} | |
| {%- endif -%} | |
| :{{- format_argument(value, escape_keys=escape_keys) -}} | |
| {%- endfor -%} | |
| {{- '}' -}} | |
| {%- elif argument is iterable and argument is not string -%} | |
| {{- '[' -}} | |
| {%- for item in argument -%} | |
| {{- format_argument(item, escape_keys=escape_keys) -}} | |
| {%- if not loop.last %},{% endif -%} | |
| {%- endfor -%} | |
| {{- ']' -}} | |
| {%- else -%} | |
| {{- argument -}} | |
| {%- endif -%} | |
| {%- endmacro -%} | |
| {%- macro strip_thinking(text) -%} | |
| {%- if text is string -%} | |
| {%- set ns = namespace(result='') -%} | |
| {%- for part in text.split('<channel|>') -%} | |
| {%- if '<|channel>' in part -%} | |
| {%- set ns.result = ns.result + part.split('<|channel>')[0] -%} | |
| {%- else -%} | |
| {%- set ns.result = ns.result + part -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {{- ns.result | trim -}} | |
| {%- endif -%} | |
| {%- endmacro -%} | |
| {%- macro format_tool_response_block(tool_name, response) -%} | |
| {{- '<|tool_response>' -}} | |
| {%- if response is mapping -%} | |
| {{- 'response:' + tool_name + '{' -}} | |
| {%- for key, value in response | dictsort -%} | |
| {{- key -}}:{{- format_argument(value, escape_keys=False) -}} | |
| {%- if not loop.last %},{% endif -%} | |
| {%- endfor -%} | |
| {{- '}' -}} | |
| {%- else -%} | |
| {{- 'response:' + tool_name + '{value:' + format_argument(response, escape_keys=False) + '}' -}} | |
| {%- endif -%} | |
| {{- '<tool_response|>' -}} | |
| {%- endmacro -%} | |
| {%- set ns = namespace(prev_message_type=None) -%} | |
| {%- set loop_messages = messages -%} | |
| {{- bos_token -}} | |
| {#- Handle System/Tool Definitions Block -#} | |
| {%- if (enable_thinking is defined and enable_thinking) or tools or messages[0]['role'] in ['system', 'developer'] -%} | |
| {{- '<|turn>system\n' -}} | |
| {#- Inject Thinking token at the very top of the FIRST system turn -#} | |
| {%- if enable_thinking is defined and enable_thinking -%} | |
| {{- '<|think|>\n' -}} | |
| {%- set ns.prev_message_type = 'think' -%} | |
| {%- endif -%} | |
| {%- if messages[0]['role'] in ['system', 'developer'] -%} | |
| {%- if messages[0]['content'] is string -%} | |
| {{- messages[0]['content'] | trim -}} | |
| {%- elif messages[0]['content'] is iterable and messages[0]['content'] is not string -%} | |
| {%- for item in messages[0]['content'] -%} | |
| {%- if item['text'] is defined and item['text'] is not none -%} | |
| {{- item['text'] | trim + ' '-}} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| {%- set loop_messages = messages[1:] -%} | |
| {%- endif -%} | |
| {%- if tools -%} | |
| {%- for tool in tools %} | |
| {{- '<|tool>' -}} | |
| {{- format_function_declaration(tool) | trim -}} | |
| {{- '<tool|>' -}} | |
| {%- endfor %} | |
| {%- set ns.prev_message_type = 'tool' -%} | |
| {%- endif -%} | |
| {{- '<turn|>\n' -}} | |
| {%- endif %} | |
| {#- Pre-scan: find last user message index for reasoning guard -#} | |
| {%- set ns_turn = namespace(last_user_idx=-1) -%} | |
| {%- for i in range(loop_messages | length) -%} | |
| {%- if loop_messages[i]['role'] == 'user' -%} | |
| {%- set ns_turn.last_user_idx = i -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {#- Loop through messages -#} | |
| {%- for message in loop_messages -%} | |
| {%- if message['role'] != 'tool' -%} | |
| {%- set ns.prev_message_type = None -%} | |
| {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%} | |
| {#- Detect continuation: suppress duplicate <|turn>model when previous non-tool message was also assistant -#} | |
| {%- set prev_nt = namespace(role=None, found=false) -%} | |
| {%- if loop.index0 > 0 -%} | |
| {%- for j in range(loop.index0 - 1, -1, -1) -%} | |
| {%- if not prev_nt.found -%} | |
| {%- if loop_messages[j]['role'] != 'tool' -%} | |
| {%- set prev_nt.role = loop_messages[j]['role'] -%} | |
| {%- set prev_nt.found = true -%} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| {%- set continue_same_model_turn = (role == 'model' and prev_nt.role == 'assistant') -%} | |
| {%- if not continue_same_model_turn -%} | |
| {{- '<|turn>' + role + '\n' }} | |
| {%- endif -%} | |
| {#- Render reasoning/reasoning_content as thinking channel -#} | |
| {%- set thinking_text = none -%} | |
| {%- if message['reasoning'] is defined and message['reasoning'] is not none -%} | |
| {%- set thinking_text = message['reasoning'] -%} | |
| {%- elif message['reasoning_content'] is defined and message['reasoning_content'] is not none -%} | |
| {%- set thinking_text = message['reasoning_content'] -%} | |
| {%- endif -%} | |
| {%- set message_tool_calls = [] -%} | |
| {%- if message['tool_calls'] is defined and message['tool_calls'] is not none -%} | |
| {%- set message_tool_calls = message['tool_calls'] -%} | |
| {%- endif -%} | |
| {%- if thinking_text and loop.index0 > ns_turn.last_user_idx and message_tool_calls -%} | |
| {{- '<|channel>thought\n' + thinking_text + '\n<channel|>' -}} | |
| {%- endif -%} | |
| {%- if message_tool_calls -%} | |
| {%- for tool_call in message_tool_calls -%} | |
| {%- set function = tool_call['function'] -%} | |
| {%- set function_arguments = function['arguments'] -%} | |
| {%- if function_arguments is mapping -%} | |
| {{- '<|tool_call>call:' + function['name'] + '{' -}} | |
| {%- set ns_args = namespace(found_first=false) -%} | |
| {%- for key, value in function_arguments | dictsort -%} | |
| {%- if ns_args.found_first %},{% endif -%} | |
| {%- set ns_args.found_first = true -%} | |
| {{- key -}}:{{- format_argument(value, escape_keys=False) -}} | |
| {%- endfor -%} | |
| {{- '}<tool_call|>' -}} | |
| {%- elif function_arguments is string -%} | |
| {%- set trimmed_arguments = function_arguments | trim -%} | |
| {%- set arguments_length = trimmed_arguments | length -%} | |
| {%- set starts_with_object = arguments_length > 0 and trimmed_arguments[:1] == '{' -%} | |
| {%- set ends_with_object = arguments_length > 0 and trimmed_arguments[arguments_length - 1:] == '}' -%} | |
| {%- if starts_with_object and ends_with_object -%} | |
| {{- '<|tool_call>call:' + function['name'] + trimmed_arguments + '<tool_call|>' -}} | |
| {%- else -%} | |
| {{- '<|tool_call>call:' + function['name'] + '{' + trimmed_arguments + '}<tool_call|>' -}} | |
| {%- endif -%} | |
| {%- else -%} | |
| {{- '<|tool_call>call:' + function['name'] + '{}<tool_call|>' -}} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- set ns.prev_message_type = 'tool_call' -%} | |
| {%- endif -%} | |
| {%- set ns_tr_out = namespace(flag=false) -%} | |
| {%- if message['tool_responses'] is defined and message['tool_responses'] -%} | |
| {#- Legacy: tool_responses embedded on the assistant message (Google/Gemma native) -#} | |
| {%- for tool_response in message['tool_responses'] -%} | |
| {{- format_tool_response_block(tool_response['name'] | default('unknown'), tool_response['response']) -}} | |
| {%- set ns_tr_out.flag = true -%} | |
| {%- set ns.prev_message_type = 'tool_response' -%} | |
| {%- endfor -%} | |
| {%- elif message_tool_calls -%} | |
| {#- OpenAI Chat Completions: forward-scan consecutive role:tool messages -#} | |
| {%- set ns_tool_scan = namespace(stopped=false) -%} | |
| {%- for k in range(loop.index0 + 1, loop_messages | length) -%} | |
| {%- if ns_tool_scan.stopped -%} | |
| {%- elif loop_messages[k]['role'] != 'tool' -%} | |
| {%- set ns_tool_scan.stopped = true -%} | |
| {%- else -%} | |
| {%- set follow = loop_messages[k] -%} | |
| {#- Resolve tool_call_id to function name -#} | |
| {%- set ns_tname = namespace(name='unknown') -%} | |
| {%- if follow['name'] is defined and follow['name'] is not none -%} | |
| {%- set ns_tname.name = follow['name'] -%} | |
| {%- endif -%} | |
| {%- for tc in message_tool_calls -%} | |
| {%- if tc['id'] is defined and follow['tool_call_id'] is defined and tc['id'] == follow['tool_call_id'] -%} | |
| {%- set ns_tname.name = tc['function']['name'] -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {#- Handle content as string or content-parts array -#} | |
| {%- set tool_body = none -%} | |
| {%- if follow['content'] is defined -%} | |
| {%- set tool_body = follow['content'] -%} | |
| {%- endif -%} | |
| {%- if tool_body is string -%} | |
| {{- format_tool_response_block(ns_tname.name, tool_body) -}} | |
| {%- elif tool_body is iterable and tool_body is not string -%} | |
| {%- set ns_txt = namespace(s='') -%} | |
| {%- for part in tool_body -%} | |
| {%- if part['type'] is defined and part['type'] == 'text' -%} | |
| {%- if part['text'] is defined and part['text'] is not none -%} | |
| {%- set ns_txt.s = ns_txt.s + part['text'] -%} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {{- format_tool_response_block(ns_tname.name, ns_txt.s) -}} | |
| {%- for part in tool_body -%} | |
| {%- if part['type'] is defined and part['type'] == 'image' -%} | |
| {{- '<|image|>' -}} | |
| {%- elif part['type'] is defined and part['type'] == 'audio' -%} | |
| {{- '<|audio|>' -}} | |
| {%- elif part['type'] is defined and part['type'] == 'video' -%} | |
| {{- '<|video|>' -}} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- else -%} | |
| {{- format_tool_response_block(ns_tname.name, tool_body) -}} | |
| {%- endif -%} | |
| {%- set ns_tr_out.flag = true -%} | |
| {%- set ns.prev_message_type = 'tool_response' -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| {%- set captured_content -%} | |
| {%- if message['content'] is string -%} | |
| {%- if role == 'model' -%} | |
| {{- strip_thinking(message['content']) -}} | |
| {%- else -%} | |
| {{- message['content'] | trim -}} | |
| {%- endif -%} | |
| {%- elif message['content'] is iterable and message['content'] is not string -%} | |
| {%- for item in message['content'] -%} | |
| {%- if item['type'] == 'text' -%} | |
| {%- if item['text'] is defined and item['text'] is not none -%} | |
| {%- if role == 'model' -%} | |
| {{- strip_thinking(item['text']) -}} | |
| {%- else -%} | |
| {{- item['text'] | trim -}} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- elif item['type'] == 'image' -%} | |
| {{- '<|image|>' -}} | |
| {%- set ns.prev_message_type = 'image' -%} | |
| {%- elif item['type'] == 'audio' -%} | |
| {{- '<|audio|>' -}} | |
| {%- set ns.prev_message_type = 'audio' -%} | |
| {%- elif item['type'] == 'video' -%} | |
| {{- '<|video|>' -}} | |
| {%- set ns.prev_message_type = 'video' -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| {%- endset -%} | |
| {{- captured_content -}} | |
| {%- set has_content = captured_content | trim | length > 0 -%} | |
| {%- if ns.prev_message_type == 'tool_call' and not ns_tr_out.flag -%} | |
| {{- '<|tool_response>' -}} | |
| {%- elif not (ns_tr_out.flag and not has_content) -%} | |
| {{- '<turn|>\n' -}} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- if add_generation_prompt -%} | |
| {%- if ns.prev_message_type != 'tool_response' and ns.prev_message_type != 'tool_call' -%} | |
| {{- '<|turn>model\n' -}} | |
| {%- if not enable_thinking | default(false) -%} | |
| {{- '<|channel>thought\n<channel|>' -}} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endif -%} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {{- bos_token -}} | |
| {%- set keep_past_thinking = keep_past_thinking | default(false) -%} | |
| {%- set ns = namespace(system_prompt="") -%} | |
| {%- if messages[0]["role"] == "system" -%} | |
| {%- set ns.system_prompt = messages[0]["content"] -%} | |
| {%- set messages = messages[1:] -%} | |
| {%- endif -%} | |
| {%- if tools -%} | |
| {%- set ns.system_prompt = ns.system_prompt + ("\n" if ns.system_prompt else "") + "List of tools: [" -%} | |
| {%- for tool in tools -%} | |
| {%- if tool is not string -%} | |
| {%- set tool = tool | tojson -%} | |
| {%- endif -%} | |
| {%- set ns.system_prompt = ns.system_prompt + tool -%} | |
| {%- if not loop.last -%} | |
| {%- set ns.system_prompt = ns.system_prompt + ", " -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- set ns.system_prompt = ns.system_prompt + "]" -%} | |
| {%- endif -%} | |
| {%- if ns.system_prompt -%} | |
| {{- "<|im_start|>system\n" + ns.system_prompt + "<|im_end|>\n" -}} | |
| {%- endif -%} | |
| {%- set ns.last_assistant_index = -1 -%} | |
| {%- for message in messages -%} | |
| {%- if message["role"] == "assistant" -%} | |
| {%- set ns.last_assistant_index = loop.index0 -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- for message in messages -%} | |
| {{- "<|im_start|>" + message["role"] + "\n" -}} | |
| {%- if message.get('tool_calls') %} | |
| {# ───── create a list to append tool calls to ───── #} | |
| {%- set tool_calls_ns = namespace(tool_calls=[])%} | |
| {%- for tool_call in message['tool_calls'] %} | |
| {%- set func_name = tool_call['function']['name'] %} | |
| {%- set func_args = tool_call['function']['arguments'] %} | |
| {# ───── create a list of func_arg strings to accumulate for each tool call ───── #} | |
| {%- set args_ns = namespace(arg_strings=[])%} | |
| {%- for arg_name, arg_value in func_args.items() %} | |
| {%- if arg_value is none %} | |
| {%- set formatted_arg_value = 'null' %} | |
| {%- elif arg_value is boolean %} | |
| {%- set formatted_arg_value = 'True' if arg_value else 'False' %} | |
| {%- elif arg_value is string %} | |
| {%- set formatted_arg_value = '"' ~ arg_value ~ '"' %} | |
| {%- elif arg_value is mapping or arg_value is iterable %} | |
| {%- set formatted_arg_value = arg_value | tojson %} | |
| {%- else %} | |
| {%- set formatted_arg_value = arg_value | string %} | |
| {%- endif %} | |
| {# ───── format each argument key,value pair ───── #} | |
| {%- set args_ns.arg_strings = args_ns.arg_strings + [arg_name ~ '=' ~ formatted_arg_value] %} | |
| {%- endfor %} | |
| {# ───── append each formatted tool call ───── #} | |
| {%- set tool_calls_ns.tool_calls = tool_calls_ns.tool_calls + [(func_name + '(' + (args_ns.arg_strings | join(", ")) + ')' )]%} | |
| {%- endfor %} | |
| {# ───── format the final tool calls ───── #} | |
| {{-'<|tool_call_start|>[' + (tool_calls_ns.tool_calls | join(", ")) + ']<|tool_call_end|>'}} | |
| {%- endif %} | |
| {%- set content = message["content"] -%} | |
| {%- if content is not string -%} | |
| {%- set content = content | tojson -%} | |
| {%- endif -%} | |
| {%- if message["role"] == "assistant" and not keep_past_thinking and loop.index0 != ns.last_assistant_index -%} | |
| {%- if "</think>" in content -%} | |
| {%- set content = content.split("</think>")[-1] | trim -%} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {{- content + "<|im_end|>\n" -}} | |
| {%- endfor -%} | |
| {%- if add_generation_prompt -%} | |
| {{- "<|im_start|>assistant\n" -}} | |
| {%- endif -%} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {{- bos_token }} | |
| {%- if custom_tools is defined %} | |
| {%- set tools = custom_tools %} | |
| {%- endif %} | |
| {%- if not tools_in_user_message is defined %} | |
| {%- set tools_in_user_message = true %} | |
| {%- endif %} | |
| {%- if not date_string is defined %} | |
| {%- if strftime_now is defined %} | |
| {%- set date_string = strftime_now("%d %b %Y") %} | |
| {%- else %} | |
| {%- set date_string = "26 Jul 2024" %} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- if not tools is defined %} | |
| {%- set tools = none %} | |
| {%- endif %} | |
| {#- This block extracts the system message, so we can slot it into the right place. #} | |
| {%- if messages[0]['role'] == 'system' %} | |
| {%- set system_message = messages[0]['content']|trim %} | |
| {%- set messages = messages[1:] %} | |
| {%- else %} | |
| {%- set system_message = "" %} | |
| {%- endif %} | |
| {#- System message #} | |
| {{- "<|start_header_id|>system<|end_header_id|>\n\n" }} | |
| {%- if tools is not none %} | |
| {{- "Environment: ipython\n" }} | |
| {%- endif %} | |
| {{- "Cutting Knowledge Date: December 2023\n" }} | |
| {{- "Today Date: " + date_string + "\n\n" }} | |
| {%- if tools is not none and not tools_in_user_message %} | |
| {{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }} | |
| {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }} | |
| {{- "Do not use variables.\n\n" }} | |
| {%- for t in tools %} | |
| {{- t | tojson(indent=4) }} | |
| {{- "\n\n" }} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- system_message }} | |
| {{- "<|eot_id|>" }} | |
| {#- Custom tools are passed in a user message with some extra guidance #} | |
| {%- if tools_in_user_message and not tools is none %} | |
| {#- Extract the first user message so we can plug it in here #} | |
| {%- if messages | length != 0 %} | |
| {%- if messages[0]['content'] is string %} | |
| {%- set first_user_message = messages[0]['content']|trim %} | |
| {%- else %} | |
| {#- expect messages[0]['content'] to be a list of objects #} | |
| {%- set first_user_message = messages[0]['content'][0]['text']|trim %} | |
| {%- endif %} | |
| {%- set messages = messages[1:] %} | |
| {%- else %} | |
| {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }} | |
| {%- endif %} | |
| {{- '<|start_header_id|>user<|end_header_id|>\n\n' -}} | |
| {{- "You are an expert in using functions/tools when necessary. You are given a query and a set of possible functions. "}} | |
| {{- "Based on the query, call one or more functions to achieve the purpose, if applicable.\n\n"}} | |
| {{- "If no functions apply, do not call any. Make sure to use any parameters specified as required. "}} | |
| {{- "If the given query lacks the parameters required by the function, "}} | |
| {{- "point it out. If a function response is given after you call a function, use it if it answers the query. "}} | |
| {{- "You should only output function calls in tool call sections.\n\n" }} | |
| {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument names and their values}. ' }} | |
| {{- "For number argument values, you do not need to wrap in quotes. If you use quotes, use double quotes. "}} | |
| {{- "Do not use variables. Here is a list of the only functions you can invoke, in JSON format.\n\n" }} | |
| {%- for t in tools %} | |
| {{- t | tojson(indent=4) }} | |
| {{- "\n\n" }} | |
| {%- endfor %} | |
| {{- first_user_message + "<|eot_id|>"}} | |
| {%- endif %} | |
| {%- for message in messages %} | |
| {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %} | |
| {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }} | |
| {%- elif 'tool_calls' in message %} | |
| {%- if not message.tool_calls|length == 1 %} | |
| {{- raise_exception("This model only supports single tool-calls at once!") }} | |
| {%- endif %} | |
| {%- set tool_call = message.tool_calls[0].function %} | |
| {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}} | |
| {{- '{"name": "' + tool_call.name + '", ' }} | |
| {{- '"parameters": ' }} | |
| {{- tool_call.arguments | tojson }} | |
| {{- "}" }} | |
| {{- "<|eot_id|>" }} | |
| {%- elif message.role == "tool" or message.role == "ipython" %} | |
| {{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }} | |
| {%- if message.content is iterable and message.content is not string %} | |
| {{- message.content | tojson }} | |
| {%- else %} | |
| {{- message.content }} | |
| {%- endif %} | |
| {{- "<|eot_id|>" }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if add_generation_prompt %} | |
| {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }} | |
| {%- endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {%- macro normalize_content(content) -%} | |
| {%- if content is string -%} | |
| {{- content -}} | |
| {%- elif content is iterable and content is not mapping -%} | |
| {%- set ns_c = namespace(text='') -%} | |
| {%- for part in content -%} | |
| {%- if part is mapping -%} | |
| {%- if part.type == 'text' -%} | |
| {%- set ns_c.text = ns_c.text + (part.text or '') -%} | |
| {%- elif part.type == 'tool-result' and part.output is mapping and part.output.type == 'text' -%} | |
| {%- set ns_c.text = ns_c.text + (part.output.value or '') -%} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {{- ns_c.text -}} | |
| {%- endif -%} | |
| {%- endmacro -%} | |
| {%- if tools %} | |
| {{- '<|im_start|>system\n' }} | |
| {%- if messages[0].role == 'system' %} | |
| {{- normalize_content(messages[0].content) + '\n\n' }} | |
| {%- endif %} | |
| {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }} | |
| {%- for tool in tools %} | |
| {{- "\n" }} | |
| {{- tool | tojson }} | |
| {%- endfor %} | |
| {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }} | |
| {%- else %} | |
| {%- if messages[0].role == 'system' %} | |
| {{- '<|im_start|>system\n' + normalize_content(messages[0].content) + '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- for message in messages %} | |
| {%- set content = normalize_content(message.content) %} | |
| {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} | |
| {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} | |
| {%- elif message.role == "assistant" %} | |
| {%- if '</think>' in content %} | |
| {%- set content = content.split('</think>')[-1].lstrip('\n') %} | |
| {%- endif %} | |
| {{- '<|im_start|>' + message.role + '\n' + content }} | |
| {%- if message.tool_calls %} | |
| {%- for tool_call in message.tool_calls %} | |
| {%- if (loop.first and content) or (not loop.first) %} | |
| {{- '\n' }} | |
| {%- endif %} | |
| {%- if tool_call.function %} | |
| {%- set tool_call = tool_call.function %} | |
| {%- endif %} | |
| {{- '<tool_call>\n{"name": "' }} | |
| {{- tool_call.name }} | |
| {{- '", "arguments": ' }} | |
| {%- if tool_call.arguments is string %} | |
| {{- tool_call.arguments }} | |
| {%- else %} | |
| {{- tool_call.arguments | tojson }} | |
| {%- endif %} | |
| {{- '}\n</tool_call>' }} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif message.role == "tool" %} | |
| {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} | |
| {{- '<|im_start|>user' }} | |
| {%- endif %} | |
| {{- '\n<tool_response>\n' }} | |
| {{- content }} | |
| {{- '\n</tool_response>' }} | |
| {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if add_generation_prompt %} | |
| {{- '<|im_start|>assistant\n' }} | |
| {%- endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {%- if messages[0]["role"] == "system" %} | |
| {%- set system_message = messages[0]["content"] %} | |
| {%- set loop_messages = messages[1:] %} | |
| {%- else %} | |
| {%- set loop_messages = messages %} | |
| {%- endif %} | |
| {%- if not tools is defined %} | |
| {%- set tools = none %} | |
| {%- endif %} | |
| {%- set user_messages = loop_messages | selectattr("role", "equalto", "user") | list %} | |
| {#- This block checks for alternating user/assistant messages, skipping tool calling messages #} | |
| {%- set ns = namespace() %} | |
| {%- set ns.index = 0 %} | |
| {%- for message in loop_messages %} | |
| {%- if not (message.role == "tool" or message.role == "tool_results" or (message.tool_calls is defined and message.tool_calls is not none)) %} | |
| {%- if (message["role"] == "user") != (ns.index % 2 == 0) %} | |
| {{- raise_exception("After the optional system message, conversation roles must alternate user/assistant/user/assistant/...") }} | |
| {%- endif %} | |
| {%- set ns.index = ns.index + 1 %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {{- bos_token }} | |
| {%- for message in loop_messages %} | |
| {%- if message["role"] == "user" %} | |
| {%- if tools is not none and (message == user_messages[-1]) %} | |
| {{- "[AVAILABLE_TOOLS][" }} | |
| {%- for tool in tools %} | |
| {%- set tool = tool.function %} | |
| {{- '{"type": "function", "function": {' }} | |
| {%- for key, val in tool.items() if key != "return" %} | |
| {%- if val is string %} | |
| {{- '"' + key + '": "' + val + '"' }} | |
| {%- else %} | |
| {{- '"' + key + '": ' + val|tojson }} | |
| {%- endif %} | |
| {%- if not loop.last %} | |
| {{- ", " }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {{- "}}" }} | |
| {%- if not loop.last %} | |
| {{- ", " }} | |
| {%- else %} | |
| {{- "]" }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {{- "[/AVAILABLE_TOOLS]" }} | |
| {%- endif %} | |
| {%- if loop.last and system_message is defined %} | |
| {{- "[INST]" + system_message + "\n\n" + message["content"] + "[/INST]" }} | |
| {%- else %} | |
| {{- "[INST]" + message["content"] + "[/INST]" }} | |
| {%- endif %} | |
| {%- elif (message.tool_calls is defined and message.tool_calls is not none) %} | |
| {{- "[TOOL_CALLS][" }} | |
| {%- for tool_call in message.tool_calls %} | |
| {%- set out = tool_call.function|tojson %} | |
| {{- out[:-1] }} | |
| {%- if not tool_call.id is defined or tool_call.id|length != 9 %} | |
| {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }} | |
| {%- endif %} | |
| {{- ', "id": "' + tool_call.id + '"}' }} | |
| {%- if not loop.last %} | |
| {{- ", " }} | |
| {%- else %} | |
| {{- "]" + eos_token }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- elif message["role"] == "assistant" %} | |
| {{- message["content"] + eos_token}} | |
| {%- elif message["role"] == "tool_results" or message["role"] == "tool" %} | |
| {%- if message.content is defined and message.content.content is defined %} | |
| {%- set content = message.content.content %} | |
| {%- else %} | |
| {%- set content = message.content %} | |
| {%- endif %} | |
| {{- '[TOOL_RESULTS]{"content": ' + content|string + ", " }} | |
| {%- if not message.tool_call_id is defined or message.tool_call_id|length != 9 %} | |
| {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }} | |
| {%- endif %} | |
| {{- '"call_id": "' + message.tool_call_id + '"}[/TOOL_RESULTS]' }} | |
| {%- else %} | |
| {{- raise_exception("Only user and assistant roles are supported, with the exception of an initial optional system message!") }} | |
| {%- endif %} | |
| {%- endfor %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% macro render_extra_keys(json_dict, handled_keys) %} | |
| {%- if json_dict is mapping %} | |
| {%- for json_key in json_dict if json_key not in handled_keys %} | |
| {%- if json_dict[json_key] is mapping or (json_dict[json_key] is iterable and json_dict[json_key] is not string) %} | |
| {{- '\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | tojson) ~ '</' ~ json_key ~ '>' }} | |
| {%- else %} | |
| {{-'\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | string) ~ '</' ~ json_key ~ '>' }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {% endmacro %} | |
| {%- set enable_thinking = enable_thinking if enable_thinking is defined else True %} | |
| {%- set truncate_history_thinking = truncate_history_thinking if truncate_history_thinking is defined else True %} | |
| {%- set ns = namespace(last_user_idx = -1) %} | |
| {%- set loop_messages = messages %} | |
| {%- for m in loop_messages %} | |
| {%- if m["role"] == "user" %} | |
| {%- set ns.last_user_idx = loop.index0 %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if messages[0]["role"] == "system" %} | |
| {%- set system_message = messages[0]["content"] %} | |
| {%- set loop_messages = messages[1:] %} | |
| {%- else %} | |
| {%- set system_message = "" %} | |
| {%- set loop_messages = messages %} | |
| {%- endif %} | |
| {%- if not tools is defined %} | |
| {%- set tools = [] %} | |
| {%- endif %} | |
| {# Recompute last_user_idx relative to loop_messages after handling system #} | |
| {%- set ns = namespace(last_user_idx = -1) %} | |
| {%- for m in loop_messages %} | |
| {%- if m["role"] == "user" %} | |
| {%- set ns.last_user_idx = loop.index0 %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if system_message is defined %} | |
| {{- "<|im_start|>system\n" + system_message }} | |
| {%- else %} | |
| {%- if tools is iterable and tools | length > 0 %} | |
| {{- "<|im_start|>system\n" }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- if tools is iterable and tools | length > 0 %} | |
| {%- if system_message is defined and system_message | length > 0 %} | |
| {{- "\n\n" }} | |
| {%- endif %} | |
| {{- "# Tools\n\nYou have access to the following functions:\n\n" }} | |
| {{- "<tools>" }} | |
| {%- for tool in tools %} | |
| {%- if tool.function is defined %} | |
| {%- set tool = tool.function %} | |
| {%- endif %} | |
| {{- "\n<function>\n<name>" ~ tool.name ~ "</name>" }} | |
| {%- if tool.description is defined %} | |
| {{- '\n<description>' ~ (tool.description | trim) ~ '</description>' }} | |
| {%- endif %} | |
| {{- '\n<parameters>' }} | |
| {%- if tool.parameters is defined and tool.parameters is mapping and tool.parameters.properties is defined and tool.parameters.properties is mapping %} | |
| {%- for param_name, param_fields in tool.parameters.properties|items %} | |
| {{- '\n<parameter>' }} | |
| {{- '\n<name>' ~ param_name ~ '</name>' }} | |
| {%- if param_fields.type is defined %} | |
| {{- '\n<type>' ~ (param_fields.type | string) ~ '</type>' }} | |
| {%- endif %} | |
| {%- if param_fields.description is defined %} | |
| {{- '\n<description>' ~ (param_fields.description | trim) ~ '</description>' }} | |
| {%- endif %} | |
| {%- if param_fields.enum is defined %} | |
| {{- '\n<enum>' ~ (param_fields.enum | tojson) ~ '</enum>' }} | |
| {%- endif %} | |
| {%- set handled_keys = ['name', 'type', 'description', 'enum'] %} | |
| {{- render_extra_keys(param_fields, handled_keys) }} | |
| {{- '\n</parameter>' }} | |
| {%- endfor %} | |
| {%- endif %} | |
| {% set handled_keys = ['type', 'properties', 'required'] %} | |
| {{- render_extra_keys(tool.parameters, handled_keys) }} | |
| {%- if tool.parameters is defined and tool.parameters.required is defined %} | |
| {{- '\n<required>' ~ (tool.parameters.required | tojson) ~ '</required>' }} | |
| {%- endif %} | |
| {{- '\n</parameters>' }} | |
| {%- set handled_keys = ['type', 'name', 'description', 'parameters'] %} | |
| {{- render_extra_keys(tool, handled_keys) }} | |
| {{- '\n</function>' }} | |
| {%- endfor %} | |
| {{- "\n</tools>" }} | |
| {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }} | |
| {%- endif %} | |
| {%- if system_message is defined %} | |
| {{- '<|im_end|>\n' }} | |
| {%- else %} | |
| {%- if tools is iterable and tools | length > 0 %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- for message in loop_messages %} | |
| {%- if message.role == "assistant" %} | |
| {# Add reasoning content in to content field for unified processing below. #} | |
| {%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %} | |
| {%- set content = "<think>\n" ~ message.reasoning_content ~ "\n</think>\n" ~ (message.content | default('', true)) %} | |
| {%- else %} | |
| {%- set content = message.content | default('', true) %} | |
| {%- if content is string -%} | |
| {# Allow downstream logic to to take care of broken thought, only handle coherent reasoning here. #} | |
| {%- if '<think>' not in content and '</think>' not in content -%} | |
| {%- set content = "<think></think>" ~ content -%} | |
| {# Fix content with closing think but not opening #} | |
| {%- elif '<think>' not in content and '</think>' in content -%} | |
| {%- set content = "<think> | |
| " ~ content -%} | |
| {%- endif -%} | |
| {%- else -%} | |
| {%- set content = content -%} | |
| {%- endif -%} | |
| {%- endif %} | |
| {%- if message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %} | |
| {# Assistant message has tool calls. #} | |
| {{- '<|im_start|>assistant\n' }} | |
| {%- set include_content = not (truncate_history_thinking and loop.index0 < ns.last_user_idx) %} | |
| {%- if content is string and content | trim | length > 0 %} | |
| {%- if include_content %} | |
| {{- (content | trim) ~ '\n' -}} | |
| {%- else %} | |
| {%- set c = (content | string) %} | |
| {%- if '</think>' in c %} | |
| {# Keep only content after the last closing think. Also generation prompt causes this. #} | |
| {%- set c = c.split('</think>')[-1] %} | |
| {%- elif '<think>' in c %} | |
| {# If <think> was opened but never closed, drop the trailing think segment #} | |
| {%- set c = c.split('<think>')[0] %} | |
| {%- endif %} | |
| {%- set c = "<think></think>" ~ c | trim %} | |
| {%- if c | length > 0 %} | |
| {{- c ~ '\n' -}} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- else %} | |
| {{- "<think></think>" -}} | |
| {%- endif %} | |
| {%- for tool_call in message.tool_calls %} | |
| {%- if tool_call.function is defined %} | |
| {%- set tool_call = tool_call.function %} | |
| {%- endif %} | |
| {{- '<tool_call>\n<function=' ~ tool_call.name ~ '>\n' -}} | |
| {%- if tool_call.arguments is defined %} | |
| {%- for args_name, args_value in tool_call.arguments|items %} | |
| {{- '<parameter=' ~ args_name ~ '>\n' -}} | |
| {%- set args_value = args_value | tojson if args_value is mapping or (args_value is iterable and args_value is not string) else args_value | string %} | |
| {{- args_value ~ '\n</parameter>\n' -}} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '</function>\n</tool_call>\n' -}} | |
| {%- endfor %} | |
| {{- '<|im_end|>\n' }} | |
| {%- else %} | |
| {# Assistant message doesn't have tool calls. #} | |
| {%- if not (truncate_history_thinking and loop.index0 < ns.last_user_idx) %} | |
| {{- '<|im_start|>assistant\n' ~ (content | default('', true) | string | trim) ~ '<|im_end|>\n' }} | |
| {%- else %} | |
| {%- set c = (content | default('', true) | string) %} | |
| {%- if '<think>' in c and '</think>' in c %} | |
| {%- set c = "<think></think>" ~ c.split('</think>')[-1] %} | |
| {%- endif %} | |
| {%- set c = c | trim %} | |
| {%- if c | length > 0 %} | |
| {{- '<|im_start|>assistant\n' ~ c ~ '<|im_end|>\n' }} | |
| {%- else %} | |
| {{- '<|im_start|>assistant\n<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- elif message.role == "user" or message.role == "system" %} | |
| {{- '<|im_start|>' + message.role + '\n' }} | |
| {%- set content = message.content | string %} | |
| {{- content }} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif message.role == "tool" %} | |
| {%- if loop.previtem and loop.previtem.role != "tool" %} | |
| {{- '<|im_start|>user\n' }} | |
| {%- endif %} | |
| {{- '<tool_response>\n' }} | |
| {{- message.content }} | |
| {{- '\n</tool_response>\n' }} | |
| {%- if not loop.last and loop.nextitem.role != "tool" %} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif loop.last %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- else %} | |
| {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if add_generation_prompt %} | |
| {%- if enable_thinking %} | |
| {{- '<|im_start|>assistant\n<think>\n' }} | |
| {%- else %} | |
| {{- '<|im_start|>assistant\n<think></think>' }} | |
| {%- endif %} | |
| {%- endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {{ '<|system|>Your name is Phi, an AI math expert developed by Microsoft.' }}{% for message in messages %}{% if message['role'] == 'system' %} {{ message['content'] }}{% if 'tools' in message and message['tools'] is not none %}{{ '<|tool|>' + message['tools'] + '<|/tool|>' }}{% endif %}{% endif %}{% endfor %}{{ '<|end|>' }}{% for message in messages %}{% if message['role'] != 'system' %}{{ '<|' + message['role'] + '|>' + message['content'] + '<|end|>' }}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ '<|assistant|>' }}{% else %}{{ eos_token }}{% endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {%- if tools %} | |
| {{- '<|im_start|>system\n' }} | |
| {%- if messages[0]['role'] == 'system' %} | |
| {{- messages[0]['content'] }} | |
| {%- else %} | |
| {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }} | |
| {%- endif %} | |
| {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }} | |
| {%- for tool in tools %} | |
| {{- "\n" }} | |
| {{- tool | tojson }} | |
| {%- endfor %} | |
| {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }} | |
| {%- else %} | |
| {%- if messages[0]['role'] == 'system' %} | |
| {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }} | |
| {%- else %} | |
| {{- '<|im_start|>system\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- for message in messages %} | |
| {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %} | |
| {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} | |
| {%- elif message.role == "assistant" %} | |
| {{- '<|im_start|>' + message.role }} | |
| {%- if message.content %} | |
| {{- '\n' + message.content }} | |
| {%- endif %} | |
| {%- for tool_call in message.tool_calls %} | |
| {%- if tool_call.function is defined %} | |
| {%- set tool_call = tool_call.function %} | |
| {%- endif %} | |
| {{- '\n<tool_call>\n{"name": "' }} | |
| {{- tool_call.name }} | |
| {{- '", "arguments": ' }} | |
| {{- tool_call.arguments | tojson }} | |
| {{- '}\n</tool_call>' }} | |
| {%- endfor %} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif message.role == "tool" %} | |
| {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} | |
| {{- '<|im_start|>user' }} | |
| {%- endif %} | |
| {{- '\n<tool_response>\n' }} | |
| {{- message.content }} | |
| {{- '\n</tool_response>' }} | |
| {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if add_generation_prompt %} | |
| {{- '<|im_start|>assistant\n' }} | |
| {%- endif %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {%- if tools %} | |
| {{- '<|im_start|>system\n' }} | |
| {%- if messages[0].role == 'system' %} | |
| {%- if messages[0].content is string %} | |
| {{- messages[0].content }} | |
| {%- else %} | |
| {%- for content in messages[0].content %} | |
| {%- if 'text' in content %} | |
| {{- content.text }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '\n\n' }} | |
| {%- endif %} | |
| {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }} | |
| {%- for tool in tools %} | |
| {{- "\n" }} | |
| {{- tool | tojson }} | |
| {%- endfor %} | |
| {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }} | |
| {%- else %} | |
| {%- if messages[0].role == 'system' %} | |
| {{- '<|im_start|>system\n' }} | |
| {%- if messages[0].content is string %} | |
| {{- messages[0].content }} | |
| {%- else %} | |
| {%- for content in messages[0].content %} | |
| {%- if 'text' in content %} | |
| {{- content.text }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- set image_count = namespace(value=0) %} | |
| {%- set video_count = namespace(value=0) %} | |
| {%- for message in messages %} | |
| {%- if message.role == "user" %} | |
| {{- '<|im_start|>' + message.role + '\n' }} | |
| {%- if message.content is string %} | |
| {{- message.content }} | |
| {%- else %} | |
| {%- for content in message.content %} | |
| {%- if content.type == 'image' or 'image' in content or 'image_url' in content %} | |
| {%- set image_count.value = image_count.value + 1 %} | |
| {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%} | |
| <|vision_start|><|image_pad|><|vision_end|> | |
| {%- elif content.type == 'video' or 'video' in content %} | |
| {%- set video_count.value = video_count.value + 1 %} | |
| {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%} | |
| <|vision_start|><|video_pad|><|vision_end|> | |
| {%- elif 'text' in content %} | |
| {{- content.text }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif message.role == "assistant" %} | |
| {{- '<|im_start|>' + message.role + '\n' }} | |
| {%- if message.content is string %} | |
| {{- message.content }} | |
| {%- else %} | |
| {%- for content_item in message.content %} | |
| {%- if 'text' in content_item %} | |
| {{- content_item.text }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {%- if message.tool_calls %} | |
| {%- for tool_call in message.tool_calls %} | |
| {%- if (loop.first and message.content) or (not loop.first) %} | |
| {{- '\n' }} | |
| {%- endif %} | |
| {%- if tool_call.function %} | |
| {%- set tool_call = tool_call.function %} | |
| {%- endif %} | |
| {{- '<tool_call>\n{"name": "' }} | |
| {{- tool_call.name }} | |
| {{- '", "arguments": ' }} | |
| {%- if tool_call.arguments is string %} | |
| {{- tool_call.arguments }} | |
| {%- else %} | |
| {{- tool_call.arguments | tojson }} | |
| {%- endif %} | |
| {{- '}\n</tool_call>' }} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '<|im_end|>\n' }} | |
| {%- elif message.role == "tool" %} | |
| {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} | |
| {{- '<|im_start|>user' }} | |
| {%- endif %} | |
| {{- '\n<tool_response>\n' }} | |
| {%- if message.content is string %} | |
| {{- message.content }} | |
| {%- else %} | |
| {%- for content in message.content %} | |
| {%- if content.type == 'image' or 'image' in content or 'image_url' in content %} | |
| {%- set image_count.value = image_count.value + 1 %} | |
| {%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%} | |
| <|vision_start|><|image_pad|><|vision_end|> | |
| {%- elif content.type == 'video' or 'video' in content %} | |
| {%- set video_count.value = video_count.value + 1 %} | |
| {%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%} | |
| <|vision_start|><|video_pad|><|vision_end|> | |
| {%- elif 'text' in content %} | |
| {{- content.text }} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- endif %} | |
| {{- '\n</tool_response>' }} | |
| {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} | |
| {{- '<|im_end|>\n' }} | |
| {%- endif %} | |
| {%- endif %} | |
| {%- endfor %} | |
| {%- if add_generation_prompt %} | |
| {{- '<|im_start|>assistant\n' }} | |
| {%- endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment