| {%- 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 <tools></tools> 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: <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 -%} | |
| {{- ' </tools>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 <tool_call></tool_call> XML tags as follows:\n<tool_call>\n{"name": <function-name>, "arguments": <args-dict>}\n</tool_call>' -}} | |
| {%- 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 -%} | |
| {{- '<tool_call>\n{"name": "' + tc.name + '", "arguments": ' -}} | |
| {%- if tc.arguments is string -%} | |
| {{- tc.arguments -}} | |
| {%- else -%} | |
| {{- tc.arguments|tojson -}} | |
| {%- endif -%} | |
| {{- '}\n</tool_call>' -}} | |
| {%- 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 -%} | |
| {{- '<tool_response>\n' + message.content -}} | |
| {%- if not loop.last -%} | |
| {{- '\n</tool_response>\n' -}} | |
| {%- else -%} | |
| {{- '\n</tool_response>' -}} | |
| {%- 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 -%} |