akra35567 commited on
Commit
8675351
·
1 Parent(s): 3f43b2d

Update modules/api.py

Browse files
Files changed (1) hide show
  1. modules/api.py +17 -17
modules/api.py CHANGED
@@ -1,10 +1,9 @@
1
  """
2
- API wrapper para o serviço Akira - VERSÃO FINAL (11/2025)
3
- Corrige erro 'str' object has no attribute get'
4
- Tolerante a JSON malformado ou encoding incorreto (ex: Baileys)
5
- Compatível com Mistral SDK novo e antigo
6
  ✅ Logs detalhados
7
- ✅ Gemini sem filtro rígido
8
  """
9
 
10
  from typing import Any
@@ -101,10 +100,12 @@ class LLMManager:
101
  temperature=temperature,
102
  top_p=self.config.TOP_P,
103
  )
104
- text = resp.choices[0].message.content
105
- if text:
106
- logger.info(f"✅ Mistral OK (tentativa {attempt})")
107
- return self._limpar_resposta(text)
 
 
108
  except Exception as e:
109
  logger.warning(f"Mistral erro {attempt}: {e}")
110
 
@@ -129,7 +130,10 @@ class LLMManager:
129
  "top_p": self.config.TOP_P,
130
  }
131
  )
132
- text = getattr(resp, "text", None) # simplificado, sem filtro rigoroso
 
 
 
133
  if text and isinstance(text, str) and text.strip():
134
  logger.info(f"✅ Gemini OK (tentativa {attempt})")
135
  return self._limpar_resposta(text)
@@ -138,8 +142,8 @@ class LLMManager:
138
  if "429" in str(e) or "quota" in str(e):
139
  time.sleep(2 ** (attempt % 3))
140
 
141
- logger.error("❌ Todos os provedores falharam.")
142
- return self.config.FALLBACK_RESPONSE
143
 
144
 
145
  # ================================
@@ -206,7 +210,7 @@ REGRAS:
206
  def akira_endpoint():
207
  try:
208
  raw_data = request.get_data(as_text=True)
209
- logger.info(f"📩 RAW recebido ({len(raw_data)} bytes): {raw_data[:500]}")
210
 
211
  try:
212
  if isinstance(request.json, dict):
@@ -218,7 +222,6 @@ REGRAS:
218
  data = {}
219
 
220
  if not isinstance(data, dict):
221
- logger.warning(f"🚨 Corpo não é dict: {type(data)}")
222
  data = {}
223
 
224
  usuario = data.get('usuario', 'Anônimo')
@@ -228,8 +231,6 @@ REGRAS:
228
  is_reply = bool(data.get('is_reply') or data.get('mensagem_original'))
229
  mensagem_original = data.get('mensagem_original') or data.get('quoted_message') or ''
230
 
231
- logger.info(f"👤 {usuario} ({numero}) disse: {mensagem}")
232
-
233
  if not isinstance(mensagem, str) or not mensagem.strip():
234
  return jsonify({'error': 'mensagem obrigatória'}), 400
235
 
@@ -238,7 +239,6 @@ REGRAS:
238
  prompt = self._build_prompt(usuario, numero, mensagem, emocao, contexto, is_privileged, is_reply, mensagem_original)
239
 
240
  resposta = self.providers.generate(prompt, max_tokens=500, temperature=0.8)
241
- logger.info(f"💬 Resposta: {resposta}")
242
 
243
  contexto.atualizar_contexto(mensagem, resposta)
244
  self.treinador.registrar_interacao(usuario, mensagem, resposta, numero, is_reply, mensagem_original)
 
1
  """
2
+ API wrapper para o serviço Akira - VERSÃO FINAL RETIFICADA (11/2025)
3
+ Gemini seguro (respeita ausência de Part)
4
+ Mistral SDK compatível (novo/antigo)
5
+ Fallback global
6
  ✅ Logs detalhados
 
7
  """
8
 
9
  from typing import Any
 
100
  temperature=temperature,
101
  top_p=self.config.TOP_P,
102
  )
103
+ text = getattr(resp, "choices", None)
104
+ if text and len(text) > 0 and hasattr(text[0], "message"):
105
+ text_val = getattr(text[0].message, "content", None)
106
+ if text_val:
107
+ logger.info(f"✅ Mistral OK (tentativa {attempt})")
108
+ return self._limpar_resposta(text_val)
109
  except Exception as e:
110
  logger.warning(f"Mistral erro {attempt}: {e}")
111
 
 
130
  "top_p": self.config.TOP_P,
131
  }
132
  )
133
+ # Acessa text de forma segura, mesmo sem 'Part'
134
+ text = getattr(resp, "text", None)
135
+ if not text and hasattr(resp, "candidates") and len(resp.candidates) > 0:
136
+ text = getattr(resp.candidates[0], "content", None)
137
  if text and isinstance(text, str) and text.strip():
138
  logger.info(f"✅ Gemini OK (tentativa {attempt})")
139
  return self._limpar_resposta(text)
 
142
  if "429" in str(e) or "quota" in str(e):
143
  time.sleep(2 ** (attempt % 3))
144
 
145
+ logger.error("❌ Todos os provedores falharam. Retornando fallback.")
146
+ return getattr(self.config, "FALLBACK_RESPONSE", "Desculpa, puto, não consegui responder.")
147
 
148
 
149
  # ================================
 
210
  def akira_endpoint():
211
  try:
212
  raw_data = request.get_data(as_text=True)
213
+ logger.info(f"📩 RAW recebido ({len(raw_data)} bytes)")
214
 
215
  try:
216
  if isinstance(request.json, dict):
 
222
  data = {}
223
 
224
  if not isinstance(data, dict):
 
225
  data = {}
226
 
227
  usuario = data.get('usuario', 'Anônimo')
 
231
  is_reply = bool(data.get('is_reply') or data.get('mensagem_original'))
232
  mensagem_original = data.get('mensagem_original') or data.get('quoted_message') or ''
233
 
 
 
234
  if not isinstance(mensagem, str) or not mensagem.strip():
235
  return jsonify({'error': 'mensagem obrigatória'}), 400
236
 
 
239
  prompt = self._build_prompt(usuario, numero, mensagem, emocao, contexto, is_privileged, is_reply, mensagem_original)
240
 
241
  resposta = self.providers.generate(prompt, max_tokens=500, temperature=0.8)
 
242
 
243
  contexto.atualizar_contexto(mensagem, resposta)
244
  self.treinador.registrar_interacao(usuario, mensagem, resposta, numero, is_reply, mensagem_original)