User: что едале настрйока class ChatCompletionRequest(BaseModel): model: str messages: list[Message] max_tokens: int = 128000 temperature: float = 1.0 top_p: float = 1.0 n: int = 1 stream: bool = False stop: list = None presence_penalty: float = 0.0 frequency_penalty: float = 0.0 logit_bias: dict = None


import uuid
import time
import logging
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
import asyncio
import json

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI()

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    model: str
    messages: list[Message]
    max_tokens: int = 128000
    temperature: float = 1.0
    top_p: float = 1.0
    n: int = 1
    stream: bool = False
    stop: list = None
    presence_penalty: float = 0.0
    frequency_penalty: float = 0.0
    logit_bias: dict = None

ALLOWED_MODELS = {
    "o1-preview": "https://yuntian-deng-o1.hf.space",
    "o1-mini": "https://yuntian-deng-o1mini.hf.space"
}

COOKIES = {
    "__stripe_mid": "ea43aada-81d9-4008-b199-efe76c14bb3519ac66",
    "__stripe_sid": "1",
    "AMP_569d78c970": "JTdCJTIyZGV2aWNlSWQlMjIlM0ElMjJkYWM1NDM2NS1kNTQ1LTRiMmItYTViZi01MDc2YWQ1NWI5MzklMjIlMkMlMjJ1c2VySWQlMjIlM0ElMjJmMzk4YmFmNS1mNTljLTRiMGMtOTYyNS1mM2ExOGU5NDNhYTclMjIlMkMlMjJzZXNzaW9uSWQlMjIlM0ExNzI5MTA0Nzc1MTk1JTJDJTIyb3B0T3V0JTIyJTNBZmFsc2UlMkMlMjJsYXN0RXZlbnRUaW1lJTIyJTNBMTcyOTEwNDc3NTIwNiUyQyUyMmxhc3RFdmVudElkJTIyJTNBMCU3RA==",
    "AMP_MKTG_569d78c970": "JTdCJTIycmVmZXJyZXIlMjIlM0ElMjJodHRwcyUzQSUyRiUyRnd3dy5nb29nbGUuY29tJTJGJTIyJTJDJTIycmVmZXJyaW5nX2RvbWFpbiUyMiUzQSUyMnd3dy5nb29nbGUuY29tJTIyJTdE",
    "aws-waf-token": "493cff6c-30c3-43ad-8adf-e087238d53be:DQoAjj1fZlYFAAAA:t/stuYnMe87hbVk4xFSuel+1M8VUMHKkduoHnND7MXRnlsIMmr8nCU2cwxmfEmNTB4rBzgUbiDKleYZpPwZovIABIXFItBfSGz05y7VhygB3KU+RORzNlfsUo8fLtvl6AKKSTX2Lwaq4+3kWeWuyaUoAHHi8T/ivaI3RWGelSH9ds6LHSyU4dKCeQsHs4EP61uMrpaqWcn4R6nyqdyHOrXgRJYrd2nltMpeu1q6QINBhWjigvGaXyjwUnLH+W/0iVDWAtQg=",
}

async def ask_question(messages, model):
    logger.info("Starting ask_question with model: %s", model)
    async with httpx.AsyncClient(timeout=99999) as client:
        base_url = ALLOWED_MODELS.get(model)
        if not base_url:
            logger.error("Invalid model: %s", model)
            return "Недопустимая модель."
        logger.info("Selected base_url: %s", base_url)
        
        prompt = "\n".join([f"{msg.role.capitalize()}: {msg.content}" for msg in messages])
        logger.debug("Generated prompt: %s", prompt)
        
        session_hash = str(uuid.uuid4())
        logger.info("Generated session_hash: %s", session_hash)
        
        payload = {
            "fn_index": 5,
            "data": [prompt, 1, 1, 0, [], []],
            "event_data": None,
            "session_hash": session_hash
        }
        logger.debug("Payload for /queue/join: %s", payload)
        
        join_url = f"{base_url}/queue/join?__theme=light"
        logger.info("Sending POST request to %s", join_url)
        try:
            response = await client.post(join_url, json=payload, cookies=COOKIES)
            response.raise_for_status()
            logger.info("Successfully joined the queue.")
        except httpx.HTTPStatusError as e:
            logger.error("HTTP error during /queue/join: %s - %s", e.response.status_code, e.response.text)
            return f"Ошибка при подключении к серверу: {e.response.status_code} - {e.response.text}"
        except Exception as e:
            logger.exception("Unexpected error during /queue/join: %s", str(e))
            return f"Ошибка при подключении к серверу: {str(e)}"
        
        data_url = f"{base_url}/queue/data"
        logger.info("Connecting to SSE at %s", data_url)
        start_time = time.time()
        timeout_seconds = 9999  # Максимальное время ожидания в секундах
        try:
            async with client.stream("GET", data_url, headers={"Accept": "text/event-stream"}, params={"session_hash": session_hash}, cookies=COOKIES) as stream:
                async for line in stream.aiter_lines():
                    current_time = time.time()
                    if current_time - start_time > timeout_seconds:
                        logger.warning("Timeout reached while waiting for response.")
                        return "Превышено время ожидания ответа от сервера."
                    
                    logger.debug("Received line: %s", line)
                    if line.startswith("data: "):
                        data = line[6:]
                        if not data.strip() or data == "[DONE]":
                            logger.debug("Empty or DONE data received, continuing.")
                            continue
                        try:
                            json_data = json.loads(data)
                            msg_type = json_data.get("msg")
                            logger.info("Received msg_type: %s", msg_type)
                            if msg_type == "process_completed":
                                conversation = json_data.get("output", {}).get("data", [])
                                logger.debug("Conversation data: %", conversation)
                                if conversation and isinstance(conversation, list):
                                    for batch in conversation:
                                        if isinstance(batch, list):
                                            for exchange in batch:
                                                if isinstance(exchange, list) and len(exchange) > 1:
                                                    bot_response = exchange[1]
                                                    logger.info("Extracted bot response.")
                                                    return bot_response
                                logger.error("Failed to extract bot response from conversation.")
                                return "Не удалось получить ответ от сервера."
                            elif msg_type in {"process_generating", "estimation", "heartbeat"}:
                                logger.debug("Ignoring msg_type: %s", msg_type)
                                continue
                        except json.JSONDecodeError:
                            logger.error("Failed to decode JSON data: %s", data)
                            continue
        except httpx.HTTPError as e:
            logger.error("HTTP error during SSE stream: %s", str(e))
            return f"Ошибка при получении ответа от сервера: {str(e)}"
        except Exception as e:
            logger.exception("Unexpected error during SSE stream: %s", str(e))
            return f"Ошибка при получении ответа от сервера: {str(e)}"
        
    logger.warning("The process was not completed.")
    return "Процесс не был завершён."

@app.get("/v1/models")
async def get_models():
    logger.info("Received request for /v1/models")
    return {
        "object": "list",
        "data": [
            {"id": "o1-preview", "object": "model"},
            {"id": "o1-mini", "object": "model"}
        ]
    }

@app.post("/v1/chat/completions")
async def chat_completion(request_data: ChatCompletionRequest):
    logger.info("Received POST request to /v1/chat/completions with model: %s", request_data.model)
    if request_data.model not in ALLOWED_MODELS:
        detail = f"Модель '{request_data.model}' не поддерживается. Используйте одну из доступных: {list(ALLOWED_MODELS.keys())}."
        logger.error(detail)
        raise HTTPException(status_code=400, detail=detail)
    logger.debug("Request data: %s", request_data)
    try:
        response_text = await ask_question(request_data.messages, request_data.model)
        logger.info("Generated response: %s", response_text)
    except Exception as e:
        logger.exception("Error during ask_question: %s", str(e))
        raise HTTPException(status_code=500, detail=f"Внутренняя ошибка сервера: {str(e)}")
    return {
        "id": f"chatcmpl-{uuid.uuid4()}",
        "object": "chat.completion",
        "created": int(time.time()),
        "model": request_data.model,
        "choices": [
            {
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": response_text
                },
                "finish_reason": "stop"
            }
        ],
        "usage": {
            "prompt_tokens": 0,
            "completion_tokens": 0,
            "total_tokens": 0
        }
    }

if __name__ == "__main__":
    logger.info("Starting server at http://127.0.0.1:8000")
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)