1{# version=v3.llama3 #}{%- macro append_new_param_info(param_declaration, comment_info, examples_info, depth) -%}
  2    {%- set offset = "" -%}
  3    {%- if depth >= 1 -%}
  4        {%- set offset = "    " * depth -%}
  5    {%- endif -%}
  6    {%- if comment_info != "<|NONE|>" -%}
  7        {{ "\n" + offset + comment_info }}
  8        {%- if examples_info | length > 0 -%}
  9            {# Append each example info #}
 10            {%- for example in examples_info -%}
 11                {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
 12            {%- endfor -%}
 13        {%- endif -%}
 14    {%- endif -%}
 15    {{ "\n" + offset + param_declaration }}
 16{%- endmacro -%}
 17
 18{%- macro convert_data_type(param_type) -%}
 19    {%- if param_type == "integer" or param_type == "float" -%}
 20        {{ "number" }}
 21    {%- else -%}
 22        {{ param_type }}
 23    {%- endif -%}
 24{%- endmacro -%}
 25
 26{%- macro get_param_type(param) -%}
 27    {%- set param_type = "any" -%}
 28
 29    {%- if "type" in param -%}
 30        {%- set raw_param_type = param["type"] -%}
 31        {%- if raw_param_type is iterable and raw_param_type is not string -%}
 32            {%- set param_type = raw_param_type | join(" | ") -%}
 33        {%- else -%}
 34            {%- set param_type = raw_param_type -%}
 35        {%- endif -%}
 36        {{ convert_data_type(param_type) }}
 37    {%- elif "oneOf" in param -%}
 38        {%- set one_of_types = param["oneOf"]|selectattr("type", "defined")|list -%}
 39        {%- set one_of_types = one_of_types|map(attribute="type")|unique|list -%}
 40        {{ convert_data_type(one_of_types | join(" | ")) }}
 41    {%- endif -%}
 42{%- endmacro -%}
 43
 44{%- macro get_format_param(param) -%}
 45    {%- if "format" in param -%}
 46        {{ param["format"] }}
 47    {%- elif "oneOf" in param -%}
 48        {%- set formats = [] -%}
 49        {%- for item in param["oneOf"] -%}
 50            {%- if "format" in item -%}
 51                {%- if item["format"] == param["oneOf"][-1]["format"] -%}
 52                    {{ item["format"] }}
 53                {%- else -%}
 54                    {{ item["format"] + " or "}}
 55                {%- endif -%}
 56            {%- endif -%}
 57        {%- endfor -%}
 58    {%- else -%}
 59        {{ "<|NONE|>" }}
 60    {%- endif -%}
 61{%- endmacro -%}
 62
 63{%- macro get_param_info(param) -%}
 64    {%- set param_type = param.get("type", "any") -%}
 65    {%- set format_param = get_format_param(param) -%}
 66
 67    {%- if "description" in param or "default" in param or format_param != "<|NONE|>" or param["maximum"] or param["minimum"] or param["maxLength"] or param["minLength"] -%}
 68        {{ "//" }}
 69        {%- if "description" in param -%}
 70            {%- set desc = param["description"] -%}
 71            {%- if not desc.endswith(".") -%}
 72                {%- set desc = desc + "." -%}
 73            {%- endif -%}
 74            {{ " " + desc }}
 75        {%- endif -%}
 76
 77        {%- if "default" in param -%}
 78            {%- set default_value = param["default"] -%}
 79            {%- if param_type == "string" -%}
 80                {%- set default_value = '"' ~ default_value ~ '"' -%}
 81            {%- endif -%}
 82            {{ " Default=" ~ default_value ~ "." }}
 83        {%- endif -%}
 84
 85        {%- set format_param = get_format_param(param) -%}
 86        {%- if format_param != "<|NONE|>" -%}
 87            {{ " Format=" ~ format_param }}
 88        {%- endif -%}
 89
 90        {%- for field, field_name in [("maximum", "Maximum"), ("minimum", "Minimum"), ("maxLength", "Maximum length"), ("minLength", "Minimum length")] -%}
 91            {%- if field in param -%}
 92                {{ " " + field_name ~ "=" ~ param[field] }}
 93            {%- endif -%}
 94        {%- endfor -%}
 95    {%- else -%}
 96        {{ "<|NONE|>"}}
 97    {%- endif -%}
 98{%- endmacro -%}
 99
100{%- macro get_enum_option_str(enum_options) -%}
101    {%- for v in enum_options -%}
102        {%- if v is string -%}
103            {{ '"' + v + '"' }}
104        {%- else -%}
105            {{ v }}
106        {%- endif -%}
107        {%- if enum_options|length > 0 and v != enum_options[-1] -%}
108            {{ " | " }}
109        {%- endif -%}
110    {%- endfor -%}
111{%- endmacro -%}
112
113{%- macro get_array_typescript(param_name, param_dic, depth) -%}
114    {%- set offset = '' -%}
115    {%- if depth >= 1 -%}
116        {%- set offset = "    " * depth -%}
117    {%- endif -%}
118    {%- set items_info = param_dic.get('items', {}) -%}
119
120    {%- if items_info|length == 0 -%}
121        {%- if param_name -%}
122            {{ "\n" + offset + param_name + ": []" }}
123        {%- else -%}
124            {{ "\n" + offset + "[]" }}
125        {%- endif -%}
126    {%- else -%}
127        {%- set array_type = get_param_type(items_info) -%}
128        {%- if array_type == 'object' -%}
129            {%- if param_name -%}
130                {{ "\n" + offset + param_name + ": {" }}
131            {%- else -%}
132                {{ "\n" + offset + "{" }}
133            {%- endif -%}
134            {{ get_parameter_typescript(items_info.get('properties', {}), items_info.get('required', []), depth + 1) -}}
135            {{- "\n" + offset + "}[]" }}
136        {%- elif array_type == 'array' -%}
137            {%- set item_info = get_array_typescript(None, items_info, depth + 1) -%}
138            {%- if not param_name -%}
139                {{ "\n" + item_info + "[]" }}
140            {%- else -%}
141                {{ "\n" + offset + param_name + ": " + item_info|trim + "[]" }}
142            {%- endif -%}
143        {%- else -%}
144            {%- if 'enum' in items_info -%}
145                {%- set item_type = get_enum_option_str(items_info['enum']) -%}
146                {%- if param_name is none -%}
147                    {{ "(" + item_type + ")[]"}}
148                {%- else -%}
149                    {{ "\n" + offset + param_name + ": (" + item_type + ")[]" }}
150                {%- endif -%}
151            {%- else -%}
152                {%- if param_name is none -%}
153                    {{ "\n" + array_type + "[]" }}
154                {%- else -%}
155                    {{ "\n" + offset + param_name + ": " + array_type + "[]," }}
156                {%- endif -%}
157            {%- endif -%}
158        {%- endif -%}
159    {%- endif -%}
160{%- endmacro -%}
161
162{%- macro get_parameter_typescript(properties, required_params, depth=0) -%}
163    {%- set res = "" -%}
164    {%- for param_name, param in properties.items() -%}
165        {%- if param is mapping -%}
166            {%- set comment_info = get_param_info(param) -%}
167            {# Param Examples #}
168            {%- set examples_info = [] -%}
169            {%- if "examples" in param -%}
170                {%- set examples_info = ["Example " + param_name + ":"] -%}
171                {%- set examples_info = examples_info + param["examples"] -%}
172            {%- endif -%}
173
174            {# Param Name declaration #}
175            {%- set param_declaration = param_name -%}
176            {%- if required_params is iterable and param_name not in required_params -%}
177                {%- set param_declaration = param_declaration + "?" -%}
178            {%- endif -%}
179
180            {%- set param_type = get_param_type(param) -%}
181
182            {# Handle indentation based on depth #}
183            {%- set offset = "" -%}
184            {%- if depth >= 1 -%}
185                {%- set offset = "    " * depth -%}
186            {%- endif -%}
187
188            {%- if param_type == "object" -%}
189                {%- if comment_info != "<|NONE|>" -%}
190                    {{ "\n" + offset + comment_info }}
191                {%- endif -%}
192                {%- if examples_info|length > 0 -%}
193                    {%- for example in examples_info -%}
194                        {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
195                    {%- endfor -%}
196                {%- endif -%}
197                {%- set param_declaration = param_declaration + ": {" -%}
198                {{ "\n" + offset + param_declaration -}}
199                {{- get_parameter_typescript(param.get("properties", {}), param.get("required", []), depth + 1) -}}
200                {{- "\n" + offset + "}," }}
201            {%- elif param_type == "array" -%}
202                {%- set item_info = param.get("items", {}) -%}
203                {%- if "type" not in item_info -%}
204                    {%- set param_declaration = param_declaration + ": []," -%}
205                    {{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
206                {%- else -%}
207                    {%- if comment_info != "<|NONE|>" -%}
208                        {{ "\n" + offset + comment_info }}
209                    {%- endif -%}
210                    {%- if examples_info|length > 0 -%}
211                        {%- for example in examples_info -%}
212                            {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
213                        {%- endfor -%}
214                    {%- endif -%}
215                    {%- set array_declaration = get_array_typescript(param_declaration, param, depth) -%}
216                    {%- if not array_declaration.endswith(",") -%}
217                        {%- set array_declaration = array_declaration + "," -%}
218                    {%- endif -%}
219                    {{ array_declaration}}
220                {%- endif -%}
221            {%- else -%}
222                {%- if "enum" in param -%}
223                    {%- set param_type = get_enum_option_str(param["enum"]) -%}
224                {%- endif -%}
225                {%- if "nullable" in param and param["nullable"] -%}
226                    {%- set param_type = param_type + " | null" -%}
227                {%- endif -%}
228                {%- set param_declaration = param_declaration + ": " + param_type + "," -%}
229                {{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
230            {%- endif -%}
231        {%- endif -%}
232    {%- endfor -%}
233{%- endmacro -%}
234
235{%- macro generate_schema_from_functions(functions, namespace='functions') -%}
236    {{ "// Supported function definitions that should be called when necessary.\n" -}}
237    {{- "namespace " + namespace + " {\n\n" -}}
238
239    {%- for function in functions -%}
240        {%- if function.get("function") -%}
241            {%- set function = function.get("function") -%}
242        {%- endif -%}
243
244        {%- set function_name = function.get("name") -%}
245        {%- if function_name -%}
246            {%- set description = function.get('description', '') -%}
247            {%- set parameters = function.get('parameters', {}) -%}
248            {{- "// " + description + "\n" -}}
249            {{- "type " + function_name -}}
250            {%- if parameters and parameters.get("properties") -%}
251                {{- " = (_: {" -}}
252                {%- set required_params = parameters.get("required", []) -%}
253                {{ get_parameter_typescript(parameters.get("properties"), required_params, 0) -}}
254                {{- "\n}) => any;\n\n" }}
255            {%- else -%}
256                {{ " = () => any;\n\n" }}
257            {%- endif -%}
258        {%- endif -%}
259    {%- endfor -%}
260    {{ "} // namespace " + namespace }}
261{%- endmacro -%}
262{%- if not tools -%}
263    {%- set tools = [] -%}
264{%- endif -%}
265{{ bos_token + '<|start_header_id|>system<|end_header_id|>\n\nYou are capable of executing available function(s) if required.\nOnly execute function(s) when absolutely necessary.\nAsk for the required input to:recipient==all\nUse JSON for function arguments.\nRespond in this format:\n>>>${recipient}\n${content}\nAvailable functions:\n' + generate_schema_from_functions(tools) + '<|eot_id|>' -}}
266{%- if tools|length > 0 and tools|selectattr("type", "equalto", "code_interpreter")|list|length > 0 -%}
267    {{ '<|start_header_id|>system<|end_header_id|>\n\nWhen you send a message containing Python code to python, it will be executed in a stateful Jupyter notebook environment. python will respond with the output of the execution or time out after 60.0 seconds. The drive at \'/mnt/data\' can be used to save and persist user files.<|eot_id|>' }}
268{%- endif -%}
269{%- for message in messages -%}
270    {%- if message['role'] == 'user' or message['role'] == 'system' -%}
271        {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
272    {%- elif message['role'] == 'tool' -%}
273        {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
274    {%- else -%}
275        {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'}}
276        {%- if message['content'] -%}
277            {{ '>>>all\n' + message['content'] }}
278        {%- endif -%}
279        {%- if 'tool_calls' in message and message['tool_calls'] -%}
280            {%- for tool_call in message['tool_calls'] -%}
281                {{ '>>>' + tool_call['function']['name'] + '\n' + tool_call['function']['arguments'] }}
282            {%- endfor -%}
283        {%- endif -%}
284        {{ '<|eot_id|>' }}
285    {%- endif -%}
286{%- endfor -%}
287{% if add_generation_prompt %}{{ '<|start_header_id|>assistant<|end_header_id|>\n\n>>>' }}{% endif %}