Spaces:
Running
Running
File size: 4,777 Bytes
9a1014e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import json
from pydantic import BaseModel, Field
from typing import List, Dict, Any, Optional
from hf_qwen_client import generate_response
from rag_context import retrieve_document_context
from chat_history import list_conversations, list_messages, format_history
class AnalisisIA(BaseModel):
redaccion_tecnica: str = Field(..., description="Análisis técnico detallado basado en las micrografías y contexto de la muestra. Máximo 3 párrafos.")
resumen_ejecutivo: str = Field(..., description="Resumen conciso y al grano para el cliente final sobre los resultados.")
conformidad_norma: bool = Field(..., description="¿Cumple la muestra con los estándares ASTM E112 en base a los datos proporcionados?")
observaciones: str = Field(..., description="Observaciones adicionales relevantes.")
analisis_regiones: Dict[str, str] = Field(
default_factory=dict,
description="Breve análisis o comentario de no más de 1 párrafo para cada región identificada en la muestra, usando el nombre de la región como clave."
)
conclusion: str = Field(..., description="Conclusión final y de cierre del reporte. Debe ser un párrafo contundente.")
def get_chat_context(user_id: int) -> str:
try:
conversations = list_conversations(user_id)
if not conversations:
return "No hay conversaciones previas del usuario."
# Tomamos la ultima conversacion del usuario
latest_conv_id = conversations[0]["id"]
messages = list_messages(latest_conv_id, user_id, limit=20)
history = format_history(messages)
return history
except Exception as e:
print(f"Error fetching chat history: {e}")
return "No se pudo recuperar el historial de chat."
def generate_agentic_report(report_id: int, muestra_id: int, user_id: int, raw_data: dict) -> dict:
chat_context = get_chat_context(user_id)
# RAG: Retrieve ASTM document context
# Create a search query based on the data
material = raw_data.get('muestra', {}).get('material', 'metal')
rag_query = f"norma ASTM E112 tamaño de grano {material}"
astm_context = retrieve_document_context(rag_query, k=3)
system_prompt = f"""Eres un experto metalurgista especializado en la norma ASTM E112.
Tu tarea es analizar los datos de mediciones de tamaño de grano de una muestra y generar conclusiones técnicas de alto valor.
CONTEXTO NORMATIVO (ASTM):
{astm_context}
CONTEXTO ADICIONAL DEL CLIENTE (Chat reciente):
{chat_context}
Debes proporcionar un JSON válido con el análisis de la muestra que respete estrictamente el esquema solicitado.
Claves requeridas: "redaccion_tecnica", "resumen_ejecutivo", "conformidad_norma" (boolean), "observaciones", "analisis_regiones" (diccionario de region -> texto), "conclusion".
Mantén la redacción técnica precisa pero limitada a 3 párrafos como máximo.
"""
import copy
clean_data = copy.deepcopy(raw_data)
# Remove heavy arrays and URLs to avoid exceeding context limits on free API
if 'material' in clean_data:
clean_data['material'].pop('muestra_image_url', None)
clean_data['material'].pop('quality_hist_path', None)
if 'region_data' in clean_data['material']:
for region_name, rdata in clean_data['material']['region_data'].items():
rdata.pop('imagen', None)
rdata.pop('hist_path', None)
for micro in rdata.get('micrografias', []):
micro.pop('imagen', None)
micro.pop('measure_imagen', None)
micro.pop('distribution_um', None)
user_prompt = f"Genera el análisis técnico en JSON puro (sin Markdown) para la siguiente muestra:\n{json.dumps(clean_data, ensure_ascii=False)}"
try:
content = generate_response(
f"{system_prompt}\n\n{user_prompt}",
max_new_tokens=1500,
)
content = content.strip()
if content.startswith("```json"):
content = content[7:-3].strip()
elif content.startswith("```"):
content = content[3:-3].strip()
analisis = json.loads(content)
validated_analisis = AnalisisIA(**analisis)
raw_data["analisis_ia"] = validated_analisis.model_dump()
return raw_data
except Exception as e:
print(f"Error calling LLM: {e}")
raw_data["analisis_ia"] = {
"redaccion_tecnica": "No se pudo generar el análisis automático.",
"resumen_ejecutivo": "Error en el agente de IA.",
"conformidad_norma": False,
"observaciones": str(e),
"conclusion": "No se pudo generar la conclusión."
}
return raw_data
|