Update app.py
Browse files
app.py
CHANGED
@@ -9,12 +9,12 @@ from langchain.chat_models import ChatOpenAI
|
|
9 |
from langchain.chains import ChatChain
|
10 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
11 |
from langchain.schema import Document
|
|
|
12 |
|
13 |
-
# ----------------- تنظیمات صفحه -----------------
|
14 |
st.set_page_config(page_title="رزمیار ارتش", page_icon="🪖", layout="wide")
|
15 |
|
16 |
# ----------------- استایل سفارشی -----------------
|
17 |
-
st.markdown("""
|
18 |
<style>
|
19 |
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
|
20 |
|
@@ -23,12 +23,132 @@ st.markdown("""
|
|
23 |
direction: rtl;
|
24 |
text-align: right;
|
25 |
}
|
26 |
-
|
27 |
.stApp {
|
28 |
background: linear-gradient(to left, #4b5e40, #2e3b2e);
|
29 |
color: #ffffff;
|
30 |
}
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
</style>
|
33 |
""", unsafe_allow_html=True)
|
34 |
|
@@ -145,10 +265,19 @@ def load_llm():
|
|
145 |
|
146 |
# ----------- پردازش سوال و بازیابی پاسخها -----------
|
147 |
def process_user_query(query: str, vectorstore, embedding_model, llm):
|
|
|
148 |
query_embedding = embedding_model.embed_query(query)
|
|
|
|
|
149 |
docs = vectorstore.similarity_search_by_vector(query_embedding, k=3)
|
150 |
context = "\n".join([doc.page_content for doc in docs])
|
151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
final_prompt = f"""با توجه به اطلاعات زیر، فقط بر اساس آنها به سؤال پاسخ بده. اگر اطلاعات کافی نیست، بگو اطلاعات کا��ی ندارم.
|
153 |
🔹 اطلاعات:\n{context}\n\n❓ سؤال: {query}
|
154 |
"""
|
@@ -159,6 +288,12 @@ def process_user_query(query: str, vectorstore, embedding_model, llm):
|
|
159 |
return clean_answer
|
160 |
|
161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
# ----------- اجرای Streamlit UI -----------
|
163 |
def run_chat_ui():
|
164 |
csv_file_path = 'output (1).csv'
|
|
|
9 |
from langchain.chains import ChatChain
|
10 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
11 |
from langchain.schema import Document
|
12 |
+
import re
|
13 |
|
|
|
14 |
st.set_page_config(page_title="رزمیار ارتش", page_icon="🪖", layout="wide")
|
15 |
|
16 |
# ----------------- استایل سفارشی -----------------
|
17 |
+
st.markdown("""
|
18 |
<style>
|
19 |
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
|
20 |
|
|
|
23 |
direction: rtl;
|
24 |
text-align: right;
|
25 |
}
|
26 |
+
|
27 |
.stApp {
|
28 |
background: linear-gradient(to left, #4b5e40, #2e3b2e);
|
29 |
color: #ffffff;
|
30 |
}
|
31 |
+
|
32 |
+
/* استایل سایدبار */
|
33 |
+
[data-testid="stSidebar"] {
|
34 |
+
width: 260px !important;
|
35 |
+
background-color: #1a2b1e;
|
36 |
+
border: none !important; /* حذف حاشیه زرد */
|
37 |
+
padding-top: 20px;
|
38 |
+
}
|
39 |
+
|
40 |
+
.menu-item {
|
41 |
+
display: flex;
|
42 |
+
align-items: center;
|
43 |
+
gap: 12px;
|
44 |
+
padding: 12px 20px;
|
45 |
+
font-size: 16px;
|
46 |
+
color: #d4d4d4;
|
47 |
+
cursor: pointer;
|
48 |
+
transition: background-color 0.3s ease;
|
49 |
+
}
|
50 |
+
|
51 |
+
.menu-item:hover {
|
52 |
+
background-color: #2e3b2e;
|
53 |
+
color: #b8860b;
|
54 |
+
}
|
55 |
+
|
56 |
+
.menu-item img {
|
57 |
+
width: 24px;
|
58 |
+
height: 24px;
|
59 |
+
}
|
60 |
+
|
61 |
+
/* استایل دکمهها */
|
62 |
+
.stButton>button {
|
63 |
+
background-color: #b8860b !important;
|
64 |
+
color: #1a2b1e !important;
|
65 |
+
font-family: 'Vazirmatn', Tahoma;
|
66 |
+
font-weight: 700;
|
67 |
+
border-radius: 10px;
|
68 |
+
padding: 12px 24px;
|
69 |
+
border: none;
|
70 |
+
transition: all 0.3s ease;
|
71 |
+
font-size: 16px;
|
72 |
+
width: 100%;
|
73 |
+
margin: 10px 0;
|
74 |
+
}
|
75 |
+
|
76 |
+
.stButton>button:hover {
|
77 |
+
background-color: #8b6508 !important;
|
78 |
+
transform: translateY(-2px);
|
79 |
+
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
|
80 |
+
}
|
81 |
+
|
82 |
+
/* استایل هدر */
|
83 |
+
.header-text {
|
84 |
+
text-align: center;
|
85 |
+
margin: 20px 0;
|
86 |
+
background-color: rgba(26, 43, 30, 0.9);
|
87 |
+
padding: 25px;
|
88 |
+
border-radius: 15px;
|
89 |
+
box-shadow: 0 6px 12px rgba(0,0,0,0.4);
|
90 |
+
}
|
91 |
+
|
92 |
+
.header-text h1 {
|
93 |
+
font-size: 42px;
|
94 |
+
color: #b8860b;
|
95 |
+
margin: 0;
|
96 |
+
font-weight: 700;
|
97 |
+
}
|
98 |
+
|
99 |
+
.subtitle {
|
100 |
+
font-size: 18px;
|
101 |
+
color: #d4d4d4;
|
102 |
+
margin-top: 10px;
|
103 |
+
}
|
104 |
+
|
105 |
+
/* استایل پیام چت */
|
106 |
+
.chat-message {
|
107 |
+
background-color: rgba(26, 43, 30, 0.95);
|
108 |
+
border: 2px solid #b8860b;
|
109 |
+
border-radius: 15px;
|
110 |
+
padding: 20px;
|
111 |
+
margin: 15px 0;
|
112 |
+
box-shadow: 0 6px 12px rgba(0,0,0,0.3);
|
113 |
+
animation: fadeIn 0.6s ease;
|
114 |
+
font-size: 18px;
|
115 |
+
color: #d4d4d4;
|
116 |
+
display: flex;
|
117 |
+
align-items: center;
|
118 |
+
gap: 15px;
|
119 |
+
}
|
120 |
+
|
121 |
+
@keyframes fadeIn {
|
122 |
+
from { opacity: 0; transform: translateY(10px); }
|
123 |
+
to { opacity: 1; transform: translateY(0); }
|
124 |
+
}
|
125 |
+
|
126 |
+
/* استایل ورودیها */
|
127 |
+
.stTextInput>div>input, .stTextArea textarea {
|
128 |
+
background-color: rgba(26, 43, 30, 0.95) !important;
|
129 |
+
border-radius: 10px !important;
|
130 |
+
border: 1px solid #b8860b !important;
|
131 |
+
padding: 12px !important;
|
132 |
+
font-family: 'Vazirmatn', Tahoma;
|
133 |
+
font-size: 16px;
|
134 |
+
color: #d4d4d4 !important;
|
135 |
+
}
|
136 |
+
|
137 |
+
img.small-logo {
|
138 |
+
width: 120px;
|
139 |
+
margin: 0 auto 20px;
|
140 |
+
display: block;
|
141 |
+
}
|
142 |
+
|
143 |
+
hr {
|
144 |
+
border: 1px solid #b8860b;
|
145 |
+
margin: 15px 0;
|
146 |
+
}
|
147 |
+
|
148 |
+
/* رفع مشکل نوار زرد */
|
149 |
+
[data-testid="stSidebar"] > div {
|
150 |
+
border: none !important;
|
151 |
+
}
|
152 |
</style>
|
153 |
""", unsafe_allow_html=True)
|
154 |
|
|
|
265 |
|
266 |
# ----------- پردازش سوال و بازیابی پاسخها -----------
|
267 |
def process_user_query(query: str, vectorstore, embedding_model, llm):
|
268 |
+
# تبدیل سوال کاربر به امبدینگ
|
269 |
query_embedding = embedding_model.embed_query(query)
|
270 |
+
|
271 |
+
# جستجوی نزدیکترین متون به سوال
|
272 |
docs = vectorstore.similarity_search_by_vector(query_embedding, k=3)
|
273 |
context = "\n".join([doc.page_content for doc in docs])
|
274 |
+
|
275 |
+
# چک کردن وجود عدد یا اطلاعات عددی در پاسخ
|
276 |
+
if "عدد" in query or "قیمت" in query: # اگر سوال عددی است
|
277 |
+
# استخراج اطلاعات عددی از متون مشابه
|
278 |
+
context = extract_numbers_from_text(context)
|
279 |
+
|
280 |
+
# ارسال متن به مدل
|
281 |
final_prompt = f"""با توجه به اطلاعات زیر، فقط بر اساس آنها به سؤال پاسخ بده. اگر اطلاعات کافی نیست، بگو اطلاعات کا��ی ندارم.
|
282 |
🔹 اطلاعات:\n{context}\n\n❓ سؤال: {query}
|
283 |
"""
|
|
|
288 |
return clean_answer
|
289 |
|
290 |
|
291 |
+
def extract_numbers_from_text(text: str):
|
292 |
+
# استخراج اعداد از متن
|
293 |
+
numbers = re.findall(r'\d+(?:\.\d+)?', text)
|
294 |
+
return "\n".join(numbers)
|
295 |
+
|
296 |
+
|
297 |
# ----------- اجرای Streamlit UI -----------
|
298 |
def run_chat_ui():
|
299 |
csv_file_path = 'output (1).csv'
|