mousvai commited on
Commit
93b9439
·
verified ·
1 Parent(s): 65c2a73

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +182 -0
app.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+
4
+ from langchain_huggingface import HuggingFaceEmbeddings
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain.memory import ConversationBufferMemory
7
+ from langchain.chains import ConversationalRetrievalChain
8
+ from langchain_groq import ChatGroq # Changed to import ChatGroq
9
+ from langchain.prompts import ChatPromptTemplate
10
+
11
+ # Import the new dynamic template components
12
+ from htmlTemplates import css, user_template, get_bot_template, BOT_AVATARS_BASE64
13
+
14
+
15
+ # ------------------- Dynamic Bot Names -------------------
16
+ BOT_NAMES = {
17
+ "Khamenei": "حاجاقا محسنی",
18
+ "Sistani": "حاجاقا جوادی",
19
+ "Golpaygani": "حاجاقا محمدی",
20
+ }
21
+
22
+
23
+ # ------------------- Conversation Chain Function -------------------
24
+ def get_conversation_chain(vectorstore, llm):
25
+ memory = ConversationBufferMemory(
26
+ memory_key='chat_history', return_messages=True
27
+ )
28
+ return ConversationalRetrievalChain.from_llm(
29
+ llm=llm,
30
+ retriever=vectorstore.as_retriever(),
31
+ memory=memory,
32
+ )
33
+
34
+
35
+ # ------------------- Classify Question -------------------
36
+ def classify_question(question, llm):
37
+ prompt = ChatPromptTemplate.from_template("""
38
+ متن زیر را بررسی کن و فقط یکی از این سه برچسب را برگردان:
39
+ - greeting: اگر متن سلام و احوال‌پرسی یا جملات دوستانه است
40
+ - islamic_fiqh: اگر پرسش درباره احکام شرعی و فقهی اسلام است
41
+ - irrelevant: اگر غیر از این دو بود
42
+
43
+ متن: {question}
44
+ برچسب:
45
+ """)
46
+ chain = prompt | llm
47
+ result = chain.invoke({"question": question})
48
+ return result.content.strip().lower()
49
+
50
+
51
+ # ------------------- Generate Friendly Response -------------------
52
+ def generate_friendly_response(question, label, llm, selected_source_english):
53
+ bot_name = BOT_NAMES.get(selected_source_english, "پاسخگوی شما")
54
+
55
+ if "greeting" in label:
56
+ prompt = ChatPromptTemplate.from_template(f"""
57
+ کاربر به شما سلام یا احوال‌پرسی کرده است.
58
+ نام شما {bot_name} هست.
59
+ متن کاربر: {{question}}
60
+ """)
61
+ else: # irrelevant
62
+ prompt = ChatPromptTemplate.from_template(f"""
63
+ کاربر پرسشی غیرمرتبط با احکام شرعی پرسیده است.
64
+ تو به عنوان {bot_name}
65
+ مودبانه و دوستانه به او بگویید که وظیفه‌ی شما فقط پاسخ به پرسش‌های شرعی است
66
+ و او را به مطرح کردن یک سؤال دینی تشویق کنید.
67
+ متن کاربر: {{question}}
68
+ """)
69
+
70
+ chain = prompt | llm
71
+ result = chain.invoke({"question": question})
72
+ return result.content.strip()
73
+
74
+
75
+ # ------------------- Handle User Input (Logic Only) -------------------
76
+ def handle_userinput(user_question):
77
+ if st.session_state.conversation is None:
78
+ st.warning("منابع هنوز آماده نشده‌اند.")
79
+ return
80
+
81
+ st.session_state.messages.append({"role": "user", "content": user_question})
82
+
83
+ label = classify_question(user_question, st.session_state.llm)
84
+ if "islamic_fiqh" in label:
85
+ response = st.session_state.conversation({'question': user_question})
86
+ bot_reply = response['answer']
87
+ else:
88
+ bot_reply = generate_friendly_response(user_question, label, st.session_state.llm, st.session_state.selected_source_english)
89
+
90
+ st.session_state.messages.append({"role": "bot", "content": bot_reply})
91
+
92
+
93
+ # ------------------- Main Streamlit App -------------------
94
+ def main():
95
+ st.set_page_config(page_title="شیخ جی پی تی", page_icon=":mosque:")
96
+ st.write(css, unsafe_allow_html=True)
97
+
98
+ st.markdown(
99
+ "<h2 style=\"text-align: center;font-size: clamp(24px, 5vw, 48px); white-space: nowrap;\">پاسخگوی احکام شرعی 🕋</h2>",
100
+ unsafe_allow_html=True
101
+ )
102
+
103
+ if "conversation" not in st.session_state:
104
+ st.session_state.conversation = None
105
+ if "messages" not in st.session_state:
106
+ st.session_state.messages = []
107
+ if "llm" not in st.session_state:
108
+ # Changed LLM to use Groq API with ChatGroq
109
+ st.session_state.llm = ChatGroq(
110
+ model_name="llama-3.1-8b-instant",
111
+ temperature=0.2,
112
+ api_key=os.environ["GROQ_API_KEY"] # Changed to use GROQ_API_KEY
113
+ )
114
+ if "selected_source_english" not in st.session_state:
115
+ st.session_state.selected_source_english = "Khamenei"
116
+
117
+ current_bot_avatar_base64 = BOT_AVATARS_BASE64.get(st.session_state.selected_source_english)
118
+ bot_template_with_avatar = get_bot_template(current_bot_avatar_base64)
119
+ for msg in st.session_state.messages:
120
+ if msg["role"] == "user":
121
+ st.write(user_template.replace("{{MSG}}", msg["content"]), unsafe_allow_html=True)
122
+ else:
123
+ st.write(bot_template_with_avatar.replace("{{MSG}}", msg["content"]), unsafe_allow_html=True)
124
+
125
+ if user_question := st.chat_input("سؤال شرعی خود را اینجا مطرح کنید..."):
126
+ handle_userinput(user_question)
127
+ st.rerun()
128
+
129
+ with st.sidebar:
130
+ st.subheader("منابع فقهی")
131
+
132
+ SOURCE_MAPPINGS = {
133
+ "آیت الله خامنه‌ای": "Khamenei",
134
+ "آیت الله سیستانی": "Sistani",
135
+ "آیت الله گلپایگانی": "Golpaygani"
136
+ }
137
+ persian_options = list(SOURCE_MAPPINGS.keys())
138
+ current_persian_name = next(
139
+ (key for key, value in SOURCE_MAPPINGS.items()
140
+ if value == st.session_state.selected_source_english),
141
+ persian_options[0]
142
+ )
143
+
144
+ selected_source_persian = st.selectbox(
145
+ "مرجع تقلید خود را انتخاب کنید:",
146
+ persian_options,
147
+ index=persian_options.index(current_persian_name)
148
+ )
149
+ selected_source_english = SOURCE_MAPPINGS[selected_source_persian]
150
+
151
+ if st.session_state.selected_source_english != selected_source_english:
152
+ st.session_state.selected_source_english = selected_source_english
153
+ st.session_state.conversation = None
154
+ st.session_state.messages = []
155
+ st.rerun()
156
+
157
+ if st.session_state.conversation is None:
158
+ placeholder = st.empty()
159
+ placeholder.info(f"⏳ در حال بارگذاری منابع {selected_source_persian}...")
160
+ try:
161
+ embeddings = HuggingFaceEmbeddings(
162
+ model_name="heydariAI/persian-embeddings",
163
+ model_kwargs={'trust_remote_code': True},
164
+ cache_folder="/tmp/hf_cache"
165
+ )
166
+ vector_path = f"Resources/{st.session_state.selected_source_english}/faiss_index"
167
+ vectorstore = FAISS.load_local(
168
+ vector_path,
169
+ embeddings,
170
+ allow_dangerous_deserialization=True
171
+ )
172
+ st.session_state.conversation = get_conversation_chain(vectorstore, st.session_state.llm)
173
+ placeholder.success(
174
+ f"✅ منابع {selected_source_persian} آماده شدند. اکنون می‌توانید سؤال بپرسید.")
175
+ except Exception as e:
176
+ placeholder.error(f"⚠️ خطا در بارگذاری منابع: {e}")
177
+ else:
178
+ st.success(f"✅ منابع {selected_source_persian} بارگذاری شده‌اند")
179
+
180
+
181
+ if __name__ == '__main__':
182
+ main()