AKIRA-SOFTEDGE / modules /mac_integration.py
Isaac Quarenta
fix: remover proibições rígidas de frases, emojis em reactions, persona alinhada
0d26485
Raw
History Blame Contribute Delete
12.4 kB
"""
MAC INTEGRATION - Integração do Sistema MAC com a Akira
=========================================================
Conecta os drives homeostáticos, orquestrador de sub-agentes
e outros componentes MAC com o fluxo existente da Akira.
"""
import time
import random
from typing import Dict, Any, Optional, List
from dataclasses import dataclass
from loguru import logger
try:
from .mac_drives import get_mac_drives
from .multi_agent_orchestrator import get_multi_agent_orchestrator
MAC_COMPONENTS_AVAILABLE = True
except ImportError:
MAC_COMPONENTS_AVAILABLE = False
logger.warning("⚠️ MAC components não disponíveis")
@dataclass
class ProactiveAction:
"""Ação proativa decidida pelo sistema MAC."""
action_type: str # react, edit, delete, send, end_conversation
reason: str
text_reaction: Optional[str] = None
confidence: float = 0.7
new_content: Optional[str] = None # for edit
message_text: Optional[str] = None # for send
target_jid: Optional[str] = None # for send
message_id: Optional[str] = None # for edit/delete
class MACIntegration:
"""
Integra o sistema MAC com a Akira.
Coordena drives, sub-agentes e outros componentes.
"""
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._initialized = False
return cls._instance
def __init__(self):
if self._initialized:
return
self._initialized = True
self.drives = None
self.orchestrator = None
if MAC_COMPONENTS_AVAILABLE:
try:
from .mac_drives import get_mac_drives
from .multi_agent_orchestrator import get_multi_agent_orchestrator
self.drives = get_mac_drives()
from .multi_agent_orchestrator import get_multi_agent_orchestrator
self.orchestrator = get_multi_agent_orchestrator()
logger.info("🧠 [MAC INTEGRATION] Sistema MAC integrado com sucesso")
except Exception as e:
logger.warning(f"⚠️ [MAC INTEGRATION] Erro ao inicializar MAC: {e}")
def process_message(self, message: str, emotion: str = "neutro",
is_group: bool = False, is_reply_to_bot: bool = False,
user_id: str = None) -> Dict[str, Any]:
"""
Processa uma mensagem usando o sistema MAC.
Returns:
Dict com contexto enriquecido para o ThinkingEngine
"""
from typing import Dict, Any
if not self.drives:
return {}
# Processar nos drives
drive_state = self.drives.process_message(
message=message,
emotion=emotion,
is_group=is_group,
is_reply_to_bot=is_reply_to_bot,
user_id=user_id
)
# Analisar com sub-agentes (se disponível)
agent_results = {}
if self.orchestrator:
try:
agent_results = self.orchestrator.analyze_message(
message=message,
context={
"emotion": emotion,
"is_group": is_group,
"is_reply_to_bot": is_reply_to_bot,
"depth": "moderada"
},
max_agents=4,
timeout=5
)
except Exception as e:
logger.debug(f"⚠️ [MAC] Sub-agentes falharam: {e}")
return {
"drives": drive_state,
"agent_results": agent_results,
"suggestions": drive_state.get("suggestions", [])
}
def get_proactive_context(self, mensagem: str = "", usuario: str = None) -> str:
"""
Gera contexto proativo para o ThinkingEngine.
"""
if not self.drives:
return ""
return self.drives.get_proactive_context(mensagem, usuario)
def get_drive_state(self) -> Dict[str, Any]:
"""Retorna o estado atual dos drives."""
if not self.drives:
return {}
return self.drives.get_drive_state()
def decide_proactive_action(
self,
message: str,
emotion: str,
is_group: bool,
user_id: str = None,
group_jid: str = None,
bot_message: str = None,
user_response: str = None,
last_interaction_time: float = None,
is_reply_to_bot: bool = False,
is_creator: bool = False
) -> Optional[ProactiveAction]:
"""
Decide se deve realizar uma ação proativa baseada em:
- Estado dos drives (críticos)
- Arousal global alto
- Menções ao criador (Isaac)
- Tópicos que chamaram atenção
- Resposta muito curta do bot (pode querer encerrar)
- Fim natural de conversa
Returns:
ProactiveAction object ou None
"""
if not self.drives:
return None
state = self.drives.get_drive_state()
arousal = state.get("global_arousal", 0)
current_time = time.time()
# 1. DRIVES CRÍTICOS → ações de autorregulação
for drive_name, drive_info in state.get("drives", {}).items():
if drive_info.get("is_critical"):
if drive_name == "curiosidade":
return ProactiveAction(
action_type="send",
reason=f"Drive curiosidade crítico - buscando informação",
message_text="Hmm, isso me deixou curiosa... vou pesquisar sobre isso.",
confidence=0.8
)
elif drive_name == "alinhamento":
return ProactiveAction(
action_type="send",
reason="Drive alinhamento crítico - verificando coerência",
message_text="Deixa eu confirmar se entendi direito...",
confidence=0.85
)
elif drive_name == "eficiencia_memetica":
return ProactiveAction(
action_type="send",
reason="Drive eficiência crítico - simplificando",
message_text="Vou direto ao ponto então.",
confidence=0.8
)
# 2. AROUSAL ALTO → necessidade de regulação
if self.drives and self.drives.get_drive_state().get("global_arousal", 0) > 0.85:
return ProactiveAction(
action_type="send",
reason="Arousal global muito alto - autorregulação",
message_text="Calma... processando...",
confidence=0.9
)
# 2.5 CRIADOR (ISAAC) MENCIONADO → atenção máxima
# Isso é verificado no nível da API (api.py) via is_creator
# 2.7 CRIADOR MENCIONADO NO GRUPO → reação automática
if is_group and is_creator and ("isaac" in message.lower() or "@isaac" in message.lower()):
# Criador mencionado no grupo - reagir com texto de reconhecimento
return ProactiveAction(
action_type="react",
reason="Criador (Isaac) mencionado no grupo",
text_reaction="👁️",
confidence=0.95
)
# 2.8 EDIÇÃO DE MENSAGEM PRÓPRIA - quando detecta erro na própria resposta
# (ex: informação incorreta, typo grave, formatação quebrada)
if bot_message and user_response:
# Se usuário corrigiu o bot ou apontou erro
correction_keywords = ["errou", "errado", "não é isso", "correção", "typo", "está errado", "incorreto"]
if any(kw in user_response.lower() for kw in correction_keywords):
return ProactiveAction(
action_type="edit",
reason="Usuário corrigiu informação na resposta do bot",
new_content="[correção]",
confidence=0.85
)
# 2.9 EXCLUSÃO DE MENSAGEM - spam, auto-promoção, conteúdo inadequado
if message:
# Detectar auto-promoção ou spam
spam_patterns = [
"compre agora", "link na bio", "meu canal", "meu site", "acesse meu",
"promoção imperdível", "clique aqui", "ganhe dinheiro", "renda extra"
]
if any(pattern in message.lower() for pattern in spam_patterns):
return ProactiveAction(
action_type="delete",
reason="Possível spam/auto-promoção detectado",
confidence=0.9
)
# 3. RESPOSTA CURTA DO BOT → possível fim de conversa
# Removido: não encerrar conversa apenas por respostas curtas
# A conversa pode ser naturalmente curta sem ser fim
# 4. RESPOSTA MUITO LONGA DO USUÁRIO + IS_GROUP → possível interesse genuíno
if is_group and user_response and len(user_response.split()) > 50:
# Resposta detalhada em grupo - pode valer a pena reagir
if random.random() < 0.15: # 15% chance
return ProactiveAction(
action_type="react",
reason="Resposta detalhada em grupo - reconhecimento",
text_reaction="👍",
confidence=0.7
)
# 5. RESPOSTA MUITO CURTA DO USUÁRIO (em reply ao bot) → possível desinteresse
# Removido: não encerrar conversa apenas por respostas curtas do usuário
# Respostas curtas podem ser naturais em conversa casual
# 6. RESPOSTA CURTA DO BOT SEM REPLY → possível fim de thread
# 6. RESPOSTA CURTA DO BOT SEM REPLY → possível fim de thread
# Removido: não encerrar conversa apenas por respostas curtas do bot
# O bot pode responder curto naturalmente sem querer encerrar
# 7. TOPIC DE INTERESSE (drive curiosidade alto + tópico técnico)
# 7. TOPIC DE INTERESSE (drive curiosidade alto + tópico técnico)
if self.drives:
drive_state = self.drives.get_drive_state()
curiosidade = drive_state.get("drives", {}).get("curiosidade", {}).get("value", 0)
if curiosidade > 0.7 and any(kw in message.lower() for kw in ["como", "por que", "o que é", "explique", "tutorial"]):
if random.random() < 0.25: # 25% chance
return ProactiveAction(
action_type="send",
reason="Curiosidade alta + pergunta técnica - oferta de aprofundamento",
message_text="Quer que eu explique mais detalhes?",
confidence=0.75
)
# 8. RARA RESPOSTA A NÃO-MENÇÃO (apenas em grupo, muito raro)
if is_group and not is_reply_to_bot:
# Chance MUITO baixa (0.5%) de responder sem menção
if random.random() < 0.005:
# Só se tópico for interessante (drives altos)
drive_state = self.drives.get_drive_state() if self.drives else {}
avg_drive = sum(d.get("value", 0) for d in drive_state.get("drives", {}).values()) / max(len(drive_state.get("drives", {})), 1)
if avg_drive > 0.6:
return ProactiveAction(
action_type="react",
reason="Interesse genuíno no tópico do grupo (raro)",
text_reaction="🔥",
confidence=0.5
)
return None
def get_proactive_context(self, mensagem: str = "", usuario: str = None) -> str:
"""
Gera contexto proativo para o ThinkingEngine.
"""
if not self.drives:
return ""
return self.drives.get_proactive_context(mensagem, usuario)
def get_drive_state(self) -> Dict[str, Any]:
"""Retorna o estado atual dos drives."""
if not self.drives:
return {}
return self.drives.get_drive_state()
def get_mac_integration() -> MACIntegration:
"""Retorna a instância singleton da integração MAC."""
return MACIntegration()