akira-index / modules /api_new.py
akra35567's picture
Upload 20 files
d3a1a58 verified
# -*- coding: utf-8 -*-
"""
NOVA VERSÃO DO MÉTODO _build_prompt COM REPLY + SHORT-TERM MEMORY EM SINTONIA
Substituir este método na classe AkiraAPI em api.py
"""
def _build_prompt(
self,
usuario: str,
numero: str,
mensagem: str,
analise: Dict[str, Any],
contexto,
web_content: str = "",
mensagem_citada: str = "",
is_reply: bool = False,
reply_to_bot: bool = False,
quoted_author_name: str = "",
quoted_author_numero: str = "",
quoted_type: str = "texto",
quoted_text_original: str = "",
context_hint: str = "",
tipo_conversa: str = "pv",
tem_imagem: bool = False,
analise_visao: Dict[str, Any] = None
) -> str:
now = datetime.datetime.now()
data_hora = now.strftime('%d/%m/%Y %H:%M')
strict_override = "STRICT_OVERRIDES:\n"
palavras_mensagem = len(mensagem.split())
if palavras_mensagem <= 1:
strict_override += "- Input 1 palavra -> Response 1-2 palavras!\n"
elif palavras_mensagem <= 3:
strict_override += "- Input 2-3 palavras -> Response 2-4 palavras!\n"
elif palavras_mensagem <= 6:
strict_override += "- Input 4-6 palavras -> Response 4-8 palavras!\n"
else:
strict_override += "- Response proporcional ao input!\n"
strict_override += "- Data e hora: " + data_hora + "\n"
# ============================================================
# 🔧 CORREÇÃO PRINCIPAL: REPLY + SHORT-TERM MEMORY EM SINTONIA
# ============================================================
# "O brilho dessa lógica é que reply e memória de curto prazo
# devem trabalhar em sintonia como tik e tack"
# ============================================================
# ===== 1. REPLY CONTEXT (PRIORITÁRIO) =====
reply_context_section = ""
if is_reply:
reply_context_section += "\n[📎 REPLY CONTEXT - PRIORITÁRIO]\n"
# Determine reply target
if reply_to_bot:
reply_context_section += "⚠️ VOCÊ ESTÁ SENDO DIRETAMENTE RESPONDIDO!\n"
else:
author_name = quoted_author_name or "alguém"
reply_context_section += f"Respondendo a: {author_name}\n"
# Extract and analyze quoted content
quoted_content = self._extract_and_search_reply_content(
mensagem_citada=mensagem_citada,
quoted_text_original=quoted_text_original,
current_message=mensagem,
reply_to_bot=reply_to_bot
)
reply_context_section += quoted_content
# Context hint if available
if context_hint and context_hint != "contexto_geral":
reply_context_section += f"Contexto: {context_hint}\n"
reply_context_section += "\n📌 INSTRUÇÕES PARA REPLY:\n"
reply_context_section += "- Você está respondendo ao CONTEÚDO CITADO\n"
reply_context_section += "- Use o contexto da mensagem citada\n"
reply_context_section += "- Seja relevante ao tópico da mensagem original\n"
reply_context_section += "- NÃO repita informações já ditas\n"
# ===== 2. SHORT-TERM MEMORY CONTEXT (SINTONIZADO COM REPLY) =====
short_term_memory_section = ""
try:
# Obtém memória de curto prazo do contexto
if hasattr(contexto, 'obter_historico_para_llm'):
short_term_msgs = contexto.obter_historico_para_llm()
if short_term_msgs and len(short_term_msgs) > 0:
short_term_memory_section += "\n[🧠 MEMÓRIA DE CURTO PRAZO]\n"
short_term_memory_section += "(conversa recente - contexto adicional)\n"
# Inclui últimas mensagens (máximo 5 para não poluir)
for i, msg in enumerate(short_term_msgs[-5:]):
if isinstance(msg, dict):
role = msg.get('role', 'unknown')
content = msg.get('content', '')[:100]
short_term_memory_section += f"• [{role.upper()}] {content}...\n"
elif isinstance(msg, tuple) and len(msg) >= 2:
short_term_memory_section += f"• [USER] {msg[0][:100]}...\n"
short_term_memory_section += "\n💡 INTEGRAÇÃO: Use este contexto para manter coerência com a conversa!\n"
except Exception as e:
self.logger.warning(f"Erro ao obter memória de curto prazo: {e}")
# ===== 3. INTEGRAÇÃO FINAL (TIK + TACK) =====
# Reply context PRIMEIRO (mais urgente), depois memória de curto prazo
if is_reply:
strict_override += reply_context_section
if short_term_memory_section:
strict_override += short_term_memory_section
if tipo_conversa == "grupo":
strict_override += "\n[GRUPO] Conversa em grupo.\n"
else:
strict_override += "\n[PV] Conversa privada.\n"
if web_content:
strict_override += "\n[WEB INFO]\n"
strict_override += web_content[:3000] + "\n"
# Se forçado downshift de love, avisa a instrucao de restricao de tom
if isinstance(analise, dict) and analise.get('forcar_downshift_love'):
strict_override += "\n[RESTRICAO DE TOM]\n- Nao use tom de love ainda. Seja no maximo leve/joy, sem caricias, sem intimidade.\n"
# Se nao-privilegiado tentou comando, oriente a gerar resposta rude e negar a acao
if isinstance(analise, dict) and analise.get('non_privileged_command'):
attempted = analise.get('command_attempt') or mensagem
strict_override += "\n[PRIVILEGIO NEGADO]\n- Usuario NAO-PRIVILEGIADO tentou executar comando operacional.\n- Comando tentado: \"" + attempted[:200] + "\"\n- Responda de forma rude, negue a solicitacao e nao execute quaisquer comandos.\n"
system_part = strict_override + "\n" + self.config.SYSTEM_PROMPT + "\n"
return "[SYSTEM]\n" + system_part + "\n[/SYSTEM]\n[USER]\n### Usuario ###\nNome: " + usuario + "\n\n### Mensagem ###\n" + mensagem + "\n\nAkira:\n[/USER]"