M17idd commited on
Commit
fb96d46
·
1 Parent(s): dc24005

Update app.py

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