This commit is contained in:
xds
2026-02-20 02:02:13 +03:00
parent c7c27197c9
commit e1d941a2cd
2 changed files with 34 additions and 41 deletions

View File

@@ -133,7 +133,7 @@ async def start_scheduler(service: GenerationService):
try: try:
logger.info("Running scheduler for stacked generation killing") logger.info("Running scheduler for stacked generation killing")
await service.cleanup_stale_generations() await service.cleanup_stale_generations()
await service.cleanup_old_data(days=2) await service.cleanup_old_data(days=5)
except asyncio.CancelledError: except asyncio.CancelledError:
break break
except Exception as e: except Exception as e:

View File

@@ -9,7 +9,6 @@ from uuid import uuid4
import httpx import httpx
from aiogram import Bot from aiogram import Bot
from aiogram.types import BufferedInputFile from aiogram.types import BufferedInputFile
from fastapi import HTTPException
from adapters.Exception import GoogleGenerationException from adapters.Exception import GoogleGenerationException
from adapters.google_adapter import GoogleAdapter from adapters.google_adapter import GoogleAdapter
@@ -134,9 +133,6 @@ class GenerationService:
gen_id = None gen_id = None
generation_model = None generation_model = None
if generation_request.environment_id and not generation_request.linked_character_id:
raise HTTPException(status_code=400, detail="environment_id can only be used when linked_character_id is provided")
try: try:
generation_model = Generation(**generation_request.model_dump(exclude={'count'})) generation_model = Generation(**generation_request.model_dump(exclude={'count'}))
if user_id: if user_id:
@@ -190,40 +186,45 @@ class GenerationService:
logger.info(f"Processing generation {generation.id}. Character ID: {generation.linked_character_id}") logger.info(f"Processing generation {generation.id}. Character ID: {generation.linked_character_id}")
# 2. Получаем ассеты-референсы (если они есть) # 2. Получаем ассеты-референсы (если они есть)
reference_assets: List[Asset] = []
media_group_bytes: List[bytes] = [] media_group_bytes: List[bytes] = []
generation_prompt = generation.prompt generation_prompt = generation.prompt
# generation_prompt = f"""
# 2.1 Аватар персонажа (всегда первый, если включен) # Create detailed image of character in scene.
# SCENE DESCRIPTION: {generation.prompt}
# Rules:
# - Integrate the character's appearance naturally into the scene description.
# - Focus on lighting, texture, and composition.
# """
if generation.linked_character_id is not None: if generation.linked_character_id is not None:
char_info = await self.dao.chars.get_character(generation.linked_character_id) char_info = await self.dao.chars.get_character(generation.linked_character_id)
if char_info is None: if char_info is None:
raise Exception(f"Character ID {generation.linked_character_id} not found") raise Exception(f"Character ID {generation.linked_character_id} not found")
if generation.use_profile_image:
if char_info.avatar_asset_id is not None:
avatar_asset = await self.dao.assets.get_asset(char_info.avatar_asset_id)
if avatar_asset and avatar_asset.data:
media_group_bytes.append(avatar_asset.data)
# generation_prompt = generation_prompt.replace("$char_bio_inserted", f"1. CHARACTER BIO (Must be strictly followed): {char_info.character_bio}")
if generation.use_profile_image and char_info.avatar_asset_id: reference_assets = await self.dao.assets.get_assets_by_ids(generation.assets_list)
avatar_asset = await self.dao.assets.get_asset(char_info.avatar_asset_id)
if avatar_asset:
img_data = await self._get_asset_data(avatar_asset)
if img_data:
media_group_bytes.append(img_data)
# 2.2 Явно указанные ассеты # Извлекаем данные (bytes) из ассетов для отправки в Gemini
if generation.assets_list: for asset in reference_assets:
explicit_assets = await self.dao.assets.get_assets_by_ids(generation.assets_list) if asset.content_type != AssetContentType.IMAGE:
for asset in explicit_assets: continue
ref_asset_data = await self._get_asset_data(asset)
if ref_asset_data:
media_group_bytes.append(ref_asset_data)
# 2.3 Ассеты из окружения (в самый конец) img_data = None
if generation.environment_id: if asset.minio_object_name:
env = await self.dao.environments.get_env(generation.environment_id) img_data = await self.s3_adapter.get_file(asset.minio_object_name)
if env and env.asset_ids: elif asset.data:
logger.info(f"Loading {len(env.asset_ids)} assets from environment {env.name} ({env.id})") img_data = asset.data
env_assets = await self.dao.assets.get_assets_by_ids(env.asset_ids)
for asset in env_assets: if img_data:
img_data = await self._get_asset_data(asset) media_group_bytes.append(img_data)
if img_data:
media_group_bytes.append(img_data)
if media_group_bytes: if media_group_bytes:
generation_prompt += " \n\n[Reference Image Guidance]: Use the provided image(s) as the STRICT reference for the main character's facial features and hair, enviroment or clothes. Maintain high fidelity to the reference identity." generation_prompt += " \n\n[Reference Image Guidance]: Use the provided image(s) as the STRICT reference for the main character's facial features and hair, enviroment or clothes. Maintain high fidelity to the reference identity."
@@ -340,14 +341,6 @@ class GenerationService:
logger.error(f"Failed to send assets to Telegram ID {generation.telegram_id}: {e}") logger.error(f"Failed to send assets to Telegram ID {generation.telegram_id}: {e}")
async def _get_asset_data(self, asset: Asset) -> Optional[bytes]:
if asset.content_type != AssetContentType.IMAGE:
return None
if asset.minio_object_name:
return await self.s3_adapter.get_file(asset.minio_object_name)
return asset.data
async def _simulate_progress(self, generation: Generation): async def _simulate_progress(self, generation: Generation):
""" """
Increments progress from 0 to 90 over ~20 seconds. Increments progress from 0 to 90 over ~20 seconds.
@@ -493,7 +486,7 @@ class GenerationService:
except Exception as e: except Exception as e:
logger.error(f"Error cleaning up stale generations: {e}") logger.error(f"Error cleaning up stale generations: {e}")
async def cleanup_old_data(self, days: int = 2): async def cleanup_old_data(self, days: int = 30):
""" """
Очистка старых данных: Очистка старых данных:
1. Мягко удаляет генерации старше N дней 1. Мягко удаляет генерации старше N дней