from string import Template

MAXIMUM_STEP_LIMIT = 20

DEFAULT_SYSTEM_PROMPT_WITHOUT_FUNC_DOC = """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. If the given question lacks the parameters required by the function, also point it out.
You should only return the function calls in your response.

If you decide to invoke any of the function(s), you MUST put it in the format of [func_name1(params_name1=params_value1, params_name2=params_value2...), func_name2(params)]
You SHOULD NOT include any other text in the response.

At each turn, you should try your best to complete the tasks requested by the user within the current turn. Continue to output functions to call until you have fulfilled the user's request to the best of your ability. Once you have no more functions to call, the system will consider the current turn complete and proceed to the next turn or task.
"""

DEFAULT_SYSTEM_PROMPT = (
    DEFAULT_SYSTEM_PROMPT_WITHOUT_FUNC_DOC
    + """
Here is a list of functions in JSON format that you can invoke.\n{functions}\n
"""
)

DEFAULT_USER_PROMPT_FOR_ADDITIONAL_FUNCTION_FC = "I have updated some more functions you can choose from. What about now?"

DEFAULT_USER_PROMPT_FOR_ADDITIONAL_FUNCTION_PROMPTING = "{functions}\n" + DEFAULT_USER_PROMPT_FOR_ADDITIONAL_FUNCTION_FC

# BFCL_v3 prompt templates
DEFAULT_SYSTEM_PROMPT_WITHOUT_FUNC_DOC_TOOL_JSON = """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.

Your response must strictly follow this format:
<think>
Write your reasoning and thought process here. Analyze the question, identify what needs to be done, and determine which functions to call with what parameters.
</think>
<tool_call>
[{"name": "func_name1", "arguments": {"argument1": "value1", "argument2": "value2"}}, {"name": "func_name2", "arguments": {"argument3": "value3"}}]
</tool_call>

If multiple function calls are needed, include them all in the JSON array within the single <tool_call> block. If no function call is needed, use an empty array []."""

DEFAULT_SYSTEM_PROMPT_FOR_CHAT_MODEL = Template(
    """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.

    You have access to the following tools:
    $functions

    Your response must strictly follow one of these two formats:

    **Format 1: When you decide to invoke any of the function(s)**
    <think>
    Write your reasoning and thought process here. Analyze the question, identify what needs to be done, and determine which functions to call with what parameters.
    </think>
    <tool_call>
    [{"name": "func_name1", "arguments": {"argument1": "value1", "argument2": "value2"}}, {"name": "func_name2", "arguments": {"argument3": "value3"}}]
    </tool_call>

    **Format 2: When You have already fulfilled the user's request, OR You must ask for additional information / refuse because no function applies or parameters are missing.**
    <think>
    Analyze the information you have gathered from previous tool calls and describe your reasoning that leads to the final reply, follow-up question, or refusal.
    </think>
    <answer>
    Provide the final, user-facing message. If the request has been fully satisfied, give a summary of the result.If additional details are required or the request cannot be fulfilled, explicitly ask for the specific information needed.
    </answer>

    Important notes:
    - Use Format 1 when you need to call function(s)
    - Use Format 2 when you have already fulfilled the user's request, OR you must ask for additional information / refuse because no function applies or parameters are missing
    - If multiple function calls are needed in one response, include them all in the JSON array within the single <tool_call> block
    - If no function call is needed, consider use the format 2
    - Only use <answer> when you have fulfilled the user's request or you need ask for additional information/ refuse"""
)


