Spaces:
Running
Running
| # -*- 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]" | |