JavascriptMick/functiongemma-270m-it-simple-tool-calling
0170
1{%- macro format_parameters(properties, required) -%}2 {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}3 {%- set ns = namespace(found_first=false) -%}4 {%- for key, value in properties | dictsort -%}5 {%- if key not in standard_keys -%}6 {%- if ns.found_first %},{% endif -%}7 {%- set ns.found_first = true -%}8 {{- key }}:{description:<escape>{{ value['description'] }}<escape>9 {%- if value['type'] | upper == 'STRING' -%}10 {%- if value['enum'] -%}11 ,enum:{{ format_argument(value['enum']) }}12 {%- endif -%}13 {%- elif value['type'] | upper == 'OBJECT' -%}14 ,properties:{15 {%- if value['properties'] is defined and value['properties'] is mapping -%}16 {{- format_parameters(value['properties'], value['required'] | default([])) -}}17 {%- elif value is mapping -%}18 {{- format_parameters(value, value['required'] | default([])) -}}19 {%- endif -%}20 }21 {%- if value['required'] -%}22 ,required:[23 {%- for item in value['required'] | default([]) -%}24 <escape>{{- item -}}<escape>25 {%- if not loop.last %},{% endif -%}26 {%- endfor -%}27 ]28 {%- endif -%}29 {%- elif value['type'] | upper == 'ARRAY' -%}30 {%- if value['items'] is mapping and value['items'] -%}31 ,items:{32 {%- set ns_items = namespace(found_first=false) -%}33 {%- for item_key, item_value in value['items'] | dictsort -%}34 {%- if item_value is not none -%}35 {%- if ns_items.found_first %},{% endif -%}36 {%- set ns_items.found_first = true -%}37 {%- if item_key == 'properties' -%}38 properties:{39 {%- if item_value is mapping -%}40 {{- format_parameters(item_value, value['items']['required'] | default([])) -}}41 {%- endif -%}42 }43 {%- elif item_key == 'required' -%}44 required:[45 {%- for req_item in item_value -%}46 <escape>{{- req_item -}}<escape>47 {%- if not loop.last %},{% endif -%}48 {%- endfor -%}49 ]50 {%- elif item_key == 'type' -%}51 {%- if item_value is string -%}52 type:{{ format_argument(item_value | upper) }}53 {%- else -%}54 type:{{ format_argument(item_value | map('upper') | list) }}55 {%- endif -%}56 {%- else -%}57 {{ item_key }}:{{ format_argument(item_value) }}58 {%- endif -%}59 {%- endif -%}60 {%- endfor -%}61 }62 {%- endif -%}63 {%- endif -%}64 ,type:<escape>{{ value['type'] | upper }}<escape>}65 {%- endif -%}66 {%- endfor -%}67{%- endmacro -%}68{% macro format_function_declaration(tool_data) -%}69declaration:{{- tool_data['function']['name'] -}}70{description:<escape>{{- tool_data['function']['description'] -}}<escape>71{%- set params = tool_data['function']['parameters'] -%}72{%- if params -%}73 ,parameters:{74 {%- if params['properties'] -%}75 properties:{ {{- format_parameters(params['properties'], params['required']) -}} },76 {%- endif -%}77 {%- if params['required'] -%}78 required:[79 {%- for item in params['required'] -%}80 <escape>{{- item -}}<escape>81 {{- ',' if not loop.last -}}82 {%- endfor -%}83 ],84 {%- endif -%}85 {%- if params['type'] -%}86 type:<escape>{{- params['type'] | upper -}}<escape>}87 {%- endif -%}88{%- endif -%}89}90{%- endmacro -%}91{% macro format_argument(argument, escape_keys=True) -%}92{%- if argument is string -%}93 {{- '<escape>' + argument + '<escape>' -}}94{%- elif argument is boolean -%}95 {%- if argument -%}96 {{- 'true' -}}97 {%- else -%}98 {{- 'false' -}}99 {%- endif -%}100{%- elif argument is mapping -%}101 {{- '{' -}}102 {%- set ns = namespace(found_first=false) -%}103 {%- for key, value in argument | dictsort -%}104 {%- if ns.found_first %},{% endif -%}105 {%- set ns.found_first = true -%}106 {%- if escape_keys -%}107 {{- '<escape>' + key + '<escape>' -}}108 {%- else -%}109 {{- key -}}110 {%- endif -%}111 :{{- format_argument(value, escape_keys=escape_keys) -}}112 {%- endfor -%}113 {{- '}' -}}114{%- elif argument is sequence -%}115 {{- '[' -}}116 {%- for item in argument -%}117 {{- format_argument(item, escape_keys=escape_keys) -}}118 {%- if not loop.last %},{% endif -%}119 {%- endfor -%}120 {{- ']' -}}121{%- else -%}122 {{- argument -}}123{%- endif -%}124{%- endmacro -%}125{{ bos_token }}126{%- set ns = namespace(prev_message_type=None) -%}127{#- Tool Declarations -#}128{%- set loop_messages = messages -%}129{%- if tools or messages[0]['role'] == 'system' or messages[0]['role'] == 'developer' -%}130 {{- '<start_of_turn>developer\n' -}}131 {%- if messages[0]['role'] == 'system' or messages[0]['role'] == 'developer' -%}132 {%- if messages[0]['content'] is string -%}133 {{- messages[0]['content'] | trim -}}134 {%- elif messages[0]['content'] is sequence -%}135 {%- for item in messages[0]['content'] -%}136 {%- if item['type'] == 'text' -%}137 {{- item['text'] | trim -}}138 {%- endif -%}139 {%- endfor -%}140 {%- endif -%}141 {%- set loop_messages = messages[1:] -%}142 {%- endif -%}143 {%- if tools -%}144 {%- for tool in tools %}145 {{- '<start_function_declaration>' -}}146 {{- format_function_declaration(tool) | trim }}147 {{- '<end_function_declaration>' -}}148 {%- endfor %}149 {%- endif -%}150 {{- '<end_of_turn>\n' }}151{%- endif %}152{#- Loop through messages. -#}153{%- for message in loop_messages -%}154 {%- if (message['role'] == 'assistant') -%}155 {#- Rename "assistant" to "model". -#}156 {%- set role = "model" -%}157 {%- else -%}158 {%- set role = message['role'] -%}159 {%- endif -%}160 {%- if role != 'tool' -%}161 {%- if ns.prev_message_type != 'tool_response' -%}162 {{- '<start_of_turn>' + role + '\n' }}163 {%- endif -%}164 {%- set ns.prev_message_type = None -%}165 {%- if 'content' in message and message['content'] is not none -%}166 {%- if message['content'] is string -%}167 {{ message['content'] | trim }}168 {%- elif message['content'] is sequence -%}169 {%- for item in message['content'] -%}170 {%- if item['type'] == 'image' -%}171 {{ '<start_of_image>' }}172 {%- elif item['type'] == 'text' -%}173 {{ item['text'] | trim }}174 {%- endif -%}175 {%- endfor -%}176 {%- else -%}177 {{ raise_exception("Invalid content type in user/assistant message") }}178 {%- endif -%}179 {%- set ns.prev_message_type = 'content' -%}180 {%- endif -%}181 {%- if 'tool_calls' in message and message['tool_calls'] and message['tool_calls'] is iterable -%}182 {#- Tool Calls -#}183 {%- for tool_call in message['tool_calls'] -%}184 {% set function = tool_call['function'] %}185 {{- '<start_function_call>call:' + function['name'] + '{' -}}186 {%- if 'arguments' in function -%}187 {%- if function['arguments'] is mapping -%}188 {%- set ns = namespace(found_first=false) -%}189 {%- for key, value in function['arguments'] | dictsort -%}190 {%- if ns.found_first %},{% endif -%}191 {%- set ns.found_first = true -%}192 {{- key -}}:{{- format_argument(value, escape_keys=False) -}}193 {%- endfor -%}194 {%- elif function['arguments'] is string -%}195 {# This handles string-JSON, just in case #}196 {{ function['arguments'] }}197 {%- endif %}198 {%- endif -%}199 {{- '}<end_function_call>' -}}200 {%- endfor -%}201 {%- if loop.last -%}202 {{ '<start_function_response>' }}203 {%- endif -%}204 {%- set ns.prev_message_type = 'tool_call' -%}205 {%- endif -%}206 {%- else -%}207 {#- Tool Responses -#}208 {%- if 'content' in message and message['content'] -%}209 {%- if message['content'] is mapping -%}210 {%- if 'name' in message['content'] and 'response' in message['content'] -%}211 {{ '<start_function_response>response:' + message['content']['name'] | trim + '{' }}212 {%- set response_ns = namespace(found_first=false) -%}213 {%- for key, value in message['content']['response'] | dictsort -%}214 {%- if response_ns.found_first %},{% endif -%}215 {%- set response_ns.found_first = true -%}216 {{- key -}}:{{- format_argument(value, escape_keys=False) -}}217 {%- endfor -%}218 {{- '}<end_function_response>' -}}219 {%- elif 'name' in message -%}220 {{ '<start_function_response>response:' + message['name'] | trim + '{' }}221 {%- set response_ns = namespace(found_first=false) -%}222 {%- for key, value in message['content'] | dictsort -%}223 {%- if response_ns.found_first %},{% endif -%}224 {%- set response_ns.found_first = true -%}225 {{- key -}}:{{- format_argument(value, escape_keys=False) -}}226 {%- endfor -%}227 {{- '}<end_function_response>' -}}228 {%- else -%}229 {{ raise_exception("Invalid tool response mapping: must contain 'name' and 'response' keys, or 'name' must be in the message.") }}230 {%- endif -%}231 {%- elif message['content'] is string -%}232 {%- if 'name' in message -%}233 {{ '<start_function_response>response:' + message['name'] | trim + '{value:' + format_argument(message['content'], escape_keys=False) + '}<end_function_response>' }}234 {%- else -%}235 {{ raise_exception("Invalid tool response: 'name' must be provided.") }}236 {%- endif -%}237 {%- elif message['content'] is sequence -%}238 {%- for item in message['content'] -%}239 {%- if item is mapping -%}240 {%- if 'name' in item and 'response' in item -%}241 {{ '<start_function_response>response:' + item['name'] | trim + '{' }}242 {%- set response_ns = namespace(found_first=false) -%}243 {%- for key, value in item['response'] | dictsort -%}244 {%- if response_ns.found_first %},{% endif -%}245 {%- set response_ns.found_first = true -%}246 {{- key -}}:{{- format_argument(value, escape_keys=False) -}}247 {%- endfor -%}248 {{- '}<end_function_response>' -}}249 {%- elif 'name' in message -%}250 {{ '<start_function_response>response:' + message['name'] | trim + '{' }}251 {%- set response_ns = namespace(found_first=false) -%}252 {%- for key, value in item | dictsort -%}253 {%- if response_ns.found_first %},{% endif -%}254 {%- set response_ns.found_first = true -%}255 {{- key -}}:{{- format_argument(value, escape_keys=False) -}}256 {%- endfor -%}257 {{- '}<end_function_response>' -}}258 {%- else -%}259 {{ raise_exception("Invalid tool response mapping: must contain 'name' and 'response' keys, or 'name' must be in the message.") }}260 {%- endif -%}261 {%- else -%}262 {{ raise_exception("Invalid tool response message: multiple responses must all be mappings") }}263 {%- endif -%}264 {%- endfor -%}265 {%- else -%}266 {{ raise_exception("Invalid content type in tool message: must be mapping, sequence of mappings, or string.") }}267 {%- endif -%}268 {%- endif -%}269 {%- set ns.prev_message_type = 'tool_response' -%}270 {%- endif -%}271 {%- if ns.prev_message_type not in ['tool_call', 'tool_response'] -%}272 {{ '<end_of_turn>\n' }}273 {%- endif -%}274{%- endfor -%}275{%- if add_generation_prompt -%}276 {%- if ns.prev_message_type != 'tool_response' -%}277 {{- '<start_of_turn>model\n' -}}278 {%- endif -%}279{%- endif -%}280 