# coding: utf-8

"""
    QuePasa RAG SaaS API

    API for RAG retrieval, managing documents, files, and related operations including Telegram integration.

    The version of the OpenAPI document: 0.0.1
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from quepasa.models.retrieve_answer_request_document_relevance_weights import RetrieveAnswerRequestDocumentRelevanceWeights
from quepasa.models.retrieve_answer_request_user_info import RetrieveAnswerRequestUserInfo
from typing import Optional, Set
from typing_extensions import Self

class RetrieveAnswerRequest(BaseModel):
    """
    RetrieveAnswerRequest
    """ # noqa: E501
    question: Optional[StrictStr] = Field(default=None, description="Natural language query to retrieve or answer.")
    domain: Optional[StrictStr] = Field(default=None, description="The name of a group of documents.")
    llm: Optional[StrictStr] = Field(default=None, description="This is the model that will generate answers to questions based on the retrieved search results. Options: - gpt-3.5-turbo-16k-0613 - mistral:mistral-large-2402 - anthropic:claude-3-5-sonnet-20240620 - replicate:meta-llama-3-70b-instruct ")
    prompt: Optional[StrictStr] = Field(default=None, description="The prompt used for RAG, with placeholders like {{LANGUAGE}} for the language in which the question was asked, and {{SOURCES}} for listing the relevant chunks. For example ```plaintext You're a bot-assistant that answers the questions.  When answering the question, use the following rules: - always answer in {{LANGUAGE}} language; - use ONLY the information from the sources below; - answer briefly in just a few sentences, strictly in accordance with the sources, and do not make any assumptions; - reference the source if you use it in the answer, e.g. [#1] or [#2][#4]; - if there is no information on the question in the sources: say that you can't find the answer and ask the user to try to reformulate the question.  Sources: {{SOURCES}} ``` ")
    answer_prompt_size: Optional[StrictInt] = Field(default=None, description="The length of the response in tokens. This parameter defines the maximum number of tokens that the model can use to generate its answer.")
    prompt_total_size: Optional[StrictInt] = Field(default=None, description="The maximum length of the prompt in tokens. This sets the upper limit for how many tokens can be used for the combined input to the model, including the user's query and the retrieved document context.")
    document_relevance_weights: Optional[RetrieveAnswerRequestDocumentRelevanceWeights] = None
    chunk_relevance_weights: Optional[RetrieveAnswerRequestDocumentRelevanceWeights] = None
    user_info: Optional[RetrieveAnswerRequestUserInfo] = None
    __properties: ClassVar[List[str]] = ["question", "domain", "llm", "prompt", "answer_prompt_size", "prompt_total_size", "document_relevance_weights", "chunk_relevance_weights", "user_info"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of RetrieveAnswerRequest from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of document_relevance_weights
        if self.document_relevance_weights:
            _dict['document_relevance_weights'] = self.document_relevance_weights.to_dict()
        # override the default output from pydantic by calling `to_dict()` of chunk_relevance_weights
        if self.chunk_relevance_weights:
            _dict['chunk_relevance_weights'] = self.chunk_relevance_weights.to_dict()
        # override the default output from pydantic by calling `to_dict()` of user_info
        if self.user_info:
            _dict['user_info'] = self.user_info.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of RetrieveAnswerRequest from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "question": obj.get("question"),
            "domain": obj.get("domain"),
            "llm": obj.get("llm"),
            "prompt": obj.get("prompt"),
            "answer_prompt_size": obj.get("answer_prompt_size"),
            "prompt_total_size": obj.get("prompt_total_size"),
            "document_relevance_weights": RetrieveAnswerRequestDocumentRelevanceWeights.from_dict(obj["document_relevance_weights"]) if obj.get("document_relevance_weights") is not None else None,
            "chunk_relevance_weights": RetrieveAnswerRequestDocumentRelevanceWeights.from_dict(obj["chunk_relevance_weights"]) if obj.get("chunk_relevance_weights") is not None else None,
            "user_info": RetrieveAnswerRequestUserInfo.from_dict(obj["user_info"]) if obj.get("user_info") is not None else None
        })
        return _obj


