Загрузка данных


"""
Этап 1: Агентный пайплайн для ОЧИСТКИ данных.

"""

import json
import re
import os
import requests
import pandas as pd

class LLMClient:
    """Чистый мультимодальный клиент для отправки текста и графиков на LLM сервер."""

    def __init__(self, base_url: str, model_name: str, api_key: str = "none"):
        
        self.base_url = base_url.rstrip("/") 
        self.server_url = self.base_url + "/v1/chat/completions"
        self.models_url = self.base_url + "/v1/models"
        self.model_name = model_name
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}",
        }

    def get_models(self) -> list:
        """Получает список доступных моделей с сервера."""
        try:
            response = requests.get(
                self.models_url, headers=self.headers, timeout=30
            )
            response.raise_for_status()
            data = response.json()

            # OpenAI-совместимые API возвращают список в объекте {"data": [...]}
            if "data" in data:
                return [model["id"] for model in data["data"]]
            return []

        except requests.exceptions.RequestException as e:
            print(f"Ошибка при получении списка моделей: {e}")
            return []
        except (KeyError, TypeError):
            print(f"Ошибка парсинга списка моделей. Ответ: {response.text}")
            return []

    def _encode_image(self, image_path: str) -> str:
        """Кодирует локальное изображение графика в Base64."""
        with open(image_path, "rb") as image_file:
            return base64.b64encode(image_file.read()).decode("utf-8")

    def send_multimodal_prompt(
        self, 
        system_role: str, 
        user_text: str, 
        temperature: float = 0.5
    ) -> str:
        """Отправляет текст и опциональный список путей к графикам (PNG/JPG) на модель."""
        
        # Начинаем формировать контент пользователя (сначала всегда идет текст)
        user_content = [{"type": "text", "text": user_text}]

        payload = {
            "model": self.model_name,
            "messages": [
                {"role": "system", "content": system_role},
                {"role": "user", "content": user_content},
            ],
            "temperature": temperature,
        }

        try:
            response = requests.post(
                self.server_url, headers=self.headers, json=payload, timeout=120
            )
            response.raise_for_status()
            return response.json()["choices"][0]["message"]["content"]

        except requests.exceptions.RequestException as e:
            return f"Ошибка соединения с VL-моделью: {e}"
        except (KeyError, IndexError):
            return f"Ошибка парсинга ответа. Сервер вернул: {response.text}"