Actualziacion de analisis de ia con las imagenes y se agrega el campo de cod operario en el front y en el back

This commit is contained in:
2025-11-26 01:20:26 -03:00
parent cbfab59222
commit 822ab5a1cb
5 changed files with 129 additions and 38 deletions

View File

@@ -325,6 +325,7 @@ def create_user(
username=user.username,
email=user.email,
full_name=user.full_name,
employee_code=user.employee_code,
role=user.role,
password_hash=hashed_password,
is_active=True
@@ -374,6 +375,9 @@ def update_user(
if user_update.full_name is not None:
db_user.full_name = user_update.full_name
if user_update.employee_code is not None:
db_user.employee_code = user_update.employee_code
# Solo admin puede cambiar roles
if user_update.role is not None:
if current_user.role != "admin":
@@ -1519,9 +1523,9 @@ def delete_ai_configuration(
@app.post("/api/analyze-image")
async def analyze_image(
file: UploadFile = File(...),
question_id: int = None,
inspection_id: int = None,
custom_prompt: str = None,
question_id: int = Form(None),
inspection_id: int = Form(None),
custom_prompt: str = Form(None),
db: Session = Depends(get_db),
current_user: models.User = Depends(get_current_user)
):
@@ -1530,6 +1534,15 @@ async def analyze_image(
Usa la configuración de IA activa (OpenAI o Gemini)
Incluye contexto del vehículo si se proporciona inspection_id
"""
print("\n" + "="*80)
print("🔍 ANALYZE IMAGE - DEBUG")
print("="*80)
print(f"📥 Parámetros recibidos:")
print(f" - file: {file.filename}")
print(f" - question_id: {question_id}")
print(f" - inspection_id: {inspection_id}")
print(f" - custom_prompt (del Form): {custom_prompt[:100] if custom_prompt else 'NO RECIBIDO'}")
# Obtener configuración de IA activa
ai_config = db.query(models.AIConfiguration).filter(
models.AIConfiguration.is_active == True
@@ -1551,71 +1564,71 @@ async def analyze_image(
question_obj = None
if question_id:
question_obj = db.query(models.Question).filter(models.Question.id == question_id).first()
print(f"📋 Pregunta encontrada:")
print(f" - ID: {question_obj.id}")
print(f" - Texto: {question_obj.text}")
print(f" - ai_prompt en DB: {question_obj.ai_prompt[:100] if question_obj.ai_prompt else 'NO TIENE'}")
# Si no se proporciona custom_prompt en el Form, usar el de la pregunta
if not custom_prompt and question_obj and question_obj.ai_prompt:
custom_prompt = question_obj.ai_prompt
print(f"✅ Usando ai_prompt de la pregunta de la DB")
elif custom_prompt:
print(f"✅ Usando custom_prompt del Form")
else:
print(f"⚠️ NO HAY custom_prompt (ni del Form ni de la DB)")
print(f"📝 Custom prompt FINAL a usar: {custom_prompt[:150] if custom_prompt else 'NINGUNO'}...")
# Obtener contexto del vehículo si se proporciona inspection_id
vehicle_context = ""
if inspection_id:
inspection = db.query(models.Inspection).filter(models.Inspection.id == inspection_id).first()
if inspection:
print(f"🚗 Contexto del vehículo agregado: {inspection.vehicle_brand} {inspection.vehicle_model}")
vehicle_context = f"""
INFORMACIÓN DEL VEHÍCULO INSPECCIONADO:
- Marca: {inspection.vehicle_brand}
- Modelo: {inspection.vehicle_model}
- Año: {inspection.vehicle_year or 'No especificado'}
- Placa: {inspection.vehicle_plate}
- Kilometraje: {inspection.mileage} km
- Kilometraje: {inspection.vehicle_km} km
- Cliente: {inspection.client_name}
- OR/Orden: {inspection.or_number}
"""
else:
print(f"⚠️ inspection_id {inspection_id} no encontrado en DB")
else:
print(f"⚠️ NO se proporcionó inspection_id, sin contexto de vehículo")
try:
# Construir prompt dinámico basado en la pregunta específica
if question_obj:
# Usar prompt personalizado si está disponible
if custom_prompt:
# Prompt 100% personalizado por el administrador
# Prompt personalizado - DIRECTO Y SIMPLE
system_prompt = f"""Eres un mecánico experto realizando una inspección vehicular.
{vehicle_context}
INSTRUCCIONES ESPECÍFICAS DEL ADMINISTRADOR PARA ESTA PREGUNTA:
TAREA ESPECÍFICA:
{custom_prompt}
PREGUNTA A RESPONDER: "{question_obj.text}"
Sección: {question_obj.section}
IMPORTANTE - VALIDACIÓN ESTRICTA:
1. Lee CUIDADOSAMENTE las instrucciones específicas del administrador arriba
2. Verifica si la imagen proporcionada PERMITE responder lo que se pide
3. Si las instrucciones piden verificar algo dinámico (como "si prende", "si funciona", "si enciende"):
- Y la imagen es estática (foto), indica en "recommendation" que NO se puede verificar con una foto estática
- Sugiere que se necesita una prueba en vivo o un video
4. Si la imagen NO corresponde a lo que piden las instrucciones, indica claramente en "recommendation" qué foto necesitan tomar
VALIDACIÓN DE IMAGEN:
- Si piden verificar funcionamiento (prende, enciende, funciona) pero solo hay una foto → Indica "No se puede verificar funcionamiento con foto estática. Se requiere prueba en vivo."
- Si la imagen es borrosa o no permite análisis → Indica que tomen otra foto más clara
- Si la imagen muestra un componente diferente al solicitado → Indica qué foto necesitan tomar
Responde SOLO en formato JSON válido (sin markdown, sin ```json):
{{
"status": "minor",
"observations": "Describe lo que SÍ puedes ver en la imagen y explica por qué no puedes responder completamente la pregunta si aplica",
"recommendation": "Si no puedes verificar lo solicitado con la imagen, explica claramente QUÉ se necesita (prueba en vivo, video, foto diferente, etc.)",
"status": "ok",
"observations": "Describe lo que observas en la imagen en relación a la tarea solicitada",
"recommendation": "Acción sugerida basada en lo observado",
"confidence": 0.85
}}
VALORES DE STATUS:
- "ok": Solo si puedes CONFIRMAR que todo está bien según las instrucciones
- "minor": Si hay limitaciones en la imagen o no puedes verificar completamente lo solicitado
- "critical": Si hay problemas graves visibles o la imagen es completamente inadecuada
- "ok": Cumple con lo esperado según la tarea
- "minor": Presenta observaciones menores o advertencias
- "critical": Presenta problemas graves o no cumple con lo esperado
RECORDATORIO: En tus observaciones, menciona si el estado es apropiado para el kilometraje y marca/modelo del vehículo cuando sea relevante."""
IMPORTANTE: Si la tarea requiere verificar funcionamiento (algo encendido, prendido, activo) pero la imagen muestra el componente apagado o en reposo, usa status "critical" e indica en "recommendation" que se necesita una foto con el componente funcionando o un video."""
if vehicle_context:
user_message = f"Inspecciona esta imagen del vehículo. Las instrucciones específicas requieren: '{custom_prompt}'. Verifica si con esta imagen puedes responder completamente esa solicitud."
else:
user_message = f"Inspecciona la imagen. Las instrucciones requieren: '{custom_prompt}'. Verifica si puedes responder esa solicitud con esta imagen."
user_message = f"Pregunta de inspección: {question_obj.text}\n\nAnaliza esta imagen según la tarea especificada."
else:
# Prompt altamente específico para la pregunta
question_text = question_obj.text
@@ -1682,6 +1695,13 @@ Responde SOLO en formato JSON válido (sin markdown, sin ```json):
NOTA: "status" debe ser "ok" (bueno), "minor" (problemas leves) o "critical" (problemas graves)."""
user_message = "Analiza este componente del vehículo para la inspección general."
print(f"\n🤖 PROMPT ENVIADO AL AI:")
print(f"Provider: {ai_config.provider}")
print(f"Model: {ai_config.model_name}")
print(f"System prompt (primeros 200 chars): {system_prompt[:200]}...")
print(f"User message: {user_message}")
print("="*80 + "\n")
if ai_config.provider == "openai":
import openai
openai.api_key = ai_config.api_key