import streamlit as st from hazm import Normalizer, SentenceTokenizer import os import docx from langchain.chat_models import ChatOpenAI from langchain.schema import SystemMessage, HumanMessage from rapidfuzz import fuzz import concurrent.futures st.markdown(""" """, unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) # ---------- احراز هویت ---------- if "authenticated" not in st.session_state: st.session_state.authenticated = False if not st.session_state.authenticated: st.markdown('', unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) username = st.text_input("نام کاربری:", placeholder="شناسه نظامی خود را وارد کنید", label_visibility="visible") password = st.text_input("رمز عبور:", placeholder="رمز عبور نظامی", type="password", label_visibility="visible") if st.button("ورود"): if username == "admin" and password == "123": st.session_state.authenticated = True st.rerun() else: st.markdown("""
نام کاربری یا رمز عبور اشتباه است.
""", unsafe_allow_html=True) st.stop() # ---------- سایدبار ---------- with st.sidebar: st.image("log.png", use_container_width=True) menu_items = [ ("گزارش عملیاتی", "https://cdn-icons-png.flaticon.com/512/3596/3596165.png"), ("تاریخچه ماموریت‌ها", "https://cdn-icons-png.flaticon.com/512/709/709496.png"), ("تحلیل داده‌های نظامی", "https://cdn-icons-png.flaticon.com/512/1828/1828932.png"), ("مدیریت منابع", "https://cdn-icons-png.flaticon.com/512/681/681494.png"), ("دستیار فرماندهی", "https://cdn-icons-png.flaticon.com/512/3601/3601646.png"), ("تنظیمات امنیتی", "https://cdn-icons-png.flaticon.com/512/2099/2099058.png"), ("پشتیبانی فنی", "https://cdn-icons-png.flaticon.com/512/597/597177.png"), ] for idx, (text, icon) in enumerate(menu_items): st.markdown(f""" """, unsafe_allow_html=True) if idx in [1, 3, 5]: st.markdown("
", unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) st.markdown("""

رزم‌یار ارتش

دستیار هوشمند ارتش جمهوری اسلامی ایران
""", unsafe_allow_html=True) # ---------- مدل زبانی ---------- llm = ChatOpenAI( base_url="https://api.together.xyz/v1", api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979', model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free" ) # ---------- پردازش فایل‌ها با کش و موازی ---------- folder_path = '46' normalizer = Normalizer() sentence_tokenizer = SentenceTokenizer() @st.cache_data(show_spinner="در حال پردازش اسناد... لطفاً صبور باشید.") def load_and_process_documents(path): def process_docx(filename): try: full_path = os.path.join(path, filename) doc = docx.Document(full_path) file_text = "\n".join([para.text for para in doc.paragraphs]) if file_text.strip(): normalized = normalizer.normalize(file_text) return sentence_tokenizer.tokenize(normalized) except: return [] return [] all_sentences = [] with concurrent.futures.ThreadPoolExecutor() as executor: results = executor.map(process_docx, [f for f in os.listdir(path) if f.endswith(".docx")]) for sentences in results: if sentences: all_sentences.extend(sentences) return all_sentences all_sentences = load_and_process_documents(folder_path) # ---------- ورودی جستجو ---------- st.markdown(""" """, unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) st.markdown(""" """, unsafe_allow_html=True) query = st.chat_input("چطور می‌تونم کمک کنم؟") if query: found = False threshold = 60 for idx, sentence in enumerate(all_sentences): similarity = fuzz.partial_ratio(query, sentence) if similarity >= threshold: next_sentences = [] for i in range(1, 10): if idx + i < len(all_sentences): next_sentences.append(all_sentences[idx + i]) total_text = sentence + " " + " ".join(next_sentences) prompt = f""" تعدادی پاسخ برای سوال زیر تولید شده است. لطفاً ابتدا این پاسخ‌ها را بررسی کن، سپس با در نظر گرفتن محتوای سوال و لحن آن، یک پاسخ نهایی حرفه‌ای، دقیق و روان ارائه کن که هم به سوال پاسخ دهد و هم از نظر نگارشی و ساختاری در سطح بالایی باشد. از تکرار اضافی پرهیز کن و محتوای چند پاسخ را در صورت نیاز با هم ترکیب کن تا بهترین نتیجه حاصل شود. سوال: {query} پاسخ‌ها: {total_text} پاسخ نهایی حرفه‌ای بازنویسی‌شده: """ response = llm([ SystemMessage(content="You are a helpful assistant."), HumanMessage(content=prompt) ]) rewritten = response.content.strip() st.markdown(f'
{rewritten}
', unsafe_allow_html=True) found = True break if not found: prompt = f"لطفاً بر اساس سوال زیر یک متن مرتبط و معنادار تولید کن:\n\nسوال: {query}" response = llm([ SystemMessage(content="You are a helpful assistant."), HumanMessage(content=prompt) ]) rewritten = response.content.strip() st.markdown(f'
{rewritten}
', unsafe_allow_html=True)