M17idd commited on
Commit
4055522
·
1 Parent(s): ec66160

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +579 -653
app.py CHANGED
@@ -13,669 +13,595 @@ from hazm import *
13
  import re
14
  import nltk
15
  nltk.download('punkt')
16
- def show_page():
17
- page = st.session_state.page
18
- st.markdown(f"## {page}")
19
- st.markdown("""
20
- <style>
21
- /* استایل برای هدر */
22
- .stAppHeader.st-emotion-cache-12fmjuu.e4hpqof0 {
23
- background-color: rgba(46,59,46, 0.8) !important; /* سبز متمایل به خاکی */
24
- color: #2e3b2e !important; /* رنگ متن روشن */
25
- font-family: 'Vazirmatn', Tahoma, sans-serif !important;
26
- padding: 20px !important; /* فضای داخلی بیشتر */
27
- border-radius: 10px !important; /* گوشه‌های گرد */
28
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
29
- }
30
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  """, unsafe_allow_html=True)
32
- st.markdown("""
33
- <style>
34
- /* بارگذاری فونت Roboto */
35
- @font-face {
36
- font-family: 'Roboto';
37
- src: url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap') format('woff2');
38
- font-weight: 400;
39
- font-style: normal;
40
- }
41
-
42
- /* تنظیم فونت برای کل سایت */
43
- html, body, [class*="css"] {
44
- font-family: 'Roboto', Tahoma, sans-serif !important;
45
- font-weight: 400 !important;
46
- direction: rtl;
47
- text-align: right;
48
- ظ color: #ffffff;
49
- }
50
-
51
- /* طراحی برای بخش استایل اپ */
52
- .stApp {
53
- background: linear-gradient(to left, #4b5e40, #2e3b2e);
54
- color: #ffffff;
55
- }
56
-
57
- /* استایل برای سایدبار */
58
- [data-testid="stSidebar"] {
59
- width: 260px !important;
60
- background-color: #1a2b1e;
61
- border: none !important;
62
- padding-top: 20px;
63
- }
64
-
65
- /* استایل برای آیتم‌های منو */
66
- .menu-item {
67
- display: flex;
68
- align-items: center;
69
- gap: 12px;
70
- padding: 12px 20px;
71
- font-size: 16px;
72
- font-weight: 600;
73
- color: #d4d4d4;
74
- cursor: pointer;
75
- transition: background-color 0.3s ease;
76
- }
77
-
78
- /* استایل برای آیتم‌های منو هنگام هاور */
79
- .menu-item:hover {
80
- background-color: #2e3b2e;
81
- color: #b8860b;
82
- }
83
-
84
- /* استایل برای آیکون‌ها در منو */
85
- .menu-item img {
86
- width: 25px;
87
- height: 25px;
88
- }
89
-
90
- /* استایل برای دکمه‌ها */
91
- .stButton>button {
92
- background-color: #b8860b !important;
93
- color: #1a2b1e !important;
94
- font-family: 'Roboto', Tahoma, sans-serif;
95
- font-weight: 700 !important;
96
- border-radius: 10px;
97
- padding: 12px 24px;
98
- border: none;
99
- transition: all 0.3s ease;
100
- font-size: 16px;
101
- width: 100%;
102
- margin: 10px 0;
103
- }
104
-
105
- /* استایل برای دکمه‌ها هنگام هاور */
106
- .stButton>button:hover {
107
- background-color: #8b6508 !important;
108
- transform: translateY(-2px);
109
- box-shadow: 0 4px 8px rgba(0,0,0,0.3);
110
- }
111
  /* استایل برای متن هدر */
112
  .header-text {
113
  text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  margin: 20px 0;
115
- background-color: rgba(26, 43, 30, 0.9);
116
- padding: 25px;
117
- border-radius: 15px;
118
- box-shadow: 0 6px 12px rgba(0,0,0,0.4);
119
- font-family: 'Roboto', Tahoma, sans-serif; /* اضافه شد */
120
  }
121
-
122
-
123
- /* استایل برای زیرنویس */
124
- .subtitle {
125
- font-size: 18px;
126
- color: #d4d4d4;
127
- font-weight: 600;
128
- margin-top: 10px;
129
- }
130
-
131
- /* استایل برای پیام‌های چت */
132
- .chat-message {
133
- flex-wrap: wrap;
134
- background-color: rgba(26, 43, 30, 0.95);
135
- border: 2px solid #b8860b;
136
- border-radius: 15px;
137
- padding: 20px;
138
- margin: 15px 0;
139
- box-shadow: 0 6px 12px rgba(0,0,0,0.3);
140
- animation: fadeIn 0.6s ease;
141
- font-size: 18px;
142
- color: #d4d4d4;
143
- font-weight: 600;
144
- display: flex;
145
- flex-wrap: wrap;
146
- align-items: center;
147
- gap: 15px;
148
- }
149
-
150
- /* انیمیشن برای ورود پیام چت */
151
- @keyframes fadeIn {
152
- from { opacity: 0; transform: translateY(10px); }
153
- to { opacity: 1; transform: translateY(0); }
154
- }
155
-
156
- /* استایل برای ورودی متن */
157
- .stTextInput>div>input, .stTextArea textarea {
158
- background-color: rgba(26, 43, 30, 0.95) !important;
159
- border-radius: 10px !important;
160
- border: 1px solid #b8860b !important;
161
- padding: 12px !important;
162
- font-family: 'Roboto', Tahoma;
163
- font-weight: 500;
164
- font-size: 16px;
165
- color: #d4d4d4 !important;
166
- }
167
-
168
- /* استایل برای خط افقی */
169
- hr {
170
- border: 1px solid #b8860b;
171
- margin: 15px 0;
172
- }
173
-
174
- /* حذف مرز از قسمت سایدبار */
175
- [data-testid="stSidebar"] > div {
176
- border: none !important;
177
- }
178
- </style>
179
-
180
- """, unsafe_allow_html=True)
181
-
182
-
183
- # ---------- احراز هویت ----------
184
- if "authenticated" not in st.session_state:
185
- st.session_state.authenticated = False
186
-
187
- if not st.session_state.authenticated:
188
- st.markdown('<style>.stTextInput > div[data-baseweb="input"] + div, .stTextInput div:has(div[role="alert"]) { display: none !important; }</style>', unsafe_allow_html=True)
189
- st.markdown("""
190
- <style>
191
- input {
192
- background-color: #2e3b2e;
193
- color: gold;
194
- border: 1px solid gold;
195
- border-radius: 10px;
196
- padding: 10px;
197
- }
198
- </style>
199
- """, unsafe_allow_html=True)
200
- st.markdown("""
201
- <style>
202
- /* فونت عمومی */
203
- html, body, [class*="css"] {
204
- font-family: 'Vazir', sans-serif;
205
- }
206
-
207
- /* استایل برای برچسب فیلدهای ورودی */
208
- label {
209
- font-size: 20px !important;
210
- color: #ffffff !important;
211
- font-weight: 800 !important;
212
- margin-bottom: 10px !important;
213
- display: block;
214
- }
215
-
216
- /* استایل برای ورودی‌ها */
217
- input[type="text"], input[type="password"] {
218
- background-color: #ffffff !important;
219
- color: #f8f8f8 !important;
220
- font-size: 18px !important;
221
- font-family: 'Vazir', sans-serif !important;
222
-
223
-
224
-
225
- /* Placeholder style */
226
- ::placeholder {
227
- color: #bbbbbb !important;
228
- opacity: 0.8 !important;
229
- font-size: 16px;
230
- }
231
- </style>
232
- """, unsafe_allow_html=True)
233
- username = st.text_input("نام کاربری:", placeholder="شناسه خود را وارد کنید",
234
- label_visibility="visible")
235
-
236
- password = st.text_input("رمز عبور:", placeholder="رمز عبور ", type="password",
237
- label_visibility="visible")
238
- st.markdown("""
239
- <style>
240
- div.stButton > button {
241
- background-image: url("https://upload.wikimedia.org/wikipedia/commons/5/59/US_Army_Universal_Camouflage_Pattern.jpg");
242
- background-size: cover;
243
- background-repeat: no-repeat;
244
- background-position: center;
245
- color: #f5deb3;
246
- font-family: 'Vazir', sans-serif;
247
- font-size: 20px;
248
- font-weight: bold;
249
- padding: 14px 35px;
250
- border: 2px solid #d4af37;
251
- border-radius: 14px;
252
- box-shadow: 0 0 18px rgba(0,0,0,0.6);
253
- transition: all 0.3s ease-in-out;
254
- }
255
-
256
- div.stButton > button:hover {
257
- filter: brightness(1.2);
258
- box-shadow: 0 0 22px #b8860b;
259
- transform: scale(1.03);
260
- }
261
-
262
- div.stButton > button:active {
263
- transform: scale(0.97);
264
- box-shadow: 0 0 12px #000;
265
- }
266
- </style>
267
- """, unsafe_allow_html=True)
268
-
269
- if st.button("ورود"):
270
- if username == "admin" and password == "123":
271
- st.session_state.authenticated = True
272
- st.rerun()
273
- else:
274
- st.markdown("""
275
- <div style="background-color: rgba(241, 196, 15, 0.6); color: #2e3b2e; padding: 10px; border-radius: 10px; border: 2px solid #2e3b2e; margin-top: 20px; text-align: center; backdrop-filter: blur(5px);">
276
- نام کاربری یا رمز عبور اشتباه است.
277
- </div>
278
- """, unsafe_allow_html=True)
279
- st.stop()
280
-
281
- # ---------- سایدبار ----------
282
- with st.sidebar:
283
- st.image("log.png", use_container_width=True)
284
- menu_items = [
285
- ("گزارش عملیاتی", "https://cdn-icons-png.flaticon.com/512/3596/3596165.png"),
286
- ("تاریخچه ماموریت‌ها", "https://cdn-icons-png.flaticon.com/512/709/709496.png"),
287
- ("تحلیل داده‌های نظامی", "https://cdn-icons-png.flaticon.com/512/1828/1828932.png"),
288
- ("مدیریت منابع", "https://cdn-icons-png.flaticon.com/512/681/681494.png"),
289
- ("دستیار فرماندهی", "https://cdn-icons-png.flaticon.com/512/3601/3601646.png"),
290
- ("تنظیمات امنیتی", "https://cdn-icons-png.flaticon.com/512/2099/2099058.png"),
291
- ("پشتیبانی فنی", "https://cdn-icons-png.flaticon.com/512/597/597177.png"),
292
- ]
293
- for idx, (text, icon) in enumerate(menu_items):
294
- st.markdown(f"""
295
- <div class="menu-item">
296
- <img src="{icon}" />
297
- {text}
298
- </div>
299
- """, unsafe_allow_html=True)
300
- if idx in [1, 3, 5]:
301
- st.markdown("<hr/>", unsafe_allow_html=True)
302
-
303
- st.markdown("""
304
- <style>
305
- /* استایل برای متن هدر */
306
- .header-text {
307
- text-align: center;
308
- margin: 50px 0;
309
- background: #2e3b2e; /* سبز زیتونی تیره جدید */
310
- padding: 60px 30px;
311
- border-radius: 25px;
312
- box-shadow: 0 12px 24px rgba(0, 0, 0, 0.8); /* سایه بیشتر */
313
- animation: slideIn 2s ease-in-out, fadeIn 3s ease-in-out;
314
- background-size: cover;
315
- background-position: center;
316
- position: relative;
317
- }
318
-
319
- /* انیمیشن ورودی */
320
- @keyframes fadeIn {
321
- 0% { opacity: 0; transform: translateY(30px); }
322
- 100% { opacity: 1; transform: translateY(0); }
323
- }
324
-
325
- @keyframes slideIn {
326
- 0% { transform: translateX(-50%); opacity: 0; }
327
- 100% { transform: translateX(0); opacity: 1; }
328
- }
329
-
330
- /* تغییر فونت برای h1 */
331
- .header-text h1 {
332
- font-family: 'Vazir', sans-serif;
333
- font-size: 62px;
334
- color: #d89b00; /* طلایی تیره‌تر */
335
- margin: 0;
336
- font-weight: 900;
337
- letter-spacing: 4px;
338
- text-shadow: 4px 4px 15px rgba(0, 0, 0, 0.9); /* سایه سیاه بیشتر */
339
- transform: scale(1.08); /* کمی بزرگتر شدن */
340
- animation: glow 2s ease-in-out infinite alternate;
341
- }
342
-
343
-
344
-
345
- /* تغییر استایل زیرعنوان */
346
- .subtitle {
347
- font-family: 'Vazir', sans-serif;
348
- font-size: 24px;
349
- color: #f8f8f8;
350
- font-weight: 700;
351
- margin-top: 15px;
352
- letter-spacing: 2px;
353
- text-shadow: 3px 3px 10px rgba(0,0,0,0.8); /* سایه بیشتر برای زیرعنوان */
354
- animation: fadeInSubtitle 2s ease-in-out;
355
- }
356
-
357
- /* انیمیشن زیرعنوان */
358
- @keyframes fadeInSubtitle {
359
- 0% { opacity: 0; transform: translateY(20px); }
360
- 100% { opacity: 1; transform: translateY(0); }
361
- }
362
-
363
- /* استایل برای دکمه‌ها */
364
- .stButton>button {
365
- background-color: #e67e22 !important; /* رنگ دکمه تغییر کرده */
366
- color: #4b5320 !important;
367
- font-family: 'Vazir', sans-serif;
368
- font-weight: 700 !important;
369
- border-radius: 20px;
370
- padding: 15px 30px;
371
- border: none;
372
- transition: all 0.3s ease;
373
- font-size: 18px;
374
- width: 100%;
375
- margin: 20px 0;
376
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
377
- }
378
-
379
- .stButton>button:hover {
380
- background-color: #f39c12 !important;
381
- transform: translateY(-4px);
382
- box-shadow: 0 8px 20px rgba(0, 0, 0, 0.6);
383
- }
384
-
385
- /* استایل برای استایل کلی صفحه */
386
- .stApp {
387
- background: #2e3b2e; /* سبز زیتونی تیره جدید */
388
- color: white;
389
- font-family: 'Vazir', sans-serif;
390
- }
391
- </style>
392
- <div class="header-text">
393
- <h1>رزم‌ یار ارتش</h1>
394
- <div class="subtitle">دستیار هوشمند ارتش جمهوری اسلامی ایران</div>
395
- </div>
396
- """, unsafe_allow_html=True)
397
-
398
- # ---------- مدل زبانی ----------
399
- llm = ChatOpenAI(
400
- base_url="https://api.together.xyz/v1",
401
- api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
402
- model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
403
- max_tokens=1024
404
- )
405
-
406
- # ---------- پردازش فایل‌ها با کش و موازی ----------
407
- folder_path = '46'
408
- normalizer = Normalizer()
409
- sentence_tokenizer = SentenceTokenizer()
410
-
411
- @st.cache_data(show_spinner="در حال پردازش اسناد... لطفاً صبور باشید.")
412
- def load_and_process_documents(path):
413
- def process_docx(filename):
414
- try:
415
- full_path = os.path.join(path, filename)
416
- doc = docx.Document(full_path)
417
- text = "\n".join([para.text for para in doc.paragraphs]) # استخراج متن
418
- normalized = normalizer.normalize(text)
419
- sentences = normalized
420
- return sentences
421
- except Exception as e:
422
- print(f"Error processing {filename}: {e}")
423
- return []
424
- with concurrent.futures.ThreadPoolExecutor() as executor:
425
- results = executor.map(process_docx, [f for f in os.listdir(path) if f.endswith(".docx")])
426
-
427
-
428
-
429
- return list(results)
430
-
431
-
432
- all_sentences = load_and_process_documents(folder_path)
433
-
434
- def clean_text(text):
435
- cleaned_text = re.sub(r'[^آ-ی۰-۹0-9،.؟!؛+\-* ]+', '', text)
436
-
437
- return cleaned_text
438
-
439
-
440
- # all_sentences = load_and_process_documents(folder_path)
441
- # st.markdown(all_sentences[2])
442
-
443
- # ---------- ورودی جستجو ----------
444
- st.markdown("""
445
- <style>
446
- /* استایل برای کلاس خاص st-emotion-cache-128upt6 eht7o1d3 */
447
- .st-emotion-cache-128upt6.eht7o1d3 {
448
- background-color: rgba(46,59,46, 0.8) !important; /* سبز تیره (44533f) */
449
- border-radius: 10px !important; /* گوشه‌های گرد */
450
- color: #d4d4d4 !important; /* رنگ متن روشن */
451
- font-family: 'Vazirmatn', Tahoma, sans-serif !important;
452
- padding: 15px !important; /* فضای داخلی بیشتر */
453
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
454
- }
455
- </style>
456
- """, unsafe_allow_html=True)
457
-
458
-
459
- st.markdown("""
460
- <style>
461
- .st-af.st-ah.st-bb.st-ar.st-as.st-ax.st-ay.st-az.st-b0.st-b1.st-b2.st-bc.st-b7 {
462
- background-color: #3a5338 !important;
463
- color: #d4d4d4 !important;
464
- border: 1px solid #c8a200 !important;
465
- border-radius: 10px;
466
- padding: 15px;
467
- }
468
- </style>
469
- """, unsafe_allow_html=True)
470
-
471
- st.markdown("""
472
- <style>
473
- /* استایل برای کلاس st-emotion-cache-yd4u6l e1togvvn1 */
474
- .st-emotion-cache-yd4u6l.e1togvvn1 {
475
- background-color: rgba(106, 127, 83, 0.8) !important; /* سبز خاکی مایل به زرد (#6a7f53) */
476
- border-radius: 10px !important; /* گوشه‌های گرد */
477
- color: #d4d4d4 !important; /* رنگ متن روشن */
478
- font-family: 'Vazirmatn', Tahoma, sans-serif !important;
479
- padding: 15px !important; /* فضای داخلی بیشتر */
480
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
481
- }
482
- </style>
483
- """, unsafe_allow_html=True)
484
- st.markdown("""
485
- <style>
486
- /* استایل برای هدر */
487
- .stAppHeader.st-emotion-cache-12fmjuu.e4hpqof0 {
488
- background-color: rgba(42, 55, 39, 0.9) !important; /* سبز تیره‌تر */
489
- color: #d4d4d4 !important; /* رنگ متن روشن */
490
- font-family: 'Vazirmatn', Tahoma, sans-serif !important;
491
- padding: 20px !important; /* فضای داخلی بیشتر */
492
- border-radius: 10px !important; /* گوشه‌های گرد */
493
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
494
- }
495
- </style>
496
- """, unsafe_allow_html=True)
497
-
498
- st.markdown("""
499
- <style>
500
- /* تغییر رنگ متن placeholder به خاکستری */
501
- textarea::placeholder {
502
- color: #ffffff !important; /* خاکستری */
503
- opacity: 1 !important; /* برای اینکه مرورگرها بهش بی‌توجه نباشن */
504
  }
505
- /* تغییر رنگ متن داخل چت اینپوت به خاکستری */
506
- textarea {
507
- color: #ffffff !important; /* خاکستری */
508
- border-radius: 10px !important;
509
- padding: 10px !important;
510
  }
511
- </style>
512
- """, unsafe_allow_html=True)
513
- query = st.chat_input("چطور می‌تونم کمک کنم؟")
514
-
515
-
516
- if query:
517
- st.markdown(f'<div class="chat-message">{query}</div>', unsafe_allow_html=True)
518
-
519
- think = st.markdown("""
520
- <div class="thinking-message">
521
- <p>در حال فکر کردن...</p>
522
- <div class="spinner"></div>
523
- </div>
524
- """, unsafe_allow_html=True)
525
-
526
- else:
527
- st.markdown("")
528
-
529
- # استایل‌ها برای چرخش و پیام در حال فکر کردن
530
- st.markdown("""
531
- <style>
532
- .thinking-message {
533
- display: flex;
534
- align-items: center;
535
- font-size: 18px;
536
- color: #ffffff;
537
- }
538
-
539
- .thinking-message p {
540
- margin-right: 10px;
541
- }
542
-
543
- .spinner {
544
- border: 4px solid #f3f3f3;
545
- border-top: 4px solid #4b6d3d; /* رنگ سبز تیره */
546
- border-radius: 50%;
547
- width: 20px;
548
- height: 20px;
549
- animation: spin 2s linear infinite;
550
- }
551
-
552
- @keyframes spin {
553
- 0% { transform: rotate(0deg); }
554
- 100% { transform: rotate(360deg); }
555
- }
556
- </style>
557
- """, unsafe_allow_html=True)
558
-
559
-
560
-
561
- if query:
562
- found = False
563
- threshold = 62
564
-
565
- for idx, sentence in enumerate(all_sentences):
566
- similarity = fuzz.partial_ratio(query, sentence)
567
- if similarity >= threshold:
568
- prompt = f"""
569
- تعدادی پاسخ برای سوال زیر تولید شده است. لطفاً ابتدا این پاسخ‌ها را بررسی کن، سپس با در نظر گرفتن محتوای سوال و لحن آن، یک پاسخ نهایی حرفه‌ای، دقیق و روان ارائه کن که هم به سوال پاسخ دهد و هم از نظر نگارشی و ساختاری در سطح بالایی باشد. پاسخ نهایی باید حداکثر 1024 کاراکتر و حداقل 512 باشد، خلاصه و واضح نوشته شود و فقط به زبان فارسی باشد. از تکرار اضافی پرهیز کن و محتوای چند پاسخ را در صورت نیاز با هم ترکیب کن.
570
-
571
- سوال:
572
- {query}
573
-
574
- پاسخ‌ها:
575
- {sentence}
576
-
577
- پاسخ نهایی حرفه‌ای بازنویسی‌شده:
578
- """
579
- response = llm([
580
- SystemMessage(content="You are a helpful assistant."),
581
- HumanMessage(content=prompt)
582
- ])
583
- rewritten = response.content.strip()
584
-
585
- # بررسی مرتبط بودن پاسخ با سؤال
586
- review_prompt = f"""
587
- لطفاً بررسی کن که آیا پاسخ زیر، حدودا به سوال زیر پاسخ داده است یا خیر یعنی کلمات کلیدی اصلی در سوال در پاسخ هست یا ن . اگر پاسخ به سوال مرتبط، درست و قابل قبول است، فقط بنویس: 'تأیید شدواگر کمی مربوط بود بنویس: 'کمی خوب''.
588
- اگر پاسخ اشتباه است یا هیچ ربطی به سوال ندارد، فقط بنویس: 'نیاز به اصلاح دارد'.
589
-
590
- سوال:
591
- {query}
592
-
593
- پاسخ:
594
- {rewritten}
595
- """
596
- review_response = llm([
597
- SystemMessage(content="You are a helpful assistant."),
598
- HumanMessage(content=review_prompt)
599
- ])
600
- review_result = review_response.content.strip()
601
- if "تأیید شد" in review_result:
602
- rewritten = clean_text(rewritten)
603
- st.markdown(f'<div class="chat-message">{rewritten}</div>', unsafe_allow_html=True)
604
- elif "کمی خوب" in review_result:
605
- final_prompt = f"""
606
- لطفاً برای سوال زیر پاسخی حرفه‌ای، دقیق و روان تولید کن که مرتبط و معتبر باشد. از زبانی جز فارسی استفاده نکن و بیا هم از سوال هم دیتای زیر و هم از پاسخ استفاده کن و پاسخ مناسبی بنویس :
607
-
608
- سوال:
609
- {query}
610
- پاسخ:
611
- {review_result}
612
- دیتا:
613
- {rewritten}
614
-
615
- """
616
- new_1response = llm([
617
- SystemMessage(content="You are a helpful assistant."),
618
- HumanMessage(content=final_prompt)
619
- ])
620
- final_answer1 = new_1response.content.strip()
621
- final_answer1 = clean_text(final_answer1)
622
- st.markdown(f'<div class="chat-message">{final_answer1}</div>', unsafe_allow_html=True)
623
-
624
- else:
625
- final_prompt = f"""
626
- لطفاً برای سوال زیر پاسخی حرفه‌ای، دقیق و روان تولید کن که مرتبط و معتبر باشد. از زبانی جز فارسی استفاده نکن :
627
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
  سوال:
629
  {query}
 
 
 
630
  """
631
- new_response = llm([
632
- SystemMessage(content="You are a helpful assistant."),
633
- HumanMessage(content=final_prompt)
634
- ])
635
- final_answer = new_response.content.strip()
636
- final_answer = clean_text(final_answer)
637
- st.markdown(f'<div class="chat-message">{final_answer}</div>', unsafe_allow_html=True)
638
-
639
- think.empty()
640
- found = True
641
- break
642
-
643
- if not found:
644
- prompt = f"لطفاً بر اساس سوال زیر یک متن مرتبط و معنادار تولید کن و از خودت ننویس و جملات معتبر باشن و از زبانی جز فارسی استفاده نکن:\n\nسوال: {query}"
645
- response = llm([
646
- SystemMessage(content="You are a helpful assistant."),
647
- HumanMessage(content=prompt)
648
- ])
649
- rewritten = response.content.strip()
 
 
650
  rewritten = clean_text(rewritten)
651
  st.markdown(f'<div class="chat-message">{rewritten}</div>', unsafe_allow_html=True)
652
- think.empty()
653
-
654
- elif page == "گزارش عملیاتی":
655
- st.success("📊 اینجا گزارش عملیاتی نمایش داده می‌شود.")
656
- st.info("🔍 لطفاً گزارش روزانه را بررسی کنید.")
657
-
658
- elif page == "تاریخچه ماموریت‌ها":
659
- st.info("🕒 تاریخچه ماموریت‌ها در این بخش قابل مشاهده است.")
660
- st.warning("⚠️ برخی ماموریت‌ها هنوز تکمیل نشده‌اند.")
661
-
662
- elif page == "تحلیل داده‌های نظامی":
663
- st.warning("📈 تحلیل داده‌های نظامی اینجا نمایش داده می‌شود.")
664
- st.success("✅ آخرین داده‌های شناسایی با موفقیت بارگذاری شد.")
665
-
666
- elif page == "مدیریت منابع":
667
- st.write("⚙️ مدیریت منابع سازمان در این صفحه انجام می‌شود.")
668
- st.info("💡 موجودی انبار به‌روزرسانی شده است.")
669
-
670
- elif page == "دستیار فرماندهی":
671
- st.write("🤖 این بخش مربوط به دستیار فرماندهی است.")
672
- st.success("👨‍✈️ دستیار آماده دریافت دستور است.")
673
-
674
- elif page == "تنظیمات امنیتی":
675
- st.error("🔒 تنظیمات امنیتی سیستم در این صفحه انجام می‌شود.")
676
- st.info("🧠 لطفاً رمز عبور را به‌صورت دوره‌ای تغییر دهید.")
677
-
678
- elif page == "پشتیبانی فنی":
679
- st.write("🛠️ با پشتیبانی فنی در این بخش در ارتباط باشید.")
680
- st.success("☎️ تیم پشتیبانی آماده پاسخگویی است.")
681
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  import re
14
  import nltk
15
  nltk.download('punkt')
16
+
17
+ st.markdown("""
18
+ <style>
19
+ /* استایل برای هدر */
20
+ .stAppHeader.st-emotion-cache-12fmjuu.e4hpqof0 {
21
+ background-color: rgba(46,59,46, 0.8) !important; /* سبز متمایل به خاکی */
22
+ color: #2e3b2e !important; /* رنگ متن روشن */
23
+ font-family: 'Vazirmatn', Tahoma, sans-serif !important;
24
+ padding: 20px !important; /* فضای داخلی بیشتر */
25
+ border-radius: 10px !important; /* گوشه‌های گرد */
26
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
27
+ }
28
+ </style>
29
+ """, unsafe_allow_html=True)
30
+ st.markdown("""
31
+ <style>
32
+ /* بارگذاری فونت Roboto */
33
+ @font-face {
34
+ font-family: 'Roboto';
35
+ src: url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap') format('woff2');
36
+ font-weight: 400;
37
+ font-style: normal;
38
+ }
39
+ /* تنظیم فونت برای کل سایت */
40
+ html, body, [class*="css"] {
41
+ font-family: 'Roboto', Tahoma, sans-serif !important;
42
+ font-weight: 400 !important;
43
+ direction: rtl;
44
+ text-align: right;
45
+ ظ color: #ffffff;
46
+ }
47
+ /* طراحی برای بخش استایل اپ */
48
+ .stApp {
49
+ background: linear-gradient(to left, #4b5e40, #2e3b2e);
50
+ color: #ffffff;
51
+ }
52
+ /* استایل برای سایدبار */
53
+ [data-testid="stSidebar"] {
54
+ width: 260px !important;
55
+ background-color: #1a2b1e;
56
+ border: none !important;
57
+ padding-top: 20px;
58
+ }
59
+ /* استایل برای آیتم‌های منو */
60
+ .menu-item {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 12px;
64
+ padding: 12px 20px;
65
+ font-size: 16px;
66
+ font-weight: 600;
67
+ color: #d4d4d4;
68
+ cursor: pointer;
69
+ transition: background-color 0.3s ease;
70
+ }
71
+ /* استایل برای آیتم‌های منو هنگام هاور */
72
+ .menu-item:hover {
73
+ background-color: #2e3b2e;
74
+ color: #b8860b;
75
+ }
76
+ /* استایل برای آیکون‌ها در منو */
77
+ .menu-item img {
78
+ width: 25px;
79
+ height: 25px;
80
+ }
81
+ /* استایل برای دکمه‌ها */
82
+ .stButton>button {
83
+ background-color: #b8860b !important;
84
+ color: #1a2b1e !important;
85
+ font-family: 'Roboto', Tahoma, sans-serif;
86
+ font-weight: 700 !important;
87
+ border-radius: 10px;
88
+ padding: 12px 24px;
89
+ border: none;
90
+ transition: all 0.3s ease;
91
+ font-size: 16px;
92
+ width: 100%;
93
+ margin: 10px 0;
94
+ }
95
+ /* استایل برای دکمه‌ها هنگام هاور */
96
+ .stButton>button:hover {
97
+ background-color: #8b6508 !important;
98
+ transform: translateY(-2px);
99
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
100
+ }
101
+ /* استایل برای متن هدر */
102
+ .header-text {
103
+ text-align: center;
104
+ margin: 20px 0;
105
+ background-color: rgba(26, 43, 30, 0.9);
106
+ padding: 25px;
107
+ border-radius: 15px;
108
+ box-shadow: 0 6px 12px rgba(0,0,0,0.4);
109
+ font-family: 'Roboto', Tahoma, sans-serif; /* اضافه شد */
110
+ }
111
+ /* استایل برای زیرنویس */
112
+ .subtitle {
113
+ font-size: 18px;
114
+ color: #d4d4d4;
115
+ font-weight: 600;
116
+ margin-top: 10px;
117
+ }
118
+ /* استایل برای پیام‌های چت */
119
+ .chat-message {
120
+ flex-wrap: wrap;
121
+ background-color: rgba(26, 43, 30, 0.95);
122
+ border: 2px solid #b8860b;
123
+ border-radius: 15px;
124
+ padding: 20px;
125
+ margin: 15px 0;
126
+ box-shadow: 0 6px 12px rgba(0,0,0,0.3);
127
+ animation: fadeIn 0.6s ease;
128
+ font-size: 18px;
129
+ color: #d4d4d4;
130
+ font-weight: 600;
131
+ display: flex;
132
+ flex-wrap: wrap;
133
+ align-items: center;
134
+ gap: 15px;
135
+ }
136
+ /* انیمیشن برای ورود پیام چت */
137
+ @keyframes fadeIn {
138
+ from { opacity: 0; transform: translateY(10px); }
139
+ to { opacity: 1; transform: translateY(0); }
140
+ }
141
+ /* استایل برای ورودی متن */
142
+ .stTextInput>div>input, .stTextArea textarea {
143
+ background-color: rgba(26, 43, 30, 0.95) !important;
144
+ border-radius: 10px !important;
145
+ border: 1px solid #b8860b !important;
146
+ padding: 12px !important;
147
+ font-family: 'Roboto', Tahoma;
148
+ font-weight: 500;
149
+ font-size: 16px;
150
+ color: #d4d4d4 !important;
151
+ }
152
+ /* استایل برای خط افقی */
153
+ hr {
154
+ border: 1px solid #b8860b;
155
+ margin: 15px 0;
156
+ }
157
+ /* حذف مرز از قسمت سایدبار */
158
+ [data-testid="stSidebar"] > div {
159
+ border: none !important;
160
+ }
161
+ </style>
162
+ """, unsafe_allow_html=True)
163
+
164
+
165
+ # ---------- احراز هویت ----------
166
+ if "authenticated" not in st.session_state:
167
+ st.session_state.authenticated = False
168
+
169
+ if not st.session_state.authenticated:
170
+ st.markdown('<style>.stTextInput > div[data-baseweb="input"] + div, .stTextInput div:has(div[role="alert"]) { display: none !important; }</style>', unsafe_allow_html=True)
171
+ st.markdown("""
172
+ <style>
173
+ input {
174
+ background-color: #2e3b2e;
175
+ color: gold;
176
+ border: 1px solid gold;
177
+ border-radius: 10px;
178
+ padding: 10px;
179
+ }
180
+ </style>
181
+ """, unsafe_allow_html=True)
182
+ st.markdown("""
183
+ <style>
184
+ /* فونت عمومی */
185
+ html, body, [class*="css"] {
186
+ font-family: 'Vazir', sans-serif;
187
+ }
188
+ /* استایل برای برچسب فیلدهای ورودی */
189
+ label {
190
+ font-size: 20px !important;
191
+ color: #ffffff !important;
192
+ font-weight: 800 !important;
193
+ margin-bottom: 10px !important;
194
+ display: block;
195
+ }
196
+ /* استایل برای ورودی‌ها */
197
+ input[type="text"], input[type="password"] {
198
+ background-color: #ffffff !important;
199
+ color: #f8f8f8 !important;
200
+ font-size: 18px !important;
201
+ font-family: 'Vazir', sans-serif !important;
202
+
203
+ /* Placeholder style */
204
+ ::placeholder {
205
+ color: #bbbbbb !important;
206
+ opacity: 0.8 !important;
207
+ font-size: 16px;
208
+ }
209
+ </style>
210
+ """, unsafe_allow_html=True)
211
+ username = st.text_input("نام کاربری:", placeholder="شناسه خود را وارد کنید",
212
+ label_visibility="visible")
213
+
214
+ password = st.text_input("رمز عبور:", placeholder="رمز عبور ", type="password",
215
+ label_visibility="visible")
216
+ st.markdown("""
217
+ <style>
218
+ div.stButton > button {
219
+ background-image: url("https://upload.wikimedia.org/wikipedia/commons/5/59/US_Army_Universal_Camouflage_Pattern.jpg");
220
+ background-size: cover;
221
+ background-repeat: no-repeat;
222
+ background-position: center;
223
+ color: #f5deb3;
224
+ font-family: 'Vazir', sans-serif;
225
+ font-size: 20px;
226
+ font-weight: bold;
227
+ padding: 14px 35px;
228
+ border: 2px solid #d4af37;
229
+ border-radius: 14px;
230
+ box-shadow: 0 0 18px rgba(0,0,0,0.6);
231
+ transition: all 0.3s ease-in-out;
232
+ }
233
+ div.stButton > button:hover {
234
+ filter: brightness(1.2);
235
+ box-shadow: 0 0 22px #b8860b;
236
+ transform: scale(1.03);
237
+ }
238
+ div.stButton > button:active {
239
+ transform: scale(0.97);
240
+ box-shadow: 0 0 12px #000;
241
+ }
242
+ </style>
243
+ """, unsafe_allow_html=True)
244
+
245
+ if st.button("ورود"):
246
+ if username == "admin" and password == "123":
247
+ st.session_state.authenticated = True
248
+ st.rerun()
249
+ else:
250
+ st.markdown("""
251
+ <div style="background-color: rgba(241, 196, 15, 0.6); color: #2e3b2e; padding: 10px; border-radius: 10px; border: 2px solid #2e3b2e; margin-top: 20px; text-align: center; backdrop-filter: blur(5px);">
252
+ نام کاربری یا رمز عبور اشتباه است.
253
+ </div>
254
+ """, unsafe_allow_html=True)
255
+ st.stop()
256
+
257
+ # ---------- سایدبار ----------
258
+ with st.sidebar:
259
+ st.image("log.png", use_container_width=True)
260
+ menu_items = [
261
+ ("گزارش عملیاتی", "https://cdn-icons-png.flaticon.com/512/3596/3596165.png"),
262
+ ("تاریخچه ماموریت‌ها", "https://cdn-icons-png.flaticon.com/512/709/709496.png"),
263
+ ("تحلیل داده‌های نظامی", "https://cdn-icons-png.flaticon.com/512/1828/1828932.png"),
264
+ ("مدیریت منابع", "https://cdn-icons-png.flaticon.com/512/681/681494.png"),
265
+ ("دستیار فرماندهی", "https://cdn-icons-png.flaticon.com/512/3601/3601646.png"),
266
+ ("تنظیمات امنیتی", "https://cdn-icons-png.flaticon.com/512/2099/2099058.png"),
267
+ ("پشتیبانی فنی", "https://cdn-icons-png.flaticon.com/512/597/597177.png"),
268
+ ]
269
+ for idx, (text, icon) in enumerate(menu_items):
270
+ st.markdown(f"""
271
+ <div class="menu-item">
272
+ <img src="{icon}" />
273
+ {text}
274
+ </div>
275
  """, unsafe_allow_html=True)
276
+ if idx in [1, 3, 5]:
277
+ st.markdown("<hr/>", unsafe_allow_html=True)
278
+
279
+ st.markdown("""
280
+ <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  /* استایل برای متن هدر */
282
  .header-text {
283
  text-align: center;
284
+ margin: 50px 0;
285
+ background: #2e3b2e; /* سبز زیتونی تیره جدید */
286
+ padding: 60px 30px;
287
+ border-radius: 25px;
288
+ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.8); /* سایه بیشتر */
289
+ animation: slideIn 2s ease-in-out, fadeIn 3s ease-in-out;
290
+ background-size: cover;
291
+ background-position: center;
292
+ position: relative;
293
+ }
294
+ /* انیمیشن ورودی */
295
+ @keyframes fadeIn {
296
+ 0% { opacity: 0; transform: translateY(30px); }
297
+ 100% { opacity: 1; transform: translateY(0); }
298
+ }
299
+ @keyframes slideIn {
300
+ 0% { transform: translateX(-50%); opacity: 0; }
301
+ 100% { transform: translateX(0); opacity: 1; }
302
+ }
303
+ /* تغییر فونت برای h1 */
304
+ .header-text h1 {
305
+ font-family: 'Vazir', sans-serif;
306
+ font-size: 62px;
307
+ color: #d89b00; /* طلایی تیره‌تر */
308
+ margin: 0;
309
+ font-weight: 900;
310
+ letter-spacing: 4px;
311
+ text-shadow: 4px 4px 15px rgba(0, 0, 0, 0.9); /* سایه سیاه بیشتر */
312
+ transform: scale(1.08); /* کمی بزرگتر شدن */
313
+ animation: glow 2s ease-in-out infinite alternate;
314
+ }
315
+ /* تغییر استایل زیرعنوان */
316
+ .subtitle {
317
+ font-family: 'Vazir', sans-serif;
318
+ font-size: 24px;
319
+ color: #f8f8f8;
320
+ font-weight: 700;
321
+ margin-top: 15px;
322
+ letter-spacing: 2px;
323
+ text-shadow: 3px 3px 10px rgba(0,0,0,0.8); /* سایه بیشتر برای زیرعنوان */
324
+ animation: fadeInSubtitle 2s ease-in-out;
325
+ }
326
+ /* انیمیشن زیرعنوان */
327
+ @keyframes fadeInSubtitle {
328
+ 0% { opacity: 0; transform: translateY(20px); }
329
+ 100% { opacity: 1; transform: translateY(0); }
330
+ }
331
+ /* استایل برای دکمه‌ها */
332
+ .stButton>button {
333
+ background-color: #e67e22 !important; /* رنگ دکمه تغییر کرده */
334
+ color: #4b5320 !important;
335
+ font-family: 'Vazir', sans-serif;
336
+ font-weight: 700 !important;
337
+ border-radius: 20px;
338
+ padding: 15px 30px;
339
+ border: none;
340
+ transition: all 0.3s ease;
341
+ font-size: 18px;
342
+ width: 100%;
343
  margin: 20px 0;
344
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
 
 
 
 
345
  }
346
+ .stButton>button:hover {
347
+ background-color: #f39c12 !important;
348
+ transform: translateY(-4px);
349
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.6);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  }
351
+ /* استایل برای استایل کلی صفحه */
352
+ .stApp {
353
+ background: #2e3b2e; /* سبز زیتونی تیره جدید */
354
+ color: white;
355
+ font-family: 'Vazir', sans-serif;
356
  }
357
+ </style>
358
+ <div class="header-text">
359
+ <h1>رزم‌ یار ارتش</h1>
360
+ <div class="subtitle">دستیار هوشمند ارتش جمهوری اسلامی ایران</div>
361
+ </div>
362
+ """, unsafe_allow_html=True)
363
+
364
+ # ---------- مدل زبانی ----------
365
+ llm = ChatOpenAI(
366
+ base_url="https://api.together.xyz/v1",
367
+ api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
368
+ model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
369
+ max_tokens=1024
370
+ )
371
+
372
+ # ---------- پردازش فایل‌ها با کش و موازی ----------
373
+ folder_path = '46'
374
+ normalizer = Normalizer()
375
+ sentence_tokenizer = SentenceTokenizer()
376
+
377
+ @st.cache_data(show_spinner="در حال پردازش اسناد... لطفاً صبور باشید.")
378
+ def load_and_process_documents(path):
379
+ def process_docx(filename):
380
+ try:
381
+ full_path = os.path.join(path, filename)
382
+ doc = docx.Document(full_path)
383
+ text = "\n".join([para.text for para in doc.paragraphs]) # استخراج متن
384
+ normalized = normalizer.normalize(text)
385
+ sentences = normalized
386
+ return sentences
387
+ except Exception as e:
388
+ print(f"Error processing {filename}: {e}")
389
+ return []
390
+ with concurrent.futures.ThreadPoolExecutor() as executor:
391
+ results = executor.map(process_docx, [f for f in os.listdir(path) if f.endswith(".docx")])
392
+
393
+
394
+
395
+ return list(results)
396
+
397
+
398
+ all_sentences = load_and_process_documents(folder_path)
399
+
400
+ def clean_text(text):
401
+ cleaned_text = re.sub(r'[^آ-ی۰-۹0-9،.؟!؛+\-* ]+', '', text)
402
+
403
+ return cleaned_text
404
+
405
+
406
+ # all_sentences = load_and_process_documents(folder_path)
407
+ # st.markdown(all_sentences[2])
408
+
409
+ # ---------- ورودی جستجو ----------
410
+ st.markdown("""
411
+ <style>
412
+ /* استایل برای کلاس خاص st-emotion-cache-128upt6 eht7o1d3 */
413
+ .st-emotion-cache-128upt6.eht7o1d3 {
414
+ background-color: rgba(46,59,46, 0.8) !important; /* سبز تیره (44533f) */
415
+ border-radius: 10px !important; /* گوشه‌های گرد */
416
+ color: #d4d4d4 !important; /* رنگ متن روشن */
417
+ font-family: 'Vazirmatn', Tahoma, sans-serif !important;
418
+ padding: 15px !important; /* فضای داخلی بیشتر */
419
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
420
+ }
421
+ </style>
422
+ """, unsafe_allow_html=True)
423
+
424
+
425
+ st.markdown("""
426
+ <style>
427
+ .st-af.st-ah.st-bb.st-ar.st-as.st-ax.st-ay.st-az.st-b0.st-b1.st-b2.st-bc.st-b7 {
428
+ background-color: #3a5338 !important;
429
+ color: #d4d4d4 !important;
430
+ border: 1px solid #c8a200 !important;
431
+ border-radius: 10px;
432
+ padding: 15px;
433
+ }
434
+ </style>
435
+ """, unsafe_allow_html=True)
436
+
437
+ st.markdown("""
438
+ <style>
439
+ /* استایل برای کلاس st-emotion-cache-yd4u6l e1togvvn1 */
440
+ .st-emotion-cache-yd4u6l.e1togvvn1 {
441
+ background-color: rgba(106, 127, 83, 0.8) !important; /* سبز خاکی مایل به زرد (#6a7f53) */
442
+ border-radius: 10px !important; /* گوشه‌های گرد */
443
+ color: #d4d4d4 !important; /* رنگ متن روشن */
444
+ font-family: 'Vazirmatn', Tahoma, sans-serif !important;
445
+ padding: 15px !important; /* فضای داخلی بیشتر */
446
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
447
+ }
448
+ </style>
449
+ """, unsafe_allow_html=True)
450
+ st.markdown("""
451
+ <style>
452
+ /* استایل برای هدر */
453
+ .stAppHeader.st-emotion-cache-12fmjuu.e4hpqof0 {
454
+ background-color: rgba(42, 55, 39, 0.9) !important; /* سبز تیره‌تر */
455
+ color: #d4d4d4 !important; /* رنگ متن روشن */
456
+ font-family: 'Vazirmatn', Tahoma, sans-serif !important;
457
+ padding: 20px !important; /* فضای داخلی بیشتر */
458
+ border-radius: 10px !important; /* گوشه‌های گرد */
459
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; /* سایه برای برجسته شدن */
460
+ }
461
+ </style>
462
+ """, unsafe_allow_html=True)
463
+
464
+ st.markdown("""
465
+ <style>
466
+ /* تغییر رنگ متن placeholder به خاکستری */
467
+ textarea::placeholder {
468
+ color: #ffffff !important; /* خاکستری */
469
+ opacity: 1 !important; /* برای اینکه مرورگرها بهش بی‌توجه نباشن */
470
+ }
471
+ /* تغییر رنگ متن داخل چت اینپوت به خاکستری */
472
+ textarea {
473
+ color: #ffffff !important; /* خاکستری */
474
+ border-radius: 10px !important;
475
+ padding: 10px !important;
476
+ }
477
+ </style>
478
+ """, unsafe_allow_html=True)
479
+ query = st.chat_input("چطور می‌تونم کمک کنم؟")
480
+
481
+
482
+ if query:
483
+ st.markdown(f'<div class="chat-message">{query}</div>', unsafe_allow_html=True)
484
+
485
+ think = st.markdown("""
486
+ <div class="thinking-message">
487
+ <p>در حال فکر کردن...</p>
488
+ <div class="spinner"></div>
489
+ </div>
490
+ """, unsafe_allow_html=True)
491
+
492
+ else:
493
+ st.markdown("")
494
+
495
+ # استایل‌ها برای چرخش و پیام در حال فکر کردن
496
+ st.markdown("""
497
+ <style>
498
+ .thinking-message {
499
+ display: flex;
500
+ align-items: center;
501
+ font-size: 18px;
502
+ color: #ffffff;
503
+ }
504
+ .thinking-message p {
505
+ margin-right: 10px;
506
+ }
507
+ .spinner {
508
+ border: 4px solid #f3f3f3;
509
+ border-top: 4px solid #4b6d3d; /* رنگ سبز تیره */
510
+ border-radius: 50%;
511
+ width: 20px;
512
+ height: 20px;
513
+ animation: spin 2s linear infinite;
514
+ }
515
+ @keyframes spin {
516
+ 0% { transform: rotate(0deg); }
517
+ 100% { transform: rotate(360deg); }
518
+ }
519
+ </style>
520
+ """, unsafe_allow_html=True)
521
+
522
+
523
+
524
+ if query:
525
+ found = False
526
+ threshold = 62
527
+
528
+ for idx, sentence in enumerate(all_sentences):
529
+ similarity = fuzz.partial_ratio(query, sentence)
530
+ if similarity >= threshold:
531
+ prompt = f"""
532
+ تعدادی پاسخ برای سوال زیر تولید شده است. لطفاً ابتدا این پاسخ‌ها را بررسی کن، سپس با در نظر گرفتن محتوای سوال و لحن آن، یک پاسخ نهایی حرفه‌ای، دقیق و روان ارائه کن که هم به سوال پاسخ دهد و هم از نظر نگارشی و ساختاری در سطح بالایی باشد. پاسخ نهایی باید حداکثر 1024 کاراکتر و حداقل 512 باشد، خلاصه و واضح نوشته شود و فقط به زبان فارسی باشد. از تکرار اضافی پرهیز کن و محتوای چند پاسخ را در صورت نیاز با هم ترکیب کن.
533
  سوال:
534
  {query}
535
+ پاسخ‌ها:
536
+ {sentence}
537
+ پاسخ نهایی حرفه‌ای بازنویسی‌شده:
538
  """
539
+ response = llm([
540
+ SystemMessage(content="You are a helpful assistant."),
541
+ HumanMessage(content=prompt)
542
+ ])
543
+ rewritten = response.content.strip()
544
+
545
+ # بررسی مرتبط بودن پاسخ با سؤال
546
+ review_prompt = f"""
547
+ لطفاً بررسی کن که آیا پاسخ زیر، حدودا به سوال زیر پاسخ داده است یا خیر یعنی کلمات کلیدی اصلی در سوال در پاسخ هست یا ن . اگر پاسخ به سوال مرتبط، درست و قابل قبول است، فقط بنویس: 'تأیید شدواگر کمی مربوط بود بنویس: 'کمی خوب''.
548
+ اگر پاسخ اشتباه است یا هیچ ربطی به سوال ندارد، فقط بنویس: 'نیاز به اصلاح دارد'.
549
+ سوال:
550
+ {query}
551
+ پاسخ:
552
+ {rewritten}
553
+ """
554
+ review_response = llm([
555
+ SystemMessage(content="You are a helpful assistant."),
556
+ HumanMessage(content=review_prompt)
557
+ ])
558
+ review_result = review_response.content.strip()
559
+ if "تأیید شد" in review_result:
560
  rewritten = clean_text(rewritten)
561
  st.markdown(f'<div class="chat-message">{rewritten}</div>', unsafe_allow_html=True)
562
+ elif "کمی خوب" in review_result:
563
+ final_prompt = f"""
564
+ لطفاً برای سوال زیر پاسخی حرفه‌ای، دقیق و روان تولید کن که مرتبط و معتبر باشد. از زبانی جز فارسی استفاده نکن و بیا هم از سوال هم دیتای زیر و هم از پاسخ استفاده کن و پاسخ مناسبی بنویس :
565
+ سوال:
566
+ {query}
567
+ پاسخ:
568
+ {review_result}
569
+ دیتا:
570
+ {rewritten}
571
+ """
572
+ new_1response = llm([
573
+ SystemMessage(content="You are a helpful assistant."),
574
+ HumanMessage(content=final_prompt)
575
+ ])
576
+ final_answer1 = new_1response.content.strip()
577
+ final_answer1 = clean_text(final_answer1)
578
+ st.markdown(f'<div class="chat-message">{final_answer1}</div>', unsafe_allow_html=True)
579
+
580
+ else:
581
+ final_prompt = f"""
582
+ لطفاً برای سوال زیر پاسخی حرفه‌ای، دقیق و روان تولید کن که مرتبط و معتبر باشد. از زبانی جز فارسی استفاده نکن :
583
+ سوال:
584
+ {query}
585
+ """
586
+ new_response = llm([
587
+ SystemMessage(content="You are a helpful assistant."),
588
+ HumanMessage(content=final_prompt)
589
+ ])
590
+ final_answer = new_response.content.strip()
591
+ final_answer = clean_text(final_answer)
592
+ st.markdown(f'<div class="chat-message">{final_answer}</div>', unsafe_allow_html=True)
593
+
594
+ think.empty()
595
+ found = True
596
+ break
597
+
598
+ if not found:
599
+ prompt = f"لطفاً بر اساس سوال زیر یک متن مرتبط و معنادار تولید کن و از خودت ننویس و جملات معتبر باشن و از زبانی جز فارسی استفاده نکن:\n\nسوال: {query}"
600
+ response = llm([
601
+ SystemMessage(content="You are a helpful assistant."),
602
+ HumanMessage(content=prompt)
603
+ ])
604
+ rewritten = response.content.strip()
605
+ rewritten = clean_text(rewritten)
606
+ st.markdown(f'<div class="chat-message">{rewritten}</div>', unsafe_allow_html=True)
607
+ think.empty()