InspiraLead / app.py
DHEIVER's picture
Update app.py
dd99e90 verified
raw
history blame
7.3 kB
import gradio as gr
from datetime import datetime
from sentence_transformers import SentenceTransformer
import numpy as np
from typing import Dict, List, Tuple
from textblob import TextBlob
import json
# Load embeddings model
model = SentenceTransformer('all-MiniLM-L6-v2')
# Load data from JSON
with open('coach_data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
PERGUNTAS = data['perguntas']
TONE_PATTERNS = data['tone_patterns']
RESPOSTAS_COACH = data['respostas_coach']
class EnhancedCoach:
def __init__(self):
self.pergunta_atual = 0
self.inicio = datetime.now()
self.historico_respostas = []
self.sessao_completa = False
self.tone_history = []
self.response_quality_metrics = []
def analyze_response_quality(self, text: str) -> Dict[str, float]:
sentences = [s.strip() for s in text.split('.') if s.strip()]
words = text.lower().split()
metrics = {
"depth": self._calculate_depth(text, words),
"clarity": self._calculate_clarity(sentences),
"specificity": self._calculate_specificity(text, words),
"actionability": self._calculate_actionability(sentences)
}
self.response_quality_metrics.append(metrics)
return metrics
def _calculate_depth(self, text: str, words: List[str]) -> float:
if not words:
return 0.0
unique_words = len(set(words))
word_length_avg = sum(len(word) for word in words) / len(words)
sentences = [s.strip() for s in text.split('.') if s.strip()]
word_variety = unique_words / len(words)
sentence_length = len(sentences)
complexity = word_length_avg / 5
depth_score = (word_variety * 0.4 +
min(sentence_length / 3, 1.0) * 0.4 +
complexity * 0.2)
return min(1.0, depth_score)
def _calculate_clarity(self, sentences: List[str]) -> float:
if not sentences:
return 0.0
avg_length = sum(len(s.split()) for s in sentences) / len(sentences)
return 1.0 if 10 <= avg_length <= 20 else 0.7
def _calculate_specificity(self, text: str, words: List[str]) -> float:
specific_indicators = [
"exemplo", "especificamente", "concretamente",
"situação", "caso", "quando", "onde", "como",
"projeto", "equipe", "reunião", "feedback",
"resultado", "impacto", "mudança", "melhoria",
"implementei", "desenvolvi", "criei", "estabeleci",
"eu", "minha", "nosso", "realizei", "fiz"
]
indicator_count = sum(text.lower().count(ind) for ind in specific_indicators)
response_length_factor = min(len(words) / 20, 1.0)
return min(1.0, (indicator_count * 0.7 + response_length_factor * 0.3))
def _calculate_actionability(self, sentences: List[str]) -> float:
action_verbs = [
"implementar", "fazer", "criar", "desenvolver", "estabelecer",
"planejar", "executar", "medir", "avaliar", "iniciar",
"construir", "liderar", "coordenar", "definir", "ajustar"
]
if not sentences:
return 0.0
actionable = sum(1 for s in sentences
if any(verb in s.lower() for verb in action_verbs))
return min(1.0, actionable / len(sentences))
def analisar_tom(self, texto: str) -> Tuple[str, float]:
texto_lower = texto.lower()
blob = TextBlob(texto)
tone_scores = {}
for tone, patterns in TONE_PATTERNS.items():
score = sum(texto_lower.count(pattern) for pattern in patterns)
tone_scores[tone] = score * (1 + abs(blob.sentiment.polarity))
predominant_tone = max(tone_scores.items(), key=lambda x: x[1])
return predominant_tone[0], predominant_tone[1]
def analisar_sentimento(self, texto: str) -> str:
positive_words = [
"consegui", "superei", "aprendi", "melhorei", "efetivo",
"cresci", "evoluí", "realizei", "alcancei", "progresso"
]
negative_words = [
"difícil", "desafiador", "complicado", "problema", "falha",
"obstáculo", "limitação", "erro", "confuso", "inseguro"
]
texto_lower = texto.lower()
positive_count = sum(1 for word in positive_words if word in texto_lower)
negative_count = sum(1 for word in negative_words if word in texto_lower)
if positive_count > negative_count:
return "positive"
elif negative_count > positive_count:
return "improvement"
return "neutral"
def extrair_acao_especifica(self, texto: str) -> str:
sentences = texto.split('.')
for sentence in sentences:
if any(action in sentence.lower() for action in ["eu", "minha", "realizei", "fiz"]):
return sentence.strip()
return texto.split('.')[0].strip()
def encontrar_melhor_resposta(self, texto_usuario: str, categoria: str) -> str:
sentimento = self.analisar_sentimento(texto_usuario)
acao_especifica = self.extrair_acao_especifica(texto_usuario)
respostas_categoria = RESPOSTAS_COACH[categoria][sentimento]
user_embedding = model.encode(texto_usuario)
melhor_resposta = None
maior_similaridade = -1
for template in respostas_categoria:
context_embedding = model.encode(template["context"])
similaridade = np.dot(user_embedding, context_embedding)
if similaridade > maior_similaridade:
maior_similaridade = similaridade
melhor_resposta = template["response"]
return melhor_resposta.format(specific_action=acao_especifica.lower())
# Rest of the methods remain the same...
# (Previous implementation of gerar_resposta, _gerar_insight_tom, etc.)
def criar_interface():
coach = EnhancedCoach()
with gr.Blocks(title="Coach de Liderança", theme=gr.themes.Soft()) as app:
gr.Markdown("""# 🚀 Coach de Liderança
Desenvolva sua liderança através de reflexão guiada e feedback personalizado.""")
chat = gr.Chatbot(
value=[[None, coach.primeira_pergunta()]],
height=600,
show_label=False
)
with gr.Row():
txt = gr.Textbox(
placeholder="Compartilhe sua reflexão aqui...",
lines=4,
label="Sua Resposta"
)
btn = gr.Button("Enviar", variant="primary")
def responder(mensagem, historico):
if not mensagem.strip():
return "", historico
resposta = coach.gerar_resposta(mensagem)
historico.append([mensagem, resposta])
return "", historico
txt.submit(responder, [txt, chat], [txt, chat])
btn.click(responder, [txt, chat], [txt, chat])
return app
if __name__ == "__main__":
app = criar_interface()
app.launch()