{%- macro json_to_python_type(json_spec) -%}
{%- set basic_type_map = {"string": "str", "number": "float", "integer": "int", "boolean": "bool"} -%}
{%- if json_spec.type is defined and basic_type_map[json_spec.type] is defined -%}
{{- basic_type_map[json_spec.type] -}}
{%- elif json_spec.type is defined and json_spec.type == "array" -%}
{%- if json_spec.items is defined -%}
{{- "list[" + json_to_python_type(json_spec.items) + "]" -}}
{%- else -%}
{{- "list" -}}
{%- endif -%}
{%- elif json_spec.type is defined and json_spec.type == "object" -%}
{%- if json_spec.additionalProperties is defined -%}
{{- "dict[str, " + json_to_python_type(json_spec.additionalProperties) + "]" -}}
{%- else -%}
{{- "dict" -}}
{%- endif -%}
{%- elif json_spec.type is defined and json_spec.type is iterable and json_spec.type is not string -%}
{{- "Union[" -}}
{%- for t in json_spec.type -%}
{{- json_to_python_type({"type": t}) -}}
{%- if not loop.last -%}, {%- endif -%}
{%- endfor -%}
{{- "]" -}}
{%- else -%}
{{- "Any" -}}
{%- endif -%}
{%- endmacro -%}
{%- set add_generation_prompt = add_generation_prompt if add_generation_prompt is defined else false -%}
{{- bos_token -}}
{%- if tools is defined and tools|length > 0 -%}
{{- '<|start_header_id|>system<|end_header_id|>\n\nYou are a function calling AI model. You are provided with function signatures within XML tags. You may call one or more functions to assist with the user query. Don\'t make assumptions about what values to plug into functions. Here are the available tools: ' -}}
{%- for tool in tools -%}
{%- set t = tool.function if tool.function is defined else tool -%}
{{- '{"type": "function", "function": {"name": "' + t.name + '", "description": "' + t.name + '(' -}}
{%- if t.parameters is defined and t.parameters.properties is defined -%}
{%- for param_name, param_fields in t.parameters.properties.items() -%}
{{- param_name + ": " + json_to_python_type(param_fields) -}}
{%- if not loop.last -%}, {%- endif -%}
{%- endfor -%}
{%- endif -%}
{{- ")" -}}
{%- if t.return is defined -%}
{{- " -> " + json_to_python_type(t.return) -}}
{%- endif -%}
{{- " - " -}}
{%- if t.description is defined -%}
{{- t.description -}}
{%- else -%}
{{- "No description available" -}}
{%- endif -%}
{{- "\n\n Args:\n" -}}
{%- if t.parameters is defined and t.parameters.properties is defined -%}
{%- for param_name, param_fields in t.parameters.properties.items() -%}
{{- " " + param_name + "(" + json_to_python_type(param_fields) + "): " -}}
{%- if param_fields.description is defined -%}
{{- param_fields.description -}}
{%- else -%}
{{- "No description available" -}}
{%- endif -%}
{%- if not loop.last -%}\n{%- endif -%}
{%- endfor -%}
{%- else -%}
{{- " No parameters" -}}
{%- endif -%}
{%- if t.return is defined and t.return.description is defined -%}
{{- "\n Returns:\n " + t.return.description -}}
{%- endif -%}
{{- '", "parameters": ' -}}
{%- if t.parameters is defined and t.parameters.properties is defined and t.parameters.properties|length > 0 -%}
{{- t.parameters|tojson -}}
{%- else -%}
{{- "{}" -}}
{%- endif -%}
{{- "}" -}}
{%- if not loop.last -%}\n{%- endif -%}
{%- endfor -%}
{{- ' Use the following pydantic model json schema for each tool call you will make: {"properties": {"name": {"title": "Name", "type": "string"}, "arguments": {"title": "Arguments", "type": "object"}}, "required": ["name", "arguments"], "title": "FunctionCall", "type": "object"}\nFor each function call return a json object with function name and arguments within XML tags as follows:\n\n{"name": , "arguments": }\n' -}}
{%- for message in messages -%}
{%- if message.role == "system" -%}{{- '\n\n' + message.content -}}{%- endif -%}
{%- endfor -%}
{{- '<|eot_id|>' -}}
{%- endif -%}
{%- for message in messages -%}
{%- if message.role == "user" or (message.role == "assistant" and message.tool_calls is not defined) -%}
{{- '<|start_header_id|>' + message.role + '<|end_header_id|>\n\n' + message.content + '<|eot_id|>' -}}
{%- elif message.role == "assistant" -%}
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
{%- if message.tool_calls is defined -%}
{%- for tool_call in message.tool_calls -%}
{%- set tc = tool_call.function if tool_call.function is defined else tool_call -%}
{{- '\n{"name": "' + tc.name + '", "arguments": ' -}}
{%- if tc.arguments is string -%}
{{- tc.arguments -}}
{%- else -%}
{{- tc.arguments|tojson -}}
{%- endif -%}
{{- '}\n' -}}
{%- endfor -%}
{%- endif -%}
{{- '<|eot_id|>' -}}
{%- elif message.role == "tool" -%}
{%- if loop.previtem and loop.previtem.role != "tool" -%}
{{- '<|start_header_id|>tool<|end_header_id|>\n\n' -}}
{%- endif -%}
{{- '\n' + message.content -}}
{%- if not loop.last -%}
{{- '\n\n' -}}
{%- else -%}
{{- '\n' -}}
{%- endif -%}
{%- if not loop.last and loop.nextitem.role != "tool" -%}
{{- '<|eot_id|>' -}}
{%- elif loop.last -%}
{{- '<|eot_id|>' -}}
{%- endif -%}
{%- elif message.role == "system" and not (tools is defined and tools|length > 0) -%}
{{- '<|start_header_id|>system<|end_header_id|>\n\n' + message.content + '<|eot_id|>' -}}
{%- endif -%}
{%- endfor -%}
{%- if add_generation_prompt -%}
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
{%- endif -%}