from dataclasses import dataclass
from typing import Any, Dict, List, Optional, Union


@dataclass
class ModelProvider:
    """
    Represents the details required to interact with a GebAI model.

    Args:
        api_key (str): The API key used for authenticating requests to the 
        model provider.
        provider_name (str): Name of the model provider.
    """
    provider_name: str
    api_key: Optional[str] = None


@dataclass
class Request:
    """
    Represents the information needed to make an inference request to a
    GenAI model.

    Args:
        model_name (str): The name of the machine learning model to be used
        for inference.
        params (Dict[str, Any]): Additional parameters to configure the model
        for inference.
        prompt (Union[str, List[Dict[str, str]]]): The input prompt or set of
        prompts to use for the inference.
        Can be a simple string or a list of dictionaries, each containing
        key-value pairs for more complex prompt structures.
    """
    model_name: str
    prompt: Union[str, List[Dict[str, str]]]
    model_version: Optional[str] = None
    params: Optional[Dict[str, Any]] = None


@dataclass
class Response:
    """
    Represents the outcome of an inference request.

    Args:
        output (Any): The result generated by the GenAI model,
        which can be of any type depending on the model and task.
    """
    output: Any


@dataclass
class CallOption:
    """
    Represents call options with llm

    Args:
        temperature (float): hyperparameter that
        controls the randomness of predictions by scaling the logits
        before applying softmax.

        presence_penalty (float)
        
    """
    temperature: Optional[float] = None
    presence_penalty: Optional[float] = None

    def asdict(self) -> Dict[str, Any]:
        return {
            "temperature": self.temperature,
            "presence_penalty": self.presence_penalty
        }
