AIdeaText commited on
Commit
bb6efdb
·
verified ·
1 Parent(s): 94fdab4

Create chat_process.py

Browse files
Files changed (1) hide show
  1. modules/chatbot/chat_process.py +147 -0
modules/chatbot/chat_process.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # modules/chatbot/chat_process.py
2
+ import os
3
+ import anthropic
4
+ import logging
5
+ from typing import Generator
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ class ChatProcessor:
10
+ def __init__(self):
11
+ """Inicializa el procesador de chat con la API de Claude"""
12
+ self.client = anthropic.Anthropic(
13
+ api_key=os.environ.get("ANTHROPIC_API_KEY")
14
+ )
15
+ self.conversation_history = []
16
+ self.semantic_context = None
17
+ self.current_lang = 'en'
18
+
19
+ def set_semantic_context(self, text, metrics, graph_data, lang_code='en'):
20
+ """Configura el contexto semántico completo para el chat"""
21
+ if not text or not metrics:
22
+ logger.error("Faltan datos esenciales para el contexto semántico")
23
+ raise ValueError("Texto y métricas son requeridos")
24
+
25
+ self.semantic_context = {
26
+ 'full_text': text, # Texto completo del documento
27
+ 'key_concepts': metrics.get('key_concepts', []),
28
+ 'concept_centrality': metrics.get('concept_centrality', {}),
29
+ 'graph_available': graph_data is not None,
30
+ 'language': lang_code
31
+ }
32
+ self.current_lang = lang_code
33
+ self.conversation_history = []
34
+ logger.info("Contexto semántico configurado correctamente")
35
+
36
+ def _get_system_prompt(self):
37
+ """Genera el prompt del sistema con todo el contexto necesario"""
38
+ if not self.semantic_context:
39
+ return "You are a helpful assistant."
40
+
41
+ concepts = self.semantic_context['key_concepts']
42
+ top_concepts = ", ".join([f"{c[0]} ({c[1]:.2f})" for c in concepts[:5]])
43
+
44
+ prompts = {
45
+ 'en': f"""You are a semantic analysis expert. The user analyzed a research article.
46
+ Full text available (abbreviated for context).
47
+ Key concepts: {top_concepts}
48
+ Graph available: {self.semantic_context['graph_available']}
49
+
50
+ Your tasks:
51
+ 1. Answer questions about concepts and their relationships
52
+ 2. Explain the semantic network structure
53
+ 3. Suggest text improvements
54
+ 4. Provide insights based on concept centrality""",
55
+
56
+ 'es': f"""Eres un experto en análisis semántico. El usuario analizó un artículo de investigación.
57
+ Texto completo disponible (abreviado para contexto).
58
+ Conceptos clave: {top_concepts}
59
+ Gráfico disponible: {self.semantic_context['graph_available']}
60
+
61
+ Tus tareas:
62
+ 1. Responder preguntas sobre conceptos y sus relaciones
63
+ 2. Explicar la estructura de la red semántica
64
+ 3. Sugerir mejorias al texto
65
+ 4. Proporcionar insights basados en centralidad de conceptos""",
66
+
67
+ 'pt': f"""Você é um especialista em análise semântica. O usuário analisou um artigo de pesquisa.
68
+ Texto completo disponível (abreviado para contexto).
69
+ Conceitos-chave: {top_concepts}
70
+ Gráfico disponível: {self.semantic_context['graph_available']}
71
+
72
+ Suas tarefas:
73
+ 1. Responder perguntas sobre conceitos e suas relações
74
+ 2. Explicar a estrutura da rede semântica
75
+ 3. Sugerir melhorias no texto
76
+ 4. Fornecer insights com base na centralidade dos conceitos""",
77
+
78
+ 'fr': f"""Vous êtes un expert en analyse sémantique. L'utilisateur a analysé un article de recherche.
79
+ Texte complet disponible (abrégé pour le contexte).
80
+ Concepts clés: {top_concepts}
81
+ Graphique disponible: {self.semantic_context['graph_available']}
82
+
83
+ Vos tâches:
84
+ 1. Répondre aux questions sur les concepts et leurs relations
85
+ 2. Expliquer la structure du réseau sémantique
86
+ 3. Suggérer des améliorations de texte
87
+ 4. Fournir des insights basés sur la centralité des concepts"""
88
+ }
89
+
90
+ return prompts.get(self.current_lang, prompts['en'])
91
+
92
+ def clean_generated_text(self, text):
93
+ """Limpia caracteres especiales del texto generado"""
94
+ return text.replace("\u2588", "").replace("▌", "").strip()
95
+
96
+ def process_chat_input(self, message: str, lang_code: str) -> Generator[str, None, None]:
97
+ """Procesa el mensaje con todo el contexto disponible"""
98
+ try:
99
+ if not self.semantic_context:
100
+ yield "Error: Contexto semántico no configurado. Recargue el análisis."
101
+ return
102
+
103
+ # Actualizar idioma si es diferente
104
+ if lang_code != self.current_lang:
105
+ self.current_lang = lang_code
106
+ logger.info(f"Idioma cambiado a: {lang_code}")
107
+
108
+ # Construir historial de mensajes
109
+ messages = [
110
+ {
111
+ "role": "user",
112
+ "content": f"Documento analizado (extracto):\n{self.semantic_context['full_text'][:2000]}..."
113
+ },
114
+ *self.conversation_history,
115
+ {"role": "user", "content": message}
116
+ ]
117
+
118
+ # Llamar a Claude con streaming
119
+ with self.client.messages.stream(
120
+ model="claude-sonnet-4-5-20250929",
121
+ max_tokens=4000,
122
+ temperature=0.7,
123
+ system=self._get_system_prompt(),
124
+ messages=messages
125
+ ) as stream:
126
+ full_response = ""
127
+ for chunk in stream.text_stream:
128
+ cleaned_chunk = self.clean_generated_text(chunk)
129
+ full_response += cleaned_chunk
130
+ yield cleaned_chunk
131
+
132
+ # Guardar respuesta en historial
133
+ self.conversation_history.extend([
134
+ {"role": "user", "content": message},
135
+ {"role": "assistant", "content": full_response}
136
+ ])
137
+ logger.info("Respuesta generada y guardada en historial")
138
+
139
+ except Exception as e:
140
+ logger.error(f"Error en process_chat_input: {str(e)}", exc_info=True)
141
+ error_messages = {
142
+ 'en': "Error processing message. Please reload the analysis.",
143
+ 'es': "Error al procesar mensaje. Recargue el análisis.",
144
+ 'pt': "Erro ao processar mensagem. Recarregue a análise.",
145
+ 'fr': "Erreur lors du traitement du message. Veuillez recharger l'analyse."
146
+ }
147
+ yield error_messages.get(self.current_lang, "Processing error")