danielhanchen commited on
Commit
05a487d
·
verified ·
1 Parent(s): 31f7cad

Update chat_template.jinja

Browse files
Files changed (1) hide show
  1. chat_template.jinja +119 -80
chat_template.jinja CHANGED
@@ -1,99 +1,138 @@
1
- {%- if tools %}
2
- {{- '<|im_start|>system\n' }}
3
- {%- if messages[0].role == 'system' %}
4
- {{- messages[0].content + '\n\n' }}
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  {%- endif %}
6
- {{- "# 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>" }}
7
- {%- for tool in tools %}
8
- {{- "\n" }}
9
- {{- tool | tojson }}
10
- {%- endfor %}
11
- {{- "\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" }}
12
  {%- else %}
13
- {%- if messages[0].role == 'system' %}
14
- {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
15
- {%- endif %}
16
  {%- endif %}
17
- {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
- {%- for forward_message in messages %}
19
- {%- set index = (messages|length - 1) - loop.index0 %}
20
- {%- set message = messages[index] %}
21
- {%- set current_content = message.content if message.content is defined and message.content is not none else '' %}
22
- {%- set tool_start = '<tool_response>' %}
23
- {%- set tool_start_length = tool_start|length %}
24
- {%- set start_of_message = current_content[:tool_start_length] %}
25
- {%- set tool_end = '</tool_response>' %}
26
- {%- set tool_end_length = tool_end|length %}
27
- {%- set start_pos = (current_content|length) - tool_end_length %}
28
- {%- if start_pos < 0 %}
29
- {%- set start_pos = 0 %}
30
- {%- endif %}
31
- {%- set end_of_message = current_content[start_pos:] %}
32
- {%- if ns.multi_step_tool and message.role == "user" and not(start_of_message == tool_start and end_of_message == tool_end) %}
33
- {%- set ns.multi_step_tool = false %}
34
- {%- set ns.last_query_index = index %}
35
  {%- endif %}
36
- {%- endfor %}
37
- {%- for message in messages %}
38
- {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
39
- {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
40
- {%- elif message.role == "assistant" %}
41
- {%- set m_content = message.content if message.content is defined and message.content is not none else '' %}
42
- {%- set content = m_content %}
43
- {%- set reasoning_content = '' %}
44
- {%- if message.reasoning_content is defined and message.reasoning_content is not none %}
45
- {%- set reasoning_content = message.reasoning_content %}
46
- {%- else %}
47
- {%- if '</think>' in m_content %}
48
- {%- set content = (m_content.split('</think>')|last).lstrip('\n') %}
49
- {%- set reasoning_content = (m_content.split('</think>')|first).rstrip('\n') %}
50
- {%- set reasoning_content = (reasoning_content.split('<think>')|last).lstrip('\n') %}
51
- {%- endif %}
52
  {%- endif %}
53
- {%- if loop.index0 > ns.last_query_index %}
54
- {%- if loop.last or (not loop.last and (not reasoning_content.strip() == '')) %}
55
- {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
56
- {%- else %}
57
- {{- '<|im_start|>' + message.role + '\n' + content }}
 
 
 
58
  {%- endif %}
59
- {%- else %}
60
- {{- '<|im_start|>' + message.role + '\n' + content }}
61
- {%- endif %}
62
- {%- if message.tool_calls %}
63
- {%- for tool_call in message.tool_calls %}
64
- {%- if (loop.first and content) or (not loop.first) %}
65
- {{- '\n' }}
66
- {%- endif %}
67
- {%- if tool_call.function %}
68
- {%- set tool_call = tool_call.function %}
69
- {%- endif %}
70
- {{- '<tool_call>\n{"name": "' }}
71
- {{- tool_call.name }}
72
- {{- '", "arguments": ' }}
73
- {%- if tool_call.arguments is string %}
74
- {{- tool_call.arguments }}
75
- {%- else %}
76
- {{- tool_call.arguments | tojson }}
77
  {%- endif %}
78
- {{- '}\n</tool_call>' }}
79
  {%- endfor %}
 
 
 
 
 
 
 
 
 
 
 
80
  {%- endif %}
 
 
 
 
 
 
 
 
 
81
  {{- '<|im_end|>\n' }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  {%- elif message.role == "tool" %}
83
- {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
84
- {{- '<|im_start|>user' }}
85
  {%- endif %}
86
- {{- '\n<tool_response>\n' }}
87
  {{- message.content }}
88
- {{- '\n</tool_response>' }}
89
- {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
 
 
90
  {{- '<|im_end|>\n' }}
91
  {%- endif %}
 
 
92
  {%- endif %}
93
  {%- endfor %}
94
  {%- if add_generation_prompt %}
95
  {{- '<|im_start|>assistant\n' }}
96
- {%- if enable_thinking is defined and enable_thinking is false %}
97
- {{- '<think>\n\n</think>\n\n' }}
98
- {%- endif %}
99
- {%- endif %}
 
1
+ {#- Copyright 2025-present the Unsloth team. All rights reserved. #}
2
+ {#- Licensed under the Apache License, Version 2.0 (the "License") #}
3
+ {#- Edits made by Unsloth to fix the chat template #}
4
+ {% macro render_item_list(item_list, tag_name='required') %}
5
+ {%- if item_list is defined and item_list is iterable and item_list | length > 0 %}
6
+ {%- if tag_name %}{{- '\n<' ~ tag_name ~ '>' -}}{% endif %}
7
+ {{- '[' }}
8
+ {%- for item in item_list -%}
9
+ {%- if loop.index > 1 %}{{- ", "}}{% endif -%}
10
+ {%- if item is string -%}
11
+ {{ "`" ~ item ~ "`" }}
12
+ {%- else -%}
13
+ {{ item }}
14
+ {%- endif -%}
15
+ {%- endfor -%}
16
+ {{- ']' }}
17
+ {%- if tag_name %}{{- '</' ~ tag_name ~ '>' -}}{% endif %}
18
  {%- endif %}
19
+ {% endmacro %}
20
+
21
+ {%- if messages[0]["role"] == "system" %}
22
+ {%- set system_message = messages[0]["content"] %}
23
+ {%- set loop_messages = messages[1:] %}
 
24
  {%- else %}
25
+ {%- set loop_messages = messages %}
 
 
26
  {%- endif %}
27
+
28
+ {%- if not tools is defined %}
29
+ {%- set tools = [] %}
30
+ {%- endif %}
31
+
32
+ {%- if system_message is defined %}
33
+ {{- "<|im_start|>system\n" + system_message }}
34
+ {%- else %}
35
+ {%- if tools is iterable and tools | length > 0 %}
36
+ {{- "<|im_start|>system\nYou are Qwen, a helpful AI assistant that can interact with a computer to solve tasks." }}
 
 
 
 
 
 
 
 
37
  {%- endif %}
38
+ {%- endif %}
39
+ {%- if tools is iterable and tools | length > 0 %}
40
+ {{- "\n\nYou have access to the following functions:\n\n" }}
41
+ {{- "<tools>" }}
42
+ {%- for tool in tools %}
43
+ {%- if tool.function is defined %}
44
+ {%- set tool = tool.function %}
 
 
 
 
 
 
 
 
 
45
  {%- endif %}
46
+ {{- "\n<function>\n<name>" ~ tool.name ~ "</name>" }}
47
+ {{- '\n<description>' ~ (tool.description | trim) ~ '</description>' }}
48
+ {{- '\n<parameters>' }}
49
+ {%- for param_name, param_fields in tool.parameters.properties|items %}
50
+ {{- '\n<parameter>' }}
51
+ {{- '\n<name>' ~ param_name ~ '</name>' }}
52
+ {%- if param_fields.type is defined %}
53
+ {{- '\n<type>' ~ (param_fields.type | string) ~ '</type>' }}
54
  {%- endif %}
55
+ {%- if param_fields.description is defined %}
56
+ {{- '\n<description>' ~ (param_fields.description | trim) ~ '</description>' }}
57
+ {%- endif %}
58
+ {{- render_item_list(param_fields.enum, 'enum') }}
59
+ {%- set handled_keys = ['type', 'description', 'enum', 'required'] %}
60
+ {%- for json_key in param_fields %}
61
+ {%- if json_key not in handled_keys %}
62
+ {%- set normed_json_key = json_key | replace("-", "_") | replace(" ", "_") | replace("$", "") %}
63
+ {%- if param_fields[json_key] is mapping %}
64
+ {{- '\n<' ~ normed_json_key ~ '>' ~ (param_fields[json_key] | tojson | safe) ~ '</' ~ normed_json_key ~ '>' }}
65
+ {%- else %}
66
+ {{- '\n<' ~ normed_json_key ~ '>' ~ (param_fields[json_key] | string) ~ '</' ~ normed_json_key ~ '>' }}
67
+ {%- endif %}
 
 
 
 
 
68
  {%- endif %}
 
69
  {%- endfor %}
70
+ {{- render_item_list(param_fields.required, 'required') }}
71
+ {{- '\n</parameter>' }}
72
+ {%- endfor %}
73
+ {{- render_item_list(tool.parameters.required, 'required') }}
74
+ {{- '\n</parameters>' }}
75
+ {%- if tool.return is defined %}
76
+ {%- if tool.return is mapping %}
77
+ {{- '\n<return>' ~ (tool.return | tojson | safe) ~ '</return>' }}
78
+ {%- else %}
79
+ {{- '\n<return>' ~ (tool.return | string) ~ '</return>' }}
80
+ {%- endif %}
81
  {%- endif %}
82
+ {{- '\n</function>' }}
83
+ {%- endfor %}
84
+ {{- "\n</tools>" }}
85
+ {{- '\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>' }}
86
+ {%- endif %}
87
+ {%- if system_message is defined %}
88
+ {{- '<|im_end|>\n' }}
89
+ {%- else %}
90
+ {%- if tools is iterable and tools | length > 0 %}
91
  {{- '<|im_end|>\n' }}
92
+ {%- endif %}
93
+ {%- endif %}
94
+ {%- for message in loop_messages %}
95
+ {%- if message.role == "assistant" and message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}
96
+ {{- '<|im_start|>' + message.role }}
97
+ {%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
98
+ {{- '\n' + message.content | trim + '\n' }}
99
+ {%- endif %}
100
+ {%- for tool_call in message.tool_calls %}
101
+ {%- if tool_call.function is defined %}
102
+ {%- set tool_call = tool_call.function %}
103
+ {%- endif %}
104
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
105
+ {%- if tool_call.arguments is defined %}
106
+ {%- for args_name, args_value in tool_call.arguments|items %}
107
+ {{- '<parameter=' + args_name + '>\n' }}
108
+ {%- set args_value = args_value if args_value is string else args_value | string %}
109
+ {{- args_value }}
110
+ {{- '\n</parameter>\n' }}
111
+ {%- endfor %}
112
+ {%- endif %}
113
+ {{- '</function>\n</tool_call>' }}
114
+ {%- endfor %}
115
+ {{- '<|im_end|>\n' }}
116
+ {%- elif message.role == "user" or message.role == "system" or message.role == "assistant" %}
117
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
118
  {%- elif message.role == "tool" %}
119
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
120
+ {{- '<|im_start|>user\n' }}
121
  {%- endif %}
122
+ {{- '<tool_response>\n' }}
123
  {{- message.content }}
124
+ {{- '\n</tool_response>\n' }}
125
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
126
+ {{- '<|im_end|>\n' }}
127
+ {%- elif loop.last %}
128
  {{- '<|im_end|>\n' }}
129
  {%- endif %}
130
+ {%- else %}
131
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>\n' }}
132
  {%- endif %}
133
  {%- endfor %}
134
  {%- if add_generation_prompt %}
135
  {{- '<|im_start|>assistant\n' }}
136
+ {%- endif %}
137
+ {#- Copyright 2025-present the Unsloth team. All rights reserved. #}
138
+ {#- Licensed under the Apache License, Version 2.0 (the "License") #}