| 1 | {%- macro json_to_python_type(json_spec) %} |
| 2 | {%- set basic_type_map = { |
| 3 | "string": "str", |
| 4 | "number": "float", |
| 5 | "integer": "int", |
| 6 | "boolean": "bool" |
| 7 | } %} |
| 8 | |
| 9 | {%- if basic_type_map[json_spec.type] is defined %} |
| 10 | {{- basic_type_map[json_spec.type] }} |
| 11 | {%- elif json_spec.type == "array" %} |
| 12 | {{- "list[" + json_to_python_type(json_spec|items) + "]" }} |
| 13 | {%- elif json_spec.type == "object" %} |
| 14 | {%- if json_spec.additionalProperties is defined %} |
| 15 | {{- "dict[str, " + json_to_python_type(json_spec.additionalProperties) + ']' }} |
| 16 | {%- else %} |
| 17 | {{- "dict" }} |
| 18 | {%- endif %} |
| 19 | {%- elif json_spec.type is iterable %} |
| 20 | {{- "Union[" }} |
| 21 | {%- for t in json_spec.type %} |
| 22 | {{- json_to_python_type({"type": t}) }} |
| 23 | {%- if not loop.last %} |
| 24 | {{- "," }} |
| 25 | {%- endif %} |
| 26 | {%- endfor %} |
| 27 | {{- "]" }} |
| 28 | {%- else %} |
| 29 | {{- "Any" }} |
| 30 | {%- endif %} |
| 31 | {%- endmacro %} |
| 32 | |
| 33 | |
| 34 | {{- bos_token }} |
| 35 | {{- "<|im_start|>system\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> " }} |
| 36 | {%- if tools is iterable and tools | length > 0 %} |
| 37 | {%- for tool in tools %} |
| 38 | {%- if tool.function is defined %} |
| 39 | {%- set tool = tool.function %} |
| 40 | {%- endif %} |
| 41 | {{- '{"type": "function", "function": ' }} |
| 42 | {{- '{"name": "' + tool.name + '", ' }} |
| 43 | {{- '"description": "' + tool.name + '(' }} |
| 44 | {%- for param_name, param_fields in tool.parameters.properties|items %} |
| 45 | {{- param_name + ": " + json_to_python_type(param_fields) }} |
| 46 | {%- if not loop.last %} |
| 47 | {{- ", " }} |
| 48 | {%- endif %} |
| 49 | {%- endfor %} |
| 50 | {{- ")" }} |
| 51 | {%- if tool.return is defined %} |
| 52 | {{- " -> " + json_to_python_type(tool.return) }} |
| 53 | {%- endif %} |
| 54 | {{- " - " + tool.description + "\n\n" }} |
| 55 | {%- for param_name, param_fields in tool.parameters.properties|items %} |
| 56 | {%- if loop.first %} |
| 57 | {{- " Args:\n" }} |
| 58 | {%- endif %} |
| 59 | {{- " " + param_name + "(" + json_to_python_type(param_fields) + "): " + param_fields.description|trim }} |
| 60 | {%- endfor %} |
| 61 | {%- if tool.return is defined and tool.return.description is defined %} |
| 62 | {{- "\n Returns:\n " + tool.return.description }} |
| 63 | {%- endif %} |
| 64 | {{- '"' }} |
| 65 | {{- ', "parameters": ' }} |
| 66 | {%- if tool.parameters.properties | length == 0 %} |
| 67 | {{- "{}" }} |
| 68 | {%- else %} |
| 69 | {{- tool.parameters|tojson }} |
| 70 | {%- endif %} |
| 71 | {{- "}" }} |
| 72 | {%- if not loop.last %} |
| 73 | {{- "\n" }} |
| 74 | {%- endif %} |
| 75 | {%- endfor %} |
| 76 | {%- endif %} |
| 77 | {{- " </tools>" }} |
| 78 | {{- '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"}} |
| 79 | ' }} |
| 80 | {{- "For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows: |
| 81 | " }} |
| 82 | {{- "<tool_call> |
| 83 | " }} |
| 84 | {{- '{"name": <function-name>, "arguments": <args-dict>} |
| 85 | ' }} |
| 86 | {{- '</tool_call><|im_end|>' }} |
| 87 | {%- for message in messages %} |
| 88 | {%- if message.role == "user" or message.role == "system" or (message.role == "assistant" and message.tool_calls is not defined) %} |
| 89 | {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} |
| 90 | {%- elif message.role == "assistant" and message.tool_calls is defined %} |
| 91 | {{- '<|im_start|>' + message.role }} |
| 92 | {%- for tool_call in message.tool_calls %} |
| 93 | {{- '\n<tool_call>\n' }} |
| 94 | {%- if tool_call.function is defined %} |
| 95 | {%- set tool_call = tool_call.function %} |
| 96 | {%- endif %} |
| 97 | {{- '{' }} |
| 98 | {{- '"name": "' }} |
| 99 | {{- tool_call.name }} |
| 100 | {{- '"' }} |
| 101 | {%- if tool_call.arguments is defined %} |
| 102 | {{- ', ' }} |
| 103 | {{- '"arguments": ' }} |
| 104 | {{- tool_call.arguments|tojson }} |
| 105 | {%- endif %} |
| 106 | {{- '}' }} |
| 107 | {{- '\n</tool_call>' }} |
| 108 | {%- endfor %} |
| 109 | {{- '<|im_end|>\n' }} |
| 110 | {%- elif message.role == "tool" %} |
| 111 | {%- if loop.previtem and loop.previtem.role != "tool" %} |
| 112 | {{- '<|im_start|>tool\n' }} |
| 113 | {%- endif %} |
| 114 | {{- '<tool_response>\n' }} |
| 115 | {{- message.content }} |
| 116 | {%- if not loop.last %} |
| 117 | {{- '\n</tool_response>\n' }} |
| 118 | {%- else %} |
| 119 | {{- '\n</tool_response>' }} |
| 120 | {%- endif %} |
| 121 | {%- if not loop.last and loop.nextitem.role != "tool" %} |
| 122 | {{- '<|im_end|>' }} |
| 123 | {%- elif loop.last %} |
| 124 | {{- '<|im_end|>' }} |
| 125 | {%- endif %} |
| 126 | {%- endif %} |
| 127 | {%- endfor %} |
| 128 | {%- if add_generation_prompt %} |
| 129 | {{- '<|im_start|>assistant\n' }} |
| 130 | {%- endif %} |