{{- if and $.Tools (le (len (slice $.Messages $i)) 2) }}
[BEGIN OF TASK INSTRUCTION]
You are an expert in composing functions. You are given a question and a set of possible functions.
Based on the question, you will need to make one or more function/tool calls to achieve the purpose.
If none of the functions can be used, point it out and refuse to answer.
If the given question lacks the parameters required by the function, also point it out.
[END OF TASK INSTRUCTION]
[BEGIN OF AVAILABLE TOOLS]
{{ $.Tools }}
[END OF AVAILABLE TOOLS]
[BEGIN OF FORMAT INSTRUCTION]
The output MUST strictly adhere to the following JSON format, and NO other text MUST be included.
The example format is as follows. Please make sure the parameter type is correct. If no function call is needed, please make tool_calls an empty list '[]'.
The current temperature in Paris, France is 22 degrees Celsius.
<|EOT|>
### Instruction:
[BEGIN OF TASK INSTRUCTION]
You are an expert in composing functions. You are given a question and a set of possible functions.
Based on the question, you will need to make one or more function/tool calls to achieve the purpose.
If none of the functions can be used, point it out and refuse to answer.
If the given question lacks the parameters required by the function, also point it out.
[END OF TASK INSTRUCTION]
[BEGIN OF AVAILABLE TOOLS]
[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","required":["location","format"],"properties":{"format":{"type":"string","description":"The temperature unit to use. Infer this from the user's location.","enum":["celsius","fahrenheit"]},"location":{"type":"string","description":"The city and state, e.g. San Francisco, CA"}}}}}]
[END OF AVAILABLE TOOLS]
[BEGIN OF FORMAT INSTRUCTION]
The output MUST strictly adhere to the following JSON format, and NO other text MUST be included.
The example format is as follows. Please make sure the parameter type is correct. If no function call is needed, please make tool_calls an empty list '[]'.
inputs:[]string{"<think>Wait, I need to call a tool</think><|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>get_temperature\n```json\n{\"city\": \"Tokyo\"}\n```<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|>"},
name:"multiple tool calls with text after",
content:"<think>Wait, I need to call a tool</think>",
input:`
tmpl:deepseek,
{"name": "tool1", "arguments": {"arg1": 1}} text
calls:[]api.ToolCall{
{"name": "tool2", "arguments": {"arg2": "value"}} text
model outputs more tokens here and then [{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}},{"name": "get_current_weather", "arguments": {"format":"celsius","location":"Toronto, Canada"}}]`,
want:false,
expectedToolCall:[]api.ToolCall{t1,t2},
expectedTokens:`model outputs more tokens here and then [{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}},{"name": "get_current_weather", "arguments": {"format":"celsius","location":"Toronto, Canada"}}]`,
model outputs more tokens here and then [{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}},{"name": "get_current_weather", "arguments": {"format":"celsius","location":"Toronto, Canada"}}]`,
want:true,
expectedToolCall:[]api.ToolCall{t1,t2,t1,t2},
expectedTokens:"",
},
},
{
{
name:"mistral incomplete json with tool calls prefix",
expectedTokens:`I'm not aware of that information. However, I can suggest searching for the weather using the "get_current_weather" function: [{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}},{"name": "get_current_weather", "arguments": {"format":"celsius","location":"Toronto, Canada"}}]`,
name:"qwen2.5 tool calls without and with prefix and text between",
name:"full overlap",
model:"qwen2.5",
buffer:[]byte("<tool_call>"),
output:`{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}} some tokens between <tool_call>{"name": "get_current_weather", "arguments": {"format":"celsius","location":"Toronto, Canada"}}</tool_call> some tokens after call`,
tag:"<tool_call>",
expectedToolCall:[]api.ToolCall{t1,t2},
i:0,
expectedTokens:"some tokens between",
found:true,
},
},
{
{
name:"qwen2.5 tool calls without prefix and invalid tool call with other tokens",
name:"qwen3 tool call with think prefix and tool prefix (sent as a single token)",
name:"partial overlap",
model:"qwen3",
buffer:[]byte("text <tool_call>"),
output:`<think>Okay, let me think what tool we should use...</think><tool_call>{"name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}}</tool_call>`,
tag:"<tool_call>",
expectedToolCall:[]api.ToolCall{t1},
i:5,
expectedTokens:"<think>Okay, let me think what tool we should use...</think>",
found:true,
},
},
{
{
name:"qwen3 tool call with think prefix, tool prefix, and whitespace (sent as separate tokens)",
name:"overlap with extra",
model:"qwen3",
buffer:[]byte("<tool_calls><tool_call>"),
output:`<think>Okay, let me think what tool we should use...</think> <tool_call>{ "name": "get_current_weather", "arguments": {"format":"fahrenheit","location":"San Francisco, CA"}} </tool_call>`,
tag:"<tool_calls>",
expectedToolCall:[]api.ToolCall{t1},
i:0,
expectedTokens:"<think>Okay, let me think what tool we should use...</think>",
found:true,
},
},
{
{
name:"qwen3 empty think prefix without tool prefix and invalid tool call",