import gradio as gr from transformers import AutoTokenizer, AutoModelForQuestionAnswering import torch import logging import warnings from typing import List, Tuple, Dict import random import hashlib from datetime import datetime logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) warnings.filterwarnings('ignore') class DiverseBiblicalCounselor: def __init__(self): logger.info("Inicializando conselheiro bíblico...") 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 = [] # Movendo os exemplos para dentro da classe self.biblical_examples = { "casamento": [ { "pergunta": "Como resolver conflitos no casamento?", "passagem": "Efésios 4:26-32", "texto": """Não se ponha o sol sobre a vossa ira. Não deis lugar ao diabo. Toda amargura, cólera, ira, gritaria e blasfêmia sejam tiradas dentre vós, bem como toda malícia. Antes, sede bondosos uns para com os outros, compassivos, perdoando uns aos outros, como também Deus vos perdoou em Cristo.""", "resposta_base": """O princípio bíblico para resolução de conflitos no casamento envolve três aspectos fundamentais: não deixar a ira se prolongar, comunicar-se com amor e praticar o perdão mútuo. A Palavra nos ensina que devemos resolver os conflitos rapidamente, não permitindo que o sol se ponha sobre nossa ira.""", "aplicacao": "Resolução diária de conflitos, perdão e reconciliação" }, { "pergunta": "Como manter um casamento forte espiritualmente?", "passagem": "Eclesiastes 4:9-12", "texto": """É melhor serem dois do que um, porque têm melhor paga do seu trabalho. Porque se um cair, o outro levanta o seu companheiro; mas ai do que estiver só; pois, caindo, não haverá outro que o levante. Também, se dois dormirem juntos, eles se aquentarão; mas um só, como se aquentará? E, se alguém prevalecer contra um, os dois lhe resistirão; e o cordão de três dobras não se quebra tão depressa.""", "resposta_base": """A força espiritual do casamento vem da união em três dimensões: o marido, a esposa e Deus. Como um cordão de três dobras, esta união proporciona apoio mútuo, fortalecimento espiritual e resistência nas adversidades.""", "aplicacao": "Desenvolvimento espiritual conjunto e oração em casal" } ], "familia": [ { "pergunta": "Como educar filhos segundo a Bíblia?", "passagem": "Provérbios 22:6", "texto": """Instrui o menino no caminho em que deve andar, e até quando envelhecer não se desviará dele.""", "resposta_base": """A educação dos filhos deve ser fundamentada nos princípios bíblicos, com amor, disciplina e instrução constante. Os pais são responsáveis por guiar seus filhos no caminho do Senhor desde cedo.""", "aplicacao": "Ensino diário dos princípios bíblicos aos filhos" } ] } 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_themes(self) -> List[str]: """Retorna lista de temas disponíveis""" return list(self.biblical_examples.keys()) def get_examples(self) -> List[List[str]]: """Retorna exemplos formatados para a interface""" examples = [] for theme in self.biblical_examples: for example in self.biblical_examples[theme]: examples.append([theme, example["pergunta"]]) return examples def get_verse_of_the_day(self) -> str: """Retorna um versículo diário baseado na data""" all_verses = [] for theme_examples in self.biblical_examples.values(): for example in theme_examples: all_verses.append({ 'passagem': example['passagem'], 'texto': example['texto'] }) today = datetime.now().strftime("%Y%m%d") random.seed(today) verse = random.choice(all_verses) return f"📖 Versículo do Dia:\n{verse['passagem']}\n\n{verse['texto']}" def save_to_history(self, question: str, theme: str, response: str, metadata: Dict): """Salva a consulta no histórico com timestamp""" 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: """Formata o histórico de consultas para exibição""" if not self.session_history: return "Nenhuma consulta realizada ainda." history_text = "📚 Histórico de Consultas:\n\n" for entry in reversed(self.session_history[-5:]): history_text += f"🕒 {entry['timestamp']}\n" history_text += f"📌 Tema: {entry['theme']}\n" history_text += f"❓ Pergunta: {entry['question']}\n" history_text += f"📖 Passagem: {entry['metadata']['passagem']}\n" history_text += "─" * 50 + "\n" return history_text def get_unique_response(self, question: str, theme: str) -> Tuple[str, Dict, str]: """Gera uma resposta única baseada na pergunta e tema""" if theme not in self.biblical_examples: return "Tema não encontrado", {}, self.format_history() question_hash = hashlib.md5(question.lower().encode()).hexdigest() examples = self.biblical_examples[theme] selected_index = int(question_hash, 16) % len(examples) example = examples[selected_index] inputs = self.tokenizer.encode_plus( question, example["texto"], return_tensors="pt", max_length=512, truncation=True, padding="max_length" ).to(self.device) with torch.no_grad(): outputs = self.model(**inputs) answer_start = torch.argmax(outputs.start_logits) answer_end = torch.argmax(outputs.end_logits) tokens = self.tokenizer.convert_ids_to_tokens(inputs["input_ids"][0]) model_answer = tokens[answer_start:answer_end + 1] model_answer = self.tokenizer.convert_tokens_to_string(model_answer) response = f""" 🕊️ Conselho Bíblico: {example['resposta_base']} 📖 Passagem Bíblica: {example['passagem']}: {example['texto']} ✝️ Aplicação Prática: {example['aplicacao']} 💭 Reflexão Adicional: {model_answer} """ metadata = { "passagem": example['passagem'], "contexto": "Baseado em princípios bíblicos para " + theme.replace('_', ' '), "aplicacao": example['aplicacao'] } history = self.save_to_history(question, theme, response, metadata) return response, metadata, history def create_interface(): counselor = DiverseBiblicalCounselor() with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🕊️ Conselheiro Bíblico ### Orientação Bíblica Personalizada """) with gr.Row(): verse_of_day = gr.Textbox( label="Versículo do Dia", value=counselor.get_verse_of_the_day(), lines=4, interactive=False ) with gr.Tabs(): with gr.TabItem("📝 Consulta"): with gr.Row(): with gr.Column(): theme = gr.Dropdown( choices=counselor.get_themes(), label="Tema", value="casamento" ) question = gr.Textbox( label="Sua Pergunta", placeholder="Digite sua pergunta...", lines=3 ) submit_btn = gr.Button("🙏 Buscar Orientação", variant="primary") with gr.Column(): answer_output = gr.Textbox( label="Resposta", lines=10 ) metadata_output = gr.Textbox( label="Referências", lines=3 ) with gr.TabItem("📚 Histórico"): history_output = gr.Textbox( label="Histórico de Consultas", value="Nenhuma consulta realizada ainda.", lines=15, interactive=False ) with gr.TabItem("ℹ️ Ajuda"): gr.Markdown(""" ### Como usar o Conselheiro Bíblico: 1. Selecione um tema relacionado à sua dúvida 2. Digite sua pergunta de forma clara e objetiva 3. Clique em "Buscar Orientação" 4. Receba orientação baseada em princípios bíblicos ### Temas Disponíveis: - Casamento: Conselhos para relacionamento conjugal - Família: Orientação para vida familiar ### Notas: - As respostas são baseadas em princípios bíblicos - Cada consulta é salva no histórico para referência futura - O versículo do dia é atualizado diariamente """) gr.Examples( examples=counselor.get_examples(), inputs=[theme, question], outputs=[answer_output, metadata_output, history_output], fn=lambda t, q: counselor.get_unique_response(q, t), label="Exemplos de Perguntas" ) submit_btn.click( fn=counselor.get_unique_response, inputs=[theme, question], outputs=[answer_output, metadata_output, history_output] ) return demo if __name__ == "__main__": try: logger.info("Iniciando aplicação...") demo = create_interface() demo.launch( server_name="0.0.0.0", share=True, show_error=True ) except Exception as e: logger.error(f"Erro ao iniciar aplicação: {str(e)}") raise