@@ -4144,31 +4144,35 @@ def gguf_function_calling(
41444144]:
41454145
41464146 function_calling_template = None
4147- if hasattr (llama , 'model_path' ):
4148- metadata = llama .metadata
4149- if metadata and "tokenizer.chat_template" in metadata :
4150- function_calling_template = metadata ["tokenizer.chat_template" ]
4151-
4152-
4147+
4148+
41534149 function_calling_template = (
41544150 "{% for message in messages %}"
41554151 "<|im_start|>{{ message.role }}\n "
41564152 # System message
41574153 "{% if message.role == 'system' %}"
4154+ "<|system|>\n "
41584155 "{{ message.content }}"
4159- "{% if tool_calls %}"
4160- "\n \n You have access to the following functions:\n "
4156+ "{% if tools %}"
4157+ "\n # Tools\n "
4158+ "\n You may call one or more functions to assist with the user query."
4159+ "\n Prefer proposing the function first; only emit `<function_calls>` when user intent to run is clear from context."
4160+ "\n \n Soft consent policy:"
4161+ "\n - Proceed immediately if the user explicitly asks to run/fetch/call/use a tool, or previously agreed, or supplied all required parameters."
4162+ "\n - Otherwise: reply with a one-line proposal naming the function and why, and end with “Proceed?”."
4163+ "\n - Do not over-ask if consent is obvious."
4164+ "\n \n You are provided with function signatures within <tools></tools> XML tags:"
4165+ "\n <tools>"
41614166 "{% for tool in tools %}"
4162- '\n {% if tool.function.get("description") %}/* {{ tool.function.description | trim }} */{% endif %}'
4163- "\n functions.{{ tool.function.name }}:\n "
4164- "{{ tool.function.parameters | tojson }}"
4165- "\n {% endfor %}"
4166- "\n You must respond to user messages with either a single message or with one or more function calls."
4167- "\n \n To respond with a message use the following format:"
4168- "\n \n message:"
4169- "\n <message>"
4170- "\n \n To respond with one or more function calls use the following format:"
4171- "\n \n <function_calls>"
4167+ "{{ tool | tojson }}"
4168+ "{% endfor %}"
4169+ "</tools>"
4170+ "\n \n You can respond in two ways:"
4171+ "\n \n 1. Message only (proposal/confirmation step):"
4172+ "\n message:"
4173+ "\n I can use `ExampleFunction` to retrieve that. Proceed?"
4174+ "\n \n 2. Message + function calls (when intent is clearly allowed by context):"
4175+ "\n message:"
41724176 "\n functions.<function_name>:"
41734177 '\n { "arg1": "value1", "arg2": "value2" }'
41744178 "\n functions.<function_name>:"
@@ -4204,6 +4208,15 @@ def gguf_function_calling(
42044208 "{% endfor %}"
42054209 "{% if add_generation_prompt %}<|im_start|>assistant\n {% endif %}"
42064210 )
4211+
4212+ if hasattr (llama , 'model_path' ):
4213+ metadata = llama .metadata
4214+ if metadata and "tokenizer.chat_template" in metadata :
4215+ function_calling_template = metadata ["tokenizer.chat_template" ]
4216+
4217+ if kwargs .get ('chat_template' ):
4218+ function_calling_template = kwargs .get ('chat_template' )
4219+
42074220 template_renderer = ImmutableSandboxedEnvironment (
42084221 autoescape = jinja2 .select_autoescape (["html" , "xml" ]),
42094222 undefined = jinja2 .StrictUndefined ,
0 commit comments