Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -3,11 +3,14 @@ from transformers import AutoTokenizer, AutoModelForQuestionAnswering
|
|
3 |
import torch
|
4 |
import logging
|
5 |
import warnings
|
6 |
-
from typing import List, Tuple, Dict
|
7 |
import random
|
8 |
from datetime import datetime
|
9 |
from dataclasses import dataclass
|
10 |
from enum import Enum
|
|
|
|
|
|
|
11 |
|
12 |
logging.basicConfig(level=logging.INFO)
|
13 |
logger = logging.getLogger(__name__)
|
@@ -29,6 +32,96 @@ class BiblicalExample:
|
|
29 |
base_response: str
|
30 |
application: str
|
31 |
sentiment: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
class SapienciaBiblica:
|
34 |
def __init__(self):
|
@@ -37,6 +130,7 @@ class SapienciaBiblica:
|
|
37 |
self.model_name = "pierreguillou/bert-base-cased-squad-v1.1-portuguese"
|
38 |
self.session_history = []
|
39 |
self.biblical_examples = self.get_default_examples_dict()
|
|
|
40 |
self.setup_model()
|
41 |
|
42 |
def setup_model(self):
|
@@ -57,109 +151,36 @@ class SapienciaBiblica:
|
|
57 |
passage="Efésios 4:29",
|
58 |
text="Não saia da vossa boca nenhuma palavra torpe, mas só a que for boa para promover a edificação, para que dê graça aos que a ouvem.",
|
59 |
base_response="A comunicação efetiva no casamento requer sabedoria, paciência e amor. A Bíblia nos ensina a usar palavras que edificam e não destroem.",
|
60 |
-
application="Pratique escuta ativa, escolha momentos adequados para conversas importantes.",
|
61 |
-
sentiment="supportive"
|
|
|
62 |
),
|
63 |
BiblicalExample(
|
64 |
-
question="Como
|
65 |
-
passage="Efésios 4:26-
|
66 |
-
text="
|
67 |
-
base_response="
|
68 |
-
application="
|
69 |
-
sentiment="instructive"
|
|
|
70 |
)
|
71 |
],
|
72 |
"familia": [
|
73 |
BiblicalExample(
|
74 |
-
question="Como
|
75 |
passage="Provérbios 22:6",
|
76 |
text="Instrui o menino no caminho em que deve andar, e até quando envelhecer não se desviará dele.",
|
77 |
-
base_response="A
|
78 |
-
application="Estabeleça
|
79 |
-
sentiment="instructive"
|
80 |
-
|
81 |
-
],
|
82 |
-
"vida_espiritual": [
|
83 |
-
BiblicalExample(
|
84 |
-
question="Como desenvolver uma vida de oração?",
|
85 |
-
passage="1 Tessalonicenses 5:17",
|
86 |
-
text="Orai sem cessar.",
|
87 |
-
base_response="A vida de oração se desenvolve através da prática constante.",
|
88 |
-
application="Reserve um tempo diário para oração.",
|
89 |
-
sentiment="spiritual"
|
90 |
-
)
|
91 |
-
],
|
92 |
-
"trabalho": [
|
93 |
-
BiblicalExample(
|
94 |
-
question="Como ter integridade no trabalho?",
|
95 |
-
passage="Colossenses 3:23",
|
96 |
-
text="E tudo quanto fizerdes, fazei-o de coração, como ao Senhor.",
|
97 |
-
base_response="Trabalhe com excelência e integridade como para o Senhor.",
|
98 |
-
application="Pratique ética e dedicação no trabalho.",
|
99 |
-
sentiment="professional"
|
100 |
)
|
101 |
],
|
102 |
-
|
103 |
-
BiblicalExample(
|
104 |
-
question="Como construir amizades verdadeiras?",
|
105 |
-
passage="Provérbios 17:17",
|
106 |
-
text="Em todo tempo ama o amigo, e na angústia nasce o irmão.",
|
107 |
-
base_response="Amizades verdadeiras são construídas com amor e lealdade.",
|
108 |
-
application="Seja presente e fiel nas amizades.",
|
109 |
-
sentiment="friendly"
|
110 |
-
)
|
111 |
-
],
|
112 |
-
"geral": [
|
113 |
-
BiblicalExample(
|
114 |
-
question="Como encontrar paz em tempos difíceis?",
|
115 |
-
passage="João 14:27",
|
116 |
-
text="Deixo-vos a paz, a minha paz vos dou.",
|
117 |
-
base_response="A verdadeira paz vem de Deus e permanece nas tribulações.",
|
118 |
-
application="Confie em Deus em todas as circunstâncias.",
|
119 |
-
sentiment="comforting"
|
120 |
-
)
|
121 |
-
]
|
122 |
}
|
123 |
|
124 |
-
def get_examples_for_interface(self) -> List[List[str]]:
|
125 |
-
examples = []
|
126 |
-
for theme in self.biblical_examples:
|
127 |
-
for example in self.biblical_examples[theme]:
|
128 |
-
examples.append([theme, example.question])
|
129 |
-
return examples
|
130 |
-
|
131 |
-
def get_verse_of_day(self) -> str:
|
132 |
-
verses = [
|
133 |
-
("João 3:16", "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito..."),
|
134 |
-
("Salmos 23:1", "O Senhor é meu pastor e nada me faltará."),
|
135 |
-
("Filipenses 4:13", "Posso todas as coisas em Cristo que me fortalece."),
|
136 |
-
("Jeremias 29:11", "Porque eu bem sei os pensamentos que tenho a vosso respeito...")
|
137 |
-
]
|
138 |
-
verse = random.choice(verses)
|
139 |
-
return f"📖 Versículo do Dia:\n{verse[0]}\n\n{verse[1]}"
|
140 |
-
|
141 |
-
def get_daily_prayer_focus(self) -> str:
|
142 |
-
focuses = [
|
143 |
-
"Gratidão e Louvor",
|
144 |
-
"Família e Relacionamentos",
|
145 |
-
"Sabedoria e Direção",
|
146 |
-
"Paz e Serenidade",
|
147 |
-
"Cura e Restauração"
|
148 |
-
]
|
149 |
-
focus = random.choice(focuses)
|
150 |
-
return f"🙏 Foco de Oração:\n{focus}"
|
151 |
-
|
152 |
-
def analyze_sentiment(self, text: str) -> str:
|
153 |
-
positive_words = {'alegria', 'esperança', 'paz', 'amor', 'gratidão', 'feliz', 'bem'}
|
154 |
-
negative_words = {'tristeza', 'medo', 'ansiedade', 'preocupação', 'angústia', 'mal', 'dor'}
|
155 |
-
|
156 |
-
text_words = set(text.lower().split())
|
157 |
-
pos_count = len(text_words.intersection(positive_words))
|
158 |
-
neg_count = len(text_words.intersection(negative_words))
|
159 |
-
|
160 |
-
return 'positive' if pos_count > neg_count else 'negative' if neg_count > pos_count else 'neutral'
|
161 |
-
|
162 |
def find_best_theme(self, question: str) -> str:
|
|
|
163 |
question = question.lower()
|
164 |
theme_keywords = {
|
165 |
"casamento": ["casamento", "cônjuge", "esposa", "marido", "casal"],
|
@@ -169,26 +190,73 @@ class SapienciaBiblica:
|
|
169 |
"relacionamentos": ["amizade", "relacionamento", "conflito", "perdão"],
|
170 |
}
|
171 |
|
|
|
|
|
|
|
172 |
for theme, keywords in theme_keywords.items():
|
173 |
-
|
174 |
-
|
175 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
|
177 |
def get_unique_response(self, question: str, theme: str = None) -> Tuple[str, Dict, str]:
|
|
|
|
|
|
|
|
|
178 |
if not theme or theme not in self.biblical_examples:
|
179 |
theme = self.find_best_theme(question)
|
180 |
-
|
181 |
-
examples = self.biblical_examples[theme]
|
182 |
-
example = random.choice(examples)
|
183 |
-
sentiment = self.analyze_sentiment(question)
|
184 |
|
185 |
-
|
186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
history = self.save_to_history(question, theme, response, metadata)
|
188 |
|
189 |
return response, metadata, history
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
def format_response(self, example: BiblicalExample, sentiment: str) -> str:
|
|
|
192 |
intro = {
|
193 |
'positive': "Que bom que você está buscando orientação! ",
|
194 |
'negative': "Entendo seu momento e estou aqui para ajudar. ",
|
@@ -210,15 +278,47 @@ Esta orientação é baseada em princípios bíblicos. Para questões específic
|
|
210 |
considere consultar sua liderança espiritual local.
|
211 |
"""
|
212 |
|
213 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
return {
|
215 |
-
"
|
216 |
-
"
|
217 |
-
"
|
218 |
-
"
|
|
|
|
|
|
|
219 |
}
|
220 |
|
221 |
def save_to_history(self, question: str, theme: str, response: str, metadata: Dict) -> str:
|
|
|
222 |
self.session_history.append({
|
223 |
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
224 |
"theme": theme,
|
@@ -229,17 +329,52 @@ considere consultar sua liderança espiritual local.
|
|
229 |
return self.format_history()
|
230 |
|
231 |
def format_history(self) -> str:
|
|
|
232 |
if not self.session_history:
|
233 |
return "Nenhuma consulta realizada ainda."
|
234 |
|
235 |
history_text = "📚 Histórico de Consultas:\n\n"
|
236 |
-
for entry in reversed(self.session_history[-5:]):
|
237 |
history_text += f"🕒 {entry['timestamp']}\n"
|
238 |
history_text += f"📌 Tema: {entry['theme']}\n"
|
239 |
history_text += f"❓ Pergunta: {entry['question']}\n"
|
|
|
|
|
240 |
history_text += "─" * 40 + "\n"
|
241 |
return history_text
|
242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
def create_interface():
|
244 |
counselor = SapienciaBiblica()
|
245 |
|
@@ -300,7 +435,7 @@ def create_interface():
|
|
300 |
interactive=False
|
301 |
)
|
302 |
|
303 |
-
#
|
304 |
gr.Examples(
|
305 |
examples=counselor.get_examples_for_interface(),
|
306 |
inputs=[theme, question],
|
|
|
3 |
import torch
|
4 |
import logging
|
5 |
import warnings
|
6 |
+
from typing import List, Tuple, Dict, Optional
|
7 |
import random
|
8 |
from datetime import datetime
|
9 |
from dataclasses import dataclass
|
10 |
from enum import Enum
|
11 |
+
from difflib import SequenceMatcher
|
12 |
+
import numpy as np
|
13 |
+
import re
|
14 |
|
15 |
logging.basicConfig(level=logging.INFO)
|
16 |
logger = logging.getLogger(__name__)
|
|
|
32 |
base_response: str
|
33 |
application: str
|
34 |
sentiment: str
|
35 |
+
keywords: List[str] = None
|
36 |
+
theme: str = ""
|
37 |
+
|
38 |
+
def __post_init__(self):
|
39 |
+
if self.keywords is None:
|
40 |
+
self.keywords = self.extract_keywords()
|
41 |
+
|
42 |
+
def extract_keywords(self) -> List[str]:
|
43 |
+
"""Extract meaningful keywords from question and response."""
|
44 |
+
text = f"{self.question} {self.base_response}"
|
45 |
+
words = text.lower().split()
|
46 |
+
# Remove common Portuguese stop words
|
47 |
+
stop_words = {'a', 'o', 'e', 'de', 'do', 'da', 'em', 'para', 'com', 'um', 'uma'}
|
48 |
+
keywords = [word for word in words if len(word) > 3 and word not in stop_words]
|
49 |
+
return list(set(keywords))
|
50 |
+
|
51 |
+
class TextProcessor:
|
52 |
+
@staticmethod
|
53 |
+
def normalize_text(text: str) -> str:
|
54 |
+
"""Normalize text by removing special characters and extra spaces."""
|
55 |
+
text = re.sub(r'[^\w\s]', ' ', text)
|
56 |
+
text = ' '.join(text.lower().split())
|
57 |
+
return text
|
58 |
+
|
59 |
+
@staticmethod
|
60 |
+
def extract_main_concepts(text: str) -> List[str]:
|
61 |
+
"""Extract main concepts from text using basic NLP techniques."""
|
62 |
+
# Remove common words and keep meaningful terms
|
63 |
+
stop_words = {'a', 'o', 'e', 'de', 'do', 'da', 'em', 'para', 'com', 'um', 'uma', 'que', 'como'}
|
64 |
+
words = TextProcessor.normalize_text(text).split()
|
65 |
+
concepts = [word for word in words if word not in stop_words and len(word) > 3]
|
66 |
+
return list(set(concepts))
|
67 |
+
|
68 |
+
class ResponseValidator:
|
69 |
+
def __init__(self):
|
70 |
+
self.text_processor = TextProcessor()
|
71 |
+
self.similarity_threshold = 0.3
|
72 |
+
self.keyword_threshold = 0.2
|
73 |
+
self.concept_match_threshold = 0.25
|
74 |
+
|
75 |
+
def calculate_text_similarity(self, text1: str, text2: str) -> float:
|
76 |
+
"""Calculate text similarity using SequenceMatcher."""
|
77 |
+
normalized_text1 = self.text_processor.normalize_text(text1)
|
78 |
+
normalized_text2 = self.text_processor.normalize_text(text2)
|
79 |
+
return SequenceMatcher(None, normalized_text1, normalized_text2).ratio()
|
80 |
+
|
81 |
+
def calculate_keyword_similarity(self, text1: str, text2: str) -> float:
|
82 |
+
"""Calculate keyword similarity between texts."""
|
83 |
+
keywords1 = set(self.text_processor.extract_main_concepts(text1))
|
84 |
+
keywords2 = set(self.text_processor.extract_main_concepts(text2))
|
85 |
+
if not keywords1 or not keywords2:
|
86 |
+
return 0.0
|
87 |
+
return len(keywords1.intersection(keywords2)) / len(keywords1.union(keywords2))
|
88 |
+
|
89 |
+
def calculate_concept_similarity(self, question: str, example: BiblicalExample) -> float:
|
90 |
+
"""Calculate concept similarity between question and example."""
|
91 |
+
question_concepts = set(self.text_processor.extract_main_concepts(question))
|
92 |
+
example_concepts = set(example.keywords)
|
93 |
+
if not question_concepts or not example_concepts:
|
94 |
+
return 0.0
|
95 |
+
return len(question_concepts.intersection(example_concepts)) / len(question_concepts.union(example_concepts))
|
96 |
+
|
97 |
+
def validate_response(self, question: str, example: BiblicalExample) -> Tuple[bool, Dict[str, float]]:
|
98 |
+
"""Validate response relevance using multiple metrics."""
|
99 |
+
text_similarity = self.calculate_text_similarity(question, example.question)
|
100 |
+
keyword_similarity = self.calculate_keyword_similarity(question, example.question)
|
101 |
+
concept_similarity = self.calculate_concept_similarity(question, example)
|
102 |
+
|
103 |
+
# Calculate weighted score
|
104 |
+
weights = {'text': 0.4, 'keyword': 0.3, 'concept': 0.3}
|
105 |
+
total_score = (
|
106 |
+
text_similarity * weights['text'] +
|
107 |
+
keyword_similarity * weights['keyword'] +
|
108 |
+
concept_similarity * weights['concept']
|
109 |
+
)
|
110 |
+
|
111 |
+
metrics = {
|
112 |
+
'text_similarity': round(text_similarity, 3),
|
113 |
+
'keyword_similarity': round(keyword_similarity, 3),
|
114 |
+
'concept_similarity': round(concept_similarity, 3),
|
115 |
+
'total_score': round(total_score, 3)
|
116 |
+
}
|
117 |
+
|
118 |
+
is_valid = (
|
119 |
+
text_similarity >= self.similarity_threshold or
|
120 |
+
keyword_similarity >= self.keyword_threshold or
|
121 |
+
concept_similarity >= self.concept_match_threshold
|
122 |
+
)
|
123 |
+
|
124 |
+
return is_valid, metrics
|
125 |
|
126 |
class SapienciaBiblica:
|
127 |
def __init__(self):
|
|
|
130 |
self.model_name = "pierreguillou/bert-base-cased-squad-v1.1-portuguese"
|
131 |
self.session_history = []
|
132 |
self.biblical_examples = self.get_default_examples_dict()
|
133 |
+
self.validator = ResponseValidator()
|
134 |
self.setup_model()
|
135 |
|
136 |
def setup_model(self):
|
|
|
151 |
passage="Efésios 4:29",
|
152 |
text="Não saia da vossa boca nenhuma palavra torpe, mas só a que for boa para promover a edificação, para que dê graça aos que a ouvem.",
|
153 |
base_response="A comunicação efetiva no casamento requer sabedoria, paciência e amor. A Bíblia nos ensina a usar palavras que edificam e não destroem.",
|
154 |
+
application="Pratique escuta ativa, escolha momentos adequados para conversas importantes, e sempre fale com amor e respeito.",
|
155 |
+
sentiment="supportive",
|
156 |
+
theme="casamento"
|
157 |
),
|
158 |
BiblicalExample(
|
159 |
+
question="Como lidar com conflitos no casamento?",
|
160 |
+
passage="Efésios 4:26-27",
|
161 |
+
text="Irai-vos e não pequeis; não se ponha o sol sobre a vossa ira. Não deis lugar ao diabo.",
|
162 |
+
base_response="Os conflitos são naturais, mas devem ser resolvidos com sabedoria e amor, sem deixar que a raiva tome conta.",
|
163 |
+
application="Resolva os conflitos no mesmo dia, pratique o perdão e busque entender o ponto de vista do cônjuge.",
|
164 |
+
sentiment="instructive",
|
165 |
+
theme="casamento"
|
166 |
)
|
167 |
],
|
168 |
"familia": [
|
169 |
BiblicalExample(
|
170 |
+
question="Como educar filhos segundo a Bíblia?",
|
171 |
passage="Provérbios 22:6",
|
172 |
text="Instrui o menino no caminho em que deve andar, e até quando envelhecer não se desviará dele.",
|
173 |
+
base_response="A educação dos filhos deve ser baseada em princípios bíblicos, com amor, disciplina e exemplo.",
|
174 |
+
application="Estabeleça rotinas de devocional em família, seja exemplo de caráter e aplique disciplina com amor.",
|
175 |
+
sentiment="instructive",
|
176 |
+
theme="familia"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
)
|
178 |
],
|
179 |
+
# Add more categories and examples as needed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
}
|
181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
def find_best_theme(self, question: str) -> str:
|
183 |
+
"""Find the most relevant theme for the question."""
|
184 |
question = question.lower()
|
185 |
theme_keywords = {
|
186 |
"casamento": ["casamento", "cônjuge", "esposa", "marido", "casal"],
|
|
|
190 |
"relacionamentos": ["amizade", "relacionamento", "conflito", "perdão"],
|
191 |
}
|
192 |
|
193 |
+
max_matches = 0
|
194 |
+
best_theme = "geral"
|
195 |
+
|
196 |
for theme, keywords in theme_keywords.items():
|
197 |
+
matches = sum(1 for keyword in keywords if keyword in question)
|
198 |
+
if matches > max_matches:
|
199 |
+
max_matches = matches
|
200 |
+
best_theme = theme
|
201 |
+
|
202 |
+
return best_theme
|
203 |
+
|
204 |
+
def find_best_example(self, question: str, theme: str) -> Tuple[Optional[BiblicalExample], Dict[str, float]]:
|
205 |
+
"""Find the most relevant example and return validation metrics."""
|
206 |
+
examples = self.biblical_examples.get(theme, self.biblical_examples["geral"])
|
207 |
+
best_score = 0
|
208 |
+
best_example = None
|
209 |
+
best_metrics = {}
|
210 |
+
|
211 |
+
for example in examples:
|
212 |
+
is_valid, metrics = self.validator.validate_response(question, example)
|
213 |
+
|
214 |
+
if is_valid and metrics['total_score'] > best_score:
|
215 |
+
best_score = metrics['total_score']
|
216 |
+
best_example = example
|
217 |
+
best_metrics = metrics
|
218 |
+
|
219 |
+
return best_example, best_metrics
|
220 |
|
221 |
def get_unique_response(self, question: str, theme: str = None) -> Tuple[str, Dict, str]:
|
222 |
+
"""Get a validated response for the given question."""
|
223 |
+
if not question.strip():
|
224 |
+
return "Por favor, faça uma pergunta específica.", {}, self.format_history()
|
225 |
+
|
226 |
if not theme or theme not in self.biblical_examples:
|
227 |
theme = self.find_best_theme(question)
|
|
|
|
|
|
|
|
|
228 |
|
229 |
+
best_example, validation_metrics = self.find_best_example(question, theme)
|
230 |
+
|
231 |
+
if not best_example:
|
232 |
+
response = self.generate_fallback_response(question, theme)
|
233 |
+
metadata = {
|
234 |
+
"theme": theme,
|
235 |
+
"status": "no_matching_example",
|
236 |
+
"validation_metrics": validation_metrics
|
237 |
+
}
|
238 |
+
return response, metadata, self.format_history()
|
239 |
+
|
240 |
+
sentiment = self.analyze_sentiment(question)
|
241 |
+
response = self.format_response(best_example, sentiment)
|
242 |
+
metadata = self.create_metadata(best_example, theme, validation_metrics)
|
243 |
history = self.save_to_history(question, theme, response, metadata)
|
244 |
|
245 |
return response, metadata, history
|
246 |
|
247 |
+
def analyze_sentiment(self, text: str) -> str:
|
248 |
+
"""Analyze the sentiment of the input text."""
|
249 |
+
positive_words = {'alegria', 'esperança', 'paz', 'amor', 'gratidão', 'feliz', 'bem'}
|
250 |
+
negative_words = {'tristeza', 'medo', 'ansiedade', 'preocupação', 'angústia', 'mal', 'dor'}
|
251 |
+
|
252 |
+
text_words = set(text.lower().split())
|
253 |
+
pos_count = len(text_words.intersection(positive_words))
|
254 |
+
neg_count = len(text_words.intersection(negative_words))
|
255 |
+
|
256 |
+
return 'positive' if pos_count > neg_count else 'negative' if neg_count > pos_count else 'neutral'
|
257 |
+
|
258 |
def format_response(self, example: BiblicalExample, sentiment: str) -> str:
|
259 |
+
"""Format the response with appropriate introduction based on sentiment."""
|
260 |
intro = {
|
261 |
'positive': "Que bom que você está buscando orientação! ",
|
262 |
'negative': "Entendo seu momento e estou aqui para ajudar. ",
|
|
|
278 |
considere consultar sua liderança espiritual local.
|
279 |
"""
|
280 |
|
281 |
+
def generate_fallback_response(self, question: str, theme: str) -> str:
|
282 |
+
"""Generate a thoughtful fallback response when no good match is found."""
|
283 |
+
theme_verses = {
|
284 |
+
"casamento": ("Efésios 5:25", "Maridos, amai vossas mulheres, como também Cristo amou a igreja..."),
|
285 |
+
"familia": ("Salmos 127:3", "Eis que os filhos são herança do Senhor..."),
|
286 |
+
"vida_espiritual": ("Filipenses 4:6", "Não andeis ansiosos por coisa alguma..."),
|
287 |
+
"trabalho": ("Colossenses 3:23", "E tudo quanto fizerdes, fazei-o de coração..."),
|
288 |
+
"relacionamentos": ("João 13:34", "Um novo mandamento vos dou: Que vos ameis uns aos outros..."),
|
289 |
+
"geral": ("Provérbios 3:5-6", "Confia no Senhor de todo o teu coração...")
|
290 |
+
}
|
291 |
+
|
292 |
+
verse = theme_verses.get(theme, theme_verses["geral"])
|
293 |
+
|
294 |
+
return f"""
|
295 |
+
🤔 Compreendo sua busca por orientação sobre {theme}...
|
296 |
+
|
297 |
+
Para melhor atendê-lo, considere reformular sua pergunta de forma mais específica,
|
298 |
+
mencionando detalhes da situação que você gostaria de abordar.
|
299 |
+
|
300 |
+
📖 Enquanto isso, reflita sobre esta passagem:
|
301 |
+
{verse[0]}: "{verse[1]}"
|
302 |
+
|
303 |
+
🙏 Lembre-se:
|
304 |
+
"Porque o SENHOR dá a sabedoria, e da sua boca vem o conhecimento e o entendimento."
|
305 |
+
- Provérbios 2:6
|
306 |
+
"""
|
307 |
+
|
308 |
+
def create_metadata(self, example: BiblicalExample, theme: str, validation_metrics: Dict[str, float]) -> Dict:
|
309 |
+
"""Create comprehensive metadata for the response."""
|
310 |
return {
|
311 |
+
"theme": theme,
|
312 |
+
"passage": example.passage,
|
313 |
+
"application": example.application,
|
314 |
+
"sentiment": example.sentiment,
|
315 |
+
"validation_metrics": validation_metrics,
|
316 |
+
"keywords_matched": example.keywords,
|
317 |
+
"response_quality": "high" if validation_metrics['total_score'] > 0.6 else "medium" if validation_metrics['total_score'] > 0.4 else "low"
|
318 |
}
|
319 |
|
320 |
def save_to_history(self, question: str, theme: str, response: str, metadata: Dict) -> str:
|
321 |
+
"""Save interaction to history and return formatted history."""
|
322 |
self.session_history.append({
|
323 |
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
324 |
"theme": theme,
|
|
|
329 |
return self.format_history()
|
330 |
|
331 |
def format_history(self) -> str:
|
332 |
+
"""Format the session history for display."""
|
333 |
if not self.session_history:
|
334 |
return "Nenhuma consulta realizada ainda."
|
335 |
|
336 |
history_text = "📚 Histórico de Consultas:\n\n"
|
337 |
+
for entry in reversed(self.session_history[-5:]): # Show last 5 entries
|
338 |
history_text += f"🕒 {entry['timestamp']}\n"
|
339 |
history_text += f"📌 Tema: {entry['theme']}\n"
|
340 |
history_text += f"❓ Pergunta: {entry['question']}\n"
|
341 |
+
if 'validation_metrics' in entry['metadata']:
|
342 |
+
history_text += f"📊 Relevância: {entry['metadata']['validation_metrics']['total_score']:.2f}\n"
|
343 |
history_text += "─" * 40 + "\n"
|
344 |
return history_text
|
345 |
|
346 |
+
def get_verse_of_day(self) -> str:
|
347 |
+
"""Get a random verse of the day."""
|
348 |
+
verses = [
|
349 |
+
("João 3:16", "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna."),
|
350 |
+
("Salmos 23:1", "O Senhor é meu pastor e nada me faltará."),
|
351 |
+
("Filipenses 4:13", "Posso todas as coisas em Cristo que me fortalece."),
|
352 |
+
("Jeremias 29:11", "Porque eu bem sei os pensamentos que tenho a vosso respeito, diz o Senhor; pensamentos de paz, e não de mal, para vos dar o fim que esperais."),
|
353 |
+
("Provérbios 3:5-6", "Confia no Senhor de todo o teu coração, e não te estribes no teu próprio entendimento. Reconhece-o em todos os teus caminhos, e ele endireitará as tuas veredas.")
|
354 |
+
]
|
355 |
+
verse = random.choice(verses)
|
356 |
+
return f"📖 Versículo do Dia:\n{verse[0]}\n\n{verse[1]}"
|
357 |
+
|
358 |
+
def get_daily_prayer_focus(self) -> str:
|
359 |
+
"""Get a random prayer focus for the day."""
|
360 |
+
focuses = [
|
361 |
+
("Gratidão e Louvor", "Agradecer a Deus por suas bênçãos e manifestar louvor"),
|
362 |
+
("Família e Relacionamentos", "Orar pela harmonia e proteção familiar"),
|
363 |
+
("Sabedoria e Direção", "Buscar orientação divina para decisões"),
|
364 |
+
("Paz e Serenidade", "Cultivar a paz interior e confiar em Deus"),
|
365 |
+
("Cura e Restauração", "Buscar a cura emocional e espiritual")
|
366 |
+
]
|
367 |
+
focus = random.choice(focuses)
|
368 |
+
return f"🙏 Foco de Oração:\n{focus[0]}\n{focus[1]}"
|
369 |
+
|
370 |
+
def get_examples_for_interface(self) -> List[List[str]]:
|
371 |
+
"""Get formatted examples for the Gradio interface."""
|
372 |
+
examples = []
|
373 |
+
for theme in self.biblical_examples:
|
374 |
+
for example in self.biblical_examples[theme]:
|
375 |
+
examples.append([theme, example.question])
|
376 |
+
return examples
|
377 |
+
|
378 |
def create_interface():
|
379 |
counselor = SapienciaBiblica()
|
380 |
|
|
|
435 |
interactive=False
|
436 |
)
|
437 |
|
438 |
+
# Examples for the interface
|
439 |
gr.Examples(
|
440 |
examples=counselor.get_examples_for_interface(),
|
441 |
inputs=[theme, question],
|