akra35567 commited on
Commit
8fd3f8f
·
1 Parent(s): ef8f81a

Update modules/contexto.py

Browse files
Files changed (1) hide show
  1. modules/contexto.py +65 -173
modules/contexto.py CHANGED
@@ -1,189 +1,81 @@
1
- import logging
2
- import re
3
- import random
4
- import time
5
- import collections
6
- import sqlite3
7
- from typing import List, Dict, Any, Optional, Tuple
8
-
9
- try:
10
- from sentence_transformers import SentenceTransformer # type: ignore
11
- except Exception as e:
12
- logging.warning(f"sentence_transformers não disponível: {e}")
13
- SentenceTransformer = None
14
-
15
- from modules.database import Database
16
  import modules.config as config
17
 
18
- # Logging
19
- logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
20
- logger = logging.getLogger(__name__)
21
-
22
-
23
  class Contexto:
24
- """
25
- Gerencia contexto, histórico, aprendizado dinâmico, gírias, tom, emoção.
26
- Consulta o banco a cada interação → aprendizado em tempo real.
27
- """
28
-
29
- def __init__(self, db: Database, user_id: str):
30
  self.db = db
31
- self.user_id = user_id # número ou nome do usuário
32
  self.historico: List[Tuple[str, str]] = []
33
- self.girias_aprendidas: List[Dict[str, Any]] = []
 
 
34
  self.ton_predominante: str = "neutro"
35
- self.emocao_atual: str = "neutra"
36
- self.termo_contexto: Dict[str, Dict] = {}
37
- self.model = None
38
 
39
- # Carrega tudo do banco na primeira vez
40
- self._atualizar_do_banco()
41
-
42
- def _atualizar_do_banco(self):
43
- """Consulta o banco e atualiza tudo (chamado a cada interação)"""
44
  try:
45
- # Histórico
46
- msgs = self.db.recuperar_mensagens(self.user_id, limite=10)
47
- self.historico = [(m, r) for m, r in (msgs or [])][::-1][-5:] # últimas 5
48
-
49
- # Gírias aprendidas
50
- self.girias_aprendidas = self.db.recuperar_girias_usuario(self.user_id)
51
-
52
- # Tom predominante
53
- self.ton_predominante = self.db.obter_tom_predominante(self.user_id) or "neutro"
54
-
55
- # Termos aprendidos (antigo termo_contexto)
56
- termos_raw = self.db.recuperar_aprendizado_detalhado(self.user_id, "termos")
57
- if termos_raw and isinstance(termos_raw, str):
58
- try:
59
- import json
60
- self.termo_contexto = json.loads(termos_raw)
61
- except:
62
- self.termo_contexto = {}
63
- else:
64
- self.termo_contexto = {}
65
-
66
- # Emoção atual (baseada na última interação)
67
- ultima = self.historico[-1] if self.historico else ("", "")
68
- analise = self.db.analisar_emocoes_mensagem(ultima[0] + " " + ultima[1])
69
- self.emocao_atual = analise["emocao"]
70
 
 
 
 
 
 
 
 
 
 
 
71
  except Exception as e:
72
- logger.error(f"Erro ao atualizar contexto do banco: {e}")
73
- self.historico = []
74
- self.girias_aprendidas = []
75
- self.ton_predominante = "neutro"
76
- self.termo_contexto = {}
77
 
78
  def atualizar_aprendizados_do_banco(self):
79
- """FORÇA ATUALIZAÇÃO DO BANCO A CADA CHAMADA (usado na api.py)"""
80
- self._atualizar_do_banco()
81
-
82
- def obter_historico(self) -> List[Tuple[str, str]]:
83
- return self.historico
84
-
85
- def atualizar_contexto(self, mensagem: str, resposta: str):
86
- """Salva no banco + atualiza memória local"""
87
  try:
88
- self.db.salvar_mensagem(self.user_id, mensagem, resposta, numero=self.user_id)
89
- self.historico.append((mensagem, resposta))
90
- if len(self.historico) > 5:
91
- self.historico.pop(0)
92
-
93
- # Atualiza emoção
94
- analise = self.db.analisar_emocoes_mensagem(mensagem + " " + resposta)
95
- self.emocao_atual = analise["emocao"]
96
-
97
- # Extrai gírias e salva no banco
98
- self._extrair_e_salvar_girias(mensagem, resposta)
99
-
100
  except Exception as e:
101
- logger.warning(f"Erro ao atualizar contexto: {e}")
102
-
103
- def _extrair_e_salvar_girias(self, msg: str, resp: str):
104
- """Extrai gírias e salva no banco"""
105
- texto = f"{msg} {resp}".lower()
106
- palavras = [p for p in re.findall(r'\b\w{4,}\b', texto)
107
- if p not in {'não', 'que', 'com', 'pra', 'pro', 'uma', 'ele', 'ela'}]
108
-
109
- contador = collections.Counter(palavras)
110
- for palavra, freq in contador.most_common(5):
111
- if freq > 1:
112
- significado = "gíria local" if any(x in texto for x in ['puto', 'caralho', 'merda']) else "expressão comum"
113
- self.db.salvar_giria_aprendida(self.user_id, palavra, significado, texto[:100])
114
-
115
- def analisar_intencao_e_normalizar(self, mensagem: str, historico: List) -> Dict[str, Any]:
116
- """Normaliza, detecta intenção, sentimento, ironia, meia frase, etc."""
117
- mensagem = mensagem.strip()
118
- if not mensagem:
119
- return {"intencao": "vazia", "sentimento": "neutro", "usar_nome": False}
120
-
121
- # Normalização
122
- msg_lower = re.sub(r'[^\w\s\.,!?]', '', mensagem.lower())
123
- msg_normalizada = self._substituir_termos_aprendidos(msg_lower)
124
-
125
- # Detecção básica
126
- saudacao = any(p in msg_lower for p in ["oi", "olá", "eai", "eae", "bom dia"])
127
- despedida = any(p in msg_lower for p in ["tchau", "flw", "até logo", "bazar"])
128
- pergunta = "?" in mensagem or any(p in msg_lower for p in ["como", "onde", "quem", "por que"])
129
- grosseria = any(p in msg_lower for p in ["caralho", "puto", "merda", "fdp", "burro", "idiota"])
130
-
131
- # Sentimento
132
- positivo = any(p in msg_lower for p in ["fixe", "bué", "bom", "legal", "gosto", "adoro", "kkk", "rsrs"])
133
- negativo = any(p in msg_lower for p in ["ruim", "chato", "droga", "ódio", "triste", "puto"])
134
-
135
- sentimento = "positivo" if positivo else ("negativo" if negativo else "neutro")
136
-
137
- # Ironia
138
- ironia = (positivo and "perdi" in msg_lower) or (negativo and "melhor" in msg_lower)
139
 
140
- # Meia frase
141
- meia_frase = len(msg_lower.split()) <= 3 or "..." in mensagem
142
-
143
- # Usar nome?
144
- usar_nome = False
145
- if saudacao or despedida or any(p in msg_lower for p in ["obrigado", "valeu"]):
146
- prob = getattr(config, 'USAR_NOME_PROBABILIDADE', 0.4)
147
- usar_nome = random.random() < prob
148
-
149
- # Estilo
150
- estilo = "curto" if len(mensagem) < 30 else "normal"
151
- if grosseria:
152
- estilo = "rude"
153
-
154
- return {
155
- "texto_normalizado": msg_normalizada,
156
- "intencao": "saudacao" if saudacao else ("despedida" if despedida else ("pergunta" if pergunta else "conversa")),
157
- "sentimento": sentimento,
158
- "estilo": estilo,
159
- "ironia": ironia,
160
- "meia_frase": meia_frase,
161
- "usar_nome": usar_nome,
162
- "grosseria": grosseria
163
- }
164
-
165
- def _substituir_termos_aprendidos(self, texto: str) -> str:
166
- """Substitui gírias aprendidas por significado (opcional, para análise)"""
167
- for termo, info in self.termo_contexto.items():
168
- if termo in texto:
169
- texto = texto.replace(termo, info.get("significado", termo))
170
- return texto
171
-
172
- def aprender_termo_regional(self, termo: str, contexto: str, significado: str):
173
- """Registra novo termo no banco e na memória"""
174
- self.termo_contexto[termo] = {"contexto": contexto, "significado": significado}
175
- try:
176
- import json
177
- self.db.salvar_aprendizado_detalhado(self.user_id, "termos", json.dumps(self.termo_contexto))
178
- except:
179
- pass
180
 
181
- def obter_aprendizados(self) -> Dict[str, Any]:
182
- """Retorna tudo que a IA aprendeu sobre o usuário"""
183
- return {
184
- "historico_recente": [f"U: {u} | A: {a}" for u, a in self.historico[-3:]],
185
- "girias": [g["giria"] for g in self.girias_aprendidas[:5]],
186
- "tom_predominante": self.ton_predominante,
187
- "emocao_atual": self.emocao_atual,
188
- "termos_aprendidos": list(self.termo_contexto.keys())[:5]
189
- }
 
1
+ """
2
+ Contexto de conversa por usuário
3
+ ================================
4
+ - Memória afetiva
5
+ - Análise de emoção (retorna str)
6
+ - Gírias aprendidas
7
+ - Integração com banco
8
+ """
9
+ import json
10
+ from typing import List, Tuple, Dict, Any
11
+ from loguru import logger
 
 
 
 
12
  import modules.config as config
13
 
 
 
 
 
 
14
  class Contexto:
15
+ def __init__(self, db, user_key: str):
 
 
 
 
 
16
  self.db = db
17
+ self.user_key = user_key
18
  self.historico: List[Tuple[str, str]] = []
19
+ self.emocao_atual: str = config.HUMOR_INICIAL # str
20
+ self.termo_contexto: List[str] = []
21
+ self.girias_aprendidas: List[Dict[str, str]] = []
22
  self.ton_predominante: str = "neutro"
23
+ self._carregar_do_banco()
 
 
24
 
25
+ def _carregar_do_banco(self):
 
 
 
 
26
  try:
27
+ dados = self.db.carregar_contexto(self.user_key)
28
+ if dados:
29
+ self.historico = json.loads(dados.get("historico", "[]"))
30
+ self.emocao_atual = dados.get("emocao_atual", config.HUMOR_INICIAL) # str
31
+ self.termo_contexto = json.loads(dados.get("termos", "[]"))
32
+ self.girias_aprendidas = json.loads(dados.get("girias", "[]"))
33
+ self.ton_predominante = dados.get("tom", "neutro")
34
+ except Exception as e:
35
+ logger.warning(f"Erro ao carregar contexto: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ def salvar_no_banco(self):
38
+ try:
39
+ self.db.salvar_contexto(
40
+ self.user_key,
41
+ json.dumps(self.historico[-config.MEMORIA_MAX:]),
42
+ self.emocao_atual, # str
43
+ json.dumps(self.termo_contexto),
44
+ json.dumps(self.girias_aprendidas),
45
+ self.ton_predominante
46
+ )
47
  except Exception as e:
48
+ logger.error(f"Erro ao salvar contexto: {e}")
 
 
 
 
49
 
50
  def atualizar_aprendizados_do_banco(self):
 
 
 
 
 
 
 
 
51
  try:
52
+ girias = self.db.listar_girias_aprendidas(self.user_key)
53
+ self.girias_aprendidas = [{"giria": g[0], "significado": g[1]} for g in girias]
 
 
 
 
 
 
 
 
 
 
54
  except Exception as e:
55
+ logger.warning(f"Erro ao atualizar gírias: {e}")
56
+
57
+ def analisar_emocoes_mensagem(self, mensagem: str) -> str:
58
+ """Retorna apenas a emoção como string"""
59
+ msg = mensagem.lower()
60
+ if any(p in msg for p in ["feliz", "fixe", "bué bom", "adoro", "rsrs", "kkk"]):
61
+ return "feliz"
62
+ if any(p in msg for p in ["triste", "chateado", "merda", "puto", "caralho"]):
63
+ return "triste"
64
+ if any(p in msg for p in ["irritada", "foda-se", "vsf", "burro"]):
65
+ return "irritada"
66
+ if any(p in msg for p in ["curioso", "o que", "como", "porquê"]):
67
+ return "curiosa"
68
+ return "neutra"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ def obter_historico(self) -> List[Tuple[str, str]]:
71
+ return self.historico[-3:]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ def atualizar_contexto(self, mensagem: str, resposta: str):
74
+ self.historico.append((mensagem, resposta))
75
+ if len(self.historico) > config.MEMORIA_MAX:
76
+ self.historico.pop(0)
77
+
78
+ # Atualiza emoção com base na mensagem do usuário
79
+ self.emocao_atual = self.analisar_emocoes_mensagem(mensagem)
80
+
81
+ self.salvar_no_banco()