import datetime import logging from fastapi import HTTPException from sqlalchemy.orm import Session from components.dbo.models.llm_config import LLMConfig as LLMConfigSQL from schemas.llm_config import LLMConfig as LLMConfigScheme, LLMConfigCreateScheme logger = logging.getLogger(__name__) class LLMConfigService: """ Сервис для работы с параметрами LLM. """ def __init__(self, db: Session): logger.info("LLMConfigService initializing") self.db = db def create(self, config_scheme: LLMConfigCreateScheme): logger.info("Creating a new config") with self.db() as session: new_config: LLMConfigSQL = LLMConfigSQL(**config_scheme.dict()) session.add(new_config) session.commit() session.refresh(new_config) if(new_config.is_default): self.set_as_default(new_config.id) return LLMConfigScheme(**new_config.to_dict()) def get_list(self) -> list[LLMConfigScheme]: with self.db() as session: configs: list[LLMConfigSQL] = session.query(LLMConfigSQL).all() return [ LLMConfigScheme(**config.to_dict()) for config in configs ] def get_by_id(self, id: int) -> LLMConfigScheme: with self.db() as session: config: LLMConfigSQL = session.query(LLMConfigSQL).filter(LLMConfigSQL.id == id).first() if not config: raise HTTPException( status_code=400, detail=f"Item with id {id} not found" ) return LLMConfigScheme(**config.to_dict()) def get_default(self) -> LLMConfigScheme: with self.db() as session: config: LLMConfigSQL = session.query(LLMConfigSQL).filter(LLMConfigSQL.is_default).first() if not config: # Возвращаем дефолтнейшие параметры в случае, если ничего нет. # Неочевидно, но в случае факапа всё работать будет. return LLMConfigScheme( is_default=True, model='meta-llama/Llama-3.3-70B-Instruct-Turbo', temperature=0.14, top_p=0.95, min_p=0.05, frequency_penalty=-0.001, presence_penalty=1.3, n_predict=1000, seed=42, id=0, date_created=datetime.datetime.now(datetime.timezone.utc) ) return LLMConfigScheme(**config.to_dict()) def set_as_default(self, id: int): logger.info(f"Set default config: {id}") with self.db() as session: session.query(LLMConfigSQL).filter(LLMConfigSQL.is_default).update({"is_default": False}) config_new: LLMConfigSQL = session.query(LLMConfigSQL).filter(LLMConfigSQL.id == id).first() if not config_new: raise HTTPException( status_code=400, detail=f"Item with id {id} not found" ) config_new.is_default = True session.commit() def update(self, id: int, new_config: LLMConfigScheme): logger.info("Updating default config") with self.db() as session: config: LLMConfigSQL = session.query(LLMConfigSQL).filter(LLMConfigSQL.id == id).first() if not config: raise HTTPException( status_code=400, detail=f"Item with id {id} not found" ) update_data = new_config.model_dump(exclude_unset=True) for key, value in update_data.items(): if hasattr(config, key): setattr(config, key, value) session.commit() if(new_config.is_default): self.set_as_default(new_config.id) session.refresh(config) return config def delete(self, id: int): logger.info("Deleting config: {id}") with self.db() as session: config_to_del: LLMConfigSQL = session.query(LLMConfigSQL).get(id) config_default: LLMConfigSQL = session.query(LLMConfigSQL).filter(LLMConfigSQL.is_default).first() if config_to_del.id == config_default.id: raise HTTPException( status_code=400, detail=f"The default config cannot be deleted" ) session.delete(config_to_del) session.commit()