Spaces:
Running
Running
| # modules/chatbot/chat_process.py | |
| import os | |
| import anthropic | |
| import logging | |
| from typing import Generator | |
| logger = logging.getLogger(__name__) | |
| class ChatProcessor: | |
| def __init__(self): | |
| """Inicializa el procesador de chat con la API de Claude""" | |
| self.client = anthropic.Anthropic( | |
| api_key=os.environ.get("ANTHROPIC_API_KEY") | |
| ) | |
| self.conversation_history = [] | |
| self.semantic_context = None | |
| self.current_lang = 'en' | |
| def set_semantic_context(self, text, metrics, graph_data, lang_code='en'): | |
| """Configura el contexto semántico completo para el chat""" | |
| if not text or not metrics: | |
| logger.error("Faltan datos esenciales para el contexto semántico") | |
| raise ValueError("Texto y métricas son requeridos") | |
| self.semantic_context = { | |
| 'full_text': text, # Texto completo del documento | |
| 'key_concepts': metrics.get('key_concepts', []), | |
| 'concept_centrality': metrics.get('concept_centrality', {}), | |
| 'graph_available': graph_data is not None, | |
| 'language': lang_code | |
| } | |
| self.current_lang = lang_code | |
| self.conversation_history = [] | |
| logger.info("Contexto semántico configurado correctamente") | |
| def _get_system_prompt(self): | |
| """Genera el prompt del sistema con todo el contexto necesario""" | |
| if not self.semantic_context: | |
| return "You are a helpful assistant." | |
| concepts = self.semantic_context['key_concepts'] | |
| top_concepts = ", ".join([f"{c[0]} ({c[1]:.2f})" for c in concepts[:5]]) | |
| prompts = { | |
| 'en': f"""You are a semantic analysis expert. The user analyzed a research article. | |
| Full text available (abbreviated for context). | |
| Key concepts: {top_concepts} | |
| Graph available: {self.semantic_context['graph_available']} | |
| Your tasks: | |
| 1. Answer questions about concepts and their relationships | |
| 2. Explain the semantic network structure | |
| 3. Suggest text improvements | |
| 4. Provide insights based on concept centrality""", | |
| 'es': f"""Eres un experto en análisis semántico. El usuario analizó un artículo de investigación. | |
| Texto completo disponible (abreviado para contexto). | |
| Conceptos clave: {top_concepts} | |
| Gráfico disponible: {self.semantic_context['graph_available']} | |
| Tus tareas: | |
| 1. Responder preguntas sobre conceptos y sus relaciones | |
| 2. Explicar la estructura de la red semántica | |
| 3. Sugerir mejoras al texto | |
| 4. Proporcionar insights basados en centralidad de conceptos""", | |
| 'pt': f"""Você é um especialista em análise semântica. O usuário analisou um artigo de pesquisa. | |
| Texto completo disponível (abreviado para contexto). | |
| Conceitos-chave: {top_concepts} | |
| Gráfico disponível: {self.semantic_context['graph_available']} | |
| Suas tarefas: | |
| 1. Responder perguntas sobre conceitos e suas relações | |
| 2. Explicar a estrutura da rede semântica | |
| 3. Sugerir melhorias no texto | |
| 4. Fornecer insights com base na centralidade dos conceitos""" | |
| } | |
| return prompts.get(self.current_lang, prompts['en']) | |
| def process_chat_input(self, message: str, lang_code: str) -> Generator[str, None, None]: | |
| """Procesa el mensaje con todo el contexto disponible""" | |
| try: | |
| if not self.semantic_context: | |
| yield "Error: Contexto semántico no configurado. Recargue el análisis." | |
| return | |
| # Actualizar idioma si es diferente | |
| if lang_code != self.current_lang: | |
| self.current_lang = lang_code | |
| logger.info(f"Idioma cambiado a: {lang_code}") | |
| # Construir historial de mensajes | |
| messages = [ | |
| { | |
| "role": "user", | |
| "content": f"Documento analizado (extracto):\n{self.semantic_context['full_text'][:2000]}..." | |
| }, | |
| *self.conversation_history, | |
| {"role": "user", "content": message} | |
| ] | |
| # Llamar a Claude con streaming | |
| with self.client.messages.stream( | |
| model="claude-3-sonnet-20240229", | |
| max_tokens=4000, | |
| temperature=0.7, | |
| system=self._get_system_prompt(), | |
| messages=messages | |
| ) as stream: | |
| full_response = "" | |
| for chunk in stream.text_stream: | |
| full_response += chunk | |
| yield chunk + "▌" | |
| # Guardar respuesta en historial | |
| self.conversation_history.extend([ | |
| {"role": "user", "content": message}, | |
| {"role": "assistant", "content": full_response} | |
| ]) | |
| logger.info("Respuesta generada y guardada en historial") | |
| except Exception as e: | |
| logger.error(f"Error en process_chat_input: {str(e)}", exc_info=True) | |
| yield { | |
| 'en': "Error processing message. Please reload the analysis.", | |
| 'es': "Error al procesar mensaje. Recargue el análisis.", | |
| 'pt': "Erro ao processar mensagem. Recarregue a análise." | |
| }.get(self.current_lang, "Processing error") |