from typing import Dict, Any, Optional, TypedDict
from pydantic import BaseModel, Field

class Tool(BaseModel):
    """
    A description of a tool that can be used by the LLM. Generally, a list of tools is provided 
    to the LLM for selection.
    """

    name: str = Field(..., description="Name of the tool.")
    """The name of the tool to be called."""
    description: str = Field(..., description="Description of the tool.")
    """
    A description of what the tool does, used by the LLM to choose when and how to call the tool.
    """
    parameters: Dict[str, Any] = Field(..., description="JSON schema object that describes the parameters of the tool.")
    """
    A JSON schema dictionary that describes the parameters of the tool.
    """

class ToolCall(BaseModel):
    """
    A description of a tool call that is generated by the LLM. The LLM can return one or multiple 
    tool calls at once.
    """

    id: Optional[str] = Field(..., description="ID of the tool call.")
    """The ID of the tool call."""
    name: str = Field(..., description="Name of the tool.")
    """The name of the tool to be called."""
    arguments: Dict[str, Any] = Field(..., default_factory=dict, description="Arguments that are used to call the tool.")
    """The arguments to call the tool with, as generated by the LLM in JSON format. """

class ToolCallDict(TypedDict):
    """
    A dictionary that describes a tool call that is generated by the LLM. The LLM can return one or multiple 
    tool calls at once. This `ToolCallDict` is another format of `ToolCall` that may be easier for developers to use.
    """

    id: str
    """The ID of the tool call."""
    name: str
    """The name of the tool to be called."""
    arguments: Dict[str, Any]
    """The arguments to call the tool with, as generated by the LLM in JSON format. """
