|
import gradio as gr |
|
from transformers import AutoTokenizer, AutoModelForQuestionAnswering |
|
import torch |
|
import logging |
|
import warnings |
|
from typing import List, Tuple, Dict |
|
import random |
|
from datetime import datetime |
|
from dataclasses import dataclass |
|
from enum import Enum |
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
warnings.filterwarnings('ignore') |
|
|
|
class ThemeType(Enum): |
|
MARRIAGE = "casamento" |
|
FAMILY = "familia" |
|
SPIRITUAL = "vida_espiritual" |
|
WORK = "trabalho" |
|
RELATIONSHIPS = "relacionamentos" |
|
GENERAL = "geral" |
|
|
|
@dataclass |
|
class BiblicalExample: |
|
question: str |
|
passage: str |
|
text: str |
|
base_response: str |
|
application: str |
|
sentiment: str |
|
|
|
class SapienciaBiblica: |
|
def __init__(self): |
|
logger.info("Inicializando SapiênciaBíblica...") |
|
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
|
self.model_name = "pierreguillou/bert-base-cased-squad-v1.1-portuguese" |
|
self.session_history = [] |
|
|
|
|
|
self.biblical_examples = { |
|
"casamento": [ |
|
BiblicalExample( |
|
question="Como resolver conflitos no casamento?", |
|
passage="Efésios 4:26-32", |
|
text="Não se ponha o sol sobre a vossa ira...", |
|
base_response="O princípio bíblico para resolução de conflitos no casamento envolve três aspectos...", |
|
application="Resolução diária de conflitos e perdão", |
|
sentiment="supportive" |
|
), |
|
|
|
], |
|
"familia": [ |
|
BiblicalExample( |
|
question="Como educar filhos segundo a Bíblia?", |
|
passage="Provérbios 22:6", |
|
text="Instrui o menino no caminho em que deve andar...", |
|
base_response="A educação dos filhos deve ser fundamentada nos princípios bíblicos...", |
|
application="Ensino diário dos princípios bíblicos", |
|
sentiment="instructive" |
|
), |
|
|
|
], |
|
|
|
} |
|
|
|
self.setup_model() |
|
|
|
def setup_model(self): |
|
try: |
|
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name) |
|
self.model = AutoModelForQuestionAnswering.from_pretrained(self.model_name) |
|
self.model.to(self.device) |
|
logger.info(f"Modelo carregado com sucesso no dispositivo: {self.device}") |
|
except Exception as e: |
|
logger.error(f"Erro ao carregar modelo: {str(e)}") |
|
raise |
|
|
|
def get_verse_of_day(self) -> str: |
|
verses = [ |
|
("João 3:16", "Porque Deus amou o mundo de tal maneira..."), |
|
("Salmos 23:1", "O Senhor é meu pastor e nada me faltará..."), |
|
|
|
] |
|
verse = random.choice(verses) |
|
return f"📖 Versículo do Dia:\n{verse[0]}\n\n{verse[1]}" |
|
|
|
def get_daily_prayer_focus(self) -> str: |
|
focuses = [ |
|
"Gratidão", |
|
"Família", |
|
"Sabedoria", |
|
|
|
] |
|
focus = random.choice(focuses) |
|
return f"🙏 Foco de Oração:\n{focus}" |
|
|
|
def analyze_sentiment(self, text: str) -> str: |
|
positive_words = {'alegria', 'esperança', 'paz', 'amor'} |
|
negative_words = {'tristeza', 'medo', 'ansiedade'} |
|
|
|
text_words = set(text.lower().split()) |
|
pos_count = len(text_words.intersection(positive_words)) |
|
neg_count = len(text_words.intersection(negative_words)) |
|
|
|
return 'positive' if pos_count > neg_count else 'negative' if neg_count > pos_count else 'neutral' |
|
|
|
def get_unique_response(self, question: str, theme: str = None) -> Tuple[str, Dict, str]: |
|
if not theme or theme not in self.biblical_examples: |
|
theme = self.find_best_theme(question) |
|
|
|
examples = self.biblical_examples.get(theme, self.biblical_examples["geral"]) |
|
example = random.choice(examples) |
|
sentiment = self.analyze_sentiment(question) |
|
|
|
response = self.format_response(example, sentiment) |
|
metadata = self.create_metadata(example, theme) |
|
history = self.save_to_history(question, theme, response, metadata) |
|
|
|
return response, metadata, history |
|
|
|
def format_response(self, example: BiblicalExample, sentiment: str) -> str: |
|
intro = { |
|
'positive': "Que bom que você está buscando orientação! ", |
|
'negative': "Entendo seu momento e estou aqui para ajudar. ", |
|
'neutral': "Agradeço sua busca por sabedoria. " |
|
} |
|
|
|
return f""" |
|
🌟 Orientação Personalizada: |
|
{intro[sentiment]}{example.base_response} |
|
|
|
📖 Passagem Bíblica: |
|
{example.passage}: {example.text} |
|
|
|
✨ Aplicação Prática: |
|
{example.application} |
|
|
|
🙏 Observação: Esta orientação é baseada em princípios bíblicos. |
|
""" |
|
|
|
def create_metadata(self, example: BiblicalExample, theme: str) -> Dict: |
|
return { |
|
"passagem": example.passage, |
|
"tema": theme, |
|
"aplicacao": example.application |
|
} |
|
|
|
def save_to_history(self, question: str, theme: str, response: str, metadata: Dict) -> str: |
|
self.session_history.append({ |
|
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), |
|
"theme": theme, |
|
"question": question, |
|
"response": response, |
|
"metadata": metadata |
|
}) |
|
return self.format_history() |
|
|
|
def format_history(self) -> str: |
|
if not self.session_history: |
|
return "Nenhuma consulta realizada ainda." |
|
|
|
return "\n\n".join([ |
|
f"🕒 {entry['timestamp']}\n📌 {entry['theme']}\n❓ {entry['question']}\n" |
|
for entry in reversed(self.session_history[-5:]) |
|
]) |
|
|
|
def find_best_theme(self, question: str) -> str: |
|
|
|
return "geral" |
|
|
|
def create_interface(): |
|
counselor = SapienciaBiblica() |
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as demo: |
|
gr.Markdown(""" |
|
# 🕊️ SapiênciaBíblica |
|
### Orientação Divina para Vida Moderna |
|
""") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
verse_of_day = gr.Textbox( |
|
label="Versículo do Dia", |
|
value=counselor.get_verse_of_day(), |
|
lines=4, |
|
interactive=False |
|
) |
|
|
|
with gr.Column(): |
|
prayer_focus = gr.Textbox( |
|
label="Foco de Oração", |
|
value=counselor.get_daily_prayer_focus(), |
|
lines=4, |
|
interactive=False |
|
) |
|
|
|
with gr.Row(): |
|
question = gr.Textbox( |
|
label="Sua Pergunta", |
|
placeholder="Digite sua pergunta...", |
|
lines=3 |
|
) |
|
theme = gr.Dropdown( |
|
choices=[t.value for t in ThemeType], |
|
label="Tema (Opcional)", |
|
value="geral" |
|
) |
|
|
|
submit_btn = gr.Button("🙏 Buscar Orientação") |
|
|
|
answer_output = gr.Textbox(label="Resposta", lines=10) |
|
metadata_output = gr.JSON(label="Detalhes") |
|
history_output = gr.Textbox(label="Histórico", lines=10) |
|
|
|
submit_btn.click( |
|
fn=counselor.get_unique_response, |
|
inputs=[question, theme], |
|
outputs=[answer_output, metadata_output, history_output] |
|
) |
|
|
|
return demo |
|
|
|
if __name__ == "__main__": |
|
try: |
|
logger.info("Iniciando SapiênciaBíblica...") |
|
demo = create_interface() |
|
demo.launch( |
|
server_name="0.0.0.0", |
|
share=True, |
|
show_error=True, |
|
server_port=7860 |
|
) |
|
except Exception as e: |
|
logger.error(f"Erro ao iniciar aplicação: {str(e)}") |
|
raise |