STABLE: Final schema sync, optimized gitignore

This commit is contained in:
Kincses
2026-02-26 08:19:25 +01:00
parent 893f39fa15
commit 505543330a
203 changed files with 11590 additions and 9542 deletions

View File

@@ -1,85 +1,70 @@
# /opt/docker/dev/service_finder/backend/app/workers/alchemist_v2_2.py
import asyncio
import logging
from sqlalchemy import select, update, func, and_, case # JAVÍTVA: and_ és case importálva
from app.db.session import SessionLocal
from sqlalchemy import select, update, func, and_, case
from app.db.session import AsyncSessionLocal
from app.models.vehicle_definitions import VehicleModelDefinition
from app.services.ai_service import AIService
# Logolás finomhangolása
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')
logger = logging.getLogger("Robot-Alchemist-v2.2")
class AlchemistBot:
def __init__(self):
self.batch_size = 5 # GPU VRAM kímélése (Ollama párhuzamosítás mellett)
self.delay_between_records = 12 # Quadro P4000 hűtési idő/késleltetés
self.batch_size = 5
self.delay_between_records = 12 # P4000 hűtési ciklus
async def synthesize_vehicle(self, vehicle_id: int):
"""AI dúsítás végrehajtása a begyűjtött kontextusból."""
async with SessionLocal() as db:
""" AI dúsítás végrehajtása az MDM logikája szerint. """
async with AsyncSessionLocal() as db:
res = await db.execute(select(VehicleModelDefinition).where(VehicleModelDefinition.id == vehicle_id))
v = res.scalar_one_or_none()
if not v or not v.raw_search_context:
logger.warning(f"⚠️ Nincs kontextus az ID:{vehicle_id} rekordhoz, átugrás.")
logger.warning(f"⚠️ Nincs feldolgozható kontextus ID:{vehicle_id}")
return
make, model = v.make, v.marketing_name
logger.info(f"🧪 Arany dúsítás indul (AI Synthesis): {make} {model}")
logger.info(f"🧪 Alkimista munka indul: {make} {model}")
# Státusz zárolása a feldolgozás idejére
await db.execute(
update(VehicleModelDefinition)
.where(VehicleModelDefinition.id == vehicle_id)
.values(status='ai_synthesis_in_progress')
)
# Munkaterület lefoglalása
v.status = 'ai_synthesis_in_progress'
await db.commit()
# AI hívás: Gold-Data kinyerése a "szemetesládából"
# AI hívás (Kívül a DB tranzakción a timeout elkerülésére)
gold_data = await AIService.get_gold_data_from_research(make, model, v.raw_search_context)
async with SessionLocal() as db:
async with AsyncSessionLocal() as db:
if gold_data:
# Értékek kinyerése és normalizálása
ccm = gold_data.get("ccm")
kw = gold_data.get("kw")
m_name = gold_data.get("marketing_name", model)[:50]
t_code = gold_data.get("technical_code")
# MDM Arany adatok rögzítése
await db.execute(
update(VehicleModelDefinition)
.where(VehicleModelDefinition.id == vehicle_id)
.values(
marketing_name=m_name,
technical_code=t_code or v.technical_code,
engine_capacity=ccm,
power_kw=kw,
features_json=gold_data, # A teljes technikai JSON (olaj, gumi, stb.)
marketing_name=gold_data.get("marketing_name", model)[:50],
technical_code=gold_data.get("technical_code") or v.technical_code,
engine_capacity=gold_data.get("ccm"),
power_kw=gold_data.get("kw"),
specifications=gold_data, # Teljes specifikáció JSONB
status='gold_enriched',
updated_at=func.now()
)
)
logger.info(f"✨ GOLD ENRICHED: {make} {m_name} ({ccm} ccm, {kw} kW)")
logger.info(f"✨ GOLD DATA GENERÁLVA: {make} {model}")
else:
# Hiba esetén visszatesszük a sorba, növelve a kísérletek számát
await db.execute(
update(VehicleModelDefinition)
.where(VehicleModelDefinition.id == vehicle_id)
.values(
status='awaiting_ai_synthesis',
attempts=v.attempts + 1,
last_error="AI extraction failed or returned empty"
)
.values(status='awaiting_ai_synthesis', attempts=v.attempts + 1)
)
logger.warning(f"⚠️ Sikertelen dúsítás: {make} {model}")
logger.warning(f"⚠️ AI hiba, visszatéve a sorba: {make} {model}")
await db.commit()
async def run(self):
logger.info("🚀 Robot 2.2 (Alchemist) ONLINE - Prioritásos feldolgozás")
logger.info("🚀 Robot 2.2 (Alchemist) ONLINE")
while True:
async with SessionLocal() as db:
# --- PRIORITÁSI LOGIKA (Megegyezik a Researcher botéval) ---
async with AsyncSessionLocal() as db:
# Prioritás: Autók (Suzuki, Toyota...) -> Többi autó -> Motorok -> Egyéb
priorities = case(
(and_(VehicleModelDefinition.vehicle_type == 'car',
VehicleModelDefinition.make.in_(['SUZUKI', 'TOYOTA', 'SKODA', 'VOLKSWAGEN', 'OPEL'])), 1),
@@ -89,7 +74,6 @@ class AlchemistBot:
else_=4
)
# Lekérdezés prioritás szerint, majd a legrégebben frissített rekordok szerint
stmt = select(VehicleModelDefinition.id).where(
VehicleModelDefinition.status == 'awaiting_ai_synthesis'
).order_by(priorities, VehicleModelDefinition.updated_at.asc()).limit(self.batch_size)
@@ -98,13 +82,11 @@ class AlchemistBot:
ids = [r[0] for r in res.fetchall()]
if not ids:
# Ha üres a tartály, pihenünk és várunk a porszívóra
await asyncio.sleep(20)
continue
for vid in ids:
await self.synthesize_vehicle(vid)
# Quadro P4000 hűtés és Ollama API tehermentesítés
await asyncio.sleep(self.delay_between_records)
if __name__ == "__main__":