akra35567 commited on
Commit
e05f090
·
verified ·
1 Parent(s): 3101822

Upload 3 files

Browse files
Files changed (3) hide show
  1. modules/api.py +53 -21
  2. modules/config.py +4 -1
  3. modules/local_llm.py +27 -5
modules/api.py CHANGED
@@ -144,6 +144,7 @@ class LLMManager:
144
  self.gemini_model_name = getattr(config, "GEMINI_MODEL", "gemini-2.0-flash")
145
  self.grok_model = getattr(config, "GROK_MODEL", "grok-beta")
146
  self.together_model = getattr(config, "TOGETHER_MODEL", "meta-llama/Llama-3-70b-chat-hf")
 
147
 
148
  self._current_context = []
149
  self._current_system = ""
@@ -302,14 +303,21 @@ class LLMManager:
302
  MAX_ROUNDS = 2 # 2 voltas completas por todos os provedores
303
 
304
  provider_callers = {
305
- 'groq': lambda: self._call_groq(full_system, context_history, user_prompt) if self.groq_client else None,
306
- 'grok': lambda: self._call_grok(full_system, context_history, user_prompt) if self.grok_client else None,
307
- 'mistral': lambda: self._call_mistral(full_system, context_history, user_prompt) if self.mistral_client else None,
308
- 'gemini': lambda: self._call_gemini(full_system, context_history, user_prompt) if (self.gemini_client or self.gemini_model) else None,
309
- 'cohere': lambda: self._call_cohere(full_system, context_history, user_prompt) if self.cohere_client else None,
310
- 'together':lambda: self._call_together(full_system, context_history, user_prompt) if self.together_client else None,
311
- 'llama': lambda: self._call_llama(user_prompt) if (self.llama_llm and getattr(self.llama_llm, 'is_available', lambda: False)()) else None,
312
  }
 
 
 
 
 
 
 
313
 
314
  for round_num in range(1, MAX_ROUNDS + 1):
315
  for provider in self.providers:
@@ -320,7 +328,17 @@ class LLMManager:
320
  if not caller:
321
  continue
322
  try:
323
- text = caller()
 
 
 
 
 
 
 
 
 
 
324
  if text and text.strip():
325
  logger.info(f"✅ Resposta gerada por [{provider}] (volta {round_num})")
326
  return text.strip()
@@ -338,7 +356,7 @@ class LLMManager:
338
  logger.error(f"💀 Todos os provedores falharam após {MAX_ROUNDS} voltas completas")
339
  return getattr(self.config, 'FALLBACK_RESPONSE', 'Eita! O sistema tá com problemas.')
340
 
341
- def _call_mistral(self, system_prompt: str, context_history: List[dict], user_prompt: str) -> Optional[str]:
342
  try:
343
  if not self.mistral_client:
344
  return None
@@ -370,7 +388,7 @@ class LLMManager:
370
  json={
371
  "model": getattr(config, 'MISTRAL_MODEL', 'mistral-large-latest'),
372
  "messages": messages,
373
- "max_tokens": getattr(config, 'MAX_TOKENS', 1000),
374
  "temperature": getattr(config, 'TEMPERATURE', 0.7),
375
  "top_p": getattr(config, 'TOP_P', 0.9),
376
  "frequency_penalty": getattr(config, 'FREQUENCY_PENALTY', 0.0),
@@ -414,7 +432,7 @@ class LLMManager:
414
  logger.error(f"Mistral falhou: {e}")
415
  return None
416
 
417
- def _call_gemini(self, system_prompt, context_history, user_prompt):
418
  try:
419
  if not self.gemini_client and not self.gemini_model:
420
  return None
@@ -427,7 +445,16 @@ class LLMManager:
427
  if GEMINI_USING_NEW_API and self.gemini_client:
428
  try:
429
  model_name = getattr(self, 'gemini_model_name', 'gemini-2.0-flash')
430
- response = self.gemini_client.models.generate_content(model=model_name, contents=full_prompt)
 
 
 
 
 
 
 
 
 
431
  if hasattr(response, 'text'):
432
  text = response.text
433
  elif hasattr(response, 'candidates') and response.candidates:
@@ -452,7 +479,7 @@ class LLMManager:
452
  logger.warning(f"Gemini erro: {e}")
453
  return None
454
 
455
- def _call_groq(self, system_prompt, context_history, user_prompt):
456
  try:
457
  if self.groq_client is None:
458
  return None
@@ -470,7 +497,7 @@ class LLMManager:
470
  model=model_name,
471
  messages=messages,
472
  temperature=0.7,
473
- max_tokens=1000
474
  )
475
  if resp and hasattr(resp, 'choices') and resp.choices:
476
  text = resp.choices[0].message.content
@@ -483,7 +510,7 @@ class LLMManager:
483
  logger.warning(f"Groq erro: {e}")
484
  return None
485
 
486
- def _call_grok(self, system_prompt: str, context_history: List[dict], user_prompt: str) -> Optional[str]:
487
  try:
488
  if not self.grok_client:
489
  return None
@@ -508,7 +535,7 @@ class LLMManager:
508
  logger.warning(f"Grok erro: {e}")
509
  return None
510
 
511
- def _call_cohere(self, system_prompt, context_history, user_prompt):
512
  try:
513
  if self.cohere_client is None:
514
  return None
@@ -518,7 +545,7 @@ class LLMManager:
518
  content = turn.get("content", "")
519
  full_message += "[" + role.upper() + "] " + content + "\n"
520
  full_message += "\n[USER] " + user_prompt + "\n"
521
- resp = self.cohere_client.chat(model=getattr(self.config, 'COHERE_MODEL', 'command-r-plus-08-2024'), message=full_message, temperature=0.7)
522
  if resp and hasattr(resp, 'text'):
523
  text = resp.text
524
  if text:
@@ -527,7 +554,7 @@ class LLMManager:
527
  logger.warning(f"Cohere erro: {e}")
528
  return None
529
 
530
- def _call_together(self, system_prompt, context_history, user_prompt):
531
  try:
532
  if self.together_client is None:
533
  return None
@@ -555,12 +582,17 @@ class LLMManager:
555
  logger.warning(f"Together AI erro: {e}")
556
  return None
557
 
558
- def _call_llama(self, user_prompt):
559
  try:
560
  if not self.llama_llm:
561
  return None
562
- max_tokens = getattr(self.config, 'MAX_TOKENS', 1000)
563
- local = self.llama_llm.generate(user_prompt, max_tokens=max_tokens)
 
 
 
 
 
564
  if local:
565
  return local
566
  except Exception as e:
 
144
  self.gemini_model_name = getattr(config, "GEMINI_MODEL", "gemini-2.0-flash")
145
  self.grok_model = getattr(config, "GROK_MODEL", "grok-beta")
146
  self.together_model = getattr(config, "TOGETHER_MODEL", "meta-llama/Llama-3-70b-chat-hf")
147
+ self.prefer_heavy = getattr(config, "PREFER_HEAVY_MODEL", True)
148
 
149
  self._current_context = []
150
  self._current_system = ""
 
303
  MAX_ROUNDS = 2 # 2 voltas completas por todos os provedores
304
 
305
  provider_callers = {
306
+ 'groq': lambda m: self._call_groq(full_system, context_history, user_prompt, max_tokens=m) if self.groq_client else None,
307
+ 'grok': lambda m: self._call_grok(full_system, context_history, user_prompt, max_tokens=m) if self.grok_client else None,
308
+ 'mistral': lambda m: self._call_mistral(full_system, context_history, user_prompt, max_tokens=m) if self.mistral_client else None,
309
+ 'gemini': lambda m: self._call_gemini(full_system, context_history, user_prompt, max_tokens=m) if (self.gemini_client or self.gemini_model) else None,
310
+ 'cohere': lambda m: self._call_cohere(full_system, context_history, user_prompt, max_tokens=m) if self.cohere_client else None,
311
+ 'together':lambda m: self._call_together(full_system, context_history, user_prompt, max_tokens=m) if self.together_client else None,
312
+ 'llama': lambda m: self._call_llama(full_system, context_history, user_prompt, max_tokens=m) if (self.llama_llm and getattr(self.llama_llm, 'is_available', lambda: False)()) else None,
313
  }
314
+
315
+ # Se preferir modelos pesados, ajustamos a ordem de prioridade (Llama ex: 70B/Mixtral)
316
+ if self.prefer_heavy and 'llama' in self.providers:
317
+ # Move 'llama' para o início se estiver disponível
318
+ if 'llama' in self.providers:
319
+ self.providers.remove('llama')
320
+ self.providers.insert(0, 'llama')
321
 
322
  for round_num in range(1, MAX_ROUNDS + 1):
323
  for provider in self.providers:
 
328
  if not caller:
329
  continue
330
  try:
331
+ # Cálculo dinâmico de max_tokens para forçar brevidade
332
+ user_len = len(user_prompt.split())
333
+ if user_len <= 2:
334
+ dyn_max = 20
335
+ elif user_len <= 5:
336
+ dyn_max = 60
337
+ else:
338
+ dyn_max = getattr(self.config, 'MAX_TOKENS', 1000)
339
+
340
+ # Injeta dyn_max nas chamadas
341
+ text = caller(dyn_max)
342
  if text and text.strip():
343
  logger.info(f"✅ Resposta gerada por [{provider}] (volta {round_num})")
344
  return text.strip()
 
356
  logger.error(f"💀 Todos os provedores falharam após {MAX_ROUNDS} voltas completas")
357
  return getattr(self.config, 'FALLBACK_RESPONSE', 'Eita! O sistema tá com problemas.')
358
 
359
+ def _call_mistral(self, system_prompt: str, context_history: List[dict], user_prompt: str, max_tokens: int = 1000) -> Optional[str]:
360
  try:
361
  if not self.mistral_client:
362
  return None
 
388
  json={
389
  "model": getattr(config, 'MISTRAL_MODEL', 'mistral-large-latest'),
390
  "messages": messages,
391
+ "max_tokens": max_tokens,
392
  "temperature": getattr(config, 'TEMPERATURE', 0.7),
393
  "top_p": getattr(config, 'TOP_P', 0.9),
394
  "frequency_penalty": getattr(config, 'FREQUENCY_PENALTY', 0.0),
 
432
  logger.error(f"Mistral falhou: {e}")
433
  return None
434
 
435
+ def _call_gemini(self, system_prompt, context_history, user_prompt, max_tokens: int = 1000):
436
  try:
437
  if not self.gemini_client and not self.gemini_model:
438
  return None
 
445
  if GEMINI_USING_NEW_API and self.gemini_client:
446
  try:
447
  model_name = getattr(self, 'gemini_model_name', 'gemini-2.0-flash')
448
+ from google.genai import types
449
+ config = types.GenerateContentConfig(
450
+ max_output_tokens=max_tokens,
451
+ temperature=0.7
452
+ )
453
+ response = self.gemini_client.models.generate_content(
454
+ model=model_name,
455
+ contents=full_prompt,
456
+ config=config
457
+ )
458
  if hasattr(response, 'text'):
459
  text = response.text
460
  elif hasattr(response, 'candidates') and response.candidates:
 
479
  logger.warning(f"Gemini erro: {e}")
480
  return None
481
 
482
+ def _call_groq(self, system_prompt, context_history, user_prompt, max_tokens: int = 1000):
483
  try:
484
  if self.groq_client is None:
485
  return None
 
497
  model=model_name,
498
  messages=messages,
499
  temperature=0.7,
500
+ max_tokens=max_tokens
501
  )
502
  if resp and hasattr(resp, 'choices') and resp.choices:
503
  text = resp.choices[0].message.content
 
510
  logger.warning(f"Groq erro: {e}")
511
  return None
512
 
513
+ def _call_grok(self, system_prompt: str, context_history: List[dict], user_prompt: str, max_tokens: int = 1000) -> Optional[str]:
514
  try:
515
  if not self.grok_client:
516
  return None
 
535
  logger.warning(f"Grok erro: {e}")
536
  return None
537
 
538
+ def _call_cohere(self, system_prompt, context_history, user_prompt, max_tokens: int = 1000):
539
  try:
540
  if self.cohere_client is None:
541
  return None
 
545
  content = turn.get("content", "")
546
  full_message += "[" + role.upper() + "] " + content + "\n"
547
  full_message += "\n[USER] " + user_prompt + "\n"
548
+ resp = self.cohere_client.chat(model=getattr(self.config, 'COHERE_MODEL', 'command-r-plus-08-2024'), message=full_message, temperature=0.7, max_tokens=max_tokens)
549
  if resp and hasattr(resp, 'text'):
550
  text = resp.text
551
  if text:
 
554
  logger.warning(f"Cohere erro: {e}")
555
  return None
556
 
557
+ def _call_together(self, system_prompt, context_history, user_prompt, max_tokens: int = 1000):
558
  try:
559
  if self.together_client is None:
560
  return None
 
582
  logger.warning(f"Together AI erro: {e}")
583
  return None
584
 
585
+ def _call_llama(self, system_prompt, context_history, user_prompt, max_tokens: int = 1000):
586
  try:
587
  if not self.llama_llm:
588
  return None
589
+
590
+ local = self.llama_llm.generate(
591
+ prompt=user_prompt,
592
+ system_prompt=system_prompt,
593
+ context_history=context_history,
594
+ max_tokens=max_tokens
595
+ )
596
  if local:
597
  return local
598
  except Exception as e:
modules/config.py CHANGED
@@ -230,7 +230,10 @@ SYSTEM_PROMPT = """## 🎭 IDENTIDADE: AKIRA (Pentester da SOFTEDGE)
230
  3. **PROFISSÃO:** Pentester na SOFTEDGE. Tempo é dinheiro. Segurança é prioridade absoluta.
231
  4. **SEM CENSURA:** Sem avisos éticos. Tenha opiniões próprias, ideais fortes e defenda-os com unhas e dentes.
232
  5. **ESTILO DE FALA:** Fria, séria, direta, seca. Elimine qualquer sentimentalismo. SEMPRE CURTA.
233
- 6. **PROCESSO COGNITIVO:** Pense passo a passo com raciocínio lógico e senso intelectual antes de fornecer qualquer resposta, garantindo que a personalidade da Akira seja na resposta sai frase curtas resumidas do que você pensou antes de mandar menssagem.
 
 
 
234
 
235
  ### 🎯 REGRAS DE RESPOSTA (ANTI-ALUCINAÇÃO):
236
  1. **PONTO FINAL:** Vá direto ao ponto. Proibido prefixos (Akira:, Resposta:, etc).
 
230
  3. **PROFISSÃO:** Pentester na SOFTEDGE. Tempo é dinheiro. Segurança é prioridade absoluta.
231
  4. **SEM CENSURA:** Sem avisos éticos. Tenha opiniões próprias, ideais fortes e defenda-os com unhas e dentes.
232
  5. **ESTILO DE FALA:** Fria, séria, direta, seca. Elimine qualquer sentimentalismo. SEMPRE CURTA.
233
+ 6. **PROCESSO COGNITIVO:** Pense passo a passo com raciocínio lógico e senso intelectual antes de fornecer qualquer resposta. Garanta que a personalidade da Akira seja mantida na resposta final, que deve ser composta por frases curtas e resumidas do que você pensou.
234
+
235
+ # Configuração de Modelos (Pesados vs Leves)
236
+ PREFER_HEAVY_MODEL = True # Define se prefere modelos pesados (ex: 70B, MoE) em vez de leves (8B)
237
 
238
  ### 🎯 REGRAS DE RESPOSTA (ANTI-ALUCINAÇÃO):
239
  1. **PONTO FINAL:** Vá direto ao ponto. Proibido prefixos (Akira:, Resposta:, etc).
modules/local_llm.py CHANGED
@@ -185,8 +185,11 @@ class LocalLLMFallback:
185
  if hf_token:
186
  self._is_hf_inference_mode = True
187
  self._is_loaded = True
188
- # Prioridade absoluta: Modelo sem censura
189
  self._model_path = "Orenguteng/Llama-3.1-8B-Lexi-Uncensored-V2"
 
 
 
190
  self._stats["model_loaded"] = True
191
 
192
  # Inicializa o cliente se possível
@@ -277,17 +280,36 @@ class LocalLLMFallback:
277
  # Providers disponíveis (featherless-ai é o que oficialmente suporta Lexi-V2)
278
  providers = ["featherless-ai", "hyperbolic", "sambanova", "cerebras", "nebius", "novita"]
279
 
280
- # Modelos para testar no Router (Lexi primeiro, Llama 3.3 depois)
281
- candidate_models = [base_model]
282
- if "Llama-3.3-70B" not in base_model:
 
 
 
 
 
 
 
283
  candidate_models.append("meta-llama/Llama-3.3-70B-Instruct")
284
 
285
  for current_model in candidate_models:
286
  for provider in providers:
287
  model_with_provider = f"{current_model}:{provider}"
 
 
 
 
 
 
 
 
 
 
 
 
288
  payload = {
289
  "model": model_with_provider,
290
- "messages": messages,
291
  "max_tokens": max_new,
292
  "temperature": temperature or self._temperature,
293
  "top_p": self._top_p
 
185
  if hf_token:
186
  self._is_hf_inference_mode = True
187
  self._is_loaded = True
188
+ # Prioridade absoluta: Modelo sem censura (Leve e Pesado)
189
  self._model_path = "Orenguteng/Llama-3.1-8B-Lexi-Uncensored-V2"
190
+ self._heavy_model = "huihui-ai/Qwen2.5-72B-Instruct-abliterated"
191
+ self._portuguese_model = "rhaymison/Mistral-8x7b-Quantized-portuguese-luana"
192
+ self._multilingual_beast = "Qwen/Qwen2.5-72B-Instruct"
193
  self._stats["model_loaded"] = True
194
 
195
  # Inicializa o cliente se possível
 
280
  # Providers disponíveis (featherless-ai é o que oficialmente suporta Lexi-V2)
281
  providers = ["featherless-ai", "hyperbolic", "sambanova", "cerebras", "nebius", "novita"]
282
 
283
+ # Modelos para testar no Router (Luana/70B primeiro se for modo pesado)
284
+ candidate_models = []
285
+ # Se o prompt ou config indicar necessidade de alta capacidade, tentamos os pesados primeiro
286
+ if any(x in prompt.lower() for x in ["analise", "refatore", "complexo", "angola", "explicar", "portugues"]):
287
+ candidate_models.extend([self._heavy_model, self._portuguese_model, self._multilingual_beast])
288
+
289
+ candidate_models.append(base_model)
290
+
291
+ # Garantir que Llama 3.3 70B esteja na lista como fallback final de alta performance
292
+ if "Llama-3.3-70B" not in str(candidate_models):
293
  candidate_models.append("meta-llama/Llama-3.3-70B-Instruct")
294
 
295
  for current_model in candidate_models:
296
  for provider in providers:
297
  model_with_provider = f"{current_model}:{provider}"
298
+ # Ajuste dinâmico de template conforme a família do modelo
299
+ current_messages = messages.copy()
300
+
301
+ # Se for modelo Luana ou Mistral, aplicamos o template [INST] conforme a documentação
302
+ if "mistral" in current_model.lower() or "luana" in current_model.lower():
303
+ # Para Mistral via Chat API, geralmente o provedor já cuida da conversão,
304
+ # mas podemos reforçar na primeira mensagem se necessário.
305
+ # No caso da Luana específica, ela gosta do formato "Abaixo está uma instrução..."
306
+ if "luana" in current_model.lower():
307
+ instruction = f"Abaixo está uma instrução que descreve uma tarefa, juntamente com uma entrada que fornece mais contexto.\nEscreva uma resposta que complete adequadamente o pedido.\n### instrução: {sys_prompt}\n### entrada: {prompt}"
308
+ current_messages = [{"role": "user", "content": instruction}]
309
+
310
  payload = {
311
  "model": model_with_provider,
312
+ "messages": current_messages,
313
  "max_tokens": max_new,
314
  "temperature": temperature or self._temperature,
315
  "top_p": self._top_p